2 Bombazars incorrect ordering effect overridden bugfix - #417
Open
DragosIonita23 wants to merge 1 commit into
Open
2 Bombazars incorrect ordering effect overridden bugfix#417DragosIonita23 wants to merge 1 commit into
DragosIonita23 wants to merge 1 commit into
Conversation
Bombazar's extra-turn/lose obligation was tracked in local closure variables private to each physical card instance. When a second Bombazar enters and destroys the first (both are exactly 6000 power), the destroyed copy's own closure state — loseAfterExtraTurn = true — still lives on and still fires at the next EndOfTurnStep (card handlers run regardless of zone, by design, per the existing code comment). The actual bug is in ordering: Match.HandleFx processes battlezone cards before graveyard cards, so the new Bombazar's "grant an extra turn" callback got appended to the shared ctx.postFxs queue before the destroyed Bombazar's "you lose" callback. The new copy's callback calls ctx.InterruptFlow() (needed to stop the engine's default turn hand-off), which sets ctx.cancel = true. The postFx loop checks ctx.cancel before running each entry, so the older Bombazar's pending loss got silently skipped — giving an unlimited chain of extra turns instead of the ruled-correct loss. Fix - Added generic Card.LocalData/Card.SetLocalData accessors (sim/game/match/card.go) — a per-card store that, unlike conditions, isn't wiped every EndOfTurnStep. - Reworked BombazarDragonOfDestiny (sim/game/cards/dm10/armored_dragon.go) to track pending obligations as an ordered queue (oldest first) in that storage instead of closures. When a Bombazar destroys an earlier copy owned by the same player, it now inherits that copy's unresolved queue before creating its own new entry. Each EndOfTurnStep resolves only the oldest entry in the queue, so an earlier "lose" is never starved by a newer "extra turn" grant — regardless of postFx ordering. - Guarded the transfer to same-controller copies only, so destroying an opponent's Bombazar can never steal their pending loss. Tests added (sim/tests/cards/bombazar_dragon_of_destiny_test.go) - Reproduces the reported bug exactly (two Bombazars back-to-back across the extra turn) — confirmed this test fails on the old code (match never closes) and passes with the fix. - Confirms destroying an opponent's Bombazar doesn't transfer their promise onto yours. Full suite (go test ./...) and the race suite (go test -race ./...) both pass.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bombazar's extra-turn/lose obligation was tracked in local closure variables private to each physical card instance. When a second Bombazar enters and destroys the first (both are exactly 6000 power), the destroyed copy's own closure state — loseAfterExtraTurn = true — still lives on and still fires at the next EndOfTurnStep (card handlers run regardless of zone, by design, per the existing code comment).
The actual bug is in ordering: Match.HandleFx processes battlezone cards before graveyard cards, so the new Bombazar's "grant an extra turn" callback got appended to the shared ctx.postFxs queue before the destroyed Bombazar's "you lose" callback. The new copy's callback calls ctx.InterruptFlow() (needed to stop the engine's default turn hand-off), which sets ctx.cancel = true. The postFx loop checks ctx.cancel before running each entry, so the older Bombazar's pending loss got silently skipped — giving an unlimited chain of extra turns instead of the ruled-correct loss.
Fix
Tests added (sim/tests/cards/bombazar_dragon_of_destiny_test.go)
Full suite (go test ./...) and the race suite (go test -race ./...) both pass.
📝 Summary
Provide a brief summary of your changes and the motivation behind them.
🎴 New Cards Added
🐞 Bugs Fixed
🔧 Other Changes
✅ Checklist
Please confirm the following before submitting your PR:
./sim/tests)📸 Screenshots (if applicable)
If there are any visual changes to the frontend, please include some screenshots or screen recordings of it