Bug details and bookmark logic for future generations:
xmage uses global bookmark per user (player.storedBookmark) -- it helps to reset all tapped mana and other actions by rollback/cancel button;
xmage uses local bookmark in effects/dialogs/engine (int bookmark = game.bookmarkState()) -- it helps to reset some actions and returns to some point in the time;
cancel or game restore process -- xmage take saved bookmark, find game state for it, restore it and delete all outdated bookmarks (all game states after restored point).
put on stack logic uses bookmarks -- xmage create bookmark, put spell on stack and try to pay/activate it -- if something goes wrong then it reset saved bookmark (e.g. restore state to "empty" stack);
global bookmark creates on first mana usage;
some choose dialogs and cards can "close" global bookmark. It's a workaround to hide cancel button after some critical actions. As example: if player saw top library card then he can't cancel it. It uses resetStoredBookmark call to do that.
the problem: that code (resetStoredBookmark) destroy all game states and all bookmarks after some point in time (example: all game states saved after first tapped mana will be lost)
so after game states destroyed -- xmage can't find it for another cancel actions like "put on stack fail" -- and spell are keeps in stack (it's like it was cast for free). That's the current issue bug.
Steps to reproduce:
activate mana ability (it will create save point -- e.g. "save" current stack);
activate something to put it on stack: ability (fixed), spell (fixed, tested), triggered (not fixed, not tested);
do some "bad" actions (game must process it to call resetStoredBookmark -- in most cases it's a simple action or response, see delve's done button example above);
stack restored to starting point (on first mana usage) -- it's important: object will be on stack, but all chosen targets or pays will be reset;
Potentially cheats/benefits:
cast without payments;
resolve ability without or unchanged targets;
Potentially bugged cards (that can broke game state), search by resetStoredBookmark
Bug details and bookmark logic for future generations:
player.storedBookmark
) -- it helps to reset all tapped mana and other actions by rollback/cancel button;int bookmark = game.bookmarkState()
) -- it helps to reset some actions and returns to some point in the time;resetStoredBookmark
call to do that.resetStoredBookmark
) destroy all game states and all bookmarks after some point in time (example: all game states saved after first tapped mana will be lost)Steps to reproduce:
resetStoredBookmark
-- in most cases it's a simple action or response, see delve's done button example above);Potentially cheats/benefits:
Potentially bugged cards (that can broke game state), search by
resetStoredBookmark
Originally posted by @JayDi85 in https://github.com/magefree/mage/issues/6937#issuecomment-668778717