DevLog 10: Networking Synchronization for Enemies

Making a multiplayer game is guaranteed to have full of challenges. In this development blog, I will tell how I'm synchronizing the enemies for BLASTRONAUT online multiplayer mode.

First of all, Blastronaut is a cooperative mining game in an infinite and destructible world. These last keywords will already summarize the challenge quite well. Luckily, it is meant to be played with friends.  That means that I can ignore some of the challenges and cheats that are common in competitive games and just say that it is OK if players can figure out some cheats or if enemies are sometimes teleporting around for clients.

The underlying networking uses Godot Steam integration. And while it solves a lot of matchmaking and connection issues it is quite limited. Basically, I can just send packets between the connected players and that is all that this networking system provides. Everything else has to be done by myself. For the enemies I had to solve the following problems:

  1. How to generate new enemies for each player?
  2. How to keep track of the enemies and make sure that they are the same for each player?
  3. How to update the enemies when they are moving?

One possible solution would be to just simulate the enemies locally for each player. I think it would kind of work unless someone can see another player's screen and get totally confused. It would also create silly moments when your friend starts shooting an empty place because he can see an enemy in there. And finally, it would not allow two players to team together to attack the same enemy. So proper networking synchronization is definitely needed.

This means that for the first problem there was only one proper solution. One of the players who hosts the game is the only one who actually generates all the enemies and sends corresponding packets to other players. This also allows the host to generate a unique networking ID for each of the enemies and use it to control them in the future.

The enemies are stored in an array where the enemy ID matches the location in the array. If some enemies are missing (eg. packets got delayed) those cells will be filled with zeros. When implemented correctly it means that all the connected players have exactly the same array at all times.

Finally, to make sure that enemies appear at the same position when they move, the host sends periodic update messages. This means that while the enemies are allowed to move by themselves, they are still periodically corrected because the movement itself is quite non-deterministic. This update is executed around once per second which is enough to keep the enemies around the same location.

Making such networking systems requires a lot of testing, and it can be quite a nuisance to manually connect multiple players together. To simplify this process I made a Godot plugin called Multirun, which is available for free at the Godot Asset Library. I also created some other tools for simplifying the work, for example, a system for displaying messages directly on the screen instead of the console window.

If this got you interested and you would like to test this multiplayer system. Then don't forget to wishlist BLASTRONAUT on Steam. The next Steam Fest is coming on February 21st and I have promised to put out a new Demo with multiplayer support.

Thank you for reading to the end. I will now reveal the last new enemy: Floater who doesn't want to harm anyone, but his floating abilities are powered by an explosive core that can cause quite a bang!



Log in with to leave a comment.

Been following this project for a while. Excellent work!!

Just found this game today, really enjoyed it. Instantly added it to my Steam and I hope to see more great stuff from you.