Exercise all-expansion Homeworld and Nexus games
This commit is contained in:
1 parent
068da48734
commit
88829b7057
5 files changed
+62
-25
No files matched your search
@@ -135,6 +135,14 @@ and five Nexus Card draw/keep decisions in the five-seat games. No Nexus
|
|||||||
effect was played in those samples; card-specific combinations and public
|
effect was played in those samples; card-specific combinations and public
|
||||||
expansion/Nexus starts remain gated.
|
expansion/Nexus starts remain gated.
|
||||||
|
|
||||||
|
Four more [all-expansion Homeworld/Nexus samples](IMPLEMENTATION_STATUS.md)
|
||||||
|
completed five/six-seat Basic and Advanced games with 2,800 accepted
|
||||||
|
actions, 74 JSON/private-view restores and unchanged source fingerprints.
|
||||||
|
Five-seat tables drew/kept three Nexus Cards and used real Homeworld
|
||||||
|
deployment decisions. Eight proposed entries were rejected by the existing
|
||||||
|
Ecaz Ambassador/Moritani Terror overlap gate; bots found alternate actions
|
||||||
|
and completed. Their unresolved priority and all public mode gates remain.
|
||||||
|
|
||||||
The bounded [native Richese Nexus Cunning shipment](NEXUS_RICHESE_RULES.md#bounded-native-cunning-prototype-27-september-2026) now uses two distinct physical No-Field tokens in one priced shipment in genuine Richese/CHOAM paired Nexus games. One token immediately reveals a reserve-capped public force group; the other remains concealed. Owner-only controls, four legal AI profiles, Karama/Guild responses, signed saved receipts and concurrent in-memory SQLite settlement are connected in Basic/Advanced. A read-only local browser fixture displayed the owner selector and no rival private panel. Same-shipment nonrepeat is a documented product interpretation; faceup-component artwork, combined modules, Betrayal and full Nexus acceptance remain gated. This code is local and not in the last verified production image.
|
The bounded [native Richese Nexus Cunning shipment](NEXUS_RICHESE_RULES.md#bounded-native-cunning-prototype-27-september-2026) now uses two distinct physical No-Field tokens in one priced shipment in genuine Richese/CHOAM paired Nexus games. One token immediately reveals a reserve-capped public force group; the other remains concealed. Owner-only controls, four legal AI profiles, Karama/Guild responses, signed saved receipts and concurrent in-memory SQLite settlement are connected in Basic/Advanced. A read-only local browser fixture displayed the owner selector and no rival private panel. Same-shipment nonrepeat is a documented product interpretation; faceup-component artwork, combined modules, Betrayal and full Nexus acceptance remain gated. This code is local and not in the last verified production image.
|
||||||
|
|
||||||
The independent [Reinforcements Battle Plan prototype](REINFORCEMENTS_RUNTIME.md)
|
The independent [Reinforcements Battle Plan prototype](REINFORCEMENTS_RUNTIME.md)
|
||||||
|
|||||||
@@ -1,5 +1,23 @@
|
|||||||
# Dune implementation status
|
# Dune implementation status
|
||||||
|
|
||||||
|
## 28 September 2026 — all-expansion Homeworld/Nexus samples
|
||||||
|
|
||||||
|
The offline combined audit setup can also enable genuine Homeworld custody with
|
||||||
|
Nexus Cards and all three expansion decks; public starts remain unchanged.
|
||||||
|
Five- and six-seat Basic/Advanced games all completed: 2,800 accepted actions,
|
||||||
|
74 JSON/private-view restores and unchanged source fingerprints. Five-seat
|
||||||
|
tables reached three Nexus Card draw/keep choices and six actual Homeworld
|
||||||
|
revival-deployment decisions. Eight proposed shipments/moves into public
|
||||||
|
Ecaz Ambassador and Moritani Terror overlaps were rejected without mutation;
|
||||||
|
bot continuations found other legal actions. The published arrival-priority
|
||||||
|
question remains unresolved. An intentionally capped ten-action Advanced save
|
||||||
|
resumed to turn-five victory with 877 accepted actions and 23 more restores.
|
||||||
|
The source-bound matrix and replay reports are in
|
||||||
|
`/tmp/dune-combined-homeworld-nexus-matrix/report.json` and
|
||||||
|
`/tmp/dune-homeworld-nexus-resume-finish/report.json`. These sample wins do not
|
||||||
|
certify individual card effects, every Homeworld entitlement or combined
|
||||||
|
expansion publication.
|
||||||
|
|
||||||
## 28 September 2026 — five/six-seat all-expansion Nexus integration samples
|
## 28 September 2026 — five/six-seat all-expansion Nexus integration samples
|
||||||
|
|
||||||
The offline-only `combined-nexus` audit setup selects all three physical
|
The offline-only `combined-nexus` audit setup selects all three physical
|
||||||
|
|||||||
@@ -115,6 +115,7 @@ node --import tsx tools/faction-games.ts --out /tmp/dune-new-choam-nexus --profi
|
|||||||
node --import tsx tools/faction-games.ts --out /tmp/dune-new-ecaz-nexus --profile ecaz-nexus
|
node --import tsx tools/faction-games.ts --out /tmp/dune-new-ecaz-nexus --profile ecaz-nexus
|
||||||
node --import tsx tools/faction-games.ts --out /tmp/dune-new-ix-nexus --profile ix-nexus
|
node --import tsx tools/faction-games.ts --out /tmp/dune-new-ix-nexus --profile ix-nexus
|
||||||
node --import tsx tools/faction-games.ts --out /tmp/dune-new-combined-nexus --profile combined-nexus
|
node --import tsx tools/faction-games.ts --out /tmp/dune-new-combined-nexus --profile combined-nexus
|
||||||
|
node --import tsx tools/faction-games.ts --out /tmp/dune-new-combined-homeworld-nexus --profile combined-homeworld-nexus
|
||||||
node --import tsx tools/faction-games.ts --out /tmp/dune-new-nexus-three --profile nexus --players 3 --rules advanced
|
node --import tsx tools/faction-games.ts --out /tmp/dune-new-nexus-three --profile nexus --players 3 --rules advanced
|
||||||
node --import tsx tools/faction-games.ts --out /tmp/dune-new-resume --resume /private/failed-combined-advanced.json
|
node --import tsx tools/faction-games.ts --out /tmp/dune-new-resume --resume /private/failed-combined-advanced.json
|
||||||
```
|
```
|
||||||
@@ -124,8 +125,8 @@ Ecaz/Moritani and combined Basic/Advanced samples. `--profile base` selects ten
|
|||||||
additional samples: Basic and Advanced with two through six players.
|
additional samples: Basic and Advanced with two through six players.
|
||||||
`--players 2..6` narrows the base, Homeworld, Nexus, combined
|
`--players 2..6` narrows the base, Homeworld, Nexus, combined
|
||||||
`homeworld-nexus`, expansion-roster or paired-Nexus profiles. The
|
`homeworld-nexus`, expansion-roster or paired-Nexus profiles. The
|
||||||
`combined-nexus` profile supports `--players 5` or `6` only. Omission or `all`
|
`combined-nexus` and `combined-homeworld-nexus` profiles support `--players 5`
|
||||||
retains every roster in a selected profile. The fixed
|
or `6` only. Omission or `all` retains every roster in a selected profile. The fixed
|
||||||
base roster adds Atreides, Harkonnen, Fremen, Emperor, Guild and Bene Gesserit
|
base roster adds Atreides, Harkonnen, Fremen, Emperor, Guild and Bene Gesserit
|
||||||
in that order. These are sample rosters, not the only rules-permitted
|
in that order. These are sample rosters, not the only rules-permitted
|
||||||
player-count configurations. Each optional module profile runs two through
|
player-count configurations. Each optional module profile runs two through
|
||||||
@@ -140,8 +141,12 @@ rosters with Nexus Cards enabled at seed offsets 98–107, 108–117 and 118–1
|
|||||||
`combined-nexus` selects five or six actual expansion factions and all three
|
`combined-nexus` selects five or six actual expansion factions and all three
|
||||||
expansion decks with Nexus Cards in Basic and Advanced. Five seats leave Richese
|
expansion decks with Nexus Cards in Basic and Advanced. Five seats leave Richese
|
||||||
absent so a player can remain unallied and draw; six seats contain every expansion
|
absent so a player can remain unallied and draw; six seats contain every expansion
|
||||||
faction. Their seed offsets are 130–131 and 128–129 respectively. The original
|
faction. Their seed offsets are 130–131 and 128–129 respectively.
|
||||||
six default samples are unchanged. Output names include the player count.
|
`combined-homeworld-nexus` reuses the same four rosters with physical Homeworld
|
||||||
|
custody added, at offsets 132–135. Its public arrival-priority gate can reject a
|
||||||
|
route where Ecaz Ambassadors and Moritani Terror both react; the bot must choose
|
||||||
|
another legal route. Neither profile establishes those pending source priorities.
|
||||||
|
The original six default samples are unchanged. Output names include the player count.
|
||||||
Homeworld's original four-seat seed offsets remain 36–37; its other rosters
|
Homeworld's original four-seat seed offsets remain 36–37; its other rosters
|
||||||
use 48–51 and 54–57. Nexus's six-seat offsets remain 38–39; its smaller
|
use 48–51 and 54–57. Nexus's six-seat offsets remain 38–39; its smaller
|
||||||
rosters use 40–47. The combined module uses offsets 58–67. These samples
|
rosters use 40–47. The combined module uses offsets 58–67. These samples
|
||||||
|
|||||||
+5
-5
@@ -6716,8 +6716,8 @@ export function initializePairedNexusGameForAudit(state: Game): Game {
|
|||||||
return initializeSetupGameForAudit(state, false, true, false, false, false, false, true);
|
return initializeSetupGameForAudit(state, false, true, false, false, false, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Offline-only all-expansion Nexus composition; not a public start gate. */
|
/** Offline-only all-expansion Nexus composition, optionally with Homeworlds; not a public start gate. */
|
||||||
export function initializeCombinedNexusGameForAudit(state: Game): Game {
|
export function initializeCombinedNexusGameForAudit(state: Game, homeworlds = false): Game {
|
||||||
requireRule(state.expansions.length === 3 &&
|
requireRule(state.expansions.length === 3 &&
|
||||||
['ix', 'choam', 'ecaz'].every(expansion => state.expansions.includes(expansion)) &&
|
['ix', 'choam', 'ecaz'].every(expansion => state.expansions.includes(expansion)) &&
|
||||||
[5, 6].includes(state.players.length) &&
|
[5, 6].includes(state.players.length) &&
|
||||||
@@ -6726,10 +6726,10 @@ export function initializeCombinedNexusGameForAudit(state: Game): Game {
|
|||||||
.every(faction => state.players.some(player => player.faction === faction)),
|
.every(faction => state.players.some(player => player.faction === faction)),
|
||||||
'The combined Nexus sample requires five or six expansion factions and their three decks.');
|
'The combined Nexus sample requires five or six expansion factions and their three decks.');
|
||||||
requireRule(!!state.nexusCards && state.nexusCards.cards === null && state.nexusCards.phase === null &&
|
requireRule(!!state.nexusCards && state.nexusCards.cards === null && state.nexusCards.phase === null &&
|
||||||
!state.homeworlds && !state.leaderSkills && !state.discoveryEnabled &&
|
!!state.homeworlds === homeworlds && !state.leaderSkills && !state.discoveryEnabled &&
|
||||||
!state.ecazTreachery && !state.techTokens && !state.strongholdCards,
|
!state.ecazTreachery && !state.techTokens && !state.strongholdCards,
|
||||||
'Enable only Nexus Cards in a fresh combined expansion lobby.');
|
'Enable only the selected Nexus and Homeworld modules in a fresh combined expansion lobby.');
|
||||||
return initializeSetupGameForAudit(state, false, true, false, false, false, false, true);
|
return initializeSetupGameForAudit(state, homeworlds, true, false, false, false, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Offline prototype entry through real Ix setup, including both expansion factions.
|
/** Offline prototype entry through real Ix setup, including both expansion factions.
|
||||||
|
|||||||
+22
-16
@@ -30,7 +30,7 @@ import { privateOutputDirectory, sourceSnapshot } from './verification';
|
|||||||
const DEFAULT_SEED = 20_260_926;
|
const DEFAULT_SEED = 20_260_926;
|
||||||
const DEFAULT_MAX_ACTIONS = 3_500;
|
const DEFAULT_MAX_ACTIONS = 3_500;
|
||||||
const DIFFICULTIES = ['Easy', 'Medium', 'Hard', 'Brutal'] as const;
|
const DIFFICULTIES = ['Easy', 'Medium', 'Hard', 'Brutal'] as const;
|
||||||
type Profile = 'base' | 'choam' | 'ecaz' | 'combined' | 'combined-nexus' | 'homeworld' | 'nexus' | 'homeworld-nexus' | 'choam-roster' | 'ecaz-roster' | 'ix-roster' | 'choam-nexus' | 'ecaz-nexus' | 'ix-nexus' | 'moritani-skills' | 'tleilaxu-skills' | 'ix-skills' | 'choam-skills';
|
type Profile = 'base' | 'choam' | 'ecaz' | 'combined' | 'combined-nexus' | 'combined-homeworld-nexus' | 'homeworld' | 'nexus' | 'homeworld-nexus' | 'choam-roster' | 'ecaz-roster' | 'ix-roster' | 'choam-nexus' | 'ecaz-nexus' | 'ix-nexus' | 'moritani-skills' | 'tleilaxu-skills' | 'ix-skills' | 'choam-skills';
|
||||||
type Rules = 'basic' | 'advanced';
|
type Rules = 'basic' | 'advanced';
|
||||||
|
|
||||||
type Scenario = {
|
type Scenario = {
|
||||||
@@ -161,6 +161,11 @@ const COMBINED_NEXUS_SCENARIOS: readonly Scenario[] = [
|
|||||||
})),
|
})),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const COMBINED_HOMEWORLD_NEXUS_SCENARIOS: readonly Scenario[] =
|
||||||
|
COMBINED_NEXUS_SCENARIOS.map(scenario => ({
|
||||||
|
...scenario, profile: 'combined-homeworld-nexus', ordinal: scenario.ordinal + 4,
|
||||||
|
}));
|
||||||
|
|
||||||
const MORITANI_SKILLS_ROSTER: readonly FactionId[] = [
|
const MORITANI_SKILLS_ROSTER: readonly FactionId[] = [
|
||||||
'moritani', 'emperor', 'guild', 'harkonnen', 'fremen', 'beneGesserit',
|
'moritani', 'emperor', 'guild', 'harkonnen', 'fremen', 'beneGesserit',
|
||||||
];
|
];
|
||||||
@@ -231,10 +236,10 @@ type Result = {
|
|||||||
function usage() {
|
function usage() {
|
||||||
return (
|
return (
|
||||||
'Usage: node --import tsx tools/faction-games.ts --out NEW_PRIVATE_DIR ' +
|
'Usage: node --import tsx tools/faction-games.ts --out NEW_PRIVATE_DIR ' +
|
||||||
'[--seed UINT32] [--profile all|base|choam|ecaz|combined|combined-nexus|homeworld|nexus|homeworld-nexus|choam-roster|ecaz-roster|ix-roster|choam-nexus|ecaz-nexus|ix-nexus|moritani-skills|tleilaxu-skills|ix-skills|choam-skills] ' +
|
'[--seed UINT32] [--profile all|base|choam|ecaz|combined|combined-nexus|combined-homeworld-nexus|homeworld|nexus|homeworld-nexus|choam-roster|ecaz-roster|ix-roster|choam-nexus|ecaz-nexus|ix-nexus|moritani-skills|tleilaxu-skills|ix-skills|choam-skills] ' +
|
||||||
'[--rules both|basic|advanced] [--players all|2|3|4|5|6] [--max-actions POSITIVE] ' +
|
'[--rules both|basic|advanced] [--players all|2|3|4|5|6] [--max-actions POSITIVE] ' +
|
||||||
'[--resume FAILED_GAME.json]\n' +
|
'[--resume FAILED_GAME.json]\n' +
|
||||||
'Runs genuine setup and gameplay offline. Default/all keeps the six expansion samples; combined-nexus adds five/six-seat Basic/Advanced all-expansion Nexus samples. Base, Homeworld, Nexus, Homeworld-Nexus, expansion roster, paired expansion Nexus and skill profiles default to their 2–6-player samples. --players requires a supported profile. Output must be a new private directory outside the checkout.'
|
'Runs genuine setup and gameplay offline. Default/all keeps the six expansion samples; combined-nexus and combined-homeworld-nexus add five/six-seat Basic/Advanced all-expansion samples. Base, Homeworld, Nexus, Homeworld-Nexus, expansion roster, paired expansion Nexus and skill profiles default to their 2–6-player samples. --players requires a supported profile. Output must be a new private directory outside the checkout.'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -265,7 +270,7 @@ function positive(value: string | undefined) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function scenarioName(scenario: Scenario) {
|
function scenarioName(scenario: Scenario) {
|
||||||
return scenario.profile === 'base' || scenario.profile === 'homeworld' || scenario.profile === 'nexus' || scenario.profile === 'homeworld-nexus' || scenario.profile === 'combined-nexus' ||
|
return scenario.profile === 'base' || scenario.profile === 'homeworld' || scenario.profile === 'nexus' || scenario.profile === 'homeworld-nexus' || scenario.profile === 'combined-nexus' || scenario.profile === 'combined-homeworld-nexus' ||
|
||||||
scenario.profile === 'choam-roster' || scenario.profile === 'ecaz-roster' || scenario.profile === 'ix-roster' || scenario.profile === 'choam-nexus' || scenario.profile === 'ecaz-nexus' || scenario.profile === 'ix-nexus' || skillProfile(scenario.profile)
|
scenario.profile === 'choam-roster' || scenario.profile === 'ecaz-roster' || scenario.profile === 'ix-roster' || scenario.profile === 'choam-nexus' || scenario.profile === 'ecaz-nexus' || scenario.profile === 'ix-nexus' || skillProfile(scenario.profile)
|
||||||
? `${scenario.profile}-${scenario.roster.length}-${scenario.rules}`
|
? `${scenario.profile}-${scenario.roster.length}-${scenario.rules}`
|
||||||
: `${scenario.profile}-${scenario.rules}`;
|
: `${scenario.profile}-${scenario.rules}`;
|
||||||
@@ -273,8 +278,8 @@ function scenarioName(scenario: Scenario) {
|
|||||||
|
|
||||||
function parseProfile(value: string | undefined) {
|
function parseProfile(value: string | undefined) {
|
||||||
const profile = value ?? 'all';
|
const profile = value ?? 'all';
|
||||||
if (!['all', 'base', 'choam', 'ecaz', 'combined', 'combined-nexus', 'homeworld', 'nexus', 'homeworld-nexus', 'choam-roster', 'ecaz-roster', 'ix-roster', 'choam-nexus', 'ecaz-nexus', 'ix-nexus', 'moritani-skills', 'tleilaxu-skills', 'ix-skills', 'choam-skills'].includes(profile))
|
if (!['all', 'base', 'choam', 'ecaz', 'combined', 'combined-nexus', 'combined-homeworld-nexus', 'homeworld', 'nexus', 'homeworld-nexus', 'choam-roster', 'ecaz-roster', 'ix-roster', 'choam-nexus', 'ecaz-nexus', 'ix-nexus', 'moritani-skills', 'tleilaxu-skills', 'ix-skills', 'choam-skills'].includes(profile))
|
||||||
throw new Error('--profile must be all, base, choam, ecaz, combined, combined-nexus, homeworld, nexus, homeworld-nexus, choam-roster, ecaz-roster, ix-roster, choam-nexus, ecaz-nexus, ix-nexus, moritani-skills, tleilaxu-skills, ix-skills or choam-skills.');
|
throw new Error('--profile must be all, base, choam, ecaz, combined, combined-nexus, combined-homeworld-nexus, homeworld, nexus, homeworld-nexus, choam-roster, ecaz-roster, ix-roster, choam-nexus, ecaz-nexus, ix-nexus, moritani-skills, tleilaxu-skills, ix-skills or choam-skills.');
|
||||||
return profile as Profile | 'all';
|
return profile as Profile | 'all';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -318,12 +323,12 @@ function freshGame(scenario: Scenario) {
|
|||||||
player.bot = DIFFICULTIES[index % DIFFICULTIES.length];
|
player.bot = DIFFICULTIES[index % DIFFICULTIES.length];
|
||||||
player.ready = true;
|
player.ready = true;
|
||||||
}
|
}
|
||||||
if (scenario.profile === 'homeworld' || scenario.profile === 'homeworld-nexus')
|
if (scenario.profile === 'homeworld' || scenario.profile === 'homeworld-nexus' || scenario.profile === 'combined-homeworld-nexus')
|
||||||
game.homeworlds = { custody: null };
|
game.homeworlds = { custody: null };
|
||||||
if (scenario.profile === 'nexus' || scenario.profile === 'homeworld-nexus' || scenario.profile === 'choam-nexus' || scenario.profile === 'ecaz-nexus' || scenario.profile === 'ix-nexus' || scenario.profile === 'combined-nexus')
|
if (scenario.profile === 'nexus' || scenario.profile === 'homeworld-nexus' || scenario.profile === 'choam-nexus' || scenario.profile === 'ecaz-nexus' || scenario.profile === 'ix-nexus' || scenario.profile === 'combined-nexus' || scenario.profile === 'combined-homeworld-nexus')
|
||||||
game.nexusCards = { cards: null, phase: null };
|
game.nexusCards = { cards: null, phase: null };
|
||||||
if (scenario.profile === 'combined-nexus')
|
if (scenario.profile === 'combined-nexus' || scenario.profile === 'combined-homeworld-nexus')
|
||||||
return initializeCombinedNexusGameForAudit(game);
|
return initializeCombinedNexusGameForAudit(game, scenario.profile === 'combined-homeworld-nexus');
|
||||||
if (scenario.profile === 'choam-nexus' || scenario.profile === 'ecaz-nexus' || scenario.profile === 'ix-nexus')
|
if (scenario.profile === 'choam-nexus' || scenario.profile === 'ecaz-nexus' || scenario.profile === 'ix-nexus')
|
||||||
return initializePairedNexusGameForAudit(game);
|
return initializePairedNexusGameForAudit(game);
|
||||||
return skillProfile(scenario.profile)
|
return skillProfile(scenario.profile)
|
||||||
@@ -384,10 +389,10 @@ function resumedGame(path: string) {
|
|||||||
game.moritaniAssassinateCallEvents
|
game.moritaniAssassinateCallEvents
|
||||||
)
|
)
|
||||||
throw new Error('--resume sample scenarios exclude unsupported optional modules.');
|
throw new Error('--resume sample scenarios exclude unsupported optional modules.');
|
||||||
const scenario = [...SCENARIOS, ...COMBINED_NEXUS_SCENARIOS, ...BASE_SCENARIOS, ...MODULE_SCENARIOS, ...EXPANSION_ROSTER_SCENARIOS, ...PAIRED_NEXUS_SCENARIOS, ...MORITANI_SKILLS_SCENARIOS, ...TLEILAXU_SKILLS_SCENARIOS, ...IX_SKILLS_SCENARIOS, ...CHOAM_SKILLS_SCENARIOS].find(
|
const scenario = [...SCENARIOS, ...COMBINED_NEXUS_SCENARIOS, ...COMBINED_HOMEWORLD_NEXUS_SCENARIOS, ...BASE_SCENARIOS, ...MODULE_SCENARIOS, ...EXPANSION_ROSTER_SCENARIOS, ...PAIRED_NEXUS_SCENARIOS, ...MORITANI_SKILLS_SCENARIOS, ...TLEILAXU_SKILLS_SCENARIOS, ...IX_SKILLS_SCENARIOS, ...CHOAM_SKILLS_SCENARIOS].find(
|
||||||
(candidate) =>
|
(candidate) =>
|
||||||
(candidate.profile === 'homeworld' || candidate.profile === 'homeworld-nexus') === !!game.homeworlds &&
|
(candidate.profile === 'homeworld' || candidate.profile === 'homeworld-nexus' || candidate.profile === 'combined-homeworld-nexus') === !!game.homeworlds &&
|
||||||
(candidate.profile === 'nexus' || candidate.profile === 'homeworld-nexus' || candidate.profile === 'choam-nexus' || candidate.profile === 'ecaz-nexus' || candidate.profile === 'ix-nexus' || candidate.profile === 'combined-nexus') === !!game.nexusCards &&
|
(candidate.profile === 'nexus' || candidate.profile === 'homeworld-nexus' || candidate.profile === 'choam-nexus' || candidate.profile === 'ecaz-nexus' || candidate.profile === 'ix-nexus' || candidate.profile === 'combined-nexus' || candidate.profile === 'combined-homeworld-nexus') === !!game.nexusCards &&
|
||||||
skillProfile(candidate.profile) === !!game.leaderSkills &&
|
skillProfile(candidate.profile) === !!game.leaderSkills &&
|
||||||
candidate.rules === (game.advanced ? 'advanced' : 'basic') &&
|
candidate.rules === (game.advanced ? 'advanced' : 'basic') &&
|
||||||
JSON.stringify(candidate.expansions) ===
|
JSON.stringify(candidate.expansions) ===
|
||||||
@@ -581,10 +586,10 @@ async function main() {
|
|||||||
const profile = parseProfile(values.profile);
|
const profile = parseProfile(values.profile);
|
||||||
const rules = parseRules(values.rules);
|
const rules = parseRules(values.rules);
|
||||||
const players = parsePlayers(values.players);
|
const players = parsePlayers(values.players);
|
||||||
if (supplied('players') && !['base', 'homeworld', 'nexus', 'homeworld-nexus', 'combined-nexus', 'choam-roster', 'ecaz-roster', 'ix-roster', 'choam-nexus', 'ecaz-nexus', 'ix-nexus'].includes(profile) && !skillProfile(profile))
|
if (supplied('players') && !['base', 'homeworld', 'nexus', 'homeworld-nexus', 'combined-nexus', 'combined-homeworld-nexus', 'choam-roster', 'ecaz-roster', 'ix-roster', 'choam-nexus', 'ecaz-nexus', 'ix-nexus'].includes(profile) && !skillProfile(profile))
|
||||||
throw new Error('--players requires a roster or optional-module profile.');
|
throw new Error('--players requires a roster or optional-module profile.');
|
||||||
if (profile === 'combined-nexus' && players !== 'all' && ![5, 6].includes(players))
|
if ((profile === 'combined-nexus' || profile === 'combined-homeworld-nexus') && players !== 'all' && ![5, 6].includes(players))
|
||||||
throw new Error('--profile combined-nexus supports only five or six players.');
|
throw new Error(`--profile ${profile} supports only five or six players.`);
|
||||||
if (skillProfile(profile) && rules === 'advanced')
|
if (skillProfile(profile) && rules === 'advanced')
|
||||||
throw new Error('Expansion Leader Skills profiles currently support only Basic samples.');
|
throw new Error('Expansion Leader Skills profiles currently support only Basic samples.');
|
||||||
const resume = values.resume ? resumedGame(values.resume) : null;
|
const resume = values.resume ? resumedGame(values.resume) : null;
|
||||||
@@ -593,6 +598,7 @@ async function main() {
|
|||||||
: profile === 'choam-roster' || profile === 'ecaz-roster' || profile === 'ix-roster' ? EXPANSION_ROSTER_SCENARIOS
|
: profile === 'choam-roster' || profile === 'ecaz-roster' || profile === 'ix-roster' ? EXPANSION_ROSTER_SCENARIOS
|
||||||
: profile === 'choam-nexus' || profile === 'ecaz-nexus' || profile === 'ix-nexus' ? PAIRED_NEXUS_SCENARIOS
|
: profile === 'choam-nexus' || profile === 'ecaz-nexus' || profile === 'ix-nexus' ? PAIRED_NEXUS_SCENARIOS
|
||||||
: profile === 'combined-nexus' ? COMBINED_NEXUS_SCENARIOS
|
: profile === 'combined-nexus' ? COMBINED_NEXUS_SCENARIOS
|
||||||
|
: profile === 'combined-homeworld-nexus' ? COMBINED_HOMEWORLD_NEXUS_SCENARIOS
|
||||||
: profile === 'base' ? BASE_SCENARIOS
|
: profile === 'base' ? BASE_SCENARIOS
|
||||||
: profile === 'moritani-skills' ? MORITANI_SKILLS_SCENARIOS
|
: profile === 'moritani-skills' ? MORITANI_SKILLS_SCENARIOS
|
||||||
: profile === 'tleilaxu-skills' ? TLEILAXU_SKILLS_SCENARIOS
|
: profile === 'tleilaxu-skills' ? TLEILAXU_SKILLS_SCENARIOS
|
||||||
|
|||||||
Reference in new issue
Block a user