38. Client programming part 2: Client resources

Resource files needed by the game client such as plan data, graphics files, and asset bundles are often distributed together with the client. However, this data may occasionally change while running the game, and it is troublesome to distribute a new client to update this data each time. For this reason, resource files needed by game clients are often received from an external source.

To get these files from the external source, checksum values like MD5 and a list of files that the client must receive are typically calculated, and the client receives this data. The client checks to see whether resource file data matches the data it currently has. If files are added or deleted or file checksum values differ, the client deletes files that are no longer needed and gets new files to save on the client device.

iFun Engine provides a client resource management feature to easily handle this process during development. You can use this service to add/delete/modify client resources even without updating the client.

You can use this client resource service with just a simple explanation on the server’s MANIFEST.json. This service works on the HTTP protocol.

38.1. Client resource service setup

38.1.1. Method 1: When the game service handles resource requests without a separate web service

38.1.1.1. Specifying a resource directory

This is generated if there is no directory called client_data in the highest-level source directory. Files the client needs to get are copied here.

If there is no client_data in CMakeLists.txt RESOURCE_DIRS, add it as follows:

...
set(RESOURCE_DIRS game_data client_data src/json_protocols)
...

Tip

If the client_data directory is not bundled with make package, check the CMakeLists.txt settings above. For more details, please see Including game resource files in a package.

38.1.1.2. MANIFEST.json settings

Configure MANIFEST.json as follows:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
{
  ...
  "ClientResourceService": {
    "use_client_resource_service" : true,

    "client_resource_service_port" : 8020,

    "client_resource_dir" : "client_data",
    "client_resource_url_base": "",
    "client_resource_list_url": "",

    "client_resource_service_threads_size": 2,

    "client_resource_max_file_size": "1000000",
  }
  ...
}

When an iFun Engine game server boots, MD5 for files under the relevant folder is automatically calculated and this data is used to create an internal resource list. HTTP requests are handled directly to get resource file downloads.

38.1.1.3. .funignore file and rules

iFun Engine check files and directories against defined patterns in .funignore file. You can hide the specific files from clients resources list. Also, you may exclude the sensitive data or unnecessary files generated by build process.

Ignore rules can be defined in. .funignore file. The file will be generated when a new project is initialized. .funignore file is based on Perl regex expression to determine whether or not they should be ignored.

.funignore file contains the following rules and single line comments that begins with # or //.

# This file contains perl regex patterns that are matched
# against specific path or file name to determine whether or not they should
# be ignored when your client requests resource data.
#
# Scope of the rules: All rules are applied to each subdirectories.
#
# Ignore all files that matched with 'data/specific.txt'
.+data/specific\.txt

# Ignore all files and subdirectories in below directories.
# Please note that all rules are applied to each subdirectories.
\.svn
\.git

# Ignore all files that match against following patterns.
# These are commonly used by many operating system or IDE
#
# Commonly used files
\.DS_Store
Thumb\.db
Desktop\.ini
^[\w\s\.,-_]+\.bak
^[\w\s\.,-_]+\.log
[Bb]in
[Oo]bj
[Bb]uilds?

# Vim
^[\w\s\.,-_]+\.sw[ponm]

# Python
venv
pip-log\.txt
^[\w\s\.,-_]+\.py[co]

38.1.2. Method 2: When resource requests are handled by a separate web server

When client_resource_list_url and client_resource_url_base in MANIFEST.json are set up, iFun Engine can redirect resource list and resource file requests to an external web server.

38.1.2.1. Creating resource list files

Run the following commands: The first parameter is the root folder path where the resource is located and the second is the path for resource list files to be generated.

$ funapi_client_resource_generator <path/to/resource/base> <path/to/list.json>

Files made this way are copied to an external web server. The relevant file URLs are set in the MANIFEST.json's client_resource_list_url.

38.1.2.2. Copying resource files to a web server

Folders including resource files are now copied to an external web server. That directory URL is set in client_resource_url_base.

