Magi

Contact info
Studies
  Scientific publications
  Master's thesis
Work
Software
Hobbies
Other Articles
  Evolution
  Metsola
  Pseudoart
Photography
Historical

© Marko Grönroos, 1998



WarWorld - In-Game Protocol

as of 10/01/2000

NOTE: The '<','>' characters below are not parts of the message structure!

NOTE: All messages end with '\0' for easy processing via strcmp() etc.

NOTE: All numeric values are integers (preferably 16-bit).


Server-2-Client Messages


INIT * Starts a new frame. Resets the clients for refresh.

NXT * Indicates that the following data belongs to the NeXT player. See "IMPORTANT

NOTES.." below.

AIM * A player's mouse cursor location. All selected units 'aim' at this

location.

NOTE: The server probably wont need this information. This

information is needed in order to animate firing units.

(sensitive to NXT)


SEL * Determines the units that are currently selected by a player.

(sensitive to NXT)

SHT * A shot. Informs the client that all the selected units shoot at the

point defined by AIM. Additionally, defines the remaining

energy value for the target.

(sensitive to NXT)


NEW * A new unit has entered the battlefield. (a player built one)

(sensitive to NXT)


POS * Unit position information, including heading (direction in the

world). Absolute position.

Extension 10/01/2000

WPT * A WayPoinT. Using waypoints instead of absolute positioning via POS

would improve networking performance a great deal. (The clients interpolate unit

positions between waypoints.)

Syntax


"INIT\0"

  • Resets the client for a new frame.

--------------------------------------------------------------------------------------------------------------------------

"NXT\0" (special)

  • The following data belongs to the NeXT player. This keyword begins a new 'chunk' of data. Right after "INIT\0" the client assumes that the NXT-sensitive data following the first "NXT\n" belongs to PLAYER_ID 0. After the next "NXT\n" all NXT-sensitive data is considered belonging to PLAYER_ID 1 and so forth. The "POS" message doesn't care about "NXT\0" since it is data concerning a unit rather than a player.

  • The aim of this solution is to make the messages compact.

"AIM <mouse_x>,<mouse_y>\0"

  • mouse_x and mouse_y represent the world-space coordinates of a player's mouse pointer. The server gets this information from the clients. And again, the server might not itself need this data.

  • Without this data animating lasers or projectiles or whatever would be impossible. PLUS! This information can be used to implement 'special' effects such as rotating gun barrels (They would follow the mouse pointer. Real-time. This is already done as of 10/01/2000)



"SEL <unit_id1>,<unit_id2>,...,<unit_idN>\0"

  • Usually the player selects only one unit at a time. As of 05/01/2000 the client does not support selecting multiple units at once (Will be supported)


"SHT <target's_unit_id>,<energy_remaining[0..100]>\0"

  • Lets the client know that all the SELected units shoot at the target at AIM.

  • If there is no enemy unit at that location (which is determined by the server) target's_unit_id can be selected freely (Say, 0.). In this case, energy_remaining must be set to 100 (=100 per cent energy => no damage).

  • If there is an enemy unit at that location, target's_unit_id equals its corresponding unit_id and energy_remaining is the amount of energy (0-100%) that the unit has left after taking the hit. If 0, the client animates an explosion and draws a nice crater :) and increments the shooter's kill count.


"NEW <unit_id>,<unit_type_id>\0"

  • Position info for this unit is transmitted after this message, like:

"NEW 43,2" // make a tank with UNIT_ID 43.

"POS 43,300,500,64"

The two possibilities for unit positioning


"POS <unit_id>,<world-space_x>,<world-space_y>,<heading[0..255]>\0"

  • Positions a unit with unit_id at (world-space_x, world-space_y) with heading heading.

  • Using POS every frame for moving units around would probably cause serious overhead when multiple targets are moving at the same time.

”WPT <unit_id>,<world-space_x>,<world-space_y>\0”

  • Gives a waypoint to a unit. The idea is that the client moves the units between waypoints to improve networking performance. The server must also know the exact location of every unit at every instant. This means that both the server and the client must have identical unit movement code with which to move the units between waypoints.

  • If the server is already programmed to move units around, the only thing to change is that, instead of broadcasting

