I'm developing a 2D action side-scroller shoot-em-up game and I recently implemented the multiplayer aspect.

When the server sends packets containing the game state (which are about 500-700 bytes) to a single client, the ping is around 32ms and it works smoothly, but the moment another client connects, both clients start to lag and the ping increases to 200ms and I am assuming that the problem lies with network congestion

So my question is, should the server automatically send data to all clients simultaneously OR should the client ask the server for an update on the game world OR is there another method I do not know about?

BTW I am using UDP protocol as I found TCP to be pretty slow after a certain amount of time in-game.

  • 1
    \$\begingroup\$ Are you sure the problem is network congestion? Have you profiled your network? \$\endgroup\$ – congusbongus Jun 23 '15 at 1:48
  • \$\begingroup\$ How do I profile my network? \$\endgroup\$ – SirBob Jun 23 '15 at 2:06
  • \$\begingroup\$ My network code is written in Python so do I use the profile module? \$\endgroup\$ – SirBob Jun 23 '15 at 2:21
  • 1
    \$\begingroup\$ That's a broad subject and better suited for other stacks. You can get started here; what you're looking for is whether your server is sending/recving too much data for the connection. If you use TCP you can also check whether ACK times are affected. \$\endgroup\$ – congusbongus Jun 23 '15 at 4:29

I think the main problem is that you try to send the whole game state every interval.

A better way would be to split the sync into events and states. Events are important things like a spell that gets casted or damage that is dealt. Events need to get send over TCP because such packages are reliable and sequenced. States are components like the position and rotation of entities. States are sent over UDP because the sequence or packet loss does not matter here, the UDP client sends every interval. Depending on the maximum player count you can use multicasting for the UDP client.


// Sent when an event was requested by a client
public struct ServerEvent
    public int affectedEntityId; // The entity that is affected by this event

    public int receiveDamageAmount;

    public int castedSpellId;
    public int castedSpellTargetEntityId;

    // ...

// Sent every interval (the Source engine uses 66.6ms)
public struct ServerState
    public int affectedEntityId;

    public float xPosition, yPosition;
    public float angle;

    // ...

Because you do not send the whole state of your game, you will need to identify content in your scene. Spells and items the players collect need to be synced so that when a client requests the casting of a spell, every other peer knows what happened. This is easily managable with IDs. Every time new content is added to the scene a new event gets spread over the network. Containing the resource itself and an ID you can easily address specific entities in the game. On the server, these resources can be stored in a dictionary that has a sample instance of every object. This gives you not only a centralized management of ingame content and versioning, you can also add new content to your project, without even updating the client application.

// Sent when a resource is instantiated
public struct ServerSpawn
    public object resourceState; // The serialized state
    public ResourceType type; // The type, identifiable with an enum
    public int resourceNetworkId;

To conclude, my approach on the problem would solve this issue by centralizing the data of your game and splitting the communication in this client/server model into events and states.

| improve this answer | |
  • \$\begingroup\$ If I do this then I have to implement both TCP and UDP protocols for my network... I cant do that because I would need to rewrite my entire network code.. Plus I already tried that it just made things more complicated and buggy \$\endgroup\$ – SirBob Jun 24 '15 at 13:52
  • \$\begingroup\$ BTW I just noticed I was sending packets at 60 packets per second... Is that bad? \$\endgroup\$ – SirBob Jun 24 '15 at 14:03
  • \$\begingroup\$ Ok but then i cant help you. If you developed your whole network code without thinking about it... \$\endgroup\$ – Doctor Niklas Jun 24 '15 at 14:03
  • \$\begingroup\$ 60 packets per seconds is way too much. The average is 15 times a second, every 66.6 miliseconds. \$\endgroup\$ – Doctor Niklas Jun 24 '15 at 14:04
  • \$\begingroup\$ Ok I tried limiting sending packets to every 5 milliseconds.. Now the clients are no longer extremely laggy and the game is playable, but the game is now pretty choppy \$\endgroup\$ – SirBob Jun 24 '15 at 14:08

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