3
\$\begingroup\$

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.

\$\endgroup\$
4
  • 1
    \$\begingroup\$ Are you sure the problem is network congestion? Have you profiled your network? \$\endgroup\$ Commented Jun 23, 2015 at 1:48
  • \$\begingroup\$ How do I profile my network? \$\endgroup\$ Commented Jun 23, 2015 at 2:06
  • \$\begingroup\$ My network code is written in Python so do I use the profile module? \$\endgroup\$ Commented Jun 23, 2015 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\$ Commented Jun 23, 2015 at 4:29

1 Answer 1

1
\$\begingroup\$

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.

Example:

// 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.

\$\endgroup\$
9
  • \$\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\$ Commented Jun 24, 2015 at 13:52
  • \$\begingroup\$ BTW I just noticed I was sending packets at 60 packets per second... Is that bad? \$\endgroup\$ Commented Jun 24, 2015 at 14:03
  • \$\begingroup\$ Ok but then i cant help you. If you developed your whole network code without thinking about it... \$\endgroup\$ Commented Jun 24, 2015 at 14:03
  • \$\begingroup\$ 60 packets per seconds is way too much. The average is 15 times a second, every 66.6 miliseconds. \$\endgroup\$ Commented Jun 24, 2015 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\$ Commented Jun 24, 2015 at 14:08

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.