-
-
Notifications
You must be signed in to change notification settings - Fork 21.4k
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
Input - fix just pressed and released with short presses #77055
Conversation
1db7c0e
to
cd934a5
Compare
@RandomShaper : On reflection I went for the approach of fixing the bug without introducing the extra parameter to give the old behaviour. The old behaviour can be emulated by calling:
But I'm struggling to think of many situations where this would be wanted. Users will likely want to simply know whether the action has been pressed recently. |
My only concern is how this change can break the assumption that just-pressed means currently pressed and the same goes for unpressed. If I'm not mistaken, with this PR it can be both true than an action has been just both pressed and unpressed and you then have to check the current state to know which happened later. |
This is why I originally had the extra parameter to try and emphasize this, but I suspect it would cause more confusion than it solves. I'm not sure there is an easy way to solve this - I would welcome ideas. It is more of a historical oversight I imagine, with the original implementer not considering this problem. Should One thing is certain - the current system of only returning true if currently pressed just plain fails to report keypresses in some situations. If you are using this to e.g. jump, or drop a bomb, this can be a massive problem, so we have a duty to fix this in some way, and many (perhaps all?) of these will involve some degree of compromise. |
Usually, users that check
The fact that the old behavior can be emulated quite easily makes me think that it's the correct thing to do. |
cd934a5
to
ede7a85
Compare
A script in a game could look like that. (Not correct GDScript syntax, but enough for the purposes.) After the change, the |
Just to point out this is a buggy script - it neglects the possibility that a key can be both pressed and released on the same frame. It would probably produce bugs with the current version, given that input can currently be missed. But yes, it is possible there could be scripts that depend on the current behaviour. We could have a backup to the old behaviour with a project setting and normally I go straight for this with a project setting. However in this case I'm not totally convinced it would be necessary and it could lead to the documentation becoming confusing. 🤔 But I'll put one in and we can debate either way. The old behaviour was flat out wrong, and likely to be capable of causing errors for anyone depending on it (even though it may appear to work in most circumstances, it would fail at e.g. low frame rates). So we could argue this should be the "the straw that broke the camel's back" for them to fix their script. But I am happy to have a backup path if this is generally preferred, I do appreciate that people sometimes don't want to deal with fixing things properly (if they aren't aware that it is broken).
Well, I'm not convinced that would be a good idea, both in terms of backward compatibility, and also because users may incorrectly think UPDATE: I've now included a project setting for the old behaviour. Although this is defaulted to the new behaviour as the new behaviour fixes the bug. |
ede7a85
to
de867ef
Compare
My question about the change was about the sample script, to understand what changes are required for users relying on the old behavior. Regarding the project setting, I don't see much the point if it defaults to the new behavior. What I suggested (default is legacy, but new projects override it to the fixed one) allows new projects to benefit from the new behavior while giving existing projects the choice to upgrade or stay, with the latter being automatic if they don't get to know about the change. Otherwise, their games will break and they won't understand. |
I do understand but am not sure this is a good idea, if we consider that this is a bug fix, rather than a feature. Existing games are broken, this fixes them. They will be missing input currently on some systems, even if it does not show on the development system. I have a couple of games which I wrote a couple of years ago that were missing input, and I had no idea why. Now it is clear - the input logic is flawed in the engine. User code is usually not at fault. If we don't fix this by default, most existing games will continue to be broken. Remember the default action of users is no action. Fixing bugs is one area where imo we have to be prepared to risk changes in behaviour (especially if we suspect it will adversely only impact very small percentage, and is easily solvable in those cases). Most users will not want to understand why there was a bug in the engine, they will just want it fixed.
This isn't an "either / or" though. The situation is very different if the change fixes 99% of games, and exposes a script error in 1% or games, versus exposing a script error in 99% of games and fixing 1%. This kind of thing is exactly why we have beta testing. If we fix a bug by default, we can quickly identify regressions, and if at that point we discover a lot of regressions we should then consider defaulting to old behaviour. If we do it before, we will never know the correct course of action. Project SettingWhile I'm not 100% sure the legacy project setting is required, it could potentially be a failsafe, and we could for example, remove it after a beta if there were no reports of regressions. The alternative script changes in order to get the old behaviour are: and
|
That's a good point. Let users catch any problems during betas/RCs. With that perspective, I wouldn't even add a project setting. Just a prominent point in the release notes would do. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But, well, now the project setting is already there, I don't think it's an issue to keep it there as a deprecated item, for extra safety. And we eventually remove it.
3562c08
to
89a3783
Compare
action.pressed = false; | ||
action.released_physics_frame = Engine::get_singleton()->get_physics_frames(); | ||
action.released_process_frame = Engine::get_singleton()->get_process_frames(); | ||
} | ||
action.strength = 0.0f; | ||
action.raw_strength = 0.0f; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These two do get overridden below (providing there are no side effects, which I don't think there are), but we could leave this in for historical / safety. It will be compiled out. But am equally happy to remove.
Previously if an action was both pressed and released on the same tick or frame, `is_action_just_pressed()` would return false, resulting in missed input. This PR separately the timestamp for pressing and releasing so each can be tested independently.
89a3783
to
a3ef092
Compare
I think I've caught all the I wasn't quite sure what the policy is on deprecated project settings in master, let me know if there's anything that needs to be added in that regard. |
Thanks! |
Hey, very nice, thanks! |
Previously if an action was both pressed and released on the same tick or frame,
is_action_just_pressed()
would return false, resulting in missed input.This PR separately the timestamp for pressing and releasing so each can be tested independently.
Fixes #73339
Master version of #77040
Notes
is_action_just_pressed()
andis_action_pressed()
.Example Project
See #77040 for demo project.
Before:
After: