Changing Main Game Loop Or Change World Class

I’m trying to change the game loop to work with a lockstep network model for my strategy game, but I don’t see an easy way to change the main game loop. It looks like the main loop that updates all the actors is inside the uworld class, but I don’t see any world class setting like there is for game mode class and world settings class. Is there an easy way to override the main update loop or another way to implement the lockstep model?

This should be a comment to the above question.

As im working on an RTS too im very interested on this topic, its would be great to have at least a good starting point to override the main game loop to implement lockstep.

Adding code to engine’s main loop is quite easy.
You need to subclass a GameEngine and reference it in your DefaultEngine.ini file like this:

[/Script/Engine.Engine]
GameEngine=/Script/Sample.SampleGameEngine

From there you can define your own Tick function.

But why would you do that? I’m not networking expert, but it seems that unreal’s net code can easily support that protocol. The easiest solution would be to use RPCs to communicate incoming commitments and actual commands.

Thanks! This looks like it should work. Didn’t see that you can override the GameEngine in the config file that easily.

If you’re making an RTS Game or any game that can have thousands of entities you can’t really keep them synced across all players in the game since the network load would be too much. I’m implementing a lockstep networking model that has each computer run the simulation on their own computers instead without syncing all of the entities current position, status, etc. To do that you have to make sure all the computers are running at a set pace.

You can read the article about the game/networking model here that will explain it much better then I can: Gamasutra - 1500 Archers on a 28.8: Network Programming in Age of Empires and Beyond.

I was referring to security aspect, which turned out to be related to article you linked. So yeah, keeping many thousands of objects in sync across network is a challenge. I don’t see however, any benefit from hacking game’s main loop to implement this idea. Making a loop update at a designated framerate(ie lock framerate to 60) won’t help, because network latency will desync clients anyways. Forcing engine to “wait” until every player is at the same simulation step won’t work either because replication works on actor/component level.

The way I see it, is just to derive from GameState and keep a simulation step counter there(not in engine). If step counter increases, all messages scheduled for this step should be executed, and new messgaes should be generated. Implementation details depend on your network type(p2p, or client-server), but all this can be achieved with replication and without messing with low-level code.

Lockstep alone wont do trick, the idea behind this is to have lockstep in a determinism environement. So this way only “orders” will be sent to server that will then send them back to each player viaa multicast RPC then each player will run the simlulation for units position, physics, damage and everything else. Every RTS work on this model, the only RTS i know that was made with Unreal was EndWars and they used the same technique. It’s seems to be the only way to have a reasonable bandwith with so much units and things to calculate in that kind of games.

I wasn’t planning on using any of the actor/component replication features since there will be to many actors to replicate across the network and keep in sync. All I will be sending is player commands across the network and at what turn they need to be executed at.

I thought about doing it the way you suggested with a GameState counter keeping track of the current turn, but this won’t solve the issue of the clients desyncing since you need to make sure all game clients are ticking physics at the same interval between turns and I think the only way to have fine grain control of the physics tick is at the game engine level. Let me know if there’s a better way to do it at the GameState level though since I’m still learning more about how the engine works.

Looks like we might have another problem, it looks like UE4 use physx which is non-deterministic according to their website: PhysX SDK: Latest Features & Libraries | NVIDIA Developer

Humm to be honest I haven’t digged yet into physics, but basing the whole physics system on a proprietary GPU system doesn’t make sense to me. That would leave everyone with AMD GPU with no physics.

On the other end you can always make your own determinism physic engine for the logic model while having physix make your graphical model looks great while having a kind of “spring” feature that always bring the graphical model as close as possible with the logic one.

I made a new question asking about physics in another thread if you’re interested: https://answers.unrealengine.com/questions/23796/are-network-games-with-large-number-of-actors-poss.html

The only replicated actors here would be Player Controllers, Player States and GameStates. With 4-player game means 12 replicated objects - not big deal.

PlayerController - Can be used to generate messages based on input or current state of game. Messages would be something like training a unit in barracks, ordering unit to attack, etc.

GameStates - Push own messages to the server, receive messages from other players.

GameState - Hold current turn counter. At end of turn, notify server that this client is done. When all clients signal end of turn, the server should increment turn count and distribute relevant commands to clients.

All remaining actors are not replicated and their state can only be changed via incoming messages.

As for physics I don’t know what you wish to do with it. If it’s just for visuals, then no problem. Simulate it traditionally and no one will ever notice that there are slight differences in simulation between objects. However if your game’s gameplay depends on physics, then you indeed have a problem. In this article you can see that physx is non-deterministic, which makes it rather difficult to use in lockstep scenario. If physics are important, a solution might be to create your own deterministic and simplified implementation of physics phenomena you need(rather doable without custom engine loop). Same thing may apply(but doesn’t need to) to path finding system.

Some features like GPU particles will be unavailable for AMD users, but traditional physics can still be simulated on CPU.

One problem with this though is your not taking into consideration each unit also has to be ticking the same number of times between each turn. So if a unit ticked on a 1 client for 20ms and on another client for 21 ms then they’ll be desynced. Is there a way to control the amount each actor is ticking from the game state? Also is the gamestate guaranteed to tick the same amount of time on each client?
Either way I’m going to have the physics problem and will probably have to use my own physics solution.

Nothing is ever guaranteed over network :slight_smile: I may be missing something, but I think that, key of this mechanism is to have everything in sync at beginning and end of our “turn”. And we could allow some temporary out-of-sync. We could have six computers, one of which is a low spec laptop. If 5 PCs perform tasks in 20ms, and laptop in 200 ms, then we would have a 180ms lag, and faster PCs should wait until laptop finishes his commands. This is interesting and I think I will implement this and see how it performs.

Anyway, in engine core files I found some interesting things. You can switch engine to fixed timestep by setting GUseFixedTimeStep to true. By default the step is 1/30s, but you can set it to anything with -FPS=x console parameter or by manually setting GFixedDeltaTime. Hope this helps.