2
\$\begingroup\$

I'm modding a FPS game by adding a 2 player co-op multiplayer to an otherwise completely single player game.

One game instance acts as the host and I try to implement the synchronization of the gamestate as host-authority. The host does a full game state sync every 3 seconds, and inbetween, the host and client mostly exchange small diffs.

The client mostly asks the host to perform certain activities, such as building, adding and removing to/from chests both players can see and interact with.

For example, the player wants to add an item to a chest, so it puts the item into the chest locally, then sends a request to the host so the host does it too on its end. However, if there is a full game state sync right at the same time, the host doesn't know about the item yet, and makes the client remove the item from the chest the client just added. Of course, a bit later the host confirms the original request-to-add and both client and server see the item correctly in their inventory. The item flickers in-and-out for the client which looks confusing.

(There is a reverse problem of this where the client removes an item, the host full sync puts it back, then the acknowledgement removes it again.)

How can I work around this?

What I thought but haven't tried yet is to set a flag on the chest/item on the client so if a full sync comes between the request and acknowledgement, it is ignored by the client with respect to that particular chest/item.

enter image description here

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Why send both full state syncs AND diffs? Are you finding your state is drifting out of synchronization using only the diffs? If so, that seems to be the root problem to solve. \$\endgroup\$
    – DMGregory
    Jun 5, 2022 at 13:29
  • \$\begingroup\$ The mod is work-in-progress. At least half of the game's interactions don't have a diff yet. The full sync acts as a safety net. I asked about the case to assess if it can be solved with minimal coding right now. Or, as you said, there can't be any resolution until all diffs are in place, which may take some time. \$\endgroup\$
    – akarnokd
    Jun 5, 2022 at 16:22

3 Answers 3

2
\$\begingroup\$

Assuming you are using a network protocol that has guaranteed delivery (so either TCP or UDP with a guaranteed delivery layer on top), you don't need to do full inventory syncs.

All you need to do is send the complete inventory when the character enters the game and then update the content with incremental AddItem/RemoveItem messages during the game session.

\$\endgroup\$
1
  • \$\begingroup\$ Thanks. I ended up doing something like this back then. Now not my problem as the game is going to receive official multiplayer run through Unity.Netcode. \$\endgroup\$
    – akarnokd
    Feb 1 at 17:47
1
\$\begingroup\$

You usually want to assume that the client is "truthful" until proven otherwise by the host. What I would do in this case is this:

When the client puts an item on the chest, I would put a timer on the client's side to not be overwritten by the host until one cycle of synchronization has taken place.

That way, the client's actions won't get deleted until the next cycle.

\$\endgroup\$
0
\$\begingroup\$

As MariaA highlighted, it's crucial not to fully trust players in the game.

Make certain the client doesn't locally add the item to the chest. The item should only appear in the chest once the server approves it.

I would also recommend modifying the synchronization process for this. Rather than updating every 3 seconds, it's more efficient to have the client wait for the server to notify it of any changes.

If implementing those change requires adjusting your codebase, it's advisable to invest the extra effort for the future integrity of the game.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .