   Hiding Input Lag in a Lockstep System
  So, I've noticed a few new games that show signs of a lockstepping for the network implementation, such as, Dead Rising 2.  And it got me thinking on this...If I wanted to hide input lag, what would I need to do, and what would it cost?The first [and only] thing that popped into my head is to run two simulations.  The first would be the deterministic version, and the second would be a local prediction simulation.  At the end of each frame, correct the local simulation slightly in favor of the real simulation.  So, what's the cost?  Well, off the top of my head I'm doubling all resources needed for a simulation [mostly just physics information], as well as doubling the sim CPU cost...  And then adding on a rather complex [for newer games] blend phase...Does this sound right?  And that's all I can really think of :)  Anyone else have a history with this problem, or just feels like theory-crafting with me on it?  [if this was in the forum FAQ or somewhere else, sorry I missed it.  Only other resource I saw was talking about Duke Nukem 3D, which said lockstepping with dead reckoning, which sounds similar to above... though I may be missing something...]   
  That is one way, and will generally be robust.Another option is to optimistically assume that the local commands will be correct and accepted, and just show them right away. This means everyone else is running slightly behind you yourself. If there ends up being an interaction that you couldn't predict, you'll be teleported (snapped) in time.;  Ack, so I think I'm missing something simple... could you go into a little more detail?  Seems to detect the error you still need to run a local and a real simulation to detect an error in prediction... and blend [snapping being the simplest form of blend :)].  ;  What he's saying is to have the local simulation always run as though any input you enter is effective, and if it's not, the server will notify you and you can migrate back to the correct gamestate. For example, the player could jump to a platform in front of them. The client believes that the player had enough distance on the jump to make it to the edge of the platform, and so it simulates that the player landed on the platform and continues to run, or whatever. Meanwhile, the server gets the player's desire to jump, and for whatever reason it disagrees with the client and thinks the player doesn't have enough distance, so they fall down a pit. It would inform the client of the result of the action, and if the client was wrong, then they'll snap your player from running along the platform, to instead be falling down a pit.The reason why you may not want to blend would be, in this example, you'd see your character warp through the ground as you interpolated between being on dry land and falling down a bottomless pit. In other game types (like RTSes), the differences aren't likely to be so binary, so interpolation is more reasonable.   ;  Ah thanks, that helps.Gives me something to think on.  Going to code up a prototype once this sprint ends...Thanks again ya two!   ;  A little sound goes a long way.If you can provide immediate audio feedback that the command has been accepted, that can buy you a quarter second, a half second, or even more, depending on the game mechanics.  Things generally don't react instantly in the real world, and if it takes a moment for the physics to catch up, most people neither notice nor care.  Generally the player is most interested that the command has been issued.  They also prefer that the lag be uniform across all players, and since the game is lockstep, that is assured.A little visual feedback also goes a long way.  If you can provide a visual indicator or small animation showing what is about to be done, the player won't object so much that it takes a moment for the simulation to catch up.  The player knows the thing is about to happen, and just like with the audio case above, they understand that the real world isn't instantly reactive.   ;Quote:Original post by Dragon88What he's saying is to have the local simulation always run as though any input you enter is effective, and if it's not, the server will notify you and you can migrate back to the correct gamestate...Isn't this getting away from a lockstep model? Sounds more like client/server with client-side prediction - not that there's anything wrong with that, it's just that you're back at having to send a lot more data than just player inputs, along with a lot more logic to keep things synchronized, which seems like the primary motivation for going lockstep. If you're not worried about bandwidth, or about having separate sims (authoritative vs. predictive), then why start from a lockstep model in the first place? (not just a rhetorical question)   ;Quote:In other game types (like RTSes), the differences aren't likely to be so binary, so interpolation is more reasonable.Actually, in an RTS, you will not speculate ahead, you'll just wait until you know everyone has the command. Meanwhile, you will play the "yes, master!" animation, which is long enough to mask any round-trip latency.Locally speculating ahead is still "lock step," in that you let the player play based on the latest available world state. This will, generally, only end up being wrong if there is some action taken by another player at about the same time -- within one round-trip latency window.A typical example is a health pack on the ground. Two players both run towards it. If they are the same distance away, then each player will believe that they got to it first. However, on the server, it will be decided that one got there before the other. One of the players is now out of sync, and needs to be put back into sync. One way of solving this is to remove the health pack, and perhaps start a small particle system animation, when locally running over it, but only play the "healing" sound, and improving the health bar, when you get the result from the server.The main problem here is that you'll need to run two simulations locally -- one for "everyone else" (which will run behind real time), and one for "you" (which will run ahead of time). This would be hard to explain in greater detail without a fancy timing diagram, so I'll probably stop here :-);  hplus0603 has it spot on.In my current game which uses lockstep, player input is immediate effective. When there is no interferenece from other players, then the local predictive copy of the simulation is identical to the remote copy, and actually runs ahead of the server. It feels like the game is simply running locally, and there is no delay whatsoever when pressing a key to do something. This is exactly how it should be.The local exact copy (i.e. the lockstepped state) runs behind this time. The predictive state may be corrected by taking the exact (lockstepped) state, copying it, and stepping it forward (AND incorporating the correct sequence of player input) to the current time.There are quite a few tricks you need to employ to get his working properly: when you provide input locally, you want it to occur on the exact same logic tick of your simulation as when it occurs remotely. If you can't achieve this, then you will get bad predictions, even without interference from other players.This means that the local predictive simulation needs to be running sufficiently far ahead in time so that if you request "Fire bullet on tick 2119" for example, by the time the server gets to tick 2119, it has already received the request from the client and has it queued up ready to execute.If, say, there is a latency spike and the request gets to the server late, then the server will execute it as soon as it can.  The local prediction (that it happened on tick 2119) will have been incorrect, and when the server sends back the composite player input so that the local lockstepped state can be stepped forward, the predictive state is recomputed by copying the exact state, and stepping it forward up to the current time.As you can see, this involves a lot of copying of the entire gamestate, and stepping game-state forward as many ticks as the size of the latency to correct the predictive state. This is is only possible if your gamestate is light, and optimized for being copied.  Simple cloning (i.e. reconstructing state) to achieve state copies would be disasterously slow.   ;  I should note that There.com had a patent on the extension of this technique, when you decide the degree of forward/back of a given object based on the likelihood that the user will interact with it. Thus, objects that came close to the user would be moved forward in time.However, I believe Quake II would display you at your forward time, and everyone else at their behind time, and therefore you had to aim in front of people who were running, so that part ought to be clear in that regard.The simplest implementation of keeping a log of state I've seen is to define all state of a component as a single struct. Then decide how many ticks of state you want to keep for anyone speculating ahead -- say 16, which gives you > 500 ms round-trip tolerance for the local user.Then, you write your simulation code something like:void simulate(state const *old_state, state *new_state, inputs const *inputs);Just call the "simulate" function on the previous output state in the array, to generate the next slot in the array, and treat the array as a round-robin buffer. This means that you need to keep memory around for any object you simulate ahead, but that'll typically only be the player and his immediate components (guns, vehicles driven, etc). There is no explicit copying, because you read from the old state, and write the new state. You're going to need those two states anyway, if you display at a higher frame rate, and need to do interpolation.