0
\$\begingroup\$

I am trying to implement a game similar to "Street Fighter" by using lockstep networking model so that two players can play remotely via Internet.

I have read a lot of articles about lockstep networking method and I can basically implement the turn/frame handling for each step.

My understanding is that if it's now turn 101 and if player A has not received turn 101 action (packet) from player B, player A has to wait.

When this situation happens, player B has to wait too because player A will not send out further actions to player B because he is waiting.

Should the game do anything for this situation? For example, I saw games like Starcraft, sometimes there is a dialog showing up to wait for other players and if the count down goes to 0, players can disconnect this hanging player.

In order to do so, I don't understand how to decide who is lagging and what the proper handling is. Both player A or player B would think the other party is lagging because he does not receive the packet for his current turn. What am I going to show to the user? And if the lagging continues, how to end the game earlier by giving a correct game result (the player who lags should be given a loss and the other player should be given a win)? Just similar to the countdown dialog in Starcraft.

And on the other hand, what if the situation is not lagging but is a disconnection from player B?

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

With a multiplayer >2 game like StarCraft you can do a best out of X to figure out who's lagging.

With a 2 player game there is no way to know who's at fault as it's a single connection, its that one connection that is having issue.

Again, there is no such thing as player B being disconnected as the one single connection gets broken, both A and B gets disconnected from one another.

You would need a 3rd party such as a game-lobby server to figure out who's at fault. If lobby server is still connected to A but both A and server lost connection to B then B got disconnected from the internet.

Now, the danger in automatically giving the player who lags a loss and the other player a win is that say player A has a fiber-optic connection or access to a botnet, and player B has a regular DSL (even a voice modem can have good ping to handle a street-fighter game), player A can easily DDOS player B into lagging and a disconnection for an easy win.

On the other hand, if you give out draws on disconnection player B seeing as he's losing can disconnect to force a draw.

Welcome to the mess that is dealing with cheaters to ensure en enjoyable experience for the other customers.

Cheers,

PS: I want to re-iterate that an actual hardware modem, even 14.4Kbps, can have a ping low enough to handle street-fighter style lock-step game if all you're sending are tiny game-controller data packets. Turning off the modem's data compression improves the ping further and can even beat DSLs connections on ping. Many rural areas are still forced to use old voice modems, just to say that you could have very different connection types playing your game, leading to the issues of packet-flooding cheaters.

\$\endgroup\$
2
  • \$\begingroup\$ Thanks for the comment. I am actually using a sub/pub server in the middle but the server only relays messages and doesn't do any game logics. Therefore, I am thinking both players will ping periodically and exchange the ping times to know who is the slower one (lagging one). Therefore, without considering packet-flooding cheaters, do you think it's a feasible way? And what others do (any typical way or industry standard?) for this kind of situations? \$\endgroup\$ – Joe Huang Jan 2 '15 at 0:24
  • \$\begingroup\$ If your server is in-between and both clients do not know each other's IP then there's no way one can flood the other and you can know which player disconnects as there are two connections (A<->Server, B<->Server). But this puts extra load on your server and adds extra latency. Once your server is under high load the player experience will suffer as the server itself will become the source of lag. There is no perfect solution, each has its advantages and drawbacks. \$\endgroup\$ – Stephane Hockenhull Jan 2 '15 at 4:17
1
\$\begingroup\$

Lockstep Networking is simple in theory but hard in practice. I've implemented lockstep networked fight systems for AAA online games and I have a few recommendations.

  1. The most important thing is player comfort. If you do an attack, you must play some kind of action on the local player immediately (ie. The next frame). This can be a swing anim, or an effect, or whatever. You MUST not wait for a reply before starting the action as the added latency will make your game feel awful to play.

  2. The most difficult part of Lockstep is to deal with the transmission latency. On LAN, its almost negligible, so it feels fast and good. However as soon as you play online, the 50 - 200ms or so of latency will make your game sluggish and unresponsive. There are a few things you can do to help this:
    a) Decouple your sent inputs from your received ones. Build your system to allow received inputs to be several frames behind where your sent ones are. This means occasionally you will have input conflicts or incorrect actions, but correcting for these is better than dealing with bad latency.
    b) The difference time between the inputs you're sending and the inputs you're recieving is called the 'Transmission Window'. It will shrink and grow depending on your latency. When it gets too big, you know that someone is lagging out. This is how you detect which players to kick. If you're sending at tick 15000 but only recieving tick 14000 from player N, it's time to kick player N out.
    c) Packet loss is your enemy. Losing a single packet in a Lockstep system will screw up your simulation. Even with reliable transmission, the delay between re-requesting a given packet and waiting for it to arrive will grow your Transmission Window like crazy. The solution is to redundantly send historical data with each packet. Lockstep input messages tend to be small, so find out what the maximum packet size for your platform is, and then pack as many old inputs in there as you can. Then, when receiving, if you're expecting input 1200 but you get 1202, you can probably get the missing inputs from the newest packet and avoid a resend.

You mentioned dealing with disconnections: I have an answer to another question that deals with this: Dealing with disconnecting players

\$\endgroup\$

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.