Respawn: Flushing the UNDO savepoints

Is there a way to reset the UNDO gamestate database? I know restart does this, but I actually want to preserve CURRENT gamestate, but effectively restart the UNDO database from scratch. This would continue to allow UNDO but put a ‘floor’ beyond which UNDO is no longer allowed. Resetting the database would be the most elegant solution, but I cannot seem to find any way to do that.

I’ve done a cursory dive into the docs and this forum’s history and come up mostly empty.

Barring any info, the ‘best’ (read DEEPLY unsatisfying) workaround I’ve come up with would be to provision a respawnLevel property in the gamestate, autosave the current position, check the UNDONE gamestate against this property, and revert to autosave state (with No more undo information is available. message) state if not equivalent. Probably all while masking some game output. Yeah, feels kludgy.

Okay, a maybe-slightly-better idea. Provision a single-turn undoFence gamestate property which is only true on respawn, and use that property to disallow further UNDOs.

Still love to just reset that database tho.

I don’t know if I’ve tracked what the scenario is you’re wanting to create… (not saying I think I have a magical solution…)

IIRC, a year or two ago there was a debate on TADS3 exhausting the memory allocated to UNDO, perhaps you can find some hint for your problem in that debate ?

Best regards from Italy,
dott. Piergiorgio.

Thanks! That was a very interesting thread, though my main takeaway was that the UNDO database seems buried in the VM, and inaccessible to game writers.

Lol, fair enough, last two missives were sent from DEEEP in the problem-grappling zone. My scenario is this: at certain points in the game I want to offer the player the option to RESPAWN (in addition to or in lieu of standard UNDO/RESTART/RESTORE options). This option is a ‘new life’ situation, like every combat video game you’ve ever seen. Narratively, it is a new character instance, discreet from the one the player had been previously driving. I don’t actually create a new PC though. It is accomplished by teleporting to a spawn point with most of their belongings, but their gameplay ‘history’ is wiped out. It felt like the cleanest thing to do was:

  1. moveIntoForTravel them to the spawn point
  2. somehow erase the UNDO database
  3. (clean up any other respawn artifacts like not-actually-but-for-example restoring enemy health or whatever)

From the player’s perspective, this means you cannot UNDO past the respawn event, that becomes “Turn 0” in a sense.

Here is my current less-kludgey-than-I-thought solution, though it does NOT actually flush the UNDO database. As alluded to above, I provision a property in a gameState object that, when set, blocks the UNDO command. And ‘fakes’ the No more undo information is available. message.

/* ====================================================================
 *
 *   modify Undo to only allow when additionalGameMain does not fence it off
 *   (use to prevent undoing beyond RESPAWN events)
 *
 * ====================================================================
 */
modify UndoAction {
    doAction(issuingActor, targetActor, targetActorPhrase, countsAsIssuerTurn) {
        if (additionalGameMain.undoFence)
            gLibMessages.undoFailed();
        else
            inherited(issuingActor, targetActor, targetActorPhrase, countsAsIssuerTurn);
    }
}
additionalGameMain : object 
    undoFence = nil // prevents UNDO beyond current turn, when set
;

Then, my RESPAWN command mucks with that property appropriately:

respawnObj : object 
    respawn() {
        additionalGameMain.undoFence = true; // set for current turn only, prevents undo beyond this point
        gPlayerChar.moveIntoForTravel(baseCamp);
        gPlayerChar.lookAround(true);
        new Fuse(self, &clearFence, 0);
    }
    clearFence() { additionalGameMain.undoFence = nil; }
;

The respawn method is invoked with new OneTimePromptDaemon(respawnObj, &respawn); to allow any other current turn effects to resolve before moving player. Note this method spawns an ADDITIONAL fuse to disable the undoFence ensuring all subsequent moves allow UNDO. It doesn’t actually clear the UNDO database, just establishes boundaries the player cannot UNDO across.

Obviously, all this is kind of counter to traditional IF player experience. I am taking a leap of faith that I can justify this to the player in a satisfying way.