Skip to content

Fix Reflection abilities and Temporary Deathknell resolution - #1

Merged
abueide merged 3 commits into
mainfrom
fix/reflection-triggered-abilities
Sep 22, 2026
Merged

abueide merged 3 commits into
mainfrom
fix/reflection-triggered-abilities

Conversation

@abueide

@abueide abueide commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

Problem and reproduction

LeBlanc Deceiver copies Honest Broker into a Temporary Reflection. When both die in one combat, only one Gold appears. The new regression reproduces 1 Gold instead of 2 before the fix. Temporary killing that Reflection also reproduces 0 Gold instead of 1.

The token's copied face already resolved its printed script while present. The bug was that the chain retained only a source ID and ability index: after the token despawned and a later request rebuilt the script cache, its queued ability had no implementation.

Fix

  • Snapshot printed ability script identity centrally when pending items are enqueued, and use it throughout ordering/targeting/payment/resolution.
  • Preserve same-request access to a departed token's last face while collecting its Deathknell.
  • Refresh transformed static sources immediately, including copied auras and play restrictions.
  • Keep copies as tokens and LeBlanc's separately granted Temporary; do not copy damage/buffs/attachments or replay Play triggers.
  • Version plugin 0.9.1, blob 16. Prior supported blobs still decode; framework wire protocol is unchanged.

Ten regressions serialize state and rebuild scripts between actions. They cover combat, Temporary before Hold scoring, multi-stage Deathknell, movement, activation/keywords, queued abilities surviving another transformation, immediate auras, copying a copy, bounce without Deathknell, and Reckoner's Arena queuing a copied Conquer trigger. Independent review found the Arena bypass; the shared queue entry point and failing-then-passing regression address it.

Official rule source

Core Rules PDF — July 16, 2026, verified against the publisher's current rules hub: 477.1.b.1 (copyable traits/rules text), 808.1.c–d (Deathknell and last-known details), 816.1.b (Temporary kills before scoring).

Verification

  • Rules library: 4,577 passed, 172 pre-existing ignores.
  • Blob compatibility: 13 passed; match-state integration: 10 passed.
  • Plugin library/projection: 10 passed.
  • bash ci/check.sh and repository treefmt --ci: passed.
  • Portable release plugin built and hardened successfully.
  • Kai's companion dependency pin passed its fast checks and all-target compile.

Additional broad hardened replay check hits an existing Temporal Portal/Repeat payment fixture assertion at net/tests/riftbound_turns.rs:1156; reproduced identically using unchanged baseline 8765cdf and a separately rebuilt 0.9.0 plugin. Not changed here. Gas benchmarks are ignored by default and not counted as passing coverage. No manual GUI/network playtest or Android build.

Integration

Kai currently builds this Agni rules copy, not the extracted agni-rfb repository. A companion Kai PR pins this branch's commit and bumps Kai to 0.21.2. Merge this PR before that integration. Rebuild/harden bundled modules for release; existing matches stay pinned to their old plugin hash. Older snapshots cannot recover the script identity of a token that had already vanished before this fix.

Companion Kai integration PR: abysl/kai#1

Review follow-up

Removed duplicated legacy CBOR conversion from three card tests and moved serialized action/choice/resolution helpers onto the shared Fixture. Current row widths are read rather than hardcoded; stable v11 fields are named in one test module. Prompt-choice policy stays explicit in each scenario. Four additional fixture tests pass. This follow-up is test/documentation only; no runtime or schema changes.

Andrea Bueide added 2 commits September 21, 2026 20:04
Reproduce LeBlanc copying Honest Broker and both dying in combat: only the original paid Gold because the despawned copy lost its script on the next request. Snapshot printed ability identity on chain items and resolve it independently of the source. Refresh transformed static sources, version blob 16 and plugin 0.9.1, and cover Temporary kills and serialized prompt flows.
Independent review found Reckoner's Arena bypassed the first snapshot hook. Reproduce a copied Kai'Sa Conquer trigger losing its source and route all production pending producers through Ctx::enqueue so card scripts cannot omit the snapshot.
Comment thread games/riftbound-turns/src/cards/here_to_help.rs Outdated
Comment thread games/riftbound-turns/src/cards/reflection_tests.rs Outdated
Comment thread games/riftbound-turns/src/cards/reflection_tests.rs Outdated
Address Agni #1 review: remove per-card CBOR row conversions and hardcoded current field counts, share the action/reload lifecycle on Fixture, and make prompt-choice policy explicit. Cover appended schema fields, nested last-known data, cache disposal, and multi-stage choices without changing runtime rules.
@abueide
abueide merged commit f0fbf9d into main Sep 22, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant