-
-
Notifications
You must be signed in to change notification settings - Fork 97
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement semi-fixed timestep / manual stepping #236
Comments
This comment was marked as outdated.
This comment was marked as outdated.
Note that Unreal engine uses semi-fixed timestep and the default is to not have fixed timestep i.e. smooth physics is default, probably for the concerns mentioned above. "Physics Sub-step" has to be enabled from the settings (and it makes code a lot harder to work with unfortunately). It's worth having and enabling by default in godot, but I'd still like the alternative to be as easy to implement/work with as it is now. Look at this article for the devs perspective, specifically the "Why doesn’t UE4 use a fixed timestep?" section:
I personally fundamentally dislike how they architected the fixed timestep interface, but they have some valid points about why semi-fixed timestep should be an option. |
It seems like the Unreal guys may have made a historical architectural mistake by assuming semi-fixed, which made it more difficult to retrofit fixed timestep. Godot and Unity are both far more agnostic in this respect and allow you to sensibly process things in either the fixed or frame update. Luckily for us, implementing semi-fixed AFTER fixed makes things a lot easier. The only gotcha with the move to semi-fixed is that you have to start using the delta in the _physics_process function, if you weren't using it before: i.e. you have to use:
rather than
On the other hand, we missed a trick by not having built in support for fixed timestep interpolation from the get go. My smoothing addon works to allow this through an extra node, but it would have been neater and easier to use (particularly for beginners) if it was a built-in feature of Spatial. This would have made us a class leader in terms of timestepping. I actually did investigate this, and got it working, however it made the code too spaghetti because Spatial etc had not been designed from the start for this kind of use. |
@lawnjelly It would be worth breaking compat in 4.0 (or 4.1 so majority of people can get Vulkan without breaking physics) if it means we can get this working natively without any messy hacks. Physics is one of those areas where you really don't want to do a lot of hacking to rewrite yourself, and is one of the few things I actively hate about other engines. I think |
The semi-fixed PR as is works seamlessly, is backward / forward compatible and there are no hacks needed, you merely change the option from Fixed to Semi-Fixed in project settings, that's it.
Using fixed timestep interpolation on the other hand is a little more involved than it could be, as it has to work within the existing framework. I tried to make this as easy to use as possible with the addon. Last time it was discussed, reduz was against having fixed timestep interpolation in core. None of the timestepping various options should have to break compatibility, afaik, I had them all working in 3.1 months ago. |
As far I understand, you should use delta anyway, otherwise changing tick rate breaks the code (it can be different per project settings even if constant in the same run) |
Fixed physics delta time is really useful for physics stability and for networking (since it's the first thing to have to get a deterministic time step). All games with such requirements can't benefit of the semi-fixed approach and so I've proposed the object interpolation approach, that solves the position problem while keeps physics delta time fixed: #671 |
I'm interested in manual stepping for a multiplayer physics based game that I'm working on. From some GDC talks that I've watched it seems like this would be very useful for that scenario. |
Just stating this is something I would find extremely useful, particularly for networked physics. It would be a great help for building multiplayer games. Definitely should be on the roadmap at some point. (4.1 seems a little far, but maybe not when compatibility is concerned.) |
This comment was marked as off-topic.
This comment was marked as off-topic.
@fakhraldin I think this is referring to frame pacing, which is a related, but orthogonal issue. EDIT: |
Describe the problem or limitation you are having in your project:
Godot currently only supports fixed timestep. While this is my preferred method, in most cases it requires the use of fixed timestep interpolation in order to prevent jitter due to aliasing between physics ticks and frames.
This interpolation is now supported via godotengine/godot#30226 ,
example addon here: https://github.com/lawnjelly/smoothing-addon
During the development of the above, a simpler alternative strategy was also discussed (used by default in some engines, e.g. Unreal) to overcome this same problem of physics ticks / frame synchronisation - the use of semi-fixed timestep. This can be simpler to work with, particularly for beginners and game jams, and can provide a more responsive input experience in certain circumstances.
On the other hand, semi-fixed can suffer from lack of deterministic behaviour. This can make debugging, testing and QA difficult in some types of game (hence why I personally prefer using fixed timestep interpolation). This is a trade off.
Anyway in the interests of a rounded approach to the problem I investigated semi-fixed as well as fixed.
Describe how this feature / enhancement will help you overcome this problem or limitation:
Semi-fixed time step overcomes the need to use fixed timestep interpolation. Semi-fixed timestep can be used to limit the problem of physics 'explosion' due to too high deltas, when stepping physics by frame deltas, and can also be used to lock physics ticks to frames, or the frame rate.
Show a mock up screenshots/video or a flow diagram explaining how your proposal will work:
I've already implemented semi-fixed using a hard coded path.
Semi-fixed logic is something like this:
This is the semi-fixed timestep selectable in project settings (note that delta smoothing is not part of this PR):
If we do decide to add semi-fixed, it is notable that it can either be hard coded (as I have done already), or implemented as a customizable callback in e.g. gdscript.
A customizable approach also has the potential for a tie in to solve the issue of the desire to manually step the physics in network games, both at the server and the client:
godotengine/godot#25068
Describe implementation detail for your proposal (in code), if possible:
I've already implemented semi-fixed timestep, as a hard coded solution, selectable from project settings:
godotengine/godot#30798
Alternatively custom manual stepping can be implemented as a callback (I've already done this in another area for delta smoothing), which also has the potential to provide a mechanism to allow manual stepping for multiplayer. However this would require some investigation because although running the main iteration from a callback is feasible, multiplayer may better be accomplished by allowing stepping from within _process during the frame update, which may or may not be feasible.
If this enhancement will not be used often, can it be worked around with a few lines of script?:
No, in both cases this would need core support.
Is there a reason why this should be core and not an add-on in the asset library?:
It cannot be implemented as an add-on.
Extra
I originally wrote the PR before godot proposals, but it seems a good idea to discuss the whole area here, as there must be overall support of the idea if we are to go ahead with it (or similar).
There are 3 possible options here:
Probably strangely for a 'proposer', I am equally happy with any of these. It really boils down to the Godot mission statement, where we want to go with the engine - become highly focused for making single player games via a common method, or make it more adaptable. This involves trade offs, more options can bring in greater complexity and surface for bugs.
Realistically, if we did add semi-fixed I would tend towards the KISS principle, keep it simple stupid and go for the hard coded approach. I think most people for whom semi-fixed would be useful would be far more likely to use it if they simply had to switch it on in project settings, then forget about it, rather than write or copy some custom scripts.
Addendum
Just to add a little as we may get to discuss this soon:
Fixed to refresh rate
Another additional option that reduz is keen on, which is changing the fixed tick rate at runtime to match the refresh rate of the monitor.
This has some advantages - it is simple to use and does not require interpolation. On the downside, it means that game behaviour will be different on different machines, and may not play nicely with variable refresh rate monitors.
Delta smoothing
For best results with interpolation and semi fixed it can be a good idea to consider delta smoothing as an additional step. This is an attempt to compensate for the sources of error in making delta measurements to drive timesteps. This is fairly easy to implement and I got this working while I was working on the timestepping last year (both hard coded and with custom script interface), and is fairly simple to add, I didn't make a PR because I was waiting for decisions on timestepping.
Fixed timestep without interpolation offers some insulation against this problem. There are also some newer APIs in vulkan and android for improving frame timing information.
The text was updated successfully, but these errors were encountered: