Y*A*R*T*S (or Yet Another Real Time Strategy game)


Network Architecture

This section hopes to explain some of the design of the networking code in YARTS.

Basic description
YARTS uses a client-server architecture, where the full game is simulated on each machine, and the network code passes data that synchronises all the individual games.

Detail
Each client sends a fixed number of UDP packets to the server every second, and the packets are always the same size.

The packets are made up of "order data" (type of order, co-ordinates, etc) and "state data" (current position, velocity vectors, heading, health)

Orders from a player to his/her units are copied onto a queue for the networking threads.

The "send thread" comes along and builds a packet by taking whatever orders are on the queue, and then padding out any extra space with the "state data" of random units owned by the local player. (You only have the definitive version of the state of your units)

The UDP packets are decoded by the server, and rebroadcast to the other players in the game.

When a player's "receive thread" gets a UDP packet, it forwards the orders to the appropriate units, and if the packet contains state data, also sets the state of the relevant units.

A TCP connection is also maintained for vital communications (since UDP is not guaranteed delivery), such as game setup, game start/end, text messages, unit deaths, etc.

Design notes
The design for the network code in YARTS was derived from experimentation, and from reading a large number of networking articles and postmortem articles on Gamasutra.

This design was chosen because it will work well over the internet (minimises bandwidth required between players), and although it introduces an extra latency penalty due to the server, it should not matter because this is an RTS, not a fast-action 3D game. It should also work well over a LAN, as the fixed-size UDP packets can either be increased in size, or they can be sent more often. We have minimized the amount of data being sent in each packet so that the game should run comfortably with a 14400bps network connection (as a fast modem does not guarantee a fast route all the way).

In practice..
The network code needs a re-write, but it performs well. Currently unit deaths are not always propagated to all players (a bug), which causes major synchronicity problems(!) Otherwise, the games stay in sync, even when hoverjets are changing course rapidly.

Improvements
To improve this system, there will eventually be a common synchronised clock on each machine that will allow position updates to be corrected using the latency of the network, to improve game synchronicity. A small (150ms) delay will be introduced between the time when the interface receives an order and when the game actually executes it. The order will be sent over the network immediately however, and scheduled for execution at the correct time on the remote machine. This will help keep orders in sync, and apparently a constant delay of 200ms is not noticable when playing an RTS. (a shorter variable delay is, however)

The server needs to maintain a small amount of game state, and to prioritise orders over game state, etc.

Orders may need to be sent via the TCP link rather than by UDP, as a dropped packet would mean catastrophe. The UDP packets each have an ID, so that packet loss can be detected, or packets arriving in a different order to which they were sent.