Multiplayer tutorial 1: concepts

Favourite 220 favourites
Tutorial written by AshleyOriginally published on 3rd, March 2014 - 4 revisions

How many players can join the same game?

The limit on how many players can join a game is likely to be the upload bandwidth on the host. The engine itself imposes no limit, but there is definite practical limit that will be encoutnered.

The problem is the host has to send a message with data for N players, to each of the N players. For example, if the host needs to send 16 bytes of data for each player, then each message will have a size around N * 16, and then that message will have to be sent N times. This creates an N-squared bandwidth requirement. For example:

10 players = 16 x 10 x 10 = 1600 bytes per update
20 players = 16 x 20 x 20 = 6400 bytes per update
30 players = 16 x 30 x 30 = 14400 bytes per update
100 players = 16 x 100 x 100 = 160000 bytes per update

Even though the player count increases linearly, the bandwidth requirement increases proportional to the square. This means even with a significantly more powerful server or less data needed per-player, it won't get you many extra players.

By default updates are sent 30 times a second, so the last example with 100 players would actually require an upload rate of about 5 megabytes/sec (or 40 megabit/sec). This is pretty high for a home connection, but not necessarily a dedicated server.

On top of that the host needs to be able to run the game for a large number of players as well, performing tasks like lag-compensated collision tests, which can be CPU-intensive. Then it may need to be rendering the game for the host if they are a participant as well. Generally the overall amount of work increases quickly with the number of players, and although it depends on the specific game and connection, it's rare to get close to 100 players in one game.

Controlling the update formats

It's possible to choose the exact data format of values tansmitted by the multiplayer engine. Used correctly this can significantly reduce the amount of bandwidth required without having any significant effect on gameplay precision. This helps make the game make more efficient use of the network, as well as likely raising the maximum number of players who can join.

If you are not familiar with bits, bytes and binary, then it has been covered extensively elsewhere. Consider starting with the following Wikipedia articles on binary numbers and byte. In short, all numbers in computing are stored in binary: each digit can only be a 0 or a 1. A byte is 8 bits, and can therefore store 2^8 (256) different values, or from 0 to 255. More bytes allows for a greater range of values to be stored. Floating-point types can also store fractional values, such as 0.3, and generally require at least four bytes.

The types you can use in Construct 2 are:

High (double, 8 bytes): a double-precision floating-point number that can store numbers without affecting their precision. It has about 15-17 significant digits of precision. However it takes 8 bytes to store a single number, which can end up increasing bandwidth requirements significantly. In practice this is unlikely to be a necessary choice.

Normal (float, 4 bytes): a single-precision floating-point number that can store fractional numbers with about 6-9 significant digits of precision. This means some numbers will be rounded to fewer significant digits. However it is usually far more practical than a double, since it only takes half as many bytes and digits beyond the first 6 are usually unimportant (e.g. 0.333333 is close enough to 0.333333333333333 for practical purposes).

Low (int16, 2 bytes): a signed 16-bit integer that can only store whole numbers in the range -32768 to 32767.

Very low (uint8, 1 byte): an unsigned 8-bit integer that can only store whole numbers in the range 0 to 255.

To minimise bandwidth, it is important to choose the lowest precision possible that will not seriously affect gameplay. For example X and Y positions can often use low (int16) precision. As long as the layout is smaller than 32767x32767 (which is very large), and sub-pixel positions are not important to gameplay (since this will round off any fractional value), it is perfectly sufficient and uses four times less bandwidth than a double.

The low (int16) and very low (uint8) precisions are useful with player inputs for peers to send to the host. Using the setbit, getbit and togglebit expressions in Construct 2, it's possible to set individual bits in these numbers. If a game uses the four arrow keys to move and space bar to shoot, these are only five controls, and can be stored in 8 bits with a 0 indicating 'not being pressed' and a 1 indicating 'being pressed'. Then the host can look at each bit and simulate the appropriate controls. This can all be done with a single byte, or an int16 if you have more than eight controls, making very efficient use of bandwidth. Similarly the host can send to peers multiple on/off states in a single value.

Share and Copy this Tutorial

You are free to copy, distribute, transmit and adapt this work with correct attribution. Click for more info.


stefanos 3,482 rep

Yeah that's nice :)

Monday, March 03, 2014 at 8:36:42 PM
Vallhalen 3,067 rep


Monday, March 03, 2014 at 8:43:51 PM
Leandrus 6,001 rep


Monday, March 03, 2014 at 8:55:27 PM
SgtConti 4,941 rep

Very interesting, hopefully the beta release comes tomorrow ;)

Monday, March 03, 2014 at 9:02:03 PM
DUTOIT 12.8k rep

Fantastic :)

Monday, March 03, 2014 at 9:05:34 PM
emoaeden 10.3k rep

I can't wait to try this !

Monday, March 03, 2014 at 9:07:53 PM
NeoBiel 4,639 rep

Meu sonho se realizando...

Monday, March 03, 2014 at 9:08:29 PM
albrektv 8,606 rep

Thank you for the lesson that you are waiting for him

Monday, March 03, 2014 at 9:11:31 PM
valdarko 6,357 rep

how it will handle data save, like itens and stuff?

Monday, March 03, 2014 at 9:33:35 PM
Joskin 6,129 rep

Yes ! Thanks a lot !

Monday, March 03, 2014 at 10:23:48 PM
jobel 17.2k rep

I'm very excited to go through this! thanks!

Monday, March 03, 2014 at 10:35:05 PM
DatapawWolf 30.9k rep

I notice this does not address the subject of host cheating. Preventing the clients is nice and all, but, for example, say the host hacks their client, they could now send whatever they want to the peers.

Now you could say that anti-cheating measures and checks could be implemented, but then you could apply that same logic to each client as well.

Thoughts, anyone?

Monday, March 03, 2014 at 11:17:34 PM
popyui 2,499 rep

Me gusta mucho esto y me da una mejor idea de como funcionan mis juegos de mis consolas

Monday, March 03, 2014 at 11:19:48 PM
DatapawWolf 30.9k rep

Also, not to spam, but addressing the "Lag Compensation" techniques. I'm sorry but if a player has a bad connection in a shooter game, too bad for them. Newer games in the Call of Duty series have notoriously infuriating lag comp which is responsible for all sorts of nonsense.

In my opinion it's a technique that is often overused and should not be looked as much as interpolation or other ways of synchronizing between peers.

Monday, March 03, 2014 at 11:29:12 PM
DatapawWolf 30.9k rep

"By default updates are sent 30 times a second"
We will be able to modify this, correct? Or send out updates only when needed? It'd be wasteful to constantly spew out that much data for something like a grid/turn based game, where movement may be as low as 1 grid square per 100ms, or not at all when a player is AFK.

Monday, March 03, 2014 at 11:32:42 PM

Leave a comment

Everyone is welcome to leave their thoughts! Register a new account or login.