Month: February 2022

Entity Synchronization

Lately I’ve been tinkering with my in-game tower map user interface, and messing with adding items back in.

With the addition of item drops, syncing item data lead me to re-work how I managed entity synchronization. The original solution was quite naive and always updated clients with full entity data, regardless if that data was identical to the data during the previous server tick.

Now, entities will only transmit data if it needs to be sent, so a stationary entity will not have its transform data sent to clients every tick unless it moves and therefore the transform information changes.

I originally put this work on hold and had planned to re-factor it in the future, but as I started to create the new DroppedItem entity, which would represent an item that has dropped in the game world, I realized that the Item information that the entity held was constantly being sent over to all clients and figured it was about time to re-factor and improve the synchronization code. Now DroppedItems only send information about what items they contain when they are initialized. Subsequent updates about the items it holds only happen if the items themselves change.

Another boon to come from this is a new way for clients to learn about new entities. Originally, as I have mentioned, the server would transmit all data about an entity to all clients, and therefore the clients had enough information to re-create the entity from every entity update from the server.

Now that it only transmits updates about entities, clients would need a way to ask the server for extra information about an entity to initialize it before they can apply the updates to it. So now, instead of always having the data needed to create the entities, if a client gets an update about an entity that does not yet exist on its end yet, it will send a message to the server asking for all information about that entity. Once the server replies, the client will create that entity and then be able to apply any subsequent updates it receives from server entity updates.

I had tinkered around with another solution in where the server would keep track of new players and new entities entering a zone and the server would handle sending the full entity payload to clients that needed it, but I thought clients requesting for that information would be a better and easier solution. I feel like having the server manage it could lead to some desync situations that would be very hard to debug and it also brings down the amount of work the server has to do during its game server tick.

I know I promised a post about the in-game map, and that is still coming. I got distracted with the updates I detailed in this post and still need to polish it up. Hoping to get to that soon as well as a post about item drops when I finish them up.

Trivo Multiplayer

When I started working on Trivo, my goal was to make sure that it could be played with friends online.

So I started off with Godot and GDScript and tried to implement their built-in solution which used ENet in the backend.

This worked fine at the start, but did get a little messy. Eventually I rewrote all of my code in C# and decided to ditch the built-in ENet solution for SteamNetworkingSockets.

The main reason I switched to this was because I wanted to take advantage of Steam’s servers to allow players to play with each other without fumbling around attempting to forward the proper ports before they could connect. I feel like most online games nowadays are expected by users to work online without forwarding ports.

So far, everything is working pretty well, I’ve tested with a few friends and it works quite well while being routed through steam servers. I was able to leverage the Steam friends functionality to allow one to join another player through their Steam friend’s list.

I plan to go into more detail about my client / server architecture in a future post, stay tuned.