38.1.2.3. MANIFEST.json settings

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
{
  ...
  "ClientResourceService": {
    "use_client_resource_service" : true,

    "client_resource_service_port" : 8020,

    "client_resource_dir" : "",
    "client_resource_url_base": "http://my.cdn.com:80/path/to/resource/base/",
    "client_resource_list_url": "http://my.cdn.com:80/path/to/list.json",

    "client_resource_service_threads_size": 2,

    "client_resource_max_file_size": "1000000",
  }
  ...
}

Now, when the game server boots, iFun Engine gets resource list files from client_resource_list_url and caches them, then redirects resource file requests to client_resource_url_base.

38.1.2.4. .funignore file and rules

the same rules are applied in funapi_client_resource_generator if resource directory has .funignore file that contains standard POSIX regex expression.

38.1.3. Updating resource data

You can update client resource files even while the server is operating.

Invoke the following method in the code.

ClientResourceService::Reload();
ClientResourceService.Reload();

Note

If the game server itself seeds resource files, iFun Engine will recalculate MD5 for files in the client_data directory. Also, if an external HTTP server is set up and client_resource_list_url is specified, it will download saved MD5 files from that URL and cache them for use.

Note

New resource files are not sent to users already playing when MD5 is recalculated. Thus, if resource files are updated, users who are already playing and newly connected users may receive different resource data.

38.2. Example: Using an external web server

In the example below, data/items.json and data/stages.json exist as resource files and are sent to clients via an external web server.

38.2.1. Getting resource lists

Enter http://localhost:8020 into a web browser. Results are similar to the following.

{
  data: [
    {
    path: "data/items.json",
    size: 2042,
    md5: "d41d8cd98f00b204e9800998ecf8427e"
    },
    {
    path: "data/stages.json",
    size: 2044527,
    md5: "9ab9626a301c2bf1444893a69a1bfac7",
    md5_front: "8fdd96188cadababf2fbcb812b43e6fb"
    }
  ],
  url: "http://my.cdn.com:80/path/to/resource/base/"
}

Tip

md5_front is the MD5 value for the first 1 MB of the file. This is to prevent the client from calculating the entire MD5 of large files, and if MD5 up to 1 MB differs, the download begins immediately. If md5_front matches, MD5 is calculated for the entire file. This field is only created for files larger than 1 MB.

38.2.2. Getting each resource file

If you now enter http://localhost:8020/data/items.json into your browser, iFun Engine redirects this to http://my.cdn.com:80/path/to/resource/base/data/items.json and the file download begins.

38.3. Client code

The client resource service is implemented in clients via an iFun Engine client plugin.

The plugin automatically requests the MD5 list and checks whether the files in it are present to compare with the MD5 of its own files. It then downloads updated or added files and removes deleted files. Files with MD5 calculated are cached to speed up MD5 calculation.

For more details, please see Client programming part 1: Plugins.

38.4. Client resource service parameters

Set the following in a MANIFEST.json ClientResourceService session.

Common definitions:

  • use_client_resource_service: Enables activation of feature (type=bool, default=false)
  • client_resource_service_port: HTTP port to bind client resource service. (type=uint64, default=0)
  • client_resource_max_file_size: Maximum size of a single client resource file. In bytes. If files are larger than this, the game server will not start. (type=uint64, default=10485760)

If there is no separate web server:

  • client_resource_dir: Directory path to save resources downloaded by the client. (type=string, default=””)

If a separate web server is used:

  • client_resource_list_url: File URL containing client resource list. Please see Creating resource list files for more on creating list files. (type=string, default=””)
  • client_resource_url_base: Base URL to receive client resources (e.g. CDN base path). If this is set, the client resource service only sends the file list to the client and redirects it to receive the production files from the relevant base URL. If this value is input, client_resource_dir is ignored, and client_resource_list_url must exist. (type=string, default=””)

Parameters with configurations that are almost never changed manually

  • client_resource_service_threads_size: Number of threads to allocate to client resource services. (type=uint64, default=2)