42. Programming part 3: Program execution parameters

Program configuration in iFun Engine is managed through MANIFEST.json.

Thus, you can send execution parameters by setting them in MANIFEST.json or by adding command line parameters.

42.1. Method 1: Using MANIFEST.json

42.1.1. Adding parameters to MANIFEST.json

Add a JSON property called arguments to MANIFEST.json as follows and define parameters to be used in it.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
{
  "version": 1,

  "components": [
    {
      "name": "MyProjectServer",

      "arguments": {
        "example_arg1": "val1",
        "example_arg2": 100
      },

      "library": "libmy_project.so",

      "dependency": {

        ...

        "SessionService": {
          "tcp_json_port": 8012,
          ...
        },

        ...
      }
    }
  ]
}

42.1.2. Reading parameters from server code

Parameters added to MANIFEST.json are sent when that server’s install function is invoked. The following is an example of reading the above MANIFEST.json.

my_project_server.cc:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
class MyProjectServer : public Component {
 public:
  static bool Install(const ArgumentMap &arguments) {
    LOG(INFO) << "Built using Engine version: " << FUNAPI_BUILD_IDENTIFIER;

    // Kickstarts the Engine's ORM.
    // Do not touch this, unless you fully understand what you are doing.
    my_project::ObjectModelInit();

    /*
     * Parameters specified in the "arguments" section in your MANIFEST.json
     * will be passed in the variable "arguments".
     * So, you can give configuration data to your game server.
     *
     * Example:
     *
     * We have in MANIFEST.json "example_arg1" and "example_arg2" that
     * have a string value and an integer value, respectively.
     * So, you can access the arguments like below:
     */
    string arg1 = arguments.FindStringArgument("example_arg1");
    LOG(INFO) << "example_arg1: " << arg1;

    int64_t arg2 = arguments.FindIntegerArgument("example_arg2");
    LOG(INFO) << "example_arg2: " << arg2;

     // You can override gflag like this: ./my_project-local --example_arg3=hahaha
    LOG(INFO) << "example_arg3: " << FLAGS_example_arg3;


    /*
     * Registers various handlers.
     * You may be interesed in this function and handlers in it.
     * Please see "event_handlers.cc"
     */
    my_project::RegisterEventHandlers();

    return true;
  }
}

server.cs:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
namespace MyProject
{
  public class Server
  {
    public static void Install(ArgumentMap arguments)
    {
      // Session open, close handlers.
      NetworkHandlerRegistry.RegisterSessionHandler (
        new NetworkHandlerRegistry.SessionOpenedHandler (OnSessionOpened),
        new NetworkHandlerRegistry.SessionClosedHandler (OnSessionClosed));

      // "echo" message handler for JSON type.
      NetworkHandlerRegistry.RegisterMessageHandler ("echo", new NetworkHandlerRegistry.JsonMessageHandler (OnEcho));

      // "echo_pbuf" message handler for Google Protocol Buffers.
      NetworkHandlerRegistry.RegisterMessageHandler ("echo_pbuf", new NetworkHandlerRegistry.ProtobufMessageHandler (OnEchoPbuf));

      // Parameters specified in the "arguments" section in your MANIFEST.json
      // will be passed in the variable "arguments".
      // So, you can give configuration data to your game server.
      //
      // Example:
      //
      // We have in MANIFEST.json "example_arg1" and "example_arg2" that
      // have a string value and an integer value, respectively.
      // So, you can access the arguments like below:
      string arg1 = arguments.FindString ("example_arg1");
      Log.Info ("example_arg1: {0}", arg1);

      Int64 arg2 = arguments.FindInteger ("example_arg2");
      Log.Info ("example_arg2: {0}", arg2);

      // You can override gflag like this: ./mono-local --example_arg3=hahaha
      Log.Info("example_arg3: {0}", Flags.GetString ("example_arg3"));

      // Registers a timer.
      //
      // Below demonstrates a repeating timer. One-shot timer is also available.
      // Please see the Timer class.
      Timer.ExpireRepeatedly(WallClock.FromSec(1), OnTick);
    }
  }
}

42.2. Method 2: Adding with Google Flag

42.2.1. Adding Google Flag

Use Google Gflag to define the execution parameters to be used in the code first.

Functions used at this time are as follows:

DEFINE_bool boolean
DEFINE_int32 32-bit integer
DEFINE_int64 64-bit integer
DEFINE_uint64 unsigned 64-bit integer
DEFINE_double double
DEFINE_string C++ string

An example follows.

DEFINE_string(my_arg1, "기본값", "my_arg1에 대한 설명");

Note

For C#, you need to add as C++ code to src/{{project_name}}_server.cc, not mono/server.cs.

42.2.2. Reading flags in server code

If this flag is needed, you can declare the flag as a function called DECLARE_XYZ() matchingDEFINE_XYZ() and use the name FLAGS_XYZ in the code.

DECLARE_XYZ() functions that can be used are as follows.

DECLARE_bool boolean
DECLARE_int32 32-bit integer
DECLARE_int64 64-bit integer
DECLARE_uint64 unsigned 64-bit integer
DECLARE_double double
DECLARE_string C++ string

my_project_server.cc:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// You can differentiate game server flavors.
DECLARE_string(example_arg3);

class MyProjectServer : public Component {
 public:
  static bool Install(const ArgumentMap &arguments) {
    LOG(INFO) << "Built using Engine version: " << FUNAPI_BUILD_IDENTIFIER;

    // Kickstarts the Engine's ORM.
    // Do not touch this, unless you fully understand what you are doing.
    my_project::ObjectModelInit();

    /*
     * Parameters specified in the "arguments" section in your MANIFEST.json
     * will be passed in the variable "arguments".
     * So, you can give configuration data to your game server.
     *
     * Example:
     *
     * We have in MANIFEST.json "example_arg1" and "example_arg2" that
     * have a string value and an integer value, respectively.
     * So, you can access the arguments like below:
     */
    string arg1 = arguments.FindStringArgument("example_arg1");
    LOG(INFO) << "example_arg1: " << arg1;

    int64_t arg2 = arguments.FindIntegerArgument("example_arg2");
    LOG(INFO) << "example_arg2: " << arg2;

     // You can override gflag like this: ./my_project-local --example_arg3=hahaha
    LOG(INFO) << "example_arg3: " << FLAGS_example_arg3;


    /*
     * Registers various handlers.
     * You may be interesed in this function and handlers in it.
     * Please see "event_handlers.cc"
     */
    my_project::RegisterEventHandlers();

    return true;
  }
}

If this flag is needed, values can be read in Flags.GetString(“XYZ”) form.

Functions that can be gotten for each type are as follows.

GetBool boolean
GetInt32 32-bit integer
GetInt64 64-bit integer
GetUInt64 unsigned 64-bit integer
GetDouble double
GetString C# string

server.cs:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
namespace MyProject
{
  public class Server
  {
    public static void Install(ArgumentMap arguments)
    {
      // Session open, close handlers.
      NetworkHandlerRegistry.RegisterSessionHandler (
        new NetworkHandlerRegistry.SessionOpenedHandler (OnSessionOpened),
        new NetworkHandlerRegistry.SessionClosedHandler (OnSessionClosed));

      // "echo" message handler for JSON type.
      NetworkHandlerRegistry.RegisterMessageHandler ("echo", new NetworkHandlerRegistry.JsonMessageHandler (OnEcho));

      // "echo_pbuf" message handler for Google Protocol Buffers.
      NetworkHandlerRegistry.RegisterMessageHandler ("echo_pbuf", new NetworkHandlerRegistry.ProtobufMessageHandler (OnEchoPbuf));

      // Parameters specified in the "arguments" section in your MANIFEST.json
      // will be passed in the variable "arguments".
      // So, you can give configuration data to your game server.
      //
      // Example:
      //
      // We have in MANIFEST.json "example_arg1" and "example_arg2" that
      // have a string value and an integer value, respectively.
      // So, you can access the arguments like below:
      string arg1 = arguments.FindString ("example_arg1");
      Log.Info ("example_arg1: {0}", arg1);

      Int64 arg2 = arguments.FindInteger ("example_arg2");
      Log.Info ("example_arg2: {0}", arg2);

      // You can override gflag like this: ./mono-local --example_arg3=hahaha
      Log.Info("example_arg3: {0}", Flags.GetString ("example_arg3"));

      // Registers a timer.
      //
      // Below demonstrates a repeating timer. One-shot timer is also available.
      // Please see the Timer class.
      Timer.ExpireRepeatedly(WallClock.FromSec(1), OnTick);
    }
  }
}

42.2.3. Sending parameters when executing command lines

The game server now recognizes the execution parameter called --example_arg3. That is, the form --example_arg3=my_value is used.

$ ./my_game_server-local --example_arg3=my_value

All parameters to be added to the environment variable called EXTRA ARGS can be listed.

$ EXTRA_ARGS="--my_arg1=my_value" ./my_game_server-local

OR

$ export EXTRA_ARGS="--my_arg1=my_value"
$ ./my_game_server-local

42.2.4. Sending parameters to the server during execution

If the game server is packaged and executed as a service, execution parameters cannot be handed over as above. In such cases, execution parameters can be defined and handed over in the files mentioned in Setting up the service.

Upstart:

Enter in export EXTRA_ARGS="--example_arg3=my_value --example_arg4=another" form within the etc/upstart/default/{{project-name}} file.

Important

You must add export, and you must also add = appearing after EXTRA_ARGS without spaces before or after.

Systemd:

Enter in EXTRA_ARGS="--example_arg3=my_value --example_arg4=another" form within etc/systemd/{{project-name}}.

Important

You must write it without export.