Game Management

Specifying game information

iFun Engine uses an App ID to internally identify Apps. A default value is used, but you can change the setting by overriding MANIFEST.json as below.

  • Component name: AppInfo

  • Arguments

    • app_id: A string 128 characters or less containing alpha-numerics, . (period), _ (underscore), and -(dash)

Client version control

iFun Engine provides Server-Client versioning management. For mobile distribution environments using Google Play and Apple App Store, you cannot control the client distribution time exactly.

For example, when a client is updated from version 1.0 to 1.1 and distributed with Google Play, for a period of time, some users will see version 1.0 while others see 1.1. To mitigate this problem, the Server must maintain a version compatibility list.

In the example above, 1.1 is the current version, but 1.0 clients need to be granted access for a period of time. Another approach is to predict the distribution completion time and schedule for server maintenance, but this causes unnecessary server down-time.

Specifying client versions

Refer to here and the following description to set the previous versions compatible with the current version.

  • Component name: AppInfo

  • Arguments

    • client_current_version: Current client version, e.g.) “7”

    • client_compatible_versions: Compatible client versions, e.g.) [“5”, “6”]

    • client_update_info: Freely set the message (only as a string) to be sent to the client when the version is incompatible.

    • client_update_uri: Update URI sent to the client if the version is incompatible.

Example

Let’s look at an example where 5 minutes ago the client version was updated from 15 to 16 and distributed, but a bug was found and version 17 was newly deployed.

iFun Engine game MANIFEST.json configuration

{
  "client_current_version": "17",
  "client_compatible_versions": ["15", "16"],
  "client_update_info": "new version available",
  "client_update_url": "https://play.google.com/store/apps/details?id=com.example.Game1"
}

Source code to check versions in a iFun Engine game

Note

In the future, it is planned for iFun Engine to automatically handle this.

#include <funapi.h>

using namespace fun;


void example() {
  string client_version = "14"; // from client

  if (not AppInfo::client_version().IsCompatible(client_version)) {
    string update_msg = AppInfo::client_version().client_update_info();
    string update_url = AppInfo::client_version().client_update_uri();

    // send update_msg, update_url to the client

    return;
  }

  // ...
}

See here for sending a message to the client.

Server flavors

You may need to run servers with different configurations. In this case, you can leverage the iFun Engine’s server flavor feature.

Let’s say we want to add additional flavors “lobby” and “game”. Then you need to add the following statement in the top-level CMakeLists.txt.

set(APP_FLAVORS lobby game)

Please make sure it appears before include(iFun Engine).

In addition, you should also have MANIFEST.json files for the flavors. src/MANIFEST.lobby.json and src/MANIFEST.game.json in this example. It’s a good idea to copy the default src/MANIFEST.json as a starting point. Once having MANIFEST files for all the flavors you set, make command will create launcher scripts for your flavors. In this example, they will have suffixes like .lobby.local, .lobby.launcher, .game.local, or .game.launcher. These launcher scripts plus your flavor-specific MANIFEST files will be automatically installed and packaged via make install and make package, respectively.

Despite different flavors, please note that we are still sharing the same code base. This means the flavors start from the same server component. To differentiate server flavors in the code, you can leverage app_flavor Google flag. This flag will be automatically set if you run your game server using one of the launcher scripts mentioned above.

Tip

If you are on VisualGDB, you need to adjust the Main executable arguments option of VisualGDB to run a specific flavor. You can find details at development-on-windows-visualgdb-flavor section.

DECLARE_string(app_flavor)

class MyGameServer : public Component {
 public:
  static bool Install(const ArgumentMap &arguments) {
    if (FLAGS_app_flavor == "lobby") {
      // Configure as a lobby server.
    } else if (FLAGS_app_flavor == "game") {
      // Configure as a game server.
    }
  }
}

If you are planning to launch your game automatically via upstart, you may want to put flavor-specific init script and default file under etc/init and etc/default. They will be automatically copied by make install and make package just like the launcher scripts and MANIFEST files.

Tip

If the app_flavor flag is set, the server is automatically tagged by the flag value. Then, you can locate servers of a particular flavor. Please refer to Server Tagging.

Package management

iFun Engine provides a feature to easily package a developed game server. If you use this feature, you don’t need to deal with the hassle and security risk of copying the game server development directory to the real server.

When working with CLion

If you select the make target menu item on the right, select the package target. If you double-click it, the compiled output is packaged in a compress file.

When working with vim and make in the terminal

If you enter make package in the console, the package file is created.

Package file naming convention and version management

The package file is a tar file compressed with gzip, with the extension tgz. The generated file name is projectname_version_install.tgz, and to update the server package version, update the VERSION file described in the Source directory structure section and make the package to automatically update the server package version.

Packaging resource directories

Although the client manages most resources, the server also has cases where resource management is required for logic implementation. (For example, the JSON table for the attributes of game items or the JSON protocol between server and client.) Making the resource directory path identical during development and live service can be hard. (Even though the entire source directory is packaged, when the developer is working under her user ID, the user ID inevitably becomes part of the path. Unless the live server uses the same ID, there will be a problem.)

To mitigate this problem, iFun Engine allows the game developer to specify a resource directory. In the top-level CMakeLists.txt, add the variable RESOURCE_DIRS before include(iFun Engine) like below. set(RESOURCE_DIRS game_data) is the only added part.

1
2
3
4
5
6
project(@project_name@ CXX C)

set(RESOURCE_DIRS game_data)

set(CMAKE_MODULE_PATH "@FUNAPI_ROOT@/share/funapi/cmake")
include(iFun Engine)

If the resource directory is specified, iFun Engine includes the directory when Packaging.

This directory location will be different during development and live service, so to access the directory, you must use the return value of ** fun::GetResRoot()** as in the example below. Now, we have server code that operates identically during development and live service.

string path = GetResRoot() + "/game_data/my_file1";