Connect genuine Ix expansion setup to playable prototypes

Add an offline Ix initializer through the real setup pipeline, supporting Basic
and Advanced play, base factions, Ixians and Tleilaxu with the full 47-card deck
and 22-card spice deck. Preserve all normal start and publication gates.

Add a reusable local prototype starter: back up the named fresh ready lobby,
initialize it once by exact version/state comparison and preserve seat/recovery
tables and other rooms. Update the existing checklist with a separate prototype
stage and document functional scope, source interpretations and later refinement.

Six new tests cover all-profile private setup, exact typed starting forces,
Face Dancer/treachery custody, JSON continuation, two fixed-seed complete games
and local SQLite write/rejection boundaries. Independent review caught a missing
JSON version update, now fixed and covered; focused checking fixed one test typing
error before the stable broad check. No new rule interpretation was introduced.

Validation: types, lint and 4,211 offline tests passed (123.237s); production build
passed (6.543s); all 40 HTTP tests passed (23.578s). Source-bound report:
20260913-ix-prototype-final/report.json, fingerprint
3b8f295593bcb314bb72308d81739006b11d949d1e5906dbf6ce0704b15ebd72.

Browser W5LE6VFB: human Ixian + Medium Tleilaxu + Hard Atreides from genuine
setup, private starting-card refresh, Weather Control, mobile stronghold placement,
then owned Brutal autopilot. Atreides won on turn 1; this short complete journey
is not proof of every card or faction interaction. Finished private hand restored
at phone width; expanded Poison Tooth was readable. Fixed-seed offline games
2026091301 (Basic) and 2026091302 (Advanced) both completed with both Ix factions.

All 64 opening room versions/hashes are unchanged. One browser room and 30 HTTP
rooms were added, totaling 95. Reused the running server; no restart or automation.

Aggregate goal counters: 59,524,858 to 59,976,567 at completed verification,
451,709 tokens before final Git overhead. Two bounded workhorse helpers handled
inventory/tests and independent review; one stable full check/build/HTTP run.
Full game scope remains active and unfinished; future work prioritizes missing
functional prototypes before exhaustive refinement and final acceptance.
This commit is contained in:
Quintine committed 2026-09-13 12:17:33 +10:00
1 parent 194471e906
commit 5a76ae0410
12 files changed
+736 -9

No files matched your search

