Sure
Both client and server simulation are updated at are using a fixed-time (or fixed rate) loop. The difference it is in how this loop on the client in respect to the server.
Let’s start from the server. The server updates the SimulationSystemGroup (that contains all the simulation logic) every 1/SimulationTickRate milliseconds. Also, in build, forces the engine refresh rate (and so the process goes to sleep) to match the same rate as well.
On the client, the SimulationSystemGroup (and so the PredictionSystemGroup) runs every frame, because the client updates at variable frame rate (and in general != SimulationTickRate, faster or slower).
The PredictionSystemGroup still needs to run a fixed time rate somehow, in order to do the same simulation the server does. But at the same time, we also want the user have immediate feedback (in case of higher frame rate) when it comes to apply inputs to the controller entity.
In order to achieve both, the PredictionSystemGroup the client run “Full” and “Partial” simulation for a given server tick (i.e Tick 100).
A Full Tick is essentially what the server does: the PredictionSystemGroup update all the underlying systems using a delta time that is equals to 1/SimulationTickRate.
A Partial Tick is, as the world says, imply running the underlying systems that are part of the PredictionSystemGroup using a delta time that is less than the 1/SimulationTickRate.
Partial ticks require the predicted ghost to “restart” simulating from the “beginning” of a give Tick (i.e tick 100), and for each successive partial update, an increasing delta time is used.
Multiple partial ticks can occur until enough real time is passed, such that the accumulated elapsed time is > fixed time.
At that point, one Full Tick is going to be simulated (dt == 1/SimulationTickRate) and the remaing part of the elapsed time is again using simulated using a partial tick.
So as an example:
Tick 100 (full)
Tick 101.2 (partial tick, we are updating 20% of the 101 tick) dt == 1/SimulationTickRate * 0.2
Tick 101.6 (partial tick, we are updating 20% of the 101 tick) dt == 1/SimulationTickRate * 0.6
Tick 102.1
- Full Tick 101, dt == 1/SimulationTickRate
- Partial Tick: 102.1 dt == 1/SimulationTickRate * 0.1