unit positions every game cycle, the server now broadcasts waypoint information as needed. (after a unit reaches a

waypoint, it is given the next if that waypoint is not the requested destination.)

  • If server path finding is not to be implemented, all the server needs to do is to broadcast the destination requested by a player as a waypoint unchanged.

  • It is assumed by this specification that stationary units may lie only at integer coordinates. In this manner we avoid transmitting floating point data. Internally, it is, of course, wise to represent coordinates as floating point values.

  • When a waypoint is reached by a unit, it stops immediately and starts waiting for the next waypoint. When the next waypoint is given the unit turns on the spot (clockwise/counter-clockwise depending on which is ’wiser’) and after reaching correct heading starts to accelerate. Thus, turn rate, acceleration and top speed must be defined for different types of units.

  • In the event that a player SELects multiple units at once and issues a move command, the server generates separate waypoints for all the units in the group. In order to prevent all units from moving to the same coordinates (on top of each other) the server might do the following: Take the first unit in the list of selected units. Take the vector from its location to the destination coordinates. Use the resulting vector as a movement vector for all the units in the group.










Client-2-Server Messages


AIM * Player's mouse cursor location. See above.

SEL * Selected units. See above.

SHT * All selected units wish to shoot at the location defined by AIM.

MOV * Tells the server that all selected units wish to move to the point defined by AIM.

BLD * Build a unit.


Syntax


"AIM <mouse_x>,<mouse_y>\0"

  • Tells the server where exactly in the world a player is pointing with his mouse.

  • SERVER NOTE: Use the old AIM value until a new value is received.


"SEL <unit_id1>,<unit_id2>,...,<unit_idN>\0"

  • A list of all the units currently SELected by the player (usually a single unit).

  • SERVER NOTE: Use the old SEL-list until a new list is received.


"SHT\0"

  • All SELected units wish to shoot at the location AIMed. Whether an enemy unit is at the location AIMed is determined by the SERVER.


"MOV\0"

  • Tell the server to drive the SELected units to the location AIMed.


"BLD <unit_type_id>\0"

  • Tell the server that the client wishes to build a unit of type unit_type_id.

  • The new unit, once built and if the player had the money, is positioned by the server using the "NEW" message defined in Server-2-Client Messages.



IMPORTANT NOTES ABOUT THE ARCHITECTURE


The relationships between the different IDs


PLAYER ID e {0,1,2,....}


During game session initialization, each player is given a PLAYER_ID (starting at 0). The PLAYER_ID is given in the order of connecting to the server. So, if a player connects to a server with no players currently connected to it, the player is given PLAYER_ID 0 and the next player gets PLAYER_ID 1 and so on. A player with PLAYER_ID==0 is considered to be the host of the game and is the only one allowed to LAUNCH the game.


WHY? * The PLAYER_ID will be used to identify players in the game. (i.e. index tables containing per-player information. Kills etc.)


UNIT ID e {0,1,2,....}


A number identifying a unit on the battlefield. This number is used to index tables containing per-unit information (owner's PLAYER_ID / unit's status information). It is important that these IDs start at 0 and increment as needed if dynamic unit generation is to be performed. A UNIT_ID that belongs to a destroyed unit may be reused as needed (and definitely should.)

Assumptions about the ordering of Server-2-Client messages


It is assumed that per-player unit information, i.e. all unit related information, is sent by the server in the order of incrementing PLAYER_ID. In other words, the server broadcasts per-player (that is, after broadcasting "INIT\0") unit information so that player 0 is the first player who's data gets sent to other players.

Prior to broadcasting each player's data the server broadcasts "NXT\0", so that the clients know that the data belongs to the player with the next PLAYER_ID. The PLAYER_ID count done by the clients is reset after each "INIT\0" so that the whole thing can start all over again.

NOTE: Unit position data may be sent in any order. It is the others that require this ordering as you probably realize looking at the Server-2-Client message definitions above.


Comments


As we can see, the amount of data sent from the server software to the clients is much larger than the amount sent from the clients to the server.

Shouldn't be too difficult to implement, depending, of course, on the current architecture of the server.