The client code consists of a bunch of modules which communicate with each other through events and function calls. The central one is GameStateModule which connects to the server and maintains the state information. Triggered by calling GameStateModule::recv_view() it will call registered event handlers when a message from the server arrives. After setting actions in objects, calling GameStateModule::send_actions() will send them to the server (see below).
If you want to use the 3D GUI (GfxModule) in your client have a look at ortsg_main.C. In a nutshell, you have to create a GfxModule object (say gfxm), hook it up to the GameStateModule, and wire the event handlers.
GameStateModule::get_game() - returns reference to game
GameStateModule::get_changes() - returns reference to structure that contains lists of incremental game state changes (see GameChanges). Now your event handler can act upon incremental changes, which may simplify your code.
Game &game = gsm.get_game();
you can access the game state using the following functions:
Examples of how to access the game state are given in GUI.C .
Accessing object properties is done like this:
gameobj->sod.? // ("server object data")
for internal properties like the owner of an object (see ServerObjData.H) An important flag is gameobj->sod.in_game which indicates whether the object is a game object (rather than a gfx object).
To access global player information such as resources, you do the following:
PlayerInfo &pi = game.get_cplayer_info(); GameObj *player = pi.global_object_map["player"]; int my_gold = player->get_int("gold");
Data members in sub-objects can be accessed like so:
See testgame/ for scripted game specifications (.bp files).
Class Game has four functions that can be called to obtain overall information about executed actions:
sint4 Game::get_view_frame() const; sint4 Game::get_action_frame() const; sint4 Game::get_merged_actions() const; sint4 Game::get_skipped_actions() const;
View frame: refers to the game simulation step count.
Action frame: refers to the number of action messages (sent by the client) that were received before the current view was computed, and hence whose results are reflected in the current world view that the client has. Note that each action message includes up to one action per object.
It is assumed that the client sends an action message in response to every view message it receives.
Merged actions: If due to network delays, or long processing between calls to GameStateModule::send_actions(), multiple action messages arrive late, they get merged into one action message to be executed next.
Skipped actions: Action messages expire and their contents totally ignored if they lag too far behind the game simulation steps.
To learn about when actions get merged or skipped please have a look at Server::recv_messages().
There is also a mechanism that allows clients to know whether a specific action for a specific object
To get this info for a given GameObj, the client can:
To get started with pathfinding have a look at libs/newpath/src and at libs/serverclient/TerrainModule.* There you will find pathfinding code that interacts with the ORTS client class and the graphical user interface. It's not that sophisticated (and a bit buggy, too), but it can give you a sense on how to plan and execute paths in ORTS.
GameStateModule options -dmin <int> -dmax <int> and -smin <int> -smax <int> can create randomized symmetric up/down network lag (-d??? in millisecs) and put the client to sleep (-s???) for a while when a view is received. To see this in action issue:
orts -m client -act -dmin 500 -dmax 1000 -smin 100 -smax 300