From 00741a37d0893cc0fc9145bc5334c7cfc62b2067 Mon Sep 17 00:00:00 2001 From: Quintine <15965533+Quintine@users.noreply.github.com> Date: Tue, 27 Oct 2026 04:33:20 +1100 Subject: [PATCH] Bind Thumper promises before the original hidden Spice draw --- components/truthtrance.tsx | 1 + components/turn-action-fields.tsx | 13 +- components/turn-action-promises.tsx | 26 +- docs/CURRENT_STATUS.md | 24 ++ docs/IMPLEMENTATION_STATUS.md | 12 + docs/RULE_DECISIONS.md | 14 + docs/TRUTHTRANCE_TURN_ACTIONS.md | 38 +++ game/bots.ts | 2 + game/engine.ts | 96 ++++++- game/reference.ts | 7 +- game/truthtrance.ts | 16 +- game/turn-action-promises.ts | 2 +- game/window-card-play.ts | 14 +- tests/fixture-truth-turn-thumper.ts | 211 +++++++++++++++ tests/truth-turn-action-controls.test.tsx | 123 ++++++++- tests/truth-turn-thumper-runtime.test.ts | 315 ++++++++++++++++++++++ tests/truthtrance.test.ts | 11 + tests/turn-action-promises.test.ts | 54 +++- tests/window-card-play.test.ts | 40 ++- 19 files changed, 985 insertions(+), 34 deletions(-) create mode 100644 tests/fixture-truth-turn-thumper.ts create mode 100644 tests/truth-turn-thumper-runtime.test.ts diff --git a/components/truthtrance.tsx b/components/truthtrance.tsx index f6943f5f..76f25e97 100644 --- a/components/truthtrance.tsx +++ b/components/truthtrance.tsx @@ -606,6 +606,7 @@ export function Truthtrance({ Weather Control, Family Atomics and Harvester refer only to their original current Storm or fresh spice-blow window. Printed Karama auction use refers only to the current ordinary lot, through immediate purchase or its winning invoice. Printed Karama shipment use grants the named active recipient’s current native shipment price; it does not require an actual force shipment. + Thumper refers only to this turn’s original first spice reveal. On turn 1 its card is still discarded, but the worm encounter is ignored. Ordinary payments may remain available after their Shipment and Movement opportunity ends.

}

{turnActionsError ?? truthQuestionText(question, leaderName, locationName, name)}

diff --git a/components/turn-action-fields.tsx b/components/turn-action-fields.tsx index ecfb5b9e..048f0e5f 100644 --- a/components/turn-action-fields.tsx +++ b/components/turn-action-fields.tsx @@ -49,7 +49,8 @@ const newPowerClaim = (game: GameView, target: string): BattlePowerClaim => : { kind: 'voice', use: true }; const windowRoleNames: Record = { weather: 'Weather Control', atomics: 'Family Atomics', harvester: 'Harvester', karamaAuction: 'Spend a printed Karama for this current ordinary lot', - karamaShipment: 'Spend a printed Karama for the current shipment-price opportunity' }; + karamaShipment: 'Spend a printed Karama for the current shipment-price opportunity', + thumper: 'Play Thumper before this turn’s first spice reveal' }; const config: MixedActionConfig = { prefix: 'turn-action', legend: 'Current battle and this-turn action conditions, with optional current facts', @@ -88,6 +89,9 @@ const config: MixedActionConfig = { unused native shipment price. The giver may be another player. The price grant counts separately from an actual force shipment; it does not require the recipient to ship forces. Other roles, Worthless conversion and recovery alone do not count. This condition closes when that original shipment-price opportunity ends. + Thumper conditions count an actual accepted future printed play before this turn's original first spice reveal. + Earlier plays, disposal, other roles and recovery alone do not count. A later reveal is a different opportunity. + This condition closes when the actual first spice draw begins. Shipment conditions concern the single future original reserve shipment after the answer. Ground-movement conditions use the maximum physical forces in one actual future move to that destination; smaller moves never add together. Bid conditions close with their named ordinary lot; Revival conditions close with your native Revival opportunity. @@ -123,7 +127,7 @@ const config: MixedActionConfig = { if (action.kind === 'windowCardPlay') { const opportunity = windowCardOpportunity(game, action.effect); if (!opportunity || opportunity.turn !== game.turn || action.source !== opportunity.source) - throw new Error('Choose the original current Storm, fresh spice-blow, ordinary-lot or active shipment-price opportunity for this printed role.'); + throw new Error('Choose the original current native window for this printed role, including the first spice reveal or active shipment price.'); } return action; }, @@ -185,7 +189,7 @@ const config: MixedActionConfig = { {!currentWindow &&

This printed role has no current original open native window.

} + {value.effect === 'thumper' && game.turn === 1 &&

On turn 1, playing Thumper still discards the card, + but its worm encounter is ignored and the normal Spice Card draw continues.

} : value.kind === 'battlePower' ? <>