44. 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.

44.1. Method 1: Using MANIFEST.json

44.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,
          ...
        },

        ...
      }
    }
  ]
}

44.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);
    }
  }
}

44.2. Method 2: Adding with Google Flag

44.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.

44.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);
    }
  }
}

44.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

44.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.