Skip to content

RollbackSynchronizer removes mutated states on rollback #383

@DustieDog

Description

@DustieDog

🐛 Description

RollbackSynchronizer is designed to use less processing power by determining how far it needs to roll back, then only simulating individual nodes from there. This works when the node has no possibility of mutating the state of the game, but as soon as the node can mutate others this logic breaks down. Consider the following, using the concepts from the mutations documentation :

Players A and B exist and use RollbackSynchronizer to sync their input and state.

  • The server is on tick 10
  • The server receives A's tick 8 input, which pushes B and calls mutate on B
  • Player B's rollback resimulates from tick 8 due to the mutation, and the world state on the server is correct.
  • The server receives A's tick 9 input, continuing with its simulation as normal.
  • Some amount of time later server then receives player B's tick 7 input. B now rolls back to 7 and resimulates, but A doesn't get resimulated for ticks 7 or 8, so when B resimulates tick 8 it doesn't get shoved, and then overwrites the data with what it believes is the 'correct' state.

At that point, B now no longer gets shoved and continues on its way. This logic expands to any behaviour that modifies states managed by RollbackSynchronizer.

Steps to reproduce

  1. Create a new netfox project that has a client and a server.
  2. Add a node that has RollbackSynchronizer manage a state and an input.
  3. Introduce latency between your client and server.
  4. Add logic that mutates the managed state at any given tick X.
  5. Update the client's input at any given tick Y, where Y < X and within the history limit.
  6. The mutation has now been removed from both the client and server's managed node.

Expected behavior

Server Reconciliation should give an accurate current world based on the inputs previously provided. In the above example, so long as B was still in range of the shove it should still be shoved.

Notes

This doesn't just apply to mutations that've already happened, but to all logic that can potentially mutate. IE if A input a shove request but B wasn't in range at the time, but after receiving the input for B it would now be in range at that time, the shove won't go through, which again is a subversion of expectation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions