Best approach to a 100% synchronized action game?

Started by
17 comments, last by hplus0603 18 years ago
Quote:You mean the use of a lockstep model for synchronization in There??


Well, the avatar starts walking immediately when you press forward, so it's a little more complex than that. We also use UDP, not TCP, so we have to deal with packet loss causing divergence. But, yes, that's the starting point of the architecture.
enum Bool { True, False, FileNotFound };
Advertisement
It can't be really lockstep then could it? Or did I mis-interpreted the term lockstep? (With lockstep I assume no states are being updated until everyone has updated the same state for the same timeframe). If you would continue anyways and find out you miss predicted some state at timeframe x, would you roll back or something?
Well, our model is something that you can develop if you start out thinking everything is lock-step, but then you want to make sure that the locally controlled client doesn't have to delay for everyone else's input. We have to manage "what" happens "when" on each client (and stay authoritative on the server) -- kind of like running a separate lock-step simulation for each separate object, and then being very careful in the interface between them.
enum Bool { True, False, FileNotFound };
Quote:
Well, our model is something that you can develop if you start out thinking everything is lock-step, but then you want to make sure that the locally controlled client doesn't have to delay for everyone else's input. We have to manage "what" happens "when" on each client (and stay authoritative on the server) -- kind of like running a separate lock-step simulation for each separate object, and then being very careful in the interface between them.


Hmmm Im still not sure Im getting this :s

So in the end nobody will wait for each other's input, so predictions must be made? Or aren't there any shared objects between players which they can interact with? Could you please explain the notion of lockstep a bit more as used in that model? It definatly sounds interesting but I can't think of any way of running seperate lockstep simulations and still have an interactive simulation without it being just a traditional deadreckoned simulation...
I think the idea is to bascially break the simulation into smaller units, which though not totally indepenent are discrete enough to be able to be locked step asynchronsouly. For instance if each player was a simple state machine driven by inputs, say up/down/left/right. Those inputs drive the characters movement. For that player a single lock step unit would just be themselves. So all the peers would have a running lock step simulation of each player. The problem arises ofcourse when they interact, becuase the entire system isn't locked step, these interactions will cause unpredicable cascading effects. Also if the one unit becomes desynced only they would freeze up.

Then u have to fall back to periodic state updates to syncrohize the system to an acceptable level of error. Your never going to get 100% sync, but that's not the goal.

I would go with a centeralized client/server, where the server is authoritve for events which can modify the world, like large goauging explosions etc..

Even though your world can have 10000 objects i suspect only 1-5% of them are in view and proably moving/active at once. Using proper scene managment and heavly optimized protocol/update scheme u can get by with such a system.

Good Luck!

-ddn
Quote:So in the end nobody will wait for each other's input, so predictions must be made?


There are cases where you can't lock-step without latency. For example, if there's a gold coin on the ground, and you and I are both close to the gold coin, and try to pick it up, and picking up is an "instant" action (like avatar movement), then both of our clients will predict that we get the coin. The server will break the tie (one of us gets the coin) and ends up sending a correction to the other. The amount of time that you may get corrected for is the same as the round-trip time between you and the server.

Another option to solve the same problem (rather than sending corrections and time travel) is to design latencies into actions. If picking up was an action that took 500 milliseconds, then the server will break the tie before any one of us actually ends up picking up the thing. We've designed our system such that we keep enough state for time travel that both of us could be on separate continents, playing on a server in a third continent, over dial-up modems, and the system will still work. That takes a bit of memory, but our take on that is that memory on the clients is cheaper than bits of bandwidth.

In our model, for each kind of interaction, you can choose points along this spectrum of instantaneous-with-possible-timetravel through latency-and-guarateed-consistent. For things that are unlikely to have contention (avatar movement), clearly choose the instant response. For things that involve many players (applying brakes to a train, or puching the "go" button on an elevator), you sometimes choose to accept some latency, and hide it with feedback animations/sounds.
enum Bool { True, False, FileNotFound };
Ah ok, thanks for clearing that up!

So basicly you have a hybrid of predicted & lockstep events in There... cool :)
So basically lockstep means "parallel simulation of the game state on all client machines"?

Some time ago, I designed a multiplayer algorithm which worked roughly as follows: each client would have its own "belief state" of the world which it simulates, and the server would have the "real state" of the world, which it then spreads to the clients (not the whole world-state per frame, just a little update), so the clients' belief states are kept at sync. This keeps traffic relatively low and is quite general. Does this algorithm have a name?

-- Mikko
Sounds a lot like like "baselining" -- ie, you send user inputs (or deltas) as your typical means of sending updates (I e, "player fired a bullet") but you cycle through all the state and send periodical full state snapshots for objects, so that an object will know that it always receives the sync-ed data every X seconds.

You don't describe how you make sure that quick interactions (jump, shoot, etc) go to the clients quickly, rather than waiting for the potentially long cycle time, though, so it's hard to tell how close it is.
enum Bool { True, False, FileNotFound };

This topic is closed to new replies.

Advertisement