🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

How to handle closely triggered client actions

Started by
3 comments, last by hplus0603 4 years, 5 months ago

Hey guys,

This is making my head explode so I hope you can help point me in the right direction. I've simplified the actual process here.

  • There is a server and multiple clients
  • The clients and the server have a 10 by 10 2D array of integers
  • The client can choose any position on the grid and change it to any integer
  • When the client changes an integer it changes locally instantly so there is no input lag
  • The request is then sent to the server and only updates on the server it if that position hasn't been set by anyone else
  • If it's updated, the change is sent to all the other clients and is updated on the clients

Now I'm sure this is a common problem but I can't wrap my head around it. What if two clients try to change an integer at roughly the same time, what is a safe way of doing this. If client 1 has already updated itself locally, but client 2 updates on the server before client 1's request makes it to the server, how do I undo what client 1 has done and update it to what client 2 did.

I hope this makes sense. I'm not really looking for specific answers. I'm more curious if this is a specific topic with a name I can research. Most networking stuff I've read is about movement interpolation, etc. Any direction is appreciated. Thank you.

Advertisement

If you have:

  • reliable, ordered messages
  • change the value and send the request atomically
  • send position, old value and new value in a change request
  • reject changes based on wrong old value on server
  • always send the update to all clients, not just other clients

It should just work correctly, because newer updates from server will always be applied in correct order and the “wrong” value on client will very soon be overwritten by the next server update it receives.

Only remaining problem would be if some other clients change the value twice very fast, such that it's back to the old value and then the change is wrongly allowed. You could fix that with also saving and sending a serial number for each update, then reject outdated requests.

wintertime said:
You could fix that with also saving and sending a serial number for each update, then reject outdated requests.

Is this TCP/IP in contrast to UDP/IP?

Or do you mean: timestamps?

The way you need to do this, is have local state for “received from server,” and “sent to server.”

What you render is “received from server” with “sent to server” as some overlay. Maybe the number-being-changed is in a different color. Maybe it's vibrating. Whatever.

Then, you send to the server “I'm changing the number at location 3, 4 from a 7 to a 9.”

The server will look at 3, 4, and if it is a 7, it will send out “location 3, 4 changed to 7,” but if it's something else, there's a race condition with another player, so the server sends back to only you a message saying “your attempt to change 3, 4 from 7 to 9 failed, the actual value is 5.” It's then up to your game to render some appropriate undo animation. Or maybe you will already have rendered it changing to something else, because presumably the reason this happened, was that some other player changed it right in front of you, and that change was sent out.

enum Bool { True, False, FileNotFound };

This topic is closed to new replies.

Advertisement