doc: Input gathering tips and tricks#452
Conversation
| To have a shared notion of time, *netfox* provides its own time synchronization | ||
| and a *tick loop*. The *tick loop* will check how much time has passed since | ||
| the last network tick, and will run as many ticks as needed to catch up. Most | ||
| often this is a single tick every few frames, but in special cases it might | ||
| need to run multiple ticks in a single loop. |
There was a problem hiding this comment.
Spelling out why we use network ticks over physics ticks can provide clarity on why this is necessary
| To have a shared notion of time, *netfox* provides its own time synchronization | |
| and a *tick loop*. The *tick loop* will check how much time has passed since | |
| the last network tick, and will run as many ticks as needed to catch up. Most | |
| often this is a single tick every few frames, but in special cases it might | |
| need to run multiple ticks in a single loop. | |
| To have a shared notion of time, *netfox* provides its own time synchronization | |
| through its *tick loop*, which handles network ticks. Network ticks are similar | |
| to physics ticks, with the exception that they dynamically speed up or slow | |
| down to keep all clients in synchronized time. Using physics ticks on two | |
| separate machines may cause drift and desync issues, and as such aren't suited | |
| for multiplayer. The *tick loop* will check how much time has passed since the | |
| last network tick, and will run as many ticks as needed to catch up. Most often | |
| this is a single tick every few frames, but in special cases it might need to | |
| run multiple ticks in a single loop. |
There was a problem hiding this comment.
More context is better context, though I didn't want to elaborate on that here - my idea was to give the absolutely minimal description ( what the thing is, but not why or how ), and for further details, direct the reader to the network time guide.
Maybe some extra context would make sense in the NetworkTime guide? What do you think?
There was a problem hiding this comment.
I think context is important where it's going to be used. Having someone read through this doc without proper context would make it harder to grasp exactly why it's done this way, and directing them to an entirely different document with more information than is needed could overwhelm them. No reason it couldn't be in both places, but I see this document as part of a starting point for people to understand the networking, whereas minimal context is more for already experienced devs.
| Since multiple ticks may be ran in a single tick loop, it makes no sense to | ||
| gather input for each tick - the hardware wouldn't update, since the ticks are | ||
| run one after the other. | ||
|
|
||
| Instead, ticks are gathered *before* each tick loop. This explains why special | ||
| measures need to be taken in some cases. |
There was a problem hiding this comment.
Multiple ticks being run in a single loop do need input gathered for each tick though. If ticks 7, 8, 9 get run for the same tick, all ticks should register a held action, but only tick 7 should register a just_pressed action.
| Since multiple ticks may be ran in a single tick loop, it makes no sense to | |
| gather input for each tick - the hardware wouldn't update, since the ticks are | |
| run one after the other. | |
| Instead, ticks are gathered *before* each tick loop. This explains why special | |
| measures need to be taken in some cases. |
There was a problem hiding this comment.
True, but I don't see yet how that leads to your suggestion of deleting those lines.
If ticks 7, 8 and 9 get run in the same loop, it makes no sense to check inputs again - they will yield the same value, as the OS hasn't updated the input devices yet. Hence running the gather code before the loop.
And the mentioned special measure is explained later, which makes it possible to have a just pressed input on tick 7, and a held input on 8 and 9.
My intention was to shed some light on why the examples and BaseNetInput use the before loop signal for input gathering.
Could you please clarify / rephrase your reasoning? Thanks!
There was a problem hiding this comment.
Referenced in a below comment.
| 0 is Empty | ||
| 1 is Up | ||
| 3 is Right: Tick | ||
| 4 is Up | ||
| 6 is Right: Tick |
There was a problem hiding this comment.
To be in line with the majority comment below, and have a non-tick contain a right input to break the correlation of right being pressed coinciding with Tick.
| 0 is Empty | |
| 1 is Up | |
| 3 is Right: Tick | |
| 4 is Up | |
| 6 is Right: Tick | |
| 0 is Up | |
| 1 is Up | |
| 2 is Up | |
| 3 is Right: Tick | |
| 4 is Up | |
| 5 is Right | |
| 6 is Right: Tick |
| _movement_buffer = Vector3.ZERO | ||
| _movement_samples = 0 |
There was a problem hiding this comment.
This would cause artifacting. If ticks 7, 8, 9 were run simultaneously, 7 would be gathered as movement, and 8, 9 would be given a movement vector of 0, even if you've been holding the buttons down continuously.
There was a problem hiding this comment.
I don't think so - _gather() only runs at the start of the loop, and then the same values are recorded for ticks 7, 8, and 9. Please let me know if I'm missing something!
There was a problem hiding this comment.
I think I was misunderstanding how _Gather applied its inputs for this and the comment for lines 21-26. If this doesn't cause an issue then the other comment shouldn't be an issue either.
| Godot provides methods such as [Input.is_action_just_pressed()] to check if a | ||
| given input was just pressed. Counterintuitively, this does not work as | ||
| expected - let's see it on a timeline: |
There was a problem hiding this comment.
Explaining the reason why it doesn't work with netfox would be beneficial to teach readers:
| Godot provides methods such as [Input.is_action_just_pressed()] to check if a | |
| given input was just pressed. Counterintuitively, this does not work as | |
| expected - let's see it on a timeline: | |
| Godot provides methods such as [Input.is_action_just_pressed()] to check if a | |
| given input was just pressed. Unfortunately, the built in function of | |
| [Input.is_action_just_pressed()] is hard-coded to work with physics ticks and | |
| process ticks, but won't work with our network ticks. See the below example: |
| This can be solved by sampling the input on each `_process()`, and setting the | ||
| corresponding variable to true: |
There was a problem hiding this comment.
Doing sticky inputs through the _input override may be a better practice, don't have an example to suggest though.
Closes #402
Rendered page