Expand recognized Truthtrance fact questions
Verify and publish checkpoint container / container (push) Canceled after 0s

This commit is contained in:
Quintine committed 2026-10-29 04:34:29 +11:00
1 parent 8ae275f598
commit 9dd386ff7a
11 files changed
+279 -16

No files matched your search

+10 -6
View File
@@ -65,6 +65,7 @@ import type { Action, Game, Player } from './engine';
import { coalitionAllies } from './coalition-alliance';
import { TRUTH_CARD_NAMES } from './truthtrance-card-names';
import { parseFreeformFactV1 } from './truthtrance-freeform-facts';
import { parseFreeformFactV2 } from './truthtrance-freeform-facts-v2';
import { CHEAP_HERO_TRAITOR } from './traitors';
import {
TRUTH_FACT_MAX_NODES, TRUTH_FACT_MAX_DEPTH, TRUTH_FACT_MAX_TERMS,
@@ -128,7 +129,7 @@ export type TruthQuestion =
text: string;
scope: 'fact' | 'currentTurn';
/** Only newly asked, explicitly recognized facts carry this stable interpretation. */
interpreted?: { version: 1; fact: Extract<TruthFact, { kind: 'hand' | 'spice' }> };
interpreted?: { version: 1; fact: Extract<TruthFact, { kind: 'hand' | 'spice' }> } | { version: 2; fact: TruthFact };
};
export type TruthAnswer = 'yes' | 'no' | 'unknown';
export type TruthQueueEntry = {
@@ -653,8 +654,11 @@ function parseQuestion(g: Game, asker: string, value: unknown): TruthQuestion {
scope: v.scope,
};
if (v.interpreted !== undefined) {
const fact = question.scope === 'fact' ? parseFreeformFactV1(question.text) : null;
const expected = fact ? { version: 1 as const, fact } : null;
const marker = record(v.interpreted);
const oldFact = question.scope === 'fact' && marker.version === 1 ? parseFreeformFactV1(question.text) : null;
const newFact = question.scope === 'fact' && marker.version === 2 ? parseFreeformFactV2(question.text) : null;
const expected = oldFact ? { version: 1 as const, fact: oldFact }
: newFact ? { version: 2 as const, fact: newFact } : null;
check(expected !== null && JSON.stringify(v.interpreted) === JSON.stringify(expected),
'The saved freeform interpretation does not match its original question.');
question.interpreted = expected;
@@ -1107,14 +1111,14 @@ export function resolveTruthAction(
p.id === current.player,
'Waiting for the Truthtrance holder to ask a question.',
);
// Derive the v1 interpretation at submission, never from client state.
// Derive the current interpretation at submission, never from client state.
// Old saved questions without this stamp retain their previous semantics.
const supplied = record(a.question);
const { interpreted: _ignoredInterpretation, ...questionInput } = supplied;
w.question = parseQuestion(g, p.id, questionInput);
if (w.question.kind === 'freeform' && w.question.scope === 'fact') {
const fact = parseFreeformFactV1(w.question.text);
if (fact) w.question.interpreted = { version: 1, fact };
const fact = parseFreeformFactV2(w.question.text);
if (fact) w.question.interpreted = { version: 2, fact };
}
if (w.question.kind === 'mixedBattlePlan')
check(effects.mixedBattleAnswers?.(g, g.players.find(other => other.id === w.question!.target)!, w.question).length,