This issue was quite a pain to debug, but at least taught me a lot about about the key multiplayer concepts in the Mirror
library I’ve been using.
So what’s going on here?
So, from a high-level, open the chest, claim an item. The item does appear in my inventory, but is also still in the chest. Why?
The steps for claiming an item are pretty straightforward:
- Remove the item from the chest
- Add the item from the player’s inventory
The wrinkle here is that I want both of these computations to happen on the Server-Side. If it was possible via some client action to perform either of these actions, it would pose a cheating risk. On the server, I can do checks for if the player is actually next to the chest, etc.
Why was one of these actions working and the other not? Well, it turns out that all network objects in Mirror (such as a character, or an item chest) can grant “authority” to a player on a network connection. If a player has authority over an object (like a player character, for instance), the player has the ability to perform actions on the behalf of the player, for instance, moving it. If an action is attempted on an object on behalf of a player who has no authority, the action just doesn’t happen. This was a little surprising to me, I would have expected an error of some kind.
The treasure chest, in fact, had no authority. It is not associated with any particular player, so this makes sense. If that’s the case, how can a player ever mutate the state of that object? This is quite a complicated issue, with several possible solutions, depending on what you need exactly. In our case, because we want any player to be able to act on the Chest, we simply disable the authority check for the particular action of removing items, resolving this bug!