Jenkins Software

Components of a multiplayer game

Major systems that go into the making of a multiplayer game

Multiplayer enabled games require additional systems and/or design considerations over single player games. I list these by category below, along with the options available for solving these problems and pros and cons of each system. This page applies to any multiplayer game, not just those using RakNet, although RakNet specific solutions are listed at the end of each section.

Discovering other systems

Direct IP entry

The oldest and simplest method, this involves typing in the IP address of the user you want to connect to. The remote user can go to a page such as http://www.whatismyip.com/ to get their IP. They can then communicate this IP to you through other communication channels such as email or instant messenger. If the remote user is behind a router, they will have to open the appropriate ports on the firewall to accept incoming connections. If they are behind a firewall, they will have to configure the firewall as well.

DNS entry

Applicable to client/server games where you control the servers, you can have a DNS entry point to the server. Connecting clients can then connect to the DNS entry rather than typing in a fixed IP address. This is useful if the IP address of the server may change. This service is available for free through http://www.dyndns.com/. RakNet provides a class to update DynDNS as well, found in Source/DynDNS.h and Source/DynDNS.cpp. This is usually used for client/server games where you host your own server.

LAN Broadcast

If the remote computer is on the same LAN, you can discover this computer by sending a datagram to the IP address 255.255.255.255 provided that the remote computer is listening on the port you send on, and will send a datagram in response. RakNet provides this through the Ping() and AdvertiseSystem() functions.

Rooms server

More sophisticated games may have a system of rooms for users to find each other. A server will contain a list of rooms, where each room contains a list of players. Players connect to that server, search for and join rooms, and start games through this system. The server is responsible for storing the IP addresses of each player and transmitting that data to other players. RakNet provides this service on the PC through the RoomsPlugin plugin, on Steam through the SteamLobby plugin, and rough equivalents on the XBOX and PS3 with their respective lobby classes. This is usually used for peer-to-peer games, where players have some significant interaction between each other before the game starts.

Directory server

Similar to the rooms server, a server maintains a list of running games. Typically, when an end-user starts a game, they upload statistics about the game to a directory server that you as the developer host. The directory server holds the IP addresses of the running games, game statistics, and allows game clients to download the list of running games. The clients would then locally connect to servers to join games in progress. This is usually used for client/server games where players host their own game servers. RakNet provides this service through the CloudServer / CloudClient projects.

 Network topology

Client/Server where you host the servers

Usually used for massively multiplayer games, you will host one or more servers that contain the game world(s) provided to the players.This is also the most expensive solution since you have to have dedicated servers with guaranteed uptime and pay for bandwidth yourself. Many companies offer this service, including http://www.dx.net/raknet_dx.php

Client/Server where users host the servers

This is used for games where if the server drops, so does the entire game session. It is nonetheless common because it has the following advantages:

  1. Easier to program because a single system can resolve contention between clients
  2. Can support a large number of players, because dedicated servers with a high bandwidth capacity can host
  3. Better for long-term gameplay sessions because a dedicated server is less likely to drop or cause problems
  4. Dedicated servers can be spread throughout the world, resulting in low-ping sessions
It is also possible to program client/server using an end-user as a host, but then you get all of the disadvantages of client/server without none of the advantages except ease of programming.

Peer to peer

This is used for more informal game sessions without dedicated servers. It is the most common topology for console games since consoles do not allow dedicated servers. The only advantage is a dedicated host is not necessary. The disadvantages are:

  1. Still need a server of some sort to find running game sessions
  2. Have to punch through routers
  3. Have to deal with host migration
  4. Have to deal with contention. If two peers do the same mutually exclusive operation at the same time, how to resolve?

RakNet provides plugins to make peer to peer programming easier: NATPunchthrough, ReadyEvent, ConnectionGraph2, FullyConnectedMesh2, and TeamBalancer

 Replicating game sessions

Other connected systems

It is usually necessary for players in a game to know about other players. Not just IP address, but things such as score, name, team, and the events when those players connect and disconnect to the game sessions.

Other game objects

There are 5 cases where a game object state needs to be sent to a remote system

  1. When creating a game object, it needs to be sent to all relevant remote systems
  2. When a remote system connects to us, they need to get all relevant game objects already in the world
  3. When a remote system disconnects from us, we need to remove game objects that should not exist when a player is not connected
  4. When we delete an object, that object should be deleted from all systems that have a copy of that object
  5. When the state of an object changes, the updated state should be sent to all systems that have a copy of that object. The state may be different depending on who the recipient is.

