Multiplayer tutorial 1: concepts

60

Index

Features on these Courses

Stats

83,095 visits, 354,448 views

Tools

License

This tutorial is licensed under CC BY 4.0. Please refer to the license text if you wish to reuse, share or remix the content contained within this tutorial.

Published on 3 Mar, 2014. Last updated 12 Sep, 2023

The Construct Multiplayer plugin

The general design of a multiplayer game in Construct looks something like this.

Flow of a multiplayer game

The life cycle of a multiplayer game will go something like this:

  1. Connect to the signalling server and log in
  2. Join a room
  3. Other peers can join and leave the game while it runs
  4. Object data and other messages like chat are exchanged with other connected peers
  5. Eventually the game ends, everyone leaves the room, and can perhaps look for a new room (back to step 2).

Note the game ends if the host disconnects. They are acting as the server for the game, so if they disconnect then the game is no longer running. This is a reason to consider running a dedicated host on a central server, particularly for larger games with more players. However it makes no difference for two-player games - the game would end anyway if the other player left.

The Multiplayer plugin has features covering the signalling phase (steps 1-2), as well as 'room' features covering the gameplay itself, such as triggers for when peers join and leave, messages are received, and so on.

Design overview

It is intended that games are designed with one object type representing both the player's controlled objects and all the other players in the game. Then the same object is used equally for everyone in the game, including yourself (and even when the host). It's wise to name this object Peer, since that's what it represents. If you have players composed of multiple objects, such as a separate gun and body, have a base Peer object and put it in a container with the other objects. This ensures that players are created and destroyed as a whole, and that their related objects are auto-picked in events with the base object, so you can largely treat the base object as representing the entire player.

Both the host and the peers are running the same project. This means your one project has to be able to handle events for both the host, who has the authoritative version of the game, and the peers, who are seeing a delayed version and only send their inputs. The most convenient way to handle this is to have two event groups dedicated to the Host and the Peer, and to activate only the appropriate one after joining a room and determining whether you became host.

The Multiplayer object's Sync object action is the fundamental way to indicate that you want to send data about objects over the network. This tells the host to send information about those objects to the peers, and tells the peers to wait to receive information about those objects. The multiplayer engine automatically creates and destroys objects that represent peers as they join and leave. (The Sync object action can also be used for other objects that do not represent peers, but most commonly it's used for peers.)

Each peer has a Peer ID assigned by the signalling server. This is a string with a short sequence of random characters to uniquely identify them. Peer IDs are generally used to be able to consistently refer to the same player even if their alias changes. The Peer ID needs to be stored in an instance variable so you know which peer a given object is representing. When an object for a peer is created by the multiplayer engine, the Multiplayer.PeerID expression is set to their peer ID, so it can be stored in its instance variable. Since you are in control of your own peer object, you can easily pick it by testing if its instance variable is equal to Multiplayer.MyID, and then modify just that instance.

Reliability modes

The last thing to mention is there are 3 modes for transmitting data. These trade off reliability for performance.

The most reliable mode is Reliable ordered. This sends a message that is tracked: if it gets dropped by the network, it will re-send it until it verifies that it arrives at the destination. It also orders messages, so they are guaranteed to arrive in the same order they were sent. This is useful, but is not the fastest: if one message is dropped and held up, it will hold up all subsequent messages until that message gets through. It also means individual messages may take multiples of the latency to arrive since it must wait at least the round-trip time to know if the message arrived. This is generally only suitable for important low-frequency messages like chat messages.

The next fastest is Reliable unordered. This sends a message that is tracked, and will also re-send it until it verifies it arrives at the destination. However messages are allowed to arrive in any order. This prevents a single held up message holding up all the subsequent messages - it can simply arrive late, after other messages that were originally sent after it. However individual messages can still take a multiple of the latency to arrive. This is suitable for gameplay events that must arrive but are unrelated to one another, like a door opening or explosion occurring.

The fastest mode is Unreliable. This sends a single message and forgets about it. If it's dropped, the message will simply never arrive at the destination. It can also arrive in a different order to the sequence it was originally sent in, and even possibly in duplicate. Generally this is suitable for regular messages, where it is more important that the message arrives as soon as possible than whether it arrives at all. If it is dropped, it is likely to be followed up quickly by the next message with newer data, so it doesn't matter. Note the engine internally uses this mode for synced objects with built-in interpolation and compensation features, so don't try to replicate that functionality with this mode.

Ready to go!

While Construct's Multiplayer plugin handles many technical details for you such as input prediction and connectivity, it's still very important to know the theory to be able to make appropriate choices regarding what data is sent where with which precision and reliability mode. Hopefully this tutorial has given you enough of an overview to begin designing your first multiplayer game with a good understanding of both what is happening behind the scenes, and what you need to do from Construct to make best use of the features. While this tutorial has focused on the theory, subsequent tutorials will cover how to address issues like input prediction and lag compensation in practice using specific features of the Multiplayer plugin.

If you're ready to start learning more, head on to Multiplayer tutorial 2: chat room!

  • 27 Comments

  • Order by
Want to leave a comment? Login or Register an account!