Imperium will use a dedicated server for handling online games. An online game is always between two human players that currently have online access. The server is written in Python and is very minimal. The server handles both TCP and UDP:
- TCP is used for all setup for the games, such as lobby handling, announcing games, player data etc.
- UDP is used for all updates once the game has started.
The server know about announced games and connected player and handles the starting of games when a player has joined an announced game. Basically everything that relates to handling a lobby. Anything to do with the real Imperium data or logic is unknown to it. When the games start the server becomes a simple data relay that just forwards packets to the other player. The only exception here is a ping packet which the server answers.
The server is available at: GitHub.
Lobby and setting up games
Imperium will have a really simple “lobby” where available games are shown and you can choose to host a game of your own. There will be no filtering, ranking or similar, all open games are available to all players. Initially when players connect to the lobby they enter a name that will be shown to other players. No filtering or sanity checks are done (yet) on these names. Time will tell if that needs to be done.
Once a name has been entered Imperium will connect to the server and show the lobby. The lobby lists games that other players host that currently await an opponent as well as the scenarios that the local player can choose to host. To join a game in the lobby simply tap on it and it will start. To host an own game just select a scenario from the list and tap Host on the next screen. Imperium will now show a waiting screen while it waits for some other player to connect to the game. Once a player connects the game starts. As soon as both players have loaded the scenario in question the server starts the game.
Game engine architecture
It’s quite hard to get a good architecture for doing realtime games. As time is a factor when resolving action it all depends on where the action is resolved so that it’s fait to both players. There are a few possibilities:
- the server resolves all action and the players just display the results and handle input. This is fait to both players, but requires a server with full knowledge of the game logic, basically a client without any graphics. Imperium’s server is very dumb and doesn’t know anything about the game other than sending some data back and forth.
- one player does all the calculations. This is unfair to the second player who will always have a lagging connection to the server. The local player will be able to perform actions and see results a bit faster, thus getting an unfair edge.
- both players calculate all action. This would be fair to both players, but would be a bit complex when it comes to keeping it all in sync.
- both players handle the calculations of the local player’s units.
The last of the options has been chosen for Imperium. Each client will handle the calculations for all the local player’s units. This is fair to both players as both handle their own units without any lag. There will be a fair deal of synchronization going on as both clients will send all changed missions to the other as well as updates for moving units. This method will make it possible that a client acts on old data, for example firing on a unit that technically has moved out of range. But as the action is very slow paced and it doesn’t really matter much if some limit will be exceeded a bit, this shouldn’t really be a problem.
All the updates for units that move or change state somehow will be sent as UDP packets to minimize lag. Periodically extra data with all missions etc will be sent so that both clients can keep their state in sync.