GitHub Documentation Patreon donate button

How best to implement an undo/rewind on the server?



  • Hi,
    I'm trying to work out the best way of implementing an undo or rewind function on the server. I realise the JSONPatch stuff gives a delta of what changed but not what it previously was.

    Is there a way to rewind the changes to the state or can anyone advise on the best way to implement one?

    Many thanks.



  • Disclaimer: I didn't implement such a thing by myself. since it is a little time consuming. so maybe someone has a better solution.

    My understanding how to achieve time traveling.

    You start with your base state:

    {
     players: {}
    }
    

    Now you add a player on server tick 1145
    state looks like this after that

    {
     players: {
      "420": {
       name: "Player 1"
      }
     }
    }
    

    Now you add a player on server tick 5000
    state looks like this after that

    {
     players: {
      "420": {
       name: "Player 1"
      },
      "125": {
       name: "Player 2"
      }
     }
    }
    

    so what you have to do is: save somewhere the base state. and every action you do on the state.
    so example:

    {
     baseState: {
      players: {}
     },
     actions: [
      {
       type: "AddPlayer",
       data: {
       id: "420",
       name: "Player 1"
       tick: 1145
      },
      {
       type: "AddPlayer",
       data: {
        id: "125",
        name: "Player 2"
       }
       tick: 5000
      }
     ]
    }
    

    So when the functions which mutate the state of the room are pure functions.
    You can just recalculate the state with all actions to a specific tick.

    if we are on tick 12'000 and we want to rewind 10 seconds. we calculate 12'000 - 10'000 so we get 2'000
    now we just recalculate all actions in the correct order again which happen to the tick 2'000
    so we would get this state:

    {
     players: {
      "420": {
       name: "Player 1"
      }
     }
    }
    

    this is the basic stuff. their can be alot of performance optimisation.
    like after 2 hours of game time you probably dont want to recalculate the hole state from tick 0.
    so you could save a snapshot of the state all 100'000 ticks

    hope this helps.



  • Thanks for the detailed answer you've given here, I hadn't though about using the server ticks to wind back the state. I had made a start by saving the JSONPatch on each state change from the current state to the previous state to a stack and then popping them to rewind the changes. My problem now is when i do an undo it triggers the broadcast patch and then I save a new undo action which would undo the undo i just performed! Struggling to find a way to not save the change made by the undo, but the ticks might help me here.
    Many thanks.


 

GitHub Documentation Patreon donate button

© 2019 Endel Dreyer