godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.14k stars 93 forks source link

Add a `subframe_timeout_enabled` property to `Timer` node #2734

Open Error7Studios opened 3 years ago

Error7Studios commented 3 years ago

Describe the project you are working on

Project requiring fast Timers

Describe the problem or limitation you are having in your project

As discussed in #48786, wait_time of Timer is limited by rendered frame speed. So with Vsync enabled, a Timer with wait_time of 0.001 will only fire 60 timeout signals instead of 1000 over 1 second.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

Add a subframe_timeout_enabled property to Timer node. When enabled, Timer will actually fire 1000 timeout signals over 1 second when wait_time is set to 0.001.

When disabled, show a warning if wait_time is set below:

    0.0166 (60 Hz) with TIMER_PROCESS_IDLE
            or
    1/(physics fps) with TIMER_PROCESS_PHYSICS

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

bool subframe_timeout_enabled [default: false]
    When true, allows 'timeout' signals to be emitted faster than rendered frame speed (default: 60 FPS)
    Only applies when process_mode set to TIMER_PROCESS_IDLE

If this enhancement will not be used often, can it be worked around with a few lines of script?

No. However, if the user does not have Vsync enabled, then they probably won't even discover this limitation.

Is there a reason why this should be core and not an add-on in the asset library?

This is a core change to the Timer node.

Calinou commented 3 years ago

Does it need to be a property? Personally, I'd have this always enabled since it seems to better match users' expectations.

We should probably limit the number of calls per frame to avoid issues with freezing, but this should probably be adjustable with a project setting instead of a per-node property. I'd set the default to something like 20, which allows up to 1,200 simulated timeouts per second at 60 FPS. Timer's timeout property hint doesn't allow setting timeout below 0.001 after all.

PS: Note that this proposal won't address https://github.com/godotengine/godot-proposals/issues/1151 because timeout signals will be "batched" together in the same rendered/physics frame.

Error7Studios commented 3 years ago

Does it need to be a property?

Nope. 🙂 Just suggested it as a non-default property for compatibility. But if it's a 4.0 change, then compatibility doesn't matter.

Personally, I'd have this always enabled since it seems to better match users' expectations.

I agree.

this should probably be adjustable with a project setting instead of a per-node property

Now that you mention it, that's an even better idea.