Support earlier Basic Truthtrance shipment promises

Accept current-turn shipment and mixed questions before Movement in bare classic Basic games. Project remaining owned Charity/normal Revival, net current auction invoices and unused outgoing refunds; do not invent future purchases, incoming Bidding aid or rival income. Physical Karama payment and shipping discounts require distinct cards. Reopen owned Charity/Revival readiness when binding and prevent voluntary spending or closure from evading an answer. Preserve unresolved foreign invoices until their actual outcome; preflight Emperor gifts and extra ally revival costs before responses.

Connect persistent earlier-phase guidance and current preparation to the actual table and retain phase5 shipping timing. Minimal required-delivery policies preserve a legal route; nonrestrictive answers retain ordinary legal payment. Document the explicit provisional witness/readiness interpretation and inherited profile boundaries.

Verify focused rules/controls, types/lint/build, two original public Basic Storm/Charity question programmes with actual purchase2 and shipment8, and four finite minimal legal policy continuations. Full rules, wider earlier-phase configurations, comprehensive assurance and deployed acceptance remain open. No strategic calibration, saved-room operation, reset, restart or deployment.
This commit is contained in:
Quintine committed 2026-10-24 13:28:06 +11:00
1 parent 6d30e7c5e1
commit 16f654071a
17 files changed
+799 -48

No files matched your search

+3
View File
@@ -1997,6 +1997,9 @@ export function GameTable({
onSectorChange={setSector}
/>
</>}
{g.status === 'playing' && g.phase < 5 && (
<ShipmentPromises game={g} act={act} busy={busy} />
)}
{g.guildBetrayalReaction ? (
<NexusGuildBetrayal game={g} act={act} busy={reactionBusy} />
) : g.richeseBetrayalReaction ? (
+34 -4
View File
@@ -19,7 +19,17 @@ export function ShipmentPromises({
const promises = liveShipmentPromises(g.shipmentPromises, g.me, g.turn);
if (!promises.length) return null;
const me = g.players.find((p) => p.id === g.me)!;
const next = g.shipmentCompletion?.actions[0];
const early = g.phase < 5;
const next = g.phase === 5 ? g.shipmentCompletion?.actions[0] : undefined;
const preparation = early ? g.shipmentPreparation?.actions[0] : undefined;
const preparationCard = preparation?.type === 'card'
? me.hand?.find(card => card.id === preparation.card) : undefined;
const preparationLabel = preparation?.type === 'charity'
? 'Claim charity'
: preparation?.type === 'revive'
? `Revive ${Number(preparation.amount)} force${Number(preparation.amount) === 1 ? '' : 's'} in Revival`
: preparationCard ? `Play ${preparationCard.name}` : null;
const blocked = busy || !!g.truthtrance || !!g.response || !!g.decision || !!g.phaseOpening;
const shipping = next && (next.type === 'ship' || next.type === 'guildShip');
const halfRate = g.karamaShipping?.player === me.id ||
(!g.guildRateCanceled &&
@@ -62,7 +72,11 @@ export function ShipmentPromises({
id="shipment-promise-guidance"
>
<h3>Your shipment promises</h3>
{g.active !== g.me && <p>
{early ? <p>
Your shipment opportunity is later this turn, during Shipment and
Movement. Keep your needed spice, forces and cards available to honor
these answers while you continue playing the current phase normally.
</p> : g.active !== g.me && <p>
Your shipment turn is still ahead. This answer stays binding while
other players finish; shipment actions become available on your turn.
</p>}
@@ -84,8 +98,10 @@ export function ShipmentPromises({
</ul>
{promises.some((p) => matchesShipment(p, null) !== p.answer) ? (
<p>
Complete a qualifying shipment before ground movement or finishing
your turn: skipping would not honor the whole claim you answered.
{early
? 'During your later Shipment and Movement turn, complete a qualifying shipment before ground movement or finishing that turn: skipping would not honor the whole claim you answered.'
: 'Complete a qualifying shipment before ground movement or finishing your turn: skipping would not honor the whole claim you answered.'}
{' '}
You can choose any legal count, sector and funding that honor all
your answers. Current facts remain fixed at the time of your answer.
</p>
@@ -96,6 +112,20 @@ export function ShipmentPromises({
and create no later card, spice or force holding obligation.
</p>
)}
{preparation && preparationLabel && (
<section aria-label="Current shipment preparation">
<p>
This preparation is available in the current phase. Your shipment
remains later this turn.
</p>
<Button className="game-action" disabled={blocked} onClick={() => {
if (blocked) return;
act(preparation);
}}>
{preparationLabel}
</Button>
</section>
)}
{next && (
<details>
<summary>Suggested next step · private</summary>
+5 -5
View File
@@ -352,11 +352,11 @@ export function Truthtrance({
</p>
{!shipmentAvailable && (
<p className="notice">
Automatic enforcement supports an unused shipment this
phase, including a player still waiting for their turn,
in Basic or Advanced
base rules, including the Guild, or a
classic payer in the Richese Semuta profile. Select
Automatic enforcement supports a later shipment this turn
in Basic base rules without optional modules. During
Shipment and Movement it also supports unused active or
waiting turns in Advanced base rules, including the Guild,
or a classic payer in the Richese Semuta profile. Select
an eligible player and finish pending decisions first.
Native No-Field shipments and other rules configurations
remain unfinished.