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.