I’m replying a post by @a-tocken from this thread.
I have a some kind of solution for this already but it’s always a compromize. I’ll probably push the commit into my ue4 fork at the end of this week. My changes include also primitive component interpolation between last two fixed timesteps + all needed settings to customize this. I’ll probably not make a PR out of this because I feel it could be done so much better if done fully in a parallel thread but that would require a lot more thought.
What I do myself is that I have two count limits for fixed timesteps. First one defines how many fixed timesteps can be between two ticks when the game runs in normal condition. When this value is exceeded due to small cpu spike etc, it starts to add counts into cumulative counter and there’s a separate hard limit for this one. Cumulative counter is always added current amount of substeps and reduced by max regular condition substep amount (and clamped into 0). Basically what this system allows is that you can momentarily exceed the fixed timestep counts when deltatime is huge for just few frames (like it’s in PIE during begin play). If this condition stays and the cumulative counter never cools down, it falls back into regular substepping. One could just freeze the sim at this point, like you suggested but that could have all kinds of other side-effects (your game time is still running when you do this but physics don’t move etc). Anyway after cumulative counter is empty again, it uses fixed timestepping again.
In theory, it should never go to this unless game totally freezes up (if you block the game thread yourself) or you run really intense physics sim on too weak CPU. Latter scenario would never run properly with this kind of system and your suggestion of just stalling the physics between the ticks after limit would probably look more pleasant to the user (but would mess up the sim for computers that can handle more steps momentarily). If this is an issue, there could be additional checks to fallback permanently to sim freezing mode in case the sim just keeps throttling back and forth to the hard limit but this starts to become quite messy already.
There are many ways to approach this problem and it’s usually specific to your game. Delaying server for all players to some safe value would be the easy solution (but more you delay, more time it’ll take for all clients to get their corrections from server).
While 100% determinism would be nice, getting close enough is often enough. There’s a night and day difference on how closely same PhysX sim goes with fixed timestepping and physx just ticking on Tick. See my post here:
https://forums.unrealengine.com/showthread.php?135955-Networked-Physics-with-PhysX&p=660531&viewfull=1#post660531 Of course this isn’t extensive test as it’s just few rigidbodies but tells much about the simulation itself when even using simple test.
PhysX 3.4 has additional scene flag to enhance determinism but according to the source comments, it mainly makes physx sim more deterministic when there are changes in the physics scene that shouldn’t directly affect existing rigidbodies (so I’d guess it just guarantees that physx keeps same order amongs existing rigidbodies for it’s internal calculations).
I’ve spent few days converting TheJamsh’s networked physics plugin to be more friendly to fixed timestepped substeps but it’s still WIP. Biggest issue with this approach is that you’d really need to delay the server a lot or do some fancier solution where server simulates individual pawns separately. This wouldn’t be as big of an issue if you could actually run the physics sim in a another thread at fixed time intervals as then you’d get constant input updates for the server sim. Now you can get different amount of fixed timesteps between your ticks but your input can be only polled once per tick. You could poll input on each substep but it wouldn’t make any difference since substeps are not truly that far in realtime from the last tick (remember they get all run as fast as CPU can handle them, not at fixed intervals).
All in all, this means that you can’t send the server steady input packets without completely fixing the rendering framerate for the game. And fixing rendering framerate is not really an option that many PC developers want to take (could work for consoles).