Like Keith said... you have 3 options for storage locations: the state, a game object (like a character, macro, table, handout, etc.), or the closure of the script, itself. The state persists between games, but it is limited in what it can store (and can make the scripts in a game behave unpredictably if it gets filled). A game object might seem like the easiest, but you would have to create the object, then have a way to encode and parse the information you want to store. (You might be storing data for multiple tokens and multiple back-moves...) The script closure gives flexibility in storing the data (using native JS structures), but it will be lost if the sandbox crashes or closes (ie, between sessions). Depending on whether you care if you lose "move-backs" when the sandbox reboots, I would suggest using either the state or the script closure. To use the closure of the script, you'll need to nest your on:chat function in an on:ready function (this will also make it so that metascripts can still be useful, if you needed them). Then your data structure can be stored in the on:ready, at a level parallel to your on:chat: on('ready', () => { const tokenHistory = {}; on('chat:message', msg => { // ... chat code here }); }); Regardless of using the state or the closure of the script, I think I would have the keys of the object be token IDs, and below that "Undo" and "Redo" properties for each token. The value of those properties would be an array where each entry was the data you needed to track for undoing a move. Maybe that's just the left and top properties, or maybe you want the rotation, too (to reset the side facing). The "Undo" array would the "the moves that can be UNDONE"... and the "Redo" array would be the moves that can be REDONE". { '-M1234567890abcdef': { Undo: [ { left: 450, top: 70, rotation: 0 }, { left: 520, top: 70, rotation, 0} ], Redo: [] }, '-Nabcdef0987654321': { Undo: [ { left: 376, top: 140, rotation: 45 } ], Redo: [ { left: 400, top: 220, rotation: 45 } ] }, // etc... } Decide a number of moves to track (maybe 5 for each token... maybe 10). Every time the token moves, drop the appropriate data into the array. If you commit something to the "Undo" array (e.g., the token makes a new move), empty the "Redo" array, since you've lost that branch point in your backtracking. If you choose to "Redo" a move, move the last entry in the "Redo" array to the "Undo" array. In this way, you give yourself the option to do - undo - redo as much as you like. That would require a command to trigger the undo vs redo. Maybe with handles like: !undo @{target|token_id} !redo @{target|token_id} Then, you could click that button, click the token, and execute the code. You could even drop buttons in chat at that point that would have the token_id already configured in the command line (instead of the targeting statement), saving you having to re-target the same tokens for "undoing" or "redoing":