I’m trying to implement GGPO netcode in my game.
The way it works is, each peer runs a full copy of the game. Every frame, every peer sends its input state for that frame to every other peer, then advances the current frame locally with the local player’s inputs, without waiting for the remote inputs, using input prediction in the meantime (essentially repeating the old inputs; player 2 will keep walking forward, etc.). When those remote inputs are finally received, GGPO will load the last valid local gamestate (the last frame we had remote inputs from), replace the current local gamestate with that valid one, then use both the previous local inputs and the newly received remote inputs to play back those frames again, in order, so the game state can be caught up to where it’s “supposed” to be.
I have several problems to solve here: namely, using UE4 deterministically, saving the input state, and implementing rollback support, but I’m tackling the last one first, since it’s probably one of the most difficult problems to solve.
I’ve spent the last few days doing a good amount of research around here, and I found that everyone else who has tried to do something similar has ultimately given up and gone with an alternative, less-robust (IMO) solution using some amount of replication.
UWorld::Tick() is called once per frame, every frame. Does anyone have any idea how it and other functions need to be tweaked in order to facilitate sometimes calling that function multiple times in a single frame? Ultimately, I’d have to call it from a custom GameMode class’s Tick function whenever a rollback occurs, but without causing an infinite loop of Tick() calling itself. Right now, I’m iteratively fixing issues as they come up, thanks to the handy assertions all over the engine’s source code.
Edit: Over the years, I’ve gotten a number of PMs seeking help for this problem. It might not be obvious, but I never actually solved it. I got caught in the weeds trying to edit the engine to facilitate determinism, which was definitely not the right way to go about getting it to work. Here are some tips.
Try asking someone who did it. The current last post in this thread is by ganoncl, who actually ended up getting an Unreal Developers Network subscription (costs $XX,XXX, but there is a 90-day trial option if you ask for it) for his team. He got Epic to help them figure out how to get rollback netcode in their UE4 fighting game, and it shipped a year or three ago.
Failing that, you can also try the UDN subscription/trial route to get Epic to help you.
Just try to avoid using Epic’s gameplay code, if you can. That was my main mistake. If you roll your own movement system, etc., and just keep it simple, then you can have an easier time creating a serializable game state.