Networking Concepts

From C4 Engine Wiki

Jump to: navigation, search

C4 has networking built in. At a very high level, the C4 networking system assumes the following:

  1. The number of players will be small enough that everyone on a map gets information for every player
  2. Actions take effect on the server before they take effect on the client

For many games (FPS deathmatch, racing games, checkers, RTS map game, etc) these are fine assumptions. However, for more ambitious projects, the limitation on the number of players, and the limitation on persistent maps, necessitate a different approach. Also, movement suffers from latency in starting and stopping because of the server-first approach. However, turning is instantaneous on the client, so it's not as noticeable as it could be.

Networking in C4 centers around controllers, much like regular actions and animations. The global TheMessageMgr is used to send messages to and from the server. You can also call methods on certain other objects, such as the Player, to send messages to that player specifically. TheMessageMgr also keeps track of which Player is the local player.

The patterns you should put into your code to make it network aware are as follows:

Deferred User Commands

  • User commands, such as "move forward" or "activate button," should be bottled up in a message and sent to the server version of the controller they take effect on. The server will echo the message to all players. Do not call controllers directly from user input code.

Server-side Controller Actions

  • Interactions between controllers and players are typically handled by the controller detecting that it is on the server, and actually applying the affect, whereas it sends a message with the results of the affect to the clients. This means you sprinkle calls to TheMessageMgr->IsServer() in your controller message handling code.

Message Journal

  • Some messages should be journaled, so that any new player joining a game in-flight will see the results of all those messages. That is implemented using SendMessageJournal. To remove a previous message that contains outdated state, override the Message::OverridesMessage() function in your message class. Most script verbs/actions use the Journal mechanism, for example, and only run on the server when in multi-player.
  • You should realize that, if a game has a number of interactive controllers, then late-joining will use more bandwidth to sync up than joining at game start. Specifically, all controllers that change state and use messages to signal that state change, will have to send those messages to each new player once the state has changed, but those messages don't need to be sent to a player who joins at the beginning. This is not likely to become a problem for smaller FPS-style maps, but may need careful attention for very large, highly interactive maps.
Personal tools