1
\$\begingroup\$

I have recently come across a certain problem in programming my MMORPG: the synchronization of shared storage units.

With shared storage unit I intend something like a "chest" that can be accessed by multiple users. Any user can take items from it or put items in it or even move items around and merge items stacks in the chest. To get the idea, think about the guild chest in WoW.

At the moment my approach with non-shared storage is to apply any transaction on the client (move/split/merge they take place instantly on the client) and then communicate to the server the change which also does validation and stuff. This works just fine: it's rather impossible that one client issues a transaction that would conflict with another of its transactions as he always sees an updated state of the storage (because he/she is the only one issuing transactions on that storage).

How do you keep a storage synchronized among its co-owners when they share a storage unit and therefore can issue conflicting transactions? For example: two players issue at the same time a move transaction of the same item.

An approach I was thinking about is scratching client-side prediction for shared storage but that adds some overhead to my work as clients at the moment are not aware (code-wise) that a storage unit is shared. Is there a smarter way to do it?

\$\endgroup\$
2
\$\begingroup\$

To eliminate the possibility of conflicting transactions, the best (and also the easiest!) thing would be to queue the requests you get, and execute them in chronological order. Update their view once a transaction is complete; if they happened to submit the same request as somebody else, the queue will ensure that the person who did it first will have their request processed. Let the other person know that their request couldn't be completed because somebody else already grabbed the item.

\$\endgroup\$
  • \$\begingroup\$ While this is technically correct, this can often lead to states that the code thinks are fine, but wasn't what the player wanted. Having things change out from under you while you're trying to change its state yourself can be frustrating. It also means you need to wait for confirmation of every action from the server before finishing it in your UI, or you could get things popping around - even with an error notification, this is pretty jarring as a user. \$\endgroup\$ – justinian Jun 26 '18 at 16:56
  • 2
    \$\begingroup\$ "but wasn't what the player wanted" - if 2 players want something single, it's natural that only one gets the thing. \$\endgroup\$ – Kromster says support Monica Jul 29 '18 at 7:34
1
\$\begingroup\$

What most games do is send a message to the server when the player starts interacting with the chest. The first player to do so gains exclusive access, until they send a message that they're done using it, and any other player trying to access the chest fails (e.g. gets a message that it's busy). If you make your inventory transactions on those chests require that the player is the one using the chest, then such collisions can't happen.

\$\endgroup\$
  • 2
    \$\begingroup\$ I feel this is not the way to do it. Its far too easy for it to go wrong. What happens if a player crashes when they are accessing the chest? Is it locked forever? \$\endgroup\$ – Imperial Justinian Jun 25 '18 at 14:26
  • \$\begingroup\$ @ImperialJustinian (Hey, sweet username!) Sure, if a player disconnects you need to clean up that state. But there are a lot more race conditions that can happen if you don't have a lock on the whole container, which are a lot more subtle. \$\endgroup\$ – justinian Jun 26 '18 at 16:49

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.