how to implement Rollback Netcode on UE5?

Hi, i have just readed that the new mortal kombat will add “Rollback Netcode” for smooth network play, anyone knows how to implement “Rollback Netcode” into unreal engine 5?

Thanks in advance for all the help

Rollback netcode has been part of UE character movement since forever.
Here’s an in depth video about it :

For a fighting game you might want to include combat moves as part of this replicated movement struct to support rollback-replay of the combat mechanics.
Extending the character movement system has always been a bit of a pain. Fortunately they also made a follow up tutorial video about that. It’s about implementing a sprinting mechanism, but could be virtually anything else :

2 Likes

Thank you @Chatouille i didn’t know that

Hi, I am a huge rollback enthusiast and happy to answer that!

Just to clarify,

Rollback in UE’s Character movement component is not the same rollback we see in fighting games and isn’t good for this kind of rollback.

Rollback in Character Movement sends movement inputs and validates them and rolls your position back in case you did something wrong, and the client doesn’t see “true” state of the game So, if both client and server move on Frame X of the game, the reality is the Client will move on frame X+Lag, he will just see from his perspective that he moved on frame X and won’t be corrected unless he hits something. If client runs side-to-side with the server, in reality he is lagging behind.

“Real” Rollback Netcode tries to keep the simulation as synced as possible, so when client sends inputs from frame X, the game “Rolls back” its state to frame X and resimulates everything with those inputs in mind. Also, when client recieves inputs from server, he does the same. So, the lag is compensated.

If UE was a deterministic game engine , you would be done here.
It isn’t sadly*, most game engines nowadays aren’t. If you will replicate inputs only, the game still might (and probably will) desync eventually, because some floating-point operation will yield microscopically different results.

So, you also have to sometimes replicate the current game state to Clients and order them to resimulate everything from the frame this state was recorded on.

So, key things to do while implementing rollback on UE architecture:

  1. Both clients and servers** need to have the same simulation framerate***, fix it to, for example, 60 fps.

  2. You need some kind of state machine object to record everything you need every frame and be able to “go back” to recorded frames and resimulate**** them. Both on clients and server.

  3. You need to record inputs as well and record them each frame and sync them between client and server

As Server:

  1. When Recieveing an input from a client, use the State Machine to go back to frame this input was from, and resimulate the game with this input in mind.

  2. At the end of the frame, replicate all the inputs you did and got from clients to every client so everyone has the same input list for each frame.

  3. Sometimes, replicate the whole game state as well to keep the simulation in sync.

As Client:

  1. When recieveing inputs from the Server, use the state machine to go back to the frame those inputs are from and resimulate the game with them in mind.

  2. When doing inputs, send an RPC to the server containing them and the frame they were done.

  3. When recieveing a game state from the server, prioritize it over your game state: Use state machine to override the state on frame the recieved game state was recorded on, go back to it, and resimulate the game to your “current” frame .

So, as you see, it’s not an easy task to take. Implementing rollback netcode is a hard thing to do, especially considering that Unreal engine has nothing to make this netcode easier to implement. You basically need to make your own ticking flow to keep the simulation synced between all players.
BUT, If you succeed, your game will play, and be programmable almost like a singleplayer game, where the only disadvantage the client has, is reaction time for attacks that might not telegraph properly because of lags. Server has this problem too, but to lesser extent. (so it’s another plus over normal replication architecture: servers don’t have as much advantage)

Cheers!

Remarks:
/* Mortal Kombat has such a big dev team, they managed to make the game bit-by-bit deterministic… It’s too hard of a task for a single programmer, though.

/** Mortal Kombat went even step further and did a p2p netcode, so they got rid of client-server hierarchy; Each player is treated as an equal player and no one has to wait for server to sync stuff. Again, it’s an incredibly hard task, though.

/*** They don’t need to, you can keep frames recorded on timestamps instead of frames and interpolate between states during resimulations, but this can make the simulation VEEEERY unstable and it’s incredibly hard to implement, idk if even Mortal Kombat has it…

/**** Resimulating usually means Ticking everything again every resimulation frame and redoing inputs each frame. So your game needs to be light in terms of computation power needed to be able to tick multiple times during one frame and not drop in speed.

5 Likes

@Rufus170 thank you for the big explanation, very useful information!