+14 -5
View File
@@ -4919,7 +4919,14 @@ export function initializeNexusGameForAudit(state: Game): Game {
'Enable Nexus cards in a fresh audit lobby first.');
return initializeSetupGameForAudit(state, !!state.homeworlds, true);
}
function initializeSetupGameForAudit(state: Game, homeworlds: boolean, nexus = false): Game {
/** Offline prototype entry through real Ix setup, including both expansion factions.
* No player action or room API bypasses the normal release gates. */
export function initializeIxGameForAudit(state: Game): Game {
requireRule(state.expansions.length === 1 && state.expansions[0] === 'ix',
'The Ix prototype requires exactly the Ixians & Tleilaxu expansion.');
return initializeSetupGameForAudit(state, false, false, true);
}
function initializeSetupGameForAudit(state: Game, homeworlds: boolean, nexus = false, ix = false): Game {
nexusCardsIntegrity(state);
homeworldRule(() => homeworldGameIntegrity(state));
homeworldBattleLossIntegrity(state);
@@ -4941,17 +4948,19 @@ function initializeSetupGameForAudit(state: Game, homeworlds: boolean, nexus = f
'The audit initializer requires two through six distinct ready players and an existing host.',
);
requireRule(
(homeworlds || nexus || g.expansions.length === 0) &&
(homeworlds || nexus || ix || g.expansions.length === 0) &&
(nexus || !g.nexusCards) &&
!g.techTokens &&
!g.strongholdCards &&
(homeworlds || !g.homeworlds) &&
g.players.every((p) =>
FACTIONS.some(
(f) => f.id === p.faction && (homeworlds || nexus || f.expansion === 'base'),
(f) => f.id === p.faction && (homeworlds || nexus || f.expansion === 'base' || (ix && f.expansion === 'ix')),
),
),
homeworlds
ix
? 'The Ix prototype supports base, Ixian and Tleilaxu factions without optional modules.'
: homeworlds
? 'The Homeworld setup audit supports implemented deck sets without Tech Tokens or Stronghold Cards.'
: 'The audit initializer supports base factions without expansions or optional modules.',
);
@@ -4979,7 +4988,7 @@ function initializeSetupGameForAudit(state: Game, homeworlds: boolean, nexus = f
!p.prediction &&
!p.advisorSetup &&
(!p.elites ||
((homeworlds || nexus) &&
((homeworlds || nexus || ix) &&
p.faction === 'ixians' &&
p.elites.reserves === 7 &&
p.elites.tanks === 0 &&
+15 -4
View File
@@ -29,6 +29,8 @@ export type RuleTopic = {
| 'Factions'
| 'Advanced & expansions';
coverage: 'Implemented' | 'Partial' | 'Planned';
/** Development progress is separate from the scope of verified rules coverage. */
developmentStage?: 'Missing' | 'Prototyped' | 'Integrated' | 'Verified' | 'Polished';
summary: string;
searchText?: string;
steps: string[];
@@ -192,6 +194,7 @@ export const RULE_TOPICS: RuleTopic[] = [
steps: [
'The linked topics contain a five-part checklist. Implemented describes only the stated feature boundary; Partial identifies remaining work and Planned means it is not active.',
'Verification entries identify focused regression suites. Passing those checks does not certify every interaction, browser journey or complete expansion game.',
'Development stages distinguish Missing functions, working Prototypes, Integrated functions, Verified behavior and Polished presentation. A prototype stage does not certify complete rules coverage; check the stated limits and evidence.',
'This checklist is being extended across the rules. Features without a checklist still have a topic-level coverage label and are not implicitly complete.',
'Advanced and full expansion faction starts remain disabled. Development fixture coverage is not permission to start an unsupported mode.',
],
@@ -1382,6 +1385,7 @@ export const RULE_TOPICS: RuleTopic[] = [
title: 'Ixians & Tleilaxu treachery deck',
category: 'Advanced & expansions',
coverage: 'Partial',
developmentStage: 'Prototyped',
summary:
'Fourteen expansion cards join the thirty-three base cards; matching names still represent distinct physical cards.',
steps: [
@@ -1390,7 +1394,14 @@ export const RULE_TOPICS: RuleTopic[] = [
'The additional Shield and Snooper behave like their base copies, including the Shield’s lasgun interaction. Kull Wahad is a Worthless card and can be played in a battle plan or converted with advanced Bene Gesserit’s Karama advantage.',
'The second Harvester is a separate card. Each available copy can be played while the fresh blow window remains open; the current implementation doubles that blow again, without multiplying pre-existing spice. Neither copy can restore a worm-destroyed blow or create spice in storm. Multiple-copy timing and multiplier interpretation remain under card-face audit.',
'With this expansion the combined deck has forty-seven distinct card identities: five ordinary projectile weapons, five ordinary poison weapons, five ordinary Shields, five ordinary Snoopers, six Worthless cards and two Harvesters, in addition to the other base and special expansion cards.',
'The complete inventory is assembled in the engine, with internal guidance and AI card recognition. Expansion starts remain disabled pending remaining rule and interaction audits; this is not a claim of complete expansion compliance.',
'The local development prototype uses genuine setup with the complete deck, Sandtrout, Ixians and Tleilaxu in Basic or Advanced play. Starting cards, private choices, controls, AI and saved continuation use the normal game paths. Public expansion starts remain disabled pending complete rule and interaction acceptance.',
],
checklist: [
{ area: 'Implementation', status: 'Partial', detail: 'Working prototype with the actual 47-card setup, both expansion factions and Sandtrout. Optional module combinations and remaining printed-card interpretations are unfinished.', evidence: ['game/cards.ts', 'game/engine.ts'] },
{ area: 'Player controls', status: 'Implemented', detail: 'Prototype rooms use the existing private setup, faction, battle-card and special-card controls. Local development initialization preserves the normal release gate.', evidence: ['components/game-table.tsx', 'tools/start-prototype.ts'] },
{ area: 'AI', status: 'Partial', detail: 'All four profiles share the existing legal private actions. Complete-game prototype runs exercise both expansion factions; comprehensive strength calibration remains later work.', evidence: ['game/bots.ts', 'tests/ix-prototype.test.ts'] },
{ area: 'Documentation', status: 'Implemented', detail: 'The prototype setup record separates functional progress, source interpretations and final acceptance.', evidence: ['docs/IX_PROTOTYPE.md'] },
{ area: 'Verification', status: 'Partial', detail: 'Genuine setup, complete prototype games, private views, physical-card custody and saved continuation have targeted checks. This does not certify every combination.', evidence: ['tests/ix-prototype.test.ts', 'tests/prototype-room.test.ts'] },
],
related: [
'ix-battle-cards',
@@ -1648,7 +1659,7 @@ export const RULE_TOPICS: RuleTopic[] = [
category: 'Advanced & expansions',
coverage: 'Partial',
summary:
'A pending spice-card effect that can cross phases and turns. Tested support exists; the expansion spice deck remains unavailable in live rooms.',
'A pending spice-card effect that can cross phases and turns. It is included in local Ix prototype setup; normal expansion starts remain gated.',
steps: [
'Drawing Sandtrout immediately breaks existing alliances and clears pending alliance offers. It is then held aside while spice draws continue. A territory drawn before the next active Shai-Hulud receives its usual spice amount.',
'The next active Shai-Hulud drawn is suppressed: it does not devour the previous territory, offer Fremen protection or a ride, or trigger its own Nexus. Discard the consumed Sandtrout with that suppressed worm.',
@@ -1670,7 +1681,7 @@ export const RULE_TOPICS: RuleTopic[] = [
category: 'Cards',
coverage: 'Partial',
summary:
'A poison weapon with an optional attack on both leaders. Engine support exists; expansion decks remain unavailable.',
'A poison weapon with an optional attack on both leaders. It is included in the local Ix prototype deck; normal expansion starts remain gated.',
steps: [
'Commit Poison Tooth in your weapon slot. After both plans are revealed, its owner chooses whether to activate it before traitor decisions proceed. Committing the card does not yet activate its poison.',
'When activated, the tooth attacks both leaders, including its owner’s leader. Chemistry in the defense slot protects that leader. Snooper and Shield Snooper do not protect against the tooth. A Chemistry card used as a weapon supplies no defense.',
@@ -1712,7 +1723,7 @@ export const RULE_TOPICS: RuleTopic[] = [
'Voice can name one of these special cards directly or use a matching generic attack or defense type. A prohibition uses the role the card actually plays. For example, forbidding poison weapons still allows Chemistry as poison defense.',
'Compulsion uses the default role. Requiring a projectile weapon can compel Weirding Way as a weapon. Requiring a projectile defense cannot force a player to turn Weirding Way into that defense. Likewise, requiring a poison weapon cannot force Chemistry out of its default defense role.',
'Prescience reveals the card occupying the requested slot. With a poison weapon and Weirding Way, a weapon question reveals the poison weapon; a defense question reveals Weirding Way. The other card remains private, and the revealed slot must remain unchanged.',
'These cards are not yet added to live room decks. Poison Tooth and Artillery Strike also have tested effects described in their own topics. Remaining Ix treachery cards, complete deck setup and expansion interactions are still in development.',
'The local Ix prototype deals the full expansion deck through genuine setup. Poison Tooth and Artillery Strike have their own topics. Complete rules compliance and combined expansion interactions remain unfinished; prototype access does not open normal expansion starts.',
],
related: [
'battle',