In order to transmit and refer to a game object, one cannot just send a pointer to that object. The object needs to be serialized into a stream format, similar to loading and saving. Some kind of identifier needs to be assigned to the object so the same object on two systems can be referred to.

If using client/server topology, all of the above 5 events will also need to be relayed through the server, if the client had initiated the event. If using a peer to peer topology, conflicts may need to be resolved concerning object state in a way that is also fair to the other peers.

RakNet provides an architectural solution to these problems through the ReplicaManager3 plugin.

Events

Game events not related to an object will also need to be relayed. For example, game start and game end, with corresponding serialized data. Game events sometimes refer to objects themselves. This can be written by hand although RakNet provides the RPC3 and RPC4 plugins to make it easier. RPC3 relies on Boost and has greater functionality, while RPC4 does not.

Interpolation

Because of bandwidth requirements, game updates are usually sent periodically rather than every game frame. Latency changes over the course of a gaming session causing remote user inputs to be behind the actual positions on the remote systems. Games have to deal with interpolation through dead reckoning. RakNet does not provide solutions for this automatically, although it provides helper and utility classes, such as DependentExtensions\Ogre3DInterpDemo\TransformationHistory.cpp used in the Ogre3DInterpDemo.

 Patching

Per-file difference based patching

The most advanced but time consuming way to patch users is to find the difference between a file the user has and the current version of that file. Under those circumstances the smallest delta can be sent and applied to the file. If the patch fails (for example, an unknown version of the file) the entire file will need to be transmitted. A database of patches will need to be maintained for this solution, as generating the patch at runtime is too time consuming.

RakNet provides the AutopatcherServer and AutopatcherClient plugins as a diff based patching system.

Per-file patching

A simpler way to patch is to find a list of changed or missing files for a client and to send only those files. One advantage of this system is that it can be used by end-user hosted game servers. For example, if a game server has a map or skins that a connecting client does not, those files can be downloaded before the game starts.

RakNet provides the FileListTransfer plugin to transfer lists of files, and the DirectoryDeltaTransfer plugin to transfer lists of changed or missing files.


 Debugging

Logging

Multiplayer games are hard to debug because a bug can be spread between two systems. For example, system A performs an action but system B does not see it, or sees it differently. The bug may be caused by latency, showing up only at certain loads. Performance or other issues may come up as the application scales with more users. While logging can help with all these problems, they are hard to correlate because the system times are different.

RakNet provides two logging solutions. The first is called SQLite3LoggerPlugin, and is based on SQLite3 on a hosted server. All logs go to the same server, and are automatically correlated. The logs can be viewed in viewer that supports SQLite although RakNet also provides a free and open source custom viewer called EchoChamber. Individual game and connectivity messages can be logged per system using the PacketLogger plugin.

Minidump

Because crashes can be hard to reproduce, Windows applications can produce minidump files. If you know what version of the code produced the crash, you can debug the crash as if you had a debugger connected at the time.

RakNet provides the CrashReporter system to make this easier. It provides additional functionality such as sending emails to the developer in the case of unattended servers.


 Lobbies and persistent data

Persistent user data

Games that persist data beyond a single session require a system to create user accounts. User accounts can store data such as game statistics, name, and logo. Users can also have friends, form clans, and perform other social tasks. In order to write such a system, a database backend is needed with a persistent sever to store this data. The users should not be able to send arbitrary queries to the database, so the server will need code to form queries based on user inputs.

RakNet provides a system called LobbyServer and LobbyClient to provide this kind of functionality for the PC. Steam, the PS3, and the XBOX already store this on their own backend. For those cases, RakNet uses the same LobbyClient interface so as to provide a unified interface to all systems.


 Security


Popular competitive games will draw cheaters. Cheaters can attack the application by

  1. Modifying the EXE to send unauthorized data (sending kill messages)
  2. Modifying the EXE to view extra data (seeing through walls)
  3. Modifying datagrams in transmit to change data sent
  4. Replaying datagrams to simulate login or game events (running bots)
  5. Introducing latency to get a competitive advantage

The game should verify all inputs for sanity when possible. This will need to be done even if cheating is not a concern, since latency will also cause unusual inputs.

RakNet can automatically protect against attacks #3 and #4 with secure connection support. Solutions already exist for protecting the EXE from modification on the PC. Protecting against latency based cheating just takes smart design decisions, such as not trusting client/peer inputs.


 See Also
Index
Autopatcher
CloudComputing
ConnectionGraph2
CrashReporter
ReplicaManager3
FullyConnectedMesh2
NATPunchthrough
PacketLogger
ReadyEvent
RPC3
TeamBalancer
SQLite3LoggerPlugin