The citation from Infocom’s documentation was an attempt to understand the “invalid” portions of your table (e.g. a cleared bit but @save_undo
succeeds). I agree that modern interpreters shouldn’t be following Infocom’s documentation. It was (apparently) a misunderstanding of the save bit that led to the current standard’s mandate that it be cleared. More an explanation of the status quo than anything that addresses your actual problem (sorry!)
I’ll try to do quick answers to your “competing concepts” area:
1b. This has to be correct because the flag is not marked as Dyn in §11.1.
2b. This is marked as Rst so it needs to be reset per §6.1.2.2.
3a. Agree with your reasoning.
4b. Same reasoning as 1b.
I think what it comes down to is that the standard doesn’t say you should be updating this flag in real-time, so you can’t expect it to be updated in real-time. The important parts are:
- The flag will be cleared on startup if undo isn’t supported.
- The flag will persist across an undo (which is pretty meaningless since the flag won’t change: as mentioned by Dannii, this is more important with save, when the save file can come from another interpreter).
As a game developer, you can only rely on these since it’s what the standard says must happen. Even if an interpreter decided to update a flag each turn, nothing requires any other interpreter to do so.
My feelings as an interpreter author:
Interpreters should never set bit 4. If it’s not set initially, that’s a signal from the game that it doesn’t want to use the corresponding opcodes. If it does wind up using them, I think the interpreter should oblige if it can, but if not, so be it.
Games should only rely on @save_undo
, not checking the bit. There may be some corner case I’m not thinking of, but if you want to make use of undo, just try calling it: you’d have to try it anyway, if the bit is set. If the bit’s not set and you try, you’ll likely just fail, but you have to handle failure anyway.
As a corollary, I don’t see any reason to care about reconciling bit 4 and @save_undo
results. While I think interpreters should clear the bit, that’s only because the standard says they should. Games ought to treat it like Infocom did: purely as a signal that they’ll probably use those opcodes. Any interpreter that’s worth using will gracefully fail (i.e. return -1 or 0) even if it cleared the bit.
Is there a specific case you’re looking to handle, such as telling the user up front that undo definitely won’t be supported? That would be reasonable, but could be hacked around by calling @save_undo
once, up front, and if it fails, just assume for the rest of the session it’s not available. You’d have to arrange for @save_undo
to be called again in a suitable location, though, before the user can try to undo, or they’d wind up undoing back to the starting message. This is a case where the interpreter saying “I don’t support undo” would be useful, now that I’ve thought about it, but it’s just not something that you can rely on. I can say with certainty Bocfel (Gargoyle’s interpreter) doesn’t behave that way, and I expect some non-trivial number of people will play the game that way. @Dannii can probably offer input as to whether ZVM sets the bit, though I’m willing to bet it doesn’t (and this would cover Parchment/Lectrote which is likely the majority of users).
I’m willing to take some time looking through various interpreters to get a definitive picture on the real-world implementation of this.