Accelerate rules-first feedback and integrate native Strongholds
Apply user priority: save/recovery/privacy/custody assurance after all rules. Add quick types/lint, concise failure-preserving reporter, verbose mode, actual empty-execution guard, signal handling and focused verify name selection; compact canonical context/handoffs without mass moves. Tooling15, six negative CLI, named/empty source-bound smokes,206 doc links; same15-case278B vs2455B,2.35s vs2.36s no compute speedclaim. Native Advanced Ix/CHOAM47-card Stronghold profile: actual firstMentat/HMS/sixeffects,18native/four legalpolicies,five genuine2..6games3129actions/no rejection, human390px LAUDR2WNv14 bank2/personal1 plan and real battle. Earlier162/6513 checks before assurance amendment; finalquick25/build/guide pass. No new preservation/privacy audit or public/deployed/full-mode claim.
This commit is contained in:
1 parent
af6d27095c
commit
e9830b6ced
27 files changed
+2339
-194
No files matched your search
+29
-7
@@ -8065,7 +8065,7 @@ function finishMandatorySkillVisibility(g: Game) {
|
||||
}
|
||||
}
|
||||
|
||||
function initializeSetup(g: Game) {
|
||||
function initializeSetup(g: Game, strongholds = !!g.strongholdCards) {
|
||||
const ecaz = byFaction(g, 'ecaz');
|
||||
if (ecaz && g.advanced) g.ecazLoyalty = { player: ecaz.id, card: null };
|
||||
if (g.discoveryEnabled) g.discoveries = createDiscoveryState(random);
|
||||
@@ -8073,7 +8073,7 @@ function initializeSetup(g: Game) {
|
||||
const choam = byFaction(g, 'choam');
|
||||
if (choam && g.advanced && !choam.leaders.some(isAuditorLeader))
|
||||
choam.leaders.push(createAuditorLeader());
|
||||
if (g.strongholdCards) {
|
||||
if (strongholds) {
|
||||
requireRule(g.advanced, 'Stronghold Cards require Advanced rules.');
|
||||
g.strongholdCards = createStrongholdCards();
|
||||
}
|
||||
@@ -9077,6 +9077,27 @@ export function initializeFactionExpansionsGameForAudit(state: Game): Game {
|
||||
!state.discoveryEnabled && !state.discoveries && !state.discoveryStash && !state.greatMaker &&
|
||||
!state.techTokens && !state.strongholdCards,
|
||||
'The faction prototype excludes optional modules, including Leader Skills and Discoveries.');
|
||||
requireFreshFactionInventory(state);
|
||||
return initializeSetupGameForAudit(state, false, false, false, false, false, false, true);
|
||||
}
|
||||
/** Fresh Advanced Ixian/CHOAM composition; normal starts and other modules stay gated. */
|
||||
export function initializeStrongholdFactionsGameForAudit(state: Game): Game {
|
||||
requireRule(state.advanced === true && state.expansions.length === 2 &&
|
||||
state.expansions.includes('ix') && state.expansions.includes('choam') &&
|
||||
state.players.some(p => p.faction === 'ixians') &&
|
||||
state.players.some(p => p.faction === 'choam') &&
|
||||
state.players.every(p => p.faction === 'ixians' || p.faction === 'choam' || faction(p.faction).expansion === 'base'),
|
||||
'Stronghold factions require Advanced native Ixians and CHOAM, classic opponents, and exactly the Ix and CHOAM decks.');
|
||||
requireRule(!state.homeworlds && !state.nexusCards && !state.leaderSkills &&
|
||||
!state.discoveryEnabled && !state.discoveries && !state.discoveryStash && !state.greatMaker &&
|
||||
!state.techTokens && !state.ecazTreachery &&
|
||||
(!state.strongholdCards || JSON.stringify(state.strongholdCards) === JSON.stringify(createStrongholdCards())),
|
||||
'Stronghold factions admit only unused Stronghold Cards, without other optional modules.');
|
||||
requireFreshFactionInventory(state);
|
||||
requireFreshBaseRuntime(state);
|
||||
return initializeSetupGameForAudit(state, false, false, false, false, false, false, true, false, true);
|
||||
}
|
||||
function requireFreshFactionInventory(state: Game) {
|
||||
requireRule(state.richeseCache === undefined && state.richeseRemoved === undefined &&
|
||||
state.ecazAmbassadors === undefined && state.moritaniTerror === undefined && state.dukeVidal === undefined &&
|
||||
state.mobileStronghold === undefined && state.ixSetupCards === undefined &&
|
||||
@@ -9091,7 +9112,6 @@ export function initializeFactionExpansionsGameForAudit(state: Game): Game {
|
||||
Object.entries(expected).every(([key, value]) => actual[key as keyof Leader] === value);
|
||||
});
|
||||
}), 'The faction initializer cannot overwrite existing inventories, leader custody or revival history.');
|
||||
return initializeSetupGameForAudit(state, false, false, false, false, false, false, true);
|
||||
}
|
||||
/** Genuine, explicitly opted-in preview; no player action enables this profile. */
|
||||
export function initializeMoritaniAssassinateGameForAudit(state: Game): Game {
|
||||
@@ -9182,7 +9202,7 @@ export function initializeEcazTreacheryGameForAudit(state: Game): Game {
|
||||
g.ecazTreachery = true;
|
||||
return initializeSetupGameForAudit(g, false, false, false, false, false, false, true, true);
|
||||
}
|
||||
function initializeSetupGameForAudit(state: Game, homeworlds: boolean, nexus = false, ix = false, discovery = false, leaderSkills = false, choam = false, factions = false, ecazTreachery = false): Game {
|
||||
function initializeSetupGameForAudit(state: Game, homeworlds: boolean, nexus = false, ix = false, discovery = false, leaderSkills = false, choam = false, factions = false, ecazTreachery = false, strongholdFactions = false): Game {
|
||||
nexusCardsIntegrity(state);
|
||||
homeworldRule(() => homeworldGameIntegrity(state));
|
||||
homeworldBattleLossIntegrity(state);
|
||||
@@ -9200,14 +9220,16 @@ function initializeSetupGameForAudit(state: Game, homeworlds: boolean, nexus = f
|
||||
(nexus || !g.nexusCards) &&
|
||||
(ecazTreachery || !g.ecazTreachery) &&
|
||||
!g.techTokens &&
|
||||
!g.strongholdCards &&
|
||||
(strongholdFactions || !g.strongholdCards) &&
|
||||
(homeworlds || !g.homeworlds) &&
|
||||
g.players.every((p) =>
|
||||
FACTIONS.some(
|
||||
(f) => f.id === p.faction && (homeworlds || nexus || f.expansion === 'base' || (ix && f.expansion === 'ix') || (choam && f.expansion === 'choam') || (factions && g.expansions.includes(f.expansion))),
|
||||
),
|
||||
),
|
||||
factions && nexus
|
||||
strongholdFactions
|
||||
? 'The Stronghold faction audit needs a fresh Advanced Ixian/CHOAM lobby without other optional modules.'
|
||||
: factions && nexus
|
||||
? 'The paired expansion Nexus audit needs a fresh lobby without other optional modules.'
|
||||
: factions
|
||||
? 'The faction prototype supports base factions and the selected expansion factions without optional modules.'
|
||||
@@ -9219,7 +9241,7 @@ function initializeSetupGameForAudit(state: Game, homeworlds: boolean, nexus = f
|
||||
? '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.',
|
||||
);
|
||||
initializeSetup(g);
|
||||
initializeSetup(g, strongholdFactions || !!g.strongholdCards);
|
||||
return normalizeAutomaticGame(g);
|
||||
}
|
||||
function ecazStartingForcesComplete(p: Player): boolean {
|
||||
|
||||
@@ -3157,6 +3157,7 @@ export const RULE_TOPICS: RuleTopic[] = [
|
||||
'mentat',
|
||||
'choam-combat',
|
||||
'mobile-stronghold',
|
||||
'stronghold-factions',
|
||||
'choam-modules',
|
||||
],
|
||||
checklist: [
|
||||
@@ -3207,6 +3208,31 @@ export const RULE_TOPICS: RuleTopic[] = [
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'stronghold-factions',
|
||||
title: 'Ixians and CHOAM with Stronghold Cards',
|
||||
category: 'Advanced & expansions',
|
||||
coverage: 'Partial',
|
||||
developmentStage: 'Verified',
|
||||
summary: 'A fresh Advanced development profile connects genuine Ixian and CHOAM setup to all six Stronghold Card effects and native continued games.',
|
||||
steps: [
|
||||
'This private local profile requires native Ixians and CHOAM, unique two-to-six-seat rosters with classic opponents, exactly the Ix and CHOAM Treachery Decks and Stronghold Cards alone. Basic, Tleilaxu, Richese, Ecaz, Moritani and other module overlays remain outside it.',
|
||||
'The canonical combined deck contains 47 physical cards, not 49: CHOAM replaces the two shared Ix cards instead of duplicating them. Genuine setup retains native Ixian starting-card choices, all original leaders and forces, the Advanced CHOAM Auditor and six initially unowned Stronghold Cards.',
|
||||
'Card ownership begins only at the real first end of Mentat and is retained through the following turn. It is not assigned by a battle fixture or reset on refresh. Hidden Mobile Stronghold interior forces and its outside pointing territory stay distinct.',
|
||||
'The mobile card copies an advantage of another currently controlled stronghold, not merely a retained card. A sole choice is automatic; multiple choices use the existing public pre-plan selection. Accepted choices stay bound to the same original battle through private plans and saved continuation.',
|
||||
'Arrakeen provides at most two spice toward actual support, not extra personal cash. Native CHOAM income uses the original bank and player payment shares, including its established traitor and own-donor exclusions. Original cyborg/suboid and starred casualties, bounty and other native income stay separate.',
|
||||
'Carthag, Habbanya, Sietch Tabr and Tuek’s Sietch retain their existing physical defense, tie, opposing-dial and played-Worthless contracts. This roster has no Richese cache or Stone Burner; that existing cross-roster interaction is not manufactured here.',
|
||||
'Bounded rule-path evidence covers native first end-Mentat ownership, eighteen original battle/copy cases, all four legal policies and five unstaged complete two-through-six-seat games. A390px human Ixian selected Arrakeen, sealed dial6/support3 with bank2/personal1 and completed the original opposed battle. Earlier comprehensive checks remain dated evidence; save/recovery/privacy/custody assurance now follows all rules. Full-card/faction/module/deployed acceptance and public expansion starts remain open.',
|
||||
],
|
||||
related: ['stronghold-cards', 'mobile-stronghold', 'choam-combat', 'setup', 'implementation-checklist'],
|
||||
checklist: [
|
||||
{ area: 'Implementation', status: 'Implemented', detail: 'Fresh native Ixian/CHOAM setup, six-card creation, actual end-Mentat ownership and original HMS/copy/CHOAM battle economy compose the existing effects without public-start or old-game changes.', evidence: ['game/engine.ts', 'game/stronghold-cards.ts', 'game/battle-resolution-quote.ts'] },
|
||||
{ area: 'Player controls', status: 'Implemented', detail: 'Existing gallery, inspector, mobile copy and support controls work through an original local setup at390px: copied bank support costs one actual personal spice and preserves the native opposed battle.', evidence: ['components/stronghold-cards.tsx', 'components/game-table.tsx'] },
|
||||
{ area: 'AI', status: 'Partial', detail: 'All four projected minimal policies produce legal current copy actions; five genuine Advanced2..6 native games complete. Strategy/calibration and other combinations remain deferred.', evidence: ['game/bots.ts', 'tools/faction-games.ts'] },
|
||||
{ area: 'Documentation', status: 'Partial', detail: 'Advanced prerequisite, physical47-card identity, native module-only profile, existing effects and pending excluded combinations are explicit.', evidence: ['docs/STRONGHOLD_CARDS.md', 'docs/RULE_DECISIONS.md'] },
|
||||
{ area: 'Verification', status: 'Partial', detail: 'Native18/four-policy smoke, five unstaged games with3129 accepted actions/no rejections/82JSON restores, human390px rule-control battle and scoped review cover this profile. Earlier162 affected and6513 full checks pass; new save/privacy/custody assurance waits until all rules, not a repeated prototype gate.', evidence: ['tests/fixture-stronghold-factions.ts', 'tests/stronghold-factions-runtime.test.ts', 'tests/stronghold-factions-recovery.test.ts', 'tests/prototype-room.test.ts'] },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'tech-tokens',
|
||||
title: 'Tech tokens: income, conquest and victory',
|
||||
|
||||
Reference in new issue
Block a user