Making a video-game has the following challenges on variable storage:

  • send player states every 50-200ms, so store position/ rotation as efficiently as possible.
  • store large blocks of data for each player regarding their cooldowns, abilities, and loadout
  • all variables have to revolve around the connection id assigned when they connect to the server, not who they say they are

solutions considered so far:

  • use an integer as a "player id" which looks up data on dozens of arrays. Inform client of this number regarding each player for them to use in the backend API. Drawback- ugly and unwieldy on the server side.
  • map each "player id" to a class. Drawback- have to iterate just to get the positions / rotations every 50-200ms.
  • make an array of structures again using the "player id" as the index. Drawback- same as above.

However, each of these solutions using the "player id" as an index doesn't work well when the concurrency is unstable- with players coming and going. There are three approaches (to the actual structure of the data sent):

  • mirror the list/array on the clients, then notify the clients when there needs to be a change made (ex: player x left, all player's >x down iterate). This has a tenancy to break things between the lag.
  • attach the player id to each positional update as opposed to inferring the clients can deduct it from the array index.
  • send a static array with an unchanging number of slots, all unoccupied positions get sent anyway. There's supposed to be a crossover point where this is more efficient than including the ids if you're utilizing a certain amount of it.

What would be the best solution to this scenario?

  • 1
    I must be missing something. Why not just have a player class that has all the player data including player ID and associate it will connection id? The connection ID is the dictionary key.
    – paparazzo
    Jan 3, 2017 at 1:03
  • yeah but the question is then how do you send it? I considered iterating over a dictionary of connection id : player class (every 50-200ms) a poor design. Secondly there's the issue covered in the last bullet list about unstable concurrency
    – hydrix
    Jan 3, 2017 at 2:13
  • Send it, iterate? Can't help you.
    – paparazzo
    Jan 3, 2017 at 3:05

1 Answer 1


My notions are too large for a comment.

Doing direct array access with the player index seems to pose some memory questions if your int is >32Bits. And even on 32Bits you will waste tons of memory just to hold a mostly empty array. Using a hashmap on the integer seems the proper approach here.

For datastructure: Use a class containing all playerdata. Your access cost will be

  • c to access the player from the hash (it is supposed to have constant access cost)
  • n * c2 to update n values from the client into the player class. c2 is the property access cost (should be neglectable).

  • I would try to keep a network of players nearby each other, so you can limit the players to be updated on each change easily.

  • Keep players that need to be updated in a dirty queue. Update only those clients that are nearby a dirty player.

Iteration is not evil by definition. In the end, you will need to work on every live player out there. If you find, that your updates don't get out fast enough, you need to throw more threads on the task. If you throw your updates to be sent into a queue, you can dynamically fire up more transmission threads to draw from the queue and push data to the clients.

  • As for transmission structure: NetIO cost is by magnitudes higher than CPU cost or memory access. So, your datastructure should not waste any bytes for "empty slots". If you are below the 1k range with a data structure, your message will be in one frame on the network. Try to keep it that way. I would even consider compression to stay below.
  • Don't transfer to text, send a binary format. The client will have to switch the bits in the right order for deserialisation - doesn't matter: The client has much more CPU/Player than the server :-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.