Support Revival answers with Richese Semuta
Verify and publish checkpoint container / container (push) Successful in 10m31s
Verify and publish checkpoint container / container (push) Successful in 10m31s
This commit is contained in:
1 parent
2eaaab876e
commit
4dfdd500e0
14 files changed
+540
-15
No files matched your search
@@ -1614,6 +1614,8 @@ export type Game = {
|
||||
purpose?: KullPurpose;
|
||||
/** New Basic Kull attempts may bind an existing structured bribe ledger. */
|
||||
bribeReceipt?: true;
|
||||
/** New Kull/Semuta attempts retain the original Revival answer ledger. */
|
||||
revivalReceipt?: true;
|
||||
stage: 'offer' | 'counter';
|
||||
selection?: { source: 'printed' | 'nexus'; card: string; nexusEvent?: string };
|
||||
intent: { kind: 'ordinary'; use: KaramaUse } | { kind: 'special'; use: SpecialKaramaIntent };
|
||||
@@ -1927,6 +1929,11 @@ export type Game = {
|
||||
| { kind: 'bribe'; index: number; value: BribePromise }
|
||||
| { kind: 'bribeExpression'; index: number; value: BribeExpressionPromise }
|
||||
| { kind: 'mixedBribe'; index: number; value: NonNullable<Game['mixedBribeQuestions']>[number] };
|
||||
revivalBinding?:
|
||||
| { kind: 'revival'; index: number; value: RevivalPromise }
|
||||
| { kind: 'leaderRevival'; index: number; value: LeaderRevivalPromise }
|
||||
| { kind: 'revivalExpression'; index: number; value: RevivalExpressionPromise }
|
||||
| { kind: 'mixedRevival'; index: number; value: NonNullable<Game['mixedRevivalQuestions']>[number] };
|
||||
parentSignature: string;
|
||||
}
|
||||
| {
|
||||
@@ -7576,6 +7583,10 @@ function truthtranceDiscardSignature(g: Game, next: TruthDiscardContinuation) {
|
||||
...(next.bribeBinding ? { bribeBinding: next.bribeBinding,
|
||||
bribePromises: g.bribePromises, bribeExpressionPromises: g.bribeExpressionPromises,
|
||||
mixedBribeQuestions: g.mixedBribeQuestions, bribePromiseSequence: g.bribePromiseSequence } : {}),
|
||||
...(next.revivalBinding ? { revivalBinding: next.revivalBinding,
|
||||
revivalPromises: g.revivalPromises, leaderRevivalPromises: g.leaderRevivalPromises,
|
||||
revivalExpressionPromises: g.revivalExpressionPromises, mixedRevivalQuestions: g.mixedRevivalQuestions,
|
||||
revivalPromiseSequence: g.revivalPromiseSequence } : {}),
|
||||
controls: nullentropyParentSignature(
|
||||
g,
|
||||
next.resume,
|
||||
@@ -7698,6 +7709,18 @@ function finishTruthtranceAnswer(g: Game) {
|
||||
else if (g.semutaPreview && record.question.kind === 'mixedBribe') continuation.bribeBinding = {
|
||||
kind: 'mixedBribe', index: g.mixedBribeQuestions!.length - 1, value: structuredClone(g.mixedBribeQuestions!.at(-1)!),
|
||||
};
|
||||
if (g.semutaPreview && record.question.kind === 'revival') continuation.revivalBinding = {
|
||||
kind: 'revival', index: g.revivalPromises!.length - 1, value: structuredClone(g.revivalPromises!.at(-1)!),
|
||||
};
|
||||
else if (g.semutaPreview && record.question.kind === 'leaderRevival') continuation.revivalBinding = {
|
||||
kind: 'leaderRevival', index: g.leaderRevivalPromises!.length - 1, value: structuredClone(g.leaderRevivalPromises!.at(-1)!),
|
||||
};
|
||||
else if (g.semutaPreview && record.question.kind === 'revivalExpression') continuation.revivalBinding = {
|
||||
kind: 'revivalExpression', index: g.revivalExpressionPromises!.length - 1, value: structuredClone(g.revivalExpressionPromises!.at(-1)!),
|
||||
};
|
||||
else if (g.semutaPreview && record.question.kind === 'mixedRevival') continuation.revivalBinding = {
|
||||
kind: 'mixedRevival', index: g.mixedRevivalQuestions!.length - 1, value: structuredClone(g.mixedRevivalQuestions!.at(-1)!),
|
||||
};
|
||||
continuation.parentSignature = truthtranceDiscardSignature(g, continuation);
|
||||
stageTreacheryDiscard(
|
||||
g,
|
||||
@@ -8720,6 +8743,45 @@ function treacheryDiscardIntegrity(g: Game) {
|
||||
'The completed mixed bribe answer no longer matches its payment binding.');
|
||||
}
|
||||
} else requireRule(!c.bribeBinding, 'This Truthtrance answer has no bribe binding.');
|
||||
const expectedRevival = g.semutaPreview &&
|
||||
(q.kind === 'revival' || q.kind === 'leaderRevival' || q.kind === 'revivalExpression' || q.kind === 'mixedRevival');
|
||||
if (expectedRevival) {
|
||||
const binding = c.revivalBinding;
|
||||
const actual = binding?.kind === 'revival' ? g.revivalPromises :
|
||||
binding?.kind === 'leaderRevival' ? g.leaderRevivalPromises :
|
||||
binding?.kind === 'revivalExpression' ? g.revivalExpressionPromises : g.mixedRevivalQuestions;
|
||||
requireRule(binding && binding.kind === q.kind && Array.isArray(actual) &&
|
||||
Number.isSafeInteger(binding.index) && binding.index >= 0 && binding.index === actual.length - 1 &&
|
||||
JSON.stringify(binding.value) === JSON.stringify(actual[binding.index]) &&
|
||||
binding.value.player === q.target && binding.value.asker === record.asker &&
|
||||
binding.value.answer === (record.answer === 'yes') && binding.value.turn === g.turn,
|
||||
'The completed Truthtrance lost its original Revival answer.');
|
||||
const emptyProgress = {total:0, normal:0, elite:0, leaders:[]};
|
||||
if (binding.kind === 'revival' && q.kind === 'revival')
|
||||
requireRule(binding.value.counter === q.counter && binding.value.minimum === q.minimum &&
|
||||
binding.value.progress === 0 && !binding.value.fulfilled && !binding.value.released &&
|
||||
g.revivalPromiseSequence?.at(-1) === binding.value.event,
|
||||
'The completed Truthtrance Revival differs from its original question.');
|
||||
else if (binding.kind === 'leaderRevival' && q.kind === 'leaderRevival')
|
||||
requireRule(binding.value.leader === q.leader && !binding.value.fulfilled && !binding.value.released &&
|
||||
g.revivalPromiseSequence?.at(-1) === binding.value.event,
|
||||
'The completed Truthtrance leader Revival differs from its original question.');
|
||||
else if (binding.kind === 'revivalExpression' && q.kind === 'revivalExpression')
|
||||
requireRule(JSON.stringify(binding.value.claim) === JSON.stringify(q.claim) &&
|
||||
JSON.stringify(binding.value.progress) === JSON.stringify(emptyProgress) &&
|
||||
!binding.value.fulfilled && !binding.value.released && g.revivalPromiseSequence?.at(-1) === binding.value.event,
|
||||
'The completed Truthtrance Revival expression differs from its original question.');
|
||||
else if (binding.kind === 'mixedRevival' && q.kind === 'mixedRevival') {
|
||||
const residual = g.revivalExpressionPromises?.at(-1);
|
||||
requireRule(JSON.stringify(binding.value.mixed) === JSON.stringify(q.mixed) &&
|
||||
(binding.value.binding ? !!residual && residual.event === binding.value.event &&
|
||||
residual.player === q.target && residual.asker === record.asker && residual.answer === binding.value.answer &&
|
||||
residual.turn === g.turn && JSON.stringify(residual.progress) === JSON.stringify(emptyProgress) &&
|
||||
!residual.fulfilled && !residual.released && g.revivalPromiseSequence?.at(-1) === binding.value.event :
|
||||
!g.revivalExpressionPromises?.some(item => item.event === binding.value.event)),
|
||||
'The completed mixed Revival answer no longer matches its return binding.');
|
||||
}
|
||||
} else requireRule(!c.revivalBinding, 'This Truthtrance answer has no Revival binding.');
|
||||
if (expectedShipment || expectedBattle || expectedMovement || expectedTraitor) {
|
||||
const actual = expectedTraitor ? g.battle?.traitorDecisionPromises : expectedMovement ? g.movementPromises : expectedShipment
|
||||
? g.shipmentPromises
|
||||
@@ -9350,6 +9412,9 @@ function semutaOfferSupported(
|
||||
if (continuation.kind === 'truthtranceDiscard' &&
|
||||
['bribe', 'bribeExpression', 'mixedBribe'].includes(continuation.record.question.kind) &&
|
||||
(!continuation.bribeBinding || !bareBasicSemutaProfile(g) || !bribePromiseModeSupported(g))) return false;
|
||||
if (continuation.kind === 'truthtranceDiscard' &&
|
||||
['revival', 'leaderRevival', 'revivalExpression', 'mixedRevival'].includes(continuation.record.question.kind) &&
|
||||
(!continuation.revivalBinding || !bareBasicSemutaProfile(g) || !revivalPromiseModeSupported(g))) return false;
|
||||
const richeseGiftDiscard = continuation.kind === 'karamaRicheseGiftDiscard';
|
||||
const richeseDiscard = richeseGiftDiscard || continuation.kind === 'karamaRicheseAuctionDiscard';
|
||||
const auctionAdvantageDiscard = continuation.kind === 'karamaAuctionAdvantageDiscard';
|
||||
@@ -19158,6 +19223,9 @@ function kullSignature(g: Game, frame: KullFrame): string {
|
||||
...(frame.bribeReceipt ? {bribeReceipt:frame.bribeReceipt,bribePromises:source.bribePromises,
|
||||
bribeExpressionPromises:source.bribeExpressionPromises,bribePromiseSequence:source.bribePromiseSequence,
|
||||
mixedBribeQuestions:source.mixedBribeQuestions} : {}),
|
||||
...(frame.revivalReceipt ? {revivalReceipt:frame.revivalReceipt,revivalPromises:source.revivalPromises,
|
||||
leaderRevivalPromises:source.leaderRevivalPromises,revivalExpressionPromises:source.revivalExpressionPromises,
|
||||
mixedRevivalQuestions:source.mixedRevivalQuestions,revivalPromiseSequence:source.revivalPromiseSequence} : {}),
|
||||
});
|
||||
}
|
||||
/** Only the verified pre-source printed profile may bind its old held cost. */
|
||||
@@ -19205,6 +19273,10 @@ function kullIntegrity(g: Game): void {
|
||||
requireRule(frame.bribeReceipt === undefined || frame.bribeReceipt === true && !g.advanced &&
|
||||
bribePromiseModeSupported(g) && !!(g.bribePromises?.length || g.bribeExpressionPromises?.length || g.mixedBribeQuestions?.length),
|
||||
'The Kull attempt has lost its original Basic bribe-answer ledger.');
|
||||
requireRule(frame.revivalReceipt === undefined || frame.revivalReceipt === true && g.semutaPreview === true &&
|
||||
revivalPromiseModeSupported(g) && !!(g.revivalPromises?.length || g.leaderRevivalPromises?.length ||
|
||||
g.revivalExpressionPromises?.length || g.mixedRevivalQuestions?.length),
|
||||
'The Kull attempt has lost its original Basic Revival-answer ledger.');
|
||||
validateKullAttemptStamp(g, frame, physicalTreacheryCards(g));
|
||||
requireRule(Number.isSafeInteger(g.kullSequence) && g.kullSequence! > 0 &&
|
||||
frame.event === JSON.stringify(['kull', g.turn, g.phase, g.kullSequence, frame.player, frame.owner]),
|
||||
@@ -19289,6 +19361,9 @@ function beginKullAttempt(g: Game, p: Player, card: Card, intent: KullFrame['int
|
||||
...(g.advanced ? { purpose: kullIntentPurpose(g, intent) } : {}),
|
||||
...(!g.advanced && (g.bribePromises?.length || g.bribeExpressionPromises?.length || g.mixedBribeQuestions?.length)
|
||||
? { bribeReceipt: true as const } : {}),
|
||||
...(g.semutaPreview && revivalPromiseModeSupported(g) && (g.revivalPromises?.length ||
|
||||
g.leaderRevivalPromises?.length || g.revivalExpressionPromises?.length || g.mixedRevivalQuestions?.length)
|
||||
? { revivalReceipt: true as const } : {}),
|
||||
worthless: structuredClone(g.pendingChoamWorthless ?? null), signature: '',
|
||||
};
|
||||
// Payment dispatch removed this control before entering its native branch.
|
||||
|
||||
@@ -14,7 +14,7 @@ export const FACTION_RULES: Record<
|
||||
'Use Kulon on your movement turn to add one territory of range. Use La La La during Revival to prevent a player’s free force returns for the phase; a reactive decision lets you stop a pending free revival before it resolves. Both cards have Karama responses before discard.',
|
||||
'Trip to Gamont returns one other player’s force from a chosen sector to its reserves during Mentat. Elite types are preserved. A Karama response precedes the return, and CHOAM gets a final opportunity after the closing market before victory is checked.',
|
||||
'Baliset prevents a player from moving into a territory occupied by CHOAM for the turn, while permitting shipment. Jubba Cloak protects CHOAM forces in one territory from a moving storm. Both powers have Karama responses before the card is discarded.',
|
||||
'New supported Basic lobbies with CHOAM and the CHOAM and Ix decks enable the Kull preview by default; the host may turn it off. Each selected faction needs its deck, and other optional modules remain outside this profile. React to a legal Karama attempt with held Kull Wahad before costs. The original card stays reserved; only a different eligible Karama can counter before the phase ban applies. Success spends Kull, retains the original unplayed card and prevents the activating player’s Karama uses for the phase. Decline or prevention resumes the original once; a prevented Kull stays held but its physical card’s effect is blocked that phase. With Richese, supported Kull and counter discards offer Semuta; ordinary bribe, simple and mixed current-lot bid, and phase-wide bid questions are supported, while Revival and alliance commitments remain unavailable. Combined turn-action questions and unfunded non-CHOAM Karama-dependent overbids remain deferred; see the Kull guide. Complete CHOAM rules remain unfinished.',
|
||||
'New supported Basic lobbies with CHOAM and the CHOAM and Ix decks enable the Kull preview by default; the host may turn it off. Each selected faction needs its deck, and other optional modules remain outside this profile. React to a legal Karama attempt with held Kull Wahad before costs. The original card stays reserved; only a different eligible Karama can counter before the phase ban applies. Success spends Kull, retains the original unplayed card and prevents the activating player’s Karama uses for the phase. Decline or prevention resumes the original once; a prevented Kull stays held but its physical card’s effect is blocked that phase. With Richese, supported Kull and counter discards offer Semuta; ordinary bribe and Revival, simple and mixed current-lot bid, and phase-wide bid questions are supported, while alliance commitments remain unavailable. Combined turn-action questions and unfunded non-CHOAM Karama-dependent overbids remain deferred; see the Kull guide. Complete CHOAM rules remain unfinished.',
|
||||
],
|
||||
advanced: [
|
||||
'Once per game, spend a real Karama and discard selected other cards for three spice each. The cash-in can occur during pending phase or power decisions, while committed battle cards remain protected. See the CHOAM special Karama topic for funding and timing details.',
|
||||
|
||||
+4
-4
@@ -3665,7 +3665,7 @@ export const RULE_TOPICS: RuleTopic[] = [
|
||||
'The private answer choices and guide use current native quotas and funding, including native free/paid selection. Earlier questions retain current Tanks and actual liabilities, project fresh normal Revival ledgers, and may prepare through actual Charity or owned opening income. Unknown future casualties do not supply forces. Earlier shipment and ground-movement promises retain their funding. Unknown gifts, future draws and foreign choices are not assumed.',
|
||||
'Your own request, spending or Finish Revival cannot evade an unmet Yes. A completed opposing effect may release an impossible answer in accepted order. A requested return does not fulfill Yes until the actual return completes; its original responses still decide the outcome.',
|
||||
'The persistent own promise panel displays progress and fulfilled/released status. Before Revival it waits for your actual Charity/Ready, ordinary/native pass, Silent zero or owned ordinary auction-payment choice; at Revival it offers a normal return or Finish Revival. Each guide belongs to its current phase and original event. Basic No remains through phase close because native readiness can reopen; stamped Advanced No ends when your opportunity finishes.',
|
||||
'This cumulative this-turn protocol is a provisional online composition of general current-turn Truthtrance authority. Optional-module compositions, special/card revival claims, grouped revival expressions and complete-mode acceptance remain required work.',
|
||||
'In supported bare Basic Richese games, force, named-leader, grouped and mixed Revival answers retain their bindings through Semuta, including with printed Kull. This cumulative this-turn protocol is a provisional online composition of general current-turn Truthtrance authority. Optional-module compositions, special/card revival claims and complete-mode acceptance remain required work.',
|
||||
],
|
||||
related: ['card-truthtrance', 'advanced-revival-order', 'truthtrance-shipment', 'truthtrance-movement', 'implementation-checklist'],
|
||||
checklist: [
|
||||
@@ -3673,7 +3673,7 @@ export const RULE_TOPICS: RuleTopic[] = [
|
||||
{ area: 'Player controls', status: 'Partial', detail: 'Structured question, target-only feasible answers and persistent event-bound normal revival/finish guide.', evidence: ['components/revival-claim-fields.tsx', 'components/revival-promises.tsx', 'components/truthtrance.tsx', 'components/game-table.tsx', 'tests/truth-revival-controls.test.tsx'] },
|
||||
{ area: 'AI', status: 'Partial', detail: 'Existing four profiles use feasible answers and the native action guide; strategy and difficulty calibration remain deferred.', evidence: ['game/bots.ts', 'tests/truth-revival-runtime.test.ts'] },
|
||||
{ area: 'Documentation', status: 'Implemented', detail: 'General authority, provisional timing/count interpretation, native order and remaining boundaries are explicit.', evidence: ['docs/TRUTHTRANCE_REVIVAL_PROMISES.md', 'docs/RULE_DECISIONS.md'] },
|
||||
{ area: 'Verification', status: 'Partial', detail: 'Focused native original-deal/death, pure and control evidence; broader combinations, browser and final deployed acceptance remain open.', evidence: ['tests/fixture-truth-revival.ts', 'tests/truth-revival-runtime.test.ts', 'tests/truth-revival-controls.test.tsx'] },
|
||||
{ area: 'Verification', status: 'Partial', detail: 'Focused native original-deal/death, pure and control evidence, including staged Richese Semuta and Kull Revival answers; broader combinations, browser and final deployed acceptance remain open.', evidence: ['tests/fixture-truth-revival.ts', 'tests/truth-revival-runtime.test.ts', 'tests/truth-revival-controls.test.tsx', 'tests/kull-richese-revival-commitment.test.ts', 'tests/kull-richese-revival-truth-semuta.test.ts', 'tests/kull-richese-revival-table-controls.test.tsx'] },
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -4861,7 +4861,7 @@ export const RULE_TOPICS: RuleTopic[] = [
|
||||
summary: 'React before a Karama is played; a distinct counter can stop Kull before its phase restriction begins.',
|
||||
steps: [
|
||||
'In a new supported Basic lobby with CHOAM and the CHOAM and Ix decks, printed Kull is enabled by default as a development preview. The host may turn it off to keep the broader non-Kull Truthtrance options. Basic supports Richese, Ixians, Tleilaxu, Ecaz, Moritani and classic factions with each seated faction’s deck and no other optional modules. In an Advanced preview lobby, the host may explicitly select printed Kull with CHOAM, classic factions and exactly the CHOAM and Ix decks, without optional modules. Advanced supports Bene Gesserit substitutions and legal special powers. Both previews withhold some structured questions and defer unfunded non-CHOAM Karama-dependent bids. Existing games are not retrofitted, and this warning does not certify complete rules.',
|
||||
'In the supported Basic printed Kull preview, simple and mixed current-lot ordinary bid, phase-wide bid and ordinary bribe questions are available, including with Richese and Semuta. Without Richese, supported Revival and alliance questions are also available. A pending Kull response holds their controls while the original transaction resolves. Combined turn-action questions and wider interactions remain incomplete.',
|
||||
'In the supported Basic printed Kull preview, simple and mixed current-lot ordinary bid, phase-wide bid, ordinary bribe and Revival questions are available, including with Richese and Semuta. Without Richese, supported alliance questions are also available. A pending Kull response holds their controls while the original transaction resolves. Combined turn-action questions and wider interactions remain incomplete.',
|
||||
'Another player’s legal Karama cancellation, shipment-rate use, immediate auction purchase, winning-bid payment or supported special activation pauses before its card and other costs. CHOAM sees the attempted player and purpose and may decline or choose a legal held Kull Wahad. Each Use names its printed source explicitly. The separate Nexus Kull guide covers additional Cunning costs in its new profile only. The same public opportunity appears without Kull in hand, so waiting does not disclose hidden ownership. Invalid attempts never open this window; CHOAM does not receive a self-targeted Kull offer.',
|
||||
'Decline resumes the original attempt once. Declaring Kull opens the ordinary CHOAM-effect response. Kull is still pending: its target may counter with a different eligible physical Karama before any phase ban applies. The interrupted card stays reserved and cannot serve as its own counter. Other eligible responders use their existing response controls.',
|
||||
'If everyone allows Kull, CHOAM discards the exact Kull card. The original attempted card remains in its owner’s hand; its effect and additional costs do not occur, and an attempted special once-per-game use remains unspent. Basic prevents that player’s Karama activations for this phase. A new Advanced attempt instead prevents only the specific effect: shipment pricing, free Treachery purchase, that faction’s special, or cancellation of the particular advantage. Other effects remain available; printed and substituted Karama share the same restriction. An allied shipment recipient is not automatically the restricted player.',
|
||||
@@ -4876,7 +4876,7 @@ export const RULE_TOPICS: RuleTopic[] = [
|
||||
example: 'Bene Gesserit attempts to use Baliset as Karama. CHOAM declares Kull. Baliset cannot also counter Kull; a different eligible Karama may. If Kull succeeds, Baliset stays held; in a new Advanced attempt BG cannot repeat that specific Karama effect this phase but may use another legal effect. If a distinct counter prevents Kull, the original Baliset attempt proceeds to its normal conversion response.',
|
||||
related: ['choam-worthless', 'nexus-choam-kull', 'faction-choam', 'card-karama', 'advanced-beneGesserit', 'special-karama', 'bidding', 'choam-karama', 'nexus-cards', 'implementation-checklist'],
|
||||
checklist: [
|
||||
{ area: 'Implementation', status: 'Partial', detail: 'Selectable Kull binds typed intents, distinct physical counters and Basic/legacy all-purpose or new Advanced semantic-effect restrictions. Different effects remain playable; phase expiry is provisional in Advanced. Basic printed Kull admits native Richese, Ixians, Tleilaxu, Ecaz and Moritani; supported clean Kull discards offer Semuta before their suspended parent resumes. Simple and mixed current-lot bid, phase-wide bid and ordinary bribe commitments can coexist with this preview including Richese; Revival and alliance commitments remain limited to the non-Richese profile. Deferred overbid recovery, whole-turn answers and broader module support remain excluded.', evidence: ['game/choam-kull.ts', 'game/kull-purpose.ts', 'game/bribe-promises.ts', 'game/engine.ts', 'tests/kull-bid-runtime.test.ts', 'tests/kull-phase-bid-runtime.test.ts', 'tests/kull-richese-phase-bid-runtime.test.ts', 'tests/kull-richese-current-bid-runtime.test.ts', 'tests/kull-richese-mixed-bid-runtime.test.ts', 'tests/kull-richese-bribe-runtime.test.ts', 'tests/kull-richese-bribe-truth-semuta.test.ts', 'tests/kull-richese-bribe-table-controls.test.tsx', 'tests/kull-truth-revival-runtime.test.ts', 'tests/kull-alliance-runtime.test.ts', 'tests/kull-richese-semuta-runtime.test.ts'] },
|
||||
{ area: 'Implementation', status: 'Partial', detail: 'Selectable Kull binds typed intents, distinct physical counters and Basic/legacy all-purpose or new Advanced semantic-effect restrictions. Different effects remain playable; phase expiry is provisional in Advanced. Basic printed Kull admits native Richese, Ixians, Tleilaxu, Ecaz and Moritani; supported clean Kull discards offer Semuta before their suspended parent resumes. Simple and mixed current-lot bid, phase-wide bid, ordinary bribe and Revival commitments can coexist with this preview including Richese; alliance commitments remain limited to the non-Richese profile. Deferred overbid recovery, whole-turn answers and broader module support remain excluded.', evidence: ['game/choam-kull.ts', 'game/kull-purpose.ts', 'game/bribe-promises.ts', 'game/engine.ts', 'tests/kull-bid-runtime.test.ts', 'tests/kull-phase-bid-runtime.test.ts', 'tests/kull-richese-phase-bid-runtime.test.ts', 'tests/kull-richese-current-bid-runtime.test.ts', 'tests/kull-richese-mixed-bid-runtime.test.ts', 'tests/kull-richese-bribe-runtime.test.ts', 'tests/kull-richese-bribe-truth-semuta.test.ts', 'tests/kull-richese-bribe-table-controls.test.tsx', 'tests/kull-richese-revival-commitment.test.ts', 'tests/kull-richese-revival-truth-semuta.test.ts', 'tests/kull-truth-revival-runtime.test.ts', 'tests/kull-alliance-runtime.test.ts', 'tests/kull-richese-semuta-runtime.test.ts'] },
|
||||
{ area: 'Player controls', status: 'Partial', detail: 'Owner-only legal held costs and decline use the Kull event; counters reuse ordinary response controls. Public viewers receive purpose/actors, not private intent payloads or hidden choices.', evidence: ['components/choam-kull.tsx', 'components/game-table.tsx'] },
|
||||
{ area: 'AI', status: 'Partial', detail: 'Legal preview participation uses projected reactor choices and ordinary distinct counter controls. Full strategy and difficulty calibration remain deferred.', evidence: ['game/bot-choam-kull.ts', 'game/bots.ts'] },
|
||||
{ area: 'Documentation', status: 'Partial', detail: 'Pending versus active restrictions, distinct custody, decline/prevention/success, BG-before-conversion and deferred overbid limits have internal explanations. Publisher-source and full-faction acceptance remain separate.', evidence: ['docs/CHOAM_KULL_DESIGN.md', 'docs/CHOAM_KULL_SOURCE_UPDATE.md', 'docs/NEXUS_CHOAM_RULES.md'] },
|
||||
|
||||
@@ -35,7 +35,7 @@ export function parseRevivalClaim(value: unknown): RevivalClaim {
|
||||
|
||||
/** The original bare native scope and the supported Basic printed-Kull roster.
|
||||
* Timing, allowance, payment, typed Tanks and actual ordinary-return sources
|
||||
* remain the engine's rules; Richese Semuta and Nexus Kull stay fenced. */
|
||||
* remain the engine's rules; unsupported Semuta and Nexus Kull stay fenced. */
|
||||
export function revivalPromiseModeSupported(game: NativePromiseScope & {
|
||||
semutaPreview?: unknown; kullPreview?: unknown; nexusKullPreview?: unknown;
|
||||
richeseBetrayalPreview?: unknown; guildBetrayalPreview?: unknown;
|
||||
@@ -43,8 +43,10 @@ export function revivalPromiseModeSupported(game: NativePromiseScope & {
|
||||
nexusHarkonnenBetrayalPreview?: unknown; moritaniAssassinatePreview?: unknown;
|
||||
mobileStronghold?: unknown;
|
||||
}): boolean {
|
||||
return nativePromiseScopeSupported(game) && !game.semutaPreview && !game.nexusKullPreview &&
|
||||
!game.richeseBetrayalPreview && (!game.kullPreview || bribePromiseModeSupported(game));
|
||||
return nativePromiseScopeSupported(game) && !game.nexusKullPreview &&
|
||||
!game.richeseBetrayalPreview &&
|
||||
(!game.semutaPreview || game.semutaPreview === true && bribePromiseModeSupported(game)) &&
|
||||
(!game.kullPreview || bribePromiseModeSupported(game));
|
||||
}
|
||||
|
||||
export function revivalClaimText(claim: RevivalClaim): string {
|
||||
|
||||
Reference in new issue
Block a user