Skip to content
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 prediction #321

Open
elementbound opened this issue Nov 3, 2024 · 2 comments
Open

Input prediction #321

elementbound opened this issue Nov 3, 2024 · 2 comments
Labels
feature New feature or request

Comments

@elementbound
Copy link
Contributor

✨ Description

Currently, RollbackSynchronizer doesn't simulate nodes it doesn't have input for. Once the input arrives, the game state is rolled back and the node is simulated.

It would be useful to be able to predict node behavior even if the input is missing, by predicting inputs.

Use case

Games could implement various input prediction mechanisms, instead of always relying on skipping simulation on missing inputs.

One common solution is input decay, where input values are weakened as the input ages. Something similar also works for racing games, where on missing inputs, the game assumes the player slowly lets go of the throttle.

Implementation notes

Rollback synchronizer should expose the following data during rollback:

  • has_input() - Do we have input for the current tick?
  • get_input_tick() - Which tick are we taking input from? Value differs from current tick if has_input() is false.
  • get_input_age() - How old is the input data we're using? In ticks.

Games can use the above to implement their own input prediction mechanism however they'd like. To ease input prediction implementations, RollbackSynchronizer may expose a signal that's emitted after applying state and input for a given tick, but before simulating the tick. This way, input nodes can apply input prediction in their own code and expose data as necessary.

Nodes should still be able to opt-out of simulation if they determine that they can't predict anything with the current input. RollbackSynchronizer should provide a mechanism for this, e.g. by exposing a skip_recording(node). This would enable nodes to do the following:

func _rollback_tick(dt, tick, is_fresh):
    if not rollback_synchronizer.get_input_age() > 4:
        # Input too old, can't predict
        rollback_synchronizer.skip_recording(self)
        return

    # [...]

To avoid breaking games during a version upgrade, input prediction should be opt-in. A flag to toggle input prediction should be included either as a property of RollbackSynchronizer, or as a project setting.

Distribution

netfox core

@elementbound elementbound added the feature New feature or request label Nov 3, 2024
@TheYellowArchitect
Copy link
Contributor

TheYellowArchitect commented Nov 4, 2024

get_history function is probably better to be split up, since there are only 2 buffers possible: State or Inputs, so no need to generalize the buffer parameter. With this, get_history for inputs should work with added logic to return a predicted input

P.S. You have no idea how hyped I am for this. It is the conclusion to all rollback - basically a full simulation running as if 0 ms. The only real problem with input prediction once it works, is the correction causing visual artifacts or being too snappy, but with input decay and tickinterpolator (and screen latency), it shouldn't be ever a problem, so I'm glad you brought up input decay, its a great technique

@elementbound
Copy link
Contributor Author

get_history function is probably better to be split up, since there are only 2 buffers possible: State or Inputs, so no need to generalize the buffer parameter. With this, get_history for inputs should work with added logic to return a predicted input

Splitting _get_history into two methods, one for state and one for input, would just duplicate code. The method tries to get any state that's available in the buffer - if there's none, it will return the latest available at any given tick. So this can be used to get the latest input and predict from there.


P.S. You have no idea how hyped I am for this.

It's been a long time coming 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants