8
\$\begingroup\$

I've currently undertaking quite an ambitious project. In short, it's a real time multiplayer strategy game which has bacteria mechanics.

Essentially, I have two remote players in the environment, and they can spawn bacteria-like units which attack each other and multiply, duplicating themselves until a resource limit is hit. This often results in around 200+ game objects being rendered to the screen, each with their own state and movement. This sounds bad, but the local gameplay against a bot is actually very good, and I've managed to make it quite performant.

However, the issue arises when I try to network this game. I have already attempted to follow this guide to implement this feature: http://www.paladinstudios.com/2013/07/10/how-to-create-an-online-multiplayer-game-with-unity/

This produces quite a slow, displeasing game experience even with the best latency. This is likely caused by having to transmit movement data for hundreds of units.

The question I am posing:

How can I optimize the networking and synchronization of many moving units between two clients?

I've already thought of one way to do this. After spawning a unit, they will only travel in one direction until they hit something - perhaps I can synchronize only when units are spawned and when they interact with another object? Would this have much benefit? What's the ideal way to implement this?

Thanks in advance for responses!

\$\endgroup\$
  • \$\begingroup\$ Is a lockstep model likely to be what I need? clintonbrennan.com/2013/12/lockstep-implementation-in-unity3d \$\endgroup\$ – Rachel Cabot Jul 8 '15 at 22:44
  • \$\begingroup\$ I'm behind a firewall and cant access the example you linked, but have you tried serializing just the object ID, position, and velocity vectors each frame? Depending how clever you get with the serialization algorithm you can reduce the state information to 7 bytes per object. If you ensure that the client assumes a missing ID from the update as a death, and new ones as a spawn, you shouldnt have any problems. \$\endgroup\$ – Stephan Jul 10 '15 at 16:04
1
\$\begingroup\$

For 200+ moving objects, you're definitely going to want to make your game lockstep. With lockstep, comes the need for determinism but that shouldn't be too hard for bacteria (which can be simulated with circle-circle collisions).

If you don't mind my shameless self-plug and want an example with the networking and simulation logic of a lockstep game, check out this asset for free: https://www.assetstore.unity3d.com/en/#!/content/36206. Unfortunately, that version doesn't include all the source code but feel free to hack it with my blessing ;). Here's a video of an early test of DPhysics: https://www.youtube.com/watch?v=NEzOghxfMdU.

The gist of lockstep is syncing input instead of output. This is because with a synchronous simulation, the only thing all clients don't know about is other clients' inputs. The article you linked in your comment explains it pretty well. I'm not sure how in-depth you'd like me to explain lockstep, so I'll cut it off here and expand this answer if you have any more questions.

Update: Think of it as an authoritative server, except the server sends input instead of game state. Since every player can produce the game state for himself from input, there's no need for the server to distribute the gamestate.

\$\endgroup\$
  • 1
    \$\begingroup\$ This approach can potentially lead to de-synching, even if everything is deterministic, just because of the latency between the inputs being shared. As an example, take a game where players try to block the movement of an object by placing walls. On one player's screen he might have timed the placement correctly, and the object is blocked. But the replication of that to the other client may arrive late, and once the wall is placed the object has already passed that location. Depending on your game mechanics, you might need to still periodically send "big picture" updates to re-sync clients. \$\endgroup\$ – Acidictadpole Jul 9 '15 at 15:15
  • \$\begingroup\$ Good point. There is 0 potential of desyncing if this is done correctly. If a packet is missed or comes very late, the client cannot advance to the next frame - he'll have to wait until the packet arrives to execute the current frame. Frames can be represented with integers. The server distributes packets marked with an integer for each frame. \$\endgroup\$ – JPtheK9 Jul 9 '15 at 17:54
  • \$\begingroup\$ Check out the networking and frame logic for yourself. \$\endgroup\$ – JPtheK9 Jul 9 '15 at 17:55
  • 1
    \$\begingroup\$ @JPtheK9 "he'll have to wait until the packet arrives to execute the current frame" And what if the packet never comes? \$\endgroup\$ – Stephan Jul 10 '15 at 15:55
  • \$\begingroup\$ Request a new one. \$\endgroup\$ – JPtheK9 Jul 10 '15 at 16:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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