By adding an extra frame of input delay, you can compensate for a single frame of dropped data, provided that you include multiple frames worth of input data per packet. In the image above you can see that, as suggested above, each input is sent multiple times, once to the first frame received and again on the one after.As you can see, the Frame+1 packet gets lost to the dimensional cleft, but because input delay is set to 2, the other player’s Frame+2 is using the input from +0. One frame later it will receive a second packet, containing Frame+1 and Frame+2’s data, allowing Frame+3 to proceed as normal with no interruptions.Simple fix for a simple problem, but there’s a big, big gotcha here that needs to be understood.simple graph showing the effect of frames being skippedIf one game is running slower than another, dropping a frame here or there, it cannot be treated the same as if it were a packet loss. This is because you lose that bonus extra buffer of delay you added to compensate for it, and get effectively nothing of value out of it. Obviously, this isn’t desirable.This leads to the most important rule of this sort of network code: The goal is to maintain complete synchronization with the other system. This includes performance issues. If one has a drop, this drop must be reflected in the other as well. Always. Anything else will lead to a desynchronization of the intended behavior.In an input delay system, you can handle this by knowing both the necessary input delay and the current amount. When a packet is received you can check to make sure that it matches the necessary input delay value from the current frame, and if that is not synchronized, then the code skips the current frame in order to keep synchronization across systems.This is different from waiting for input! The process becomes this:When a packet is received, test to see if the frame for the data given matches the minimal input delay, wait if there was a drop on the other side.When it's time to run the game, the input is necessary, so test with the real input delay value to make sure that you have the data for this frame.This simple model can compensate for single packet losses trivially and still retains full timing synchronization across systems. You can periodically send pings to determine what the minimal input delay should be.simple graph showing rollbacks in actionBut, as we all know, input delay models suck. What we really want is rollbacks, which is the model used by GGPO, Supercade, and RollCaster. This is a system where it runs the game ahead of the opponent’s input, and then when new input data is received it ‘rolls back’ the game and reruns it with the new input. Think of it like retconning things that didn’t really happen.This graph suspiciously looks very similar to our input delay model. That’s because it’s basically the same except that we’re waiting for input data from a different frame! In this case, the current frame minus the rollback amount determines the frame that we acquire data from.You might notice this is parallel here: Input delay is done by adding to the frame before it is sent, rollbacks are done by subtracting from the current frame before getting the input. This way, not only can you mix the two as you see fit, as long as the input delay and amount of rollbacks sum to at least the necessary amount of input delay, the performance will be smooth and clean. Magic!I’m not going into the details of writing the rollbacks themselves into the game engine in this article, but assuming you have that part, that is literally the only change you need to make in order to make them work.But of course, if you have rollbacks, you have what is fundamentally a partially asynchronous networking model. This means you can do some extra magic tricks on top that you couldn’t do before!simple graph showing how rollbacks hide packet lossBecause of the way the model works, if you’re willing to rollback a few more frames than is set, you no longer need any sort of extraneous input buffer to keep everything running along smoothly. Instead you can just keep the game running like normal and then do a couple extra frames of rollback when the data is finally received.Obviously you want to put a reasonable limit on this so you don’t end up one second out without the correct input. RollCaster allows only one extra frame of rollback before forcing a block for input and forcing resynchronization. GGPO will run along for quite awhile as long as it can keep verifying that both systems are running at the same timing.And if you’re wondering, the rule from above regarding keeping synchronization with the other system’s performance must be upheld. If you detect that the other computer is running slowly and has dropped a frame, then you must also wait a frame to keep synchronization, even in a rollback setup. If you don’t do this the two computers will slowly drift out of t