Compose World Skills cards with selected ordinary decks

This commit is contained in:
Quintine committed 2026-10-17 23:07:39 +11:00
1 parent b9330d489e
commit 01985af36b
36 files changed
+1201 -283

No files matched your search

+9 -6
View File
@@ -1,7 +1,7 @@
import { classicNexusModulesProfile, mixedE1E2NexusProfile, mixedE3NexusProfile, pairedE3NexusProfile, pairedNexusModulesProfile, singleE1E2NexusProfile, standaloneE3NexusProfile } from './nexus-module-profile';
import { nativeFactionTechProfile } from './faction-module-profile';
import { classicDiscoveryLeaderSkillsProfile, classicDiscoveryNexusProfile, homeworldDiscoveryProfile, discoveryModeSupported, discoveryModuleProfile, mixedE1E2DiscoveryNexusProfile, mixedE3DiscoveryNexusProfile, pairedDiscoveryNexusProfile, pairedE3DiscoveryNexusProfile, singleE1E2DiscoveryNexusProfile, standaloneE3DiscoveryNexusProfile } from './discovery-module-profile';
import { advancedMoritaniLeaderSkillsProfile, advancedNativeLeaderSkillsProfile, homeworldLeaderSkillsProfile, independentTreacheryLeaderSkillsProfile, classicNexusLeaderSkillsProfile, classicTechLeaderSkillsProfile, guildBetrayalNexusLeaderSkillsProfile, mixedE1E2NexusLeaderSkillsProfile, mixedE3NexusLeaderSkillsProfile, nativeDiscoveryLeaderSkillsProfile, nativeEcazLeaderSkillsProfile, nativeExpansionLeaderSkillsProfile, nativeTechLeaderSkillsProfile, ordinaryLeaderSkillModeSupported, pairedE3LeaderSkillsProfile, pairedE3NexusLeaderSkillsProfile, pairedNexusLeaderSkillsProfile, singleE1E2NexusLeaderSkillsProfile, standaloneE3NexusLeaderSkillsProfile, strongholdLeaderSkillsProfile } from './leader-skill-profile';
import { advancedMoritaniLeaderSkillsProfile, selectedDeckLeaderSkillsProfile, homeworldLeaderSkillsProfile, independentTreacheryLeaderSkillsProfile, classicNexusLeaderSkillsProfile, classicTechLeaderSkillsProfile, guildBetrayalNexusLeaderSkillsProfile, mixedE1E2NexusLeaderSkillsProfile, mixedE3NexusLeaderSkillsProfile, nativeDiscoveryLeaderSkillsProfile, nativeEcazLeaderSkillsProfile, nativeExpansionLeaderSkillsProfile, nativeTechLeaderSkillsProfile, ordinaryLeaderSkillModeSupported, pairedE3LeaderSkillsProfile, pairedE3NexusLeaderSkillsProfile, pairedNexusLeaderSkillsProfile, singleE1E2NexusLeaderSkillsProfile, standaloneE3NexusLeaderSkillsProfile, strongholdLeaderSkillsProfile } from './leader-skill-profile';
import { bribeTimingBlock, maximumBribe, type BribeOptions } from './bribe-options';
import { quoteSpicePlacement, stormExposesTerritory, stormSectorAfter, wormConsumesForces } from './disaster-rules';
import { isStormCardDistance, type StormCardComponent } from './storm-cards';
@@ -8805,7 +8805,7 @@ function leaderSkillsIntegrity(g: Game) {
if (leader.gholaBy === undefined) continue;
const controller = g.players.find((p) => p.id === leader.gholaBy);
requireRule(
(foreignProfileAllowed ??= advancedNativeLeaderSkillsProfile(g)) &&
(foreignProfileAllowed ??= g.advanced && selectedDeckLeaderSkillsProfile(g)) &&
controller?.faction === 'tleilaxu' &&
controller.id !== owner.id &&
leader.faction === owner.faction &&
@@ -10708,7 +10708,7 @@ export function initializeLeaderSkillsGameForAudit(state: Game): Game {
const homeworlds = homeworldLeaderSkillsProfile(state);
const independent = independentTreacheryLeaderSkillsProfile(state);
if (state.ecazTreachery) {
requireRule(independent, 'Independent Treachery with Leader Skills requires a fresh supported classic or native lobby with only optional original Tech Tokens and Advanced Stronghold Cards.');
requireRule(independent, 'Independent cards with Skills require a fresh supported selected-deck roster with original Homeworlds/Tech/Advanced Strongholds; Nexus/Discovery and native E3 Worlds remain gated.');
requireFreshBaseRuntime(state);
requireFreshFactionInventory(state);
}
@@ -10749,8 +10749,10 @@ function independentCardRoster(g: Game): boolean {
});
}
function ecazHomeworldProfile(g: Game): boolean {
if (g.homeworlds && g.leaderSkills && !g.sandtrout && independentTreacheryLeaderSkillsProfile(g)) return true;
return !!g.homeworlds && g.ecazTreachery === true && independentCardRoster(g) &&
!g.expansions.includes('ecaz') && g.players.length >= 2 && g.players.length <= 6 &&
!g.players.some(player => player.faction === 'ecaz' || player.faction === 'moritani') &&
g.players.length >= 2 && g.players.length <= 6 &&
!g.nexusCards && !g.leaderSkills &&
((!g.techTokens && !g.strongholdCards) || independentCardModulesProfile(g)) &&
!g.discoveryEnabled && !g.discoveries && !g.discoveryStash && !g.greatMaker && !g.sandtrout &&
@@ -10763,7 +10765,8 @@ function ecazHomeworldProfile(g: Game): boolean {
function independentCardModulesProfile(g: Game): boolean {
if ((g.techTokens || g.strongholdCards) && g.leaderSkills && !g.sandtrout &&
independentTreacheryLeaderSkillsProfile(g)) return true;
if (!g.ecazTreachery || (!g.techTokens && !g.strongholdCards) || !independentCardRoster(g) || g.expansions.includes('ecaz') ||
if (!g.ecazTreachery || (!g.techTokens && !g.strongholdCards) || !independentCardRoster(g) ||
g.players.some(player => player.faction === 'ecaz' || player.faction === 'moritani') ||
g.players.length < (g.techTokens ? 3 : 2) || g.players.length > 6 ||
(g.strongholdCards && !g.advanced) ||
g.nexusCards || g.leaderSkills ||
@@ -13947,7 +13950,7 @@ function recruitsPlayBlock(g: Game, owner: Player, card: Card): string | null {
if (!g.ecazTreachery || !ecazTreacheryDefinition(card) || card.id !== RECRUITS_CARD_ID)
return 'Choose the physical Recruits card from the enabled Ecaz Treachery Cards variant.';
if (!recruitsModeSupported(g))
return 'Recruits requires a supported independent-card profile: faction-only, all14 Skills with optional original phase modules, or the existing native Homeworld compositions.';
return 'Recruits requires a supported independent-card profile: faction-only, all14 Skills with original World/phase modules, or existing native Homeworld compositions.';
if (g.status !== 'playing' || g.phase !== 4)
return 'Play Recruits during Revival.';
if (g.recruits?.turn === g.turn)
+34 -92
View File
@@ -233,17 +233,17 @@ function semutaLeaderSkillContext(game: LeaderSkillProfile): boolean {
game.expansions.includes('choam') && !!game.players?.some(p => p.faction === 'richese');
}
/** E1/E2 native skills may add Tech and Advanced Strongholds; original roster/decks remain. */
function nativeLeaderSkillModulesSupported(game: LeaderSkillProfile): boolean {
/** Selected ordinary decks retain original module envelopes; actual E3 seats are separate. */
function selectedDeckLeaderSkillModulesSupported(game: LeaderSkillProfile): boolean {
if (game.homeworlds) return homeworldLeaderSkillModulesSupported(game);
if (noOtherLeaderSkillModules(game) || pairedNexusLeaderSkillsProfile(game) ||
if (noOtherLeaderSkillModules(game) || independentTreacheryLeaderSkillsProfile(game) || pairedNexusLeaderSkillsProfile(game) ||
singleE1E2NexusLeaderSkillsProfile(game) || mixedE1E2NexusLeaderSkillsProfile(game)) return true;
if (game.discoveryEnabled || game.discoveries) return discoveryLeaderSkillModulesSupported(game);
const players = game.players;
if ((!game.techTokens && !game.strongholdCards) || !players ||
players.length < (game.techTokens ? 3 : 2) || players.length > 6 ||
(game.strongholdCards && game.advanced !== true) ||
game.expansions.length < 1 || game.expansions.length > 2 ||
game.expansions.length < 1 || game.expansions.length > 3 ||
game.homeworlds || game.nexusCards || game.discoveries || game.discoveryEnabled ||
game.ecazTreachery || (game.semutaPreview && !semutaLeaderSkillContext(game)) ||
game.moritaniAssassinatePreview || game.advancedPreview || game.kullPreview ||
@@ -251,7 +251,7 @@ function nativeLeaderSkillModulesSupported(game: LeaderSkillProfile): boolean {
game.nexusIxianReplacementPreview || game.nexusIxianBetrayalPreview ||
game.nexusHarkonnenBetrayalPreview) return false;
for (const expansion of game.expansions)
if (expansion !== 'ix' && expansion !== 'choam') return false;
if (expansion !== 'ix' && expansion !== 'choam' && expansion !== 'ecaz') return false;
for (let i = 0; i < players.length; i++)
for (let j = 0; j < i; j++) if (players[j].faction === players[i].faction) return false;
return true;
@@ -303,7 +303,7 @@ export function classicTechLeaderSkillsProfile(game: LeaderSkillProfile): boolea
export function strongholdLeaderSkillsProfile(game: LeaderSkillProfile): boolean {
if (!game.strongholdCards || game.advanced !== true) return false;
if (independentTreacheryLeaderSkillsProfile(game)) return true;
if (game.expansions.length) return advancedNativeLeaderSkillsProfile(game) ||
if (game.expansions.length) return selectedDeckLeaderSkillsProfile(game) ||
advancedMoritaniLeaderSkillsProfile(game) || nativeEcazLeaderSkillsProfile(game);
const players = game.players;
if (!players || players.length < (game.techTokens ? 3 : 2) || players.length > 6 ||
@@ -386,102 +386,44 @@ export function nativeEcazLeaderSkillsProfile(game: LeaderSkillProfile): boolean
return native;
}
/** Native Basic Tleilaxu, including Face Dancers; foreign gholas are Advanced. */
export function basicTleilaxuLeaderSkillsProfile(game: LeaderSkillProfile): boolean {
return game.advanced === false && game.expansions.length === 1 &&
game.expansions[0] === 'ix' && nativeLeaderSkillModulesSupported(game) &&
!!game.players?.some(player => player.faction === 'tleilaxu') &&
game.players.every(player => player.faction === 'tleilaxu' ||
FACTIONS.some(faction => faction.id === player.faction && faction.expansion === 'base'));
}
/** Basic Ixians, optionally with native Tleilaxu, keep the ordinary Ix inventories. */
export function basicIxLeaderSkillsProfile(game: LeaderSkillProfile): boolean {
return game.advanced === false && game.expansions.length === 1 &&
game.expansions[0] === 'ix' && nativeLeaderSkillModulesSupported(game) &&
!!game.players?.some(player => player.faction === 'ixians') &&
game.players.every(player => ['ixians', 'tleilaxu'].includes(player.faction) ||
FACTIONS.some(faction => faction.id === player.faction && faction.expansion === 'base'));
}
/** Basic CHOAM's ordinary leaders and economy; Auditor belongs to Advanced. */
export function basicChoamLeaderSkillsProfile(game: LeaderSkillProfile): boolean {
return game.advanced === false && game.expansions.length === 1 &&
game.expansions[0] === 'choam' && nativeLeaderSkillModulesSupported(game) &&
!!game.players?.some(player => player.faction === 'choam') &&
game.players.every(player => player.faction === 'choam' ||
FACTIONS.some(faction => faction.id === player.faction && faction.expansion === 'base'));
}
/** Native Basic Richese/CHOAM setup, without unrelated optional overlays. */
export function basicRicheseLeaderSkillsProfile(game: LeaderSkillProfile): boolean {
/** Base/E1/E2 seats with selected ordinary decks, Basic or Advanced; no faction prerequisite. */
export function selectedDeckLeaderSkillsProfile(game: LeaderSkillProfile): boolean {
const players = game.players;
if (game.advanced !== false || game.expansions.length !== 1 ||
game.expansions[0] !== 'choam' || !players || players.length < 2 || players.length > 6 ||
!nativeLeaderSkillModulesSupported(game) ||
(game.semutaPreview && !semutaLeaderSkillContext(game)) || game.moritaniAssassinatePreview ||
game.advancedPreview || game.kullPreview || game.nexusKullPreview ||
game.guildBetrayalPreview || game.richeseBetrayalPreview ||
game.nexusIxianReplacementPreview || game.nexusIxianBetrayalPreview ||
game.nexusHarkonnenBetrayalPreview) return false;
let native = false;
for (let i = 0; i < players.length; i++) {
const player = players[i];
for (let j = 0; j < i; j++) if (players[j].faction === player.faction) return false;
if (player.faction === 'richese') native = true;
else if (player.faction !== 'choam') {
let classic = false;
for (const faction of FACTIONS)
if (faction.id === player.faction && faction.expansion === 'base') { classic = true; break; }
if (!classic) return false;
}
}
return native;
}
export function basicExpansionLeaderSkillsProfile(game: LeaderSkillProfile): boolean {
return basicMoritaniLeaderSkillsProfile(game) || basicTleilaxuLeaderSkillsProfile(game) ||
basicIxLeaderSkillsProfile(game) || basicChoamLeaderSkillsProfile(game) || basicRicheseLeaderSkillsProfile(game);
}
/** Source-clear Advanced native factions; optional decks never imply a seated faction. */
export function advancedNativeLeaderSkillsProfile(game: LeaderSkillProfile): boolean {
const players = game.players;
if (game.advanced !== true || !players || players.length < 2 || players.length > 6 ||
game.expansions.length < 1 || game.expansions.length > 2 ||
(game.expansions.length === 2 && game.expansions[0] === game.expansions[1]) ||
!nativeLeaderSkillModulesSupported(game) ||
if (typeof game.advanced !== 'boolean' || !players || players.length < 2 || players.length > 6 ||
game.expansions.length < 1 || game.expansions.length > 3 ||
!selectedDeckLeaderSkillModulesSupported(game) ||
(game.semutaPreview && !semutaLeaderSkillContext(game)) ||
game.moritaniAssassinatePreview || game.advancedPreview ||
game.kullPreview || game.nexusKullPreview ||
game.guildBetrayalPreview || game.richeseBetrayalPreview ||
game.nexusIxianReplacementPreview || game.nexusIxianBetrayalPreview ||
game.nexusHarkonnenBetrayalPreview) return false;
for (const expansion of game.expansions)
if (expansion !== 'ix' && expansion !== 'choam') return false;
let native = false;
for (let i = 0; i < game.expansions.length; i++) {
const expansion = game.expansions[i];
if (expansion !== 'ix' && expansion !== 'choam' && expansion !== 'ecaz') return false;
for (let j = 0; j < i; j++) if (game.expansions[j] === expansion) return false;
}
for (let i = 0; i < players.length; i++) {
const player = players[i];
// Six seats at most: check prior seats without allocating per-rule quote sets.
for (let j = 0; j < i; j++) if (players[j].faction === player.faction) return false;
if (player.faction === 'ixians' || player.faction === 'tleilaxu' ||
player.faction === 'choam' || player.faction === 'richese') {
if (!game.expansions.includes(player.faction === 'choam' || player.faction === 'richese' ? 'choam' : 'ix')) return false;
native = true;
} else {
let classic = false;
for (const faction of FACTIONS)
if (faction.id === player.faction && faction.expansion === 'base') { classic = true; break; }
if (!classic) return false;
}
let selected = false;
for (const faction of FACTIONS)
if (faction.id === player.faction) {
selected = faction.expansion === 'base' ||
((faction.expansion === 'ix' || faction.expansion === 'choam') &&
game.expansions.includes(faction.expansion));
break;
}
if (!selected) return false;
}
return native;
return true;
}
export function nativeExpansionLeaderSkillsProfile(game: LeaderSkillProfile): boolean {
return (game.expansions.length > 0 && independentTreacheryLeaderSkillsProfile(game)) ||
mixedE3NexusLeaderSkillsProfile(game) || mixedE1E2NexusLeaderSkillsProfile(game) || pairedE3NexusLeaderSkillsProfile(game) ||
basicExpansionLeaderSkillsProfile(game) || advancedNativeLeaderSkillsProfile(game) ||
basicMoritaniLeaderSkillsProfile(game) || selectedDeckLeaderSkillsProfile(game) ||
advancedMoritaniLeaderSkillsProfile(game) || nativeEcazLeaderSkillsProfile(game);
}
@@ -506,7 +448,7 @@ function homeworldLeaderSkillModulesSupported(game: LeaderSkillProfile): boolean
!standaloneE3NexusLeaderSkillsProfile(game)) ||
(game.discoveryEnabled !== true && (game.discoveryEnabled || game.discoveries || game.discoveryStash || game.greatMaker)) ||
(game.techTokens && players.length < 3) || (game.strongholdCards && !game.advanced) ||
game.ecazTreachery ||
(game.ecazTreachery && !independentTreacheryLeaderSkillsProfile(game)) ||
game.semutaPreview || game.advancedPreview ||
(game.moritaniAssassinatePreview && (!game.advanced || game.expansions.length !== 1 ||
game.expansions[0] !== 'ecaz' || !players.some(player => player.faction === 'moritani'))) ||
@@ -535,18 +477,18 @@ export function homeworldLeaderSkillsProfile(game: LeaderSkillProfile): boolean
/** Independent cards with classic, selected E1/E2 or standalone/paired E3 all14 setup. */
export function independentTreacheryLeaderSkillsProfile(game: LeaderSkillProfile): boolean {
const e3 = game.expansions.length === 1 && game.expansions[0] === 'ecaz';
if (game.ecazTreachery !== true || game.expansions.length > 2 ||
if (game.ecazTreachery !== true || game.expansions.length > 3 ||
typeof game.advanced !== 'boolean' || !game.players ||
game.players.length < (game.techTokens ? 3 : 2) || game.players.length > 6 ||
(game.strongholdCards && game.advanced !== true) ||
game.homeworlds || game.nexusCards || game.discoveries || game.discoveryEnabled ||
game.nexusCards || game.discoveries || game.discoveryEnabled ||
game.discoveryStash || game.greatMaker ||
game.semutaPreview || game.advancedPreview ||
game.kullPreview || game.nexusKullPreview || game.guildBetrayalPreview ||
game.richeseBetrayalPreview || game.nexusIxianReplacementPreview ||
game.nexusIxianBetrayalPreview || game.nexusHarkonnenBetrayalPreview) return false;
for (let i = 0; i < game.expansions.length; i++) {
if (!e3 && game.expansions[i] !== 'ix' && game.expansions[i] !== 'choam') return false;
if (game.expansions[i] !== 'ix' && game.expansions[i] !== 'choam' && game.expansions[i] !== 'ecaz') return false;
for (let j = 0; j < i; j++) if (game.expansions[j] === game.expansions[i]) return false;
}
const players = game.players;
@@ -562,9 +504,9 @@ export function independentTreacheryLeaderSkillsProfile(game: LeaderSkillProfile
}
if (!selected) return false;
}
// Preserve the native Advanced Skills/Harkonnen and shared-Duke boundaries.
if (e3 && nativeE3 && game.advanced &&
players.some(player => player.faction === 'harkonnen')) return false;
// Actual E3 seats retain their one-family, non-World and Advanced Harkonnen boundaries.
if (nativeE3 && (!e3 || game.homeworlds ||
(game.advanced && players.some(player => player.faction === 'harkonnen')))) return false;
if (game.moritaniAssassinatePreview && (!e3 || !game.advanced ||
!players.some(player => player.faction === 'moritani'))) return false;
return true;
+11 -11
View File
@@ -3415,7 +3415,7 @@ export const RULE_TOPICS: RuleTopic[] = [
'The mobile card copies a currently controlled stronghold, even if another faction still holds that location’s card. Holding a card after leaving its location does not itself make that location an eligible copy. The choice is public and fixed before battle plans; a sole eligible advantage is announced automatically.',
'Arrakeen pays only for actual support and creates no personal cash. CHOAM force-payment income includes the bank contribution, subject to its normal traitor and donor exclusions. Carthag does not protect an empty or Worthless defense, stop Poison Tooth, or remove a Shield’s Lasgun explosion risk.',
'Sietch Tabr uses the opposing dial, excluding leaders and other bonuses. A single traitor victory qualifies; mutual destruction does not. Tuek pays after an ordinary loss or a single traitor outcome as well as a win; a double traitor gives neither faction spice. Habbanya also decides a tied Stone Burner comparison.',
'Fresh Advanced classic or supported E1/E2 native all14 Skills retains original Strongholds2–6 and optional Tech3–6. Independent cards may also be selected within their No-World/Nexus/Discovery envelope. Original deck/cache and real end-Mentat claims remain. Arrakeen funds actual support, not personal income or reserve fees; only the final actual payer debit qualifies for mandatory normal Banker income. Rescue preserves the support charge, then card cleanup and Tech finish before Face Dance. Specific copied-defense/skill-Stone and unrelated module guards remain; no save conversion.',
'Fresh Advanced classic or supported E1/E2 all14 Skills retains original Strongholds2–6 and optional Tech3–6, including its independent-card/World envelope. Native E3 card Worlds and Nexus/Discovery combinations remain separate. Original deck/cache and actual end-Mentat claims stay. Arrakeen funds only local holder-plan support, never native World support, personal cash or reserve fees; normal Banker uses the final actual payer debit. Rescue preserves support, then cleanup and Tech precede Face Dance. Specific copied-defense/skill-Stone and unrelated guards remain.',
'Standalone or paired Ecaz/Moritani Skills retains these original Advanced phase modules, optionally independent cards, with exact ecaz33/36, native five-disc training and original roster exclusions. Normal Warmaster one on a temporary Duke never grants trained three. Winner Suk precedes unused-disc assassination, printed bounty, winner Tech and one Mentat replacement. Ecaz-held support belongs only to the selected Ecaz plan, not an allied Moritani plan; fixed and variable armies stay separate. Mixed E3 families and shared-Duke assignment remain guarded.',
'Fresh independent Treachery previews compose classic or selected Ix/CHOAM native/base rosters, including original Homeworlds, with Advanced Strongholds2–6 and optional Tech3–6. Actual end-Mentat earns custody. Reinforcements adds no supported counters; Harass vacates control without transferring a retained card early. Exact native fee/return, original card effects and winner Tech order remain; other overlays stay guarded.',
'The six effects, public ownership and pre-plan choice are integrated in development games. Enable Stronghold Cards in an Advanced preview lobby. Complete Advanced compliance and every expansion interaction remain under verification.',
@@ -3523,7 +3523,7 @@ export const RULE_TOPICS: RuleTopic[] = [
'Fremen reserve arrivals and Guild cross-planet or return shipments do not trigger Heighliners. A stopped shipment never arrives and cannot trigger it. Bene Gesserit accompanying forces do arrive from off planet and can trigger the token even after a Guild shipment.',
'A battle winner takes one tech token from the defeated faction after casualties and played-card decisions. With several available tokens, the winner chooses. A winner still takes the token if no winning forces survive. Mutual destruction has no winner and transfers no token.',
'Owning all three tokens counts as one additional stronghold at victory checks. An alliance cannot combine separate token holdings to qualify: one member must own the complete set. Multiple sides reaching the victory target can share the win.',
'Token ownership and pending income are public and persist. Fresh classic, E1/E2 native or standalone/paired Ecaz/Moritani all14 Skills retains original Tech3–6 Basic/Advanced; Advanced may add Strongholds2–6, with independent cards within the No-World/Nexus/Discovery envelope. Rescue or board-spice awards precede winner Tech and later Face Dance. Mandatory normal Banker waits for real Mentat, separate from phase-end Tech; fees and Harass are neither free revival nor off-planet shipment. Native CHOAM opening income is not poverty Charity. Two-player Tech, mixed E3 and full combined acceptance remain guarded.',
'Token ownership and pending income are public and persist. Fresh classic, selected E1/E2 or standalone/paired E3 all14 keeps original Tech3–6 Basic/Advanced and optional Advanced Strongholds2–6. Classic/E1/E2 Worlds may also select the independent cards; native E3 card Worlds and Nexus/Discovery retain their own guards. Rescue/board-spice precedes winner Tech and Face Dance. Mandatory normal Banker waits for Mentat, separate from phase-end Tech; fees/H returns are not revival/shipment. Native CHOAM opening income is not poverty Charity. Two-player Tech and full combined acceptance remain unfinished.',
'Without Skills, fresh native E1/E2 families or standalone Ecaz OR Moritani with classic opponents may preserve unused original Tech Tokens through the local factions entry, Basic/Advanced three through six players; Advanced stronghold-factions adds the original six Stronghold Cards. Native payments, typed casualties, selected Ecaz lead rewards and Moritani original assassination remain separate. Split allied holdings never qualify as a complete set. Basic odd Occupy, Richese cache/No-Field rulings, unrelated overlays, public starts and saved-game conversion remain guarded.',
'Classic or selected Ix/CHOAM native/base independent-card previews, including Homeworlds, retain unused Tech3–6 Basic/Advanced and optional Advanced Strongholds2–6. Recruits changes current native rates without repeating Axlotl or advancing payout. Harass deposits and reserve fees are not free Revival or off-planet shipment. Original phase income/native custody/winner rewards remain; other overlays stay separate.',
],
@@ -4064,9 +4064,9 @@ export const RULE_TOPICS: RuleTopic[] = [
).join(' '),
steps: [
'Homeworlds are an optional module from Ecaz & Moritani, available under the official rules with Basic or Advanced play. They are separate locations outside Arrakis; they do not receive ordinary storm movement or count as ordinary strongholds.',
'Fresh private Homeworld prototypes retain all fourteen Skills, Discovery7/8 or both in classic or supported E1/E2 and standalone Ecaz OR Moritani tables. Original Nexus entries additionally support single or paired one-family E1/E2, natives from BOTH selected Ix+CHOAM families with union47, and standalone OR paired Ecaz/Moritani/ecaz33 with classics, with or without Skills. Basic/Advanced2–6, Tech3+ and Advanced Strongholds2+ retain original setup, native placement, phase-end industry and source-local held cards. Advanced Moritani/paired E3 excludes Harkonnen; otherwise legal standalone no-Skills Ecaz/Harkonnen does not lift its separate Duke Cunning exclusion. Winning typed native Suk saves stay at that home; external Emperor returns allocate physical normal/elite counters to original homes as the existing interpretation. Normal revival separately deposits Sardaukar at Salusa. Nested battles receive no Homeworld bonus. Mixed E3/three-family Nexus, pending effects, public starts and played-save conversion remain separate.',
'Fresh classic/E1/E2 World all14 uses actual registered seats and selected ordinary decks in Basic/Advanced; no expansion faction or independent card is required to unlock training. Independent cards may join original Tech3+/Advanced Strongholds2+ in this envelope. Original no-card Nexus/Discovery and native E3 World profiles retain their separate roster/effect limits. Actual starting hands, Ix card-before-training and ordinary native discs remain; Auditor/shared Duke never train. Typed native Suk saves stay at that home; external Emperor returns allocate original Kaitain/Salusa destinations. No nested location gains an ordinary Stronghold benefit or saved history by default.',
'Each faction uses its own card and matching world token. In Basic play the Emperor uses Kaitain alone. Advanced play adds Salusa Secundus for its Sardaukar; movement can transfer both force types between the two Emperor worlds.',
'Fresh classic Basic/Advanced independent36-card/Homeworld setup connects all three bounded effects: Harass returns actual typed undialed forces through native custody, never on an own World; Recruits doubles current native rates with provisional separate-request thresholds; Reinforcements seals exact native reserve fee sources and excludes an on-World fee from physical dial/casualties while preserving original face/support. Other rosters/overlays, whole-mode acceptance and public starts remain guarded.',
'Fresh supported classic/E1/E2 Worlds compose original all14 and the independent36/38/50-card setup, optionally Tech3+/Advanced Strongholds2+. Recruits observes current native rates/typed limits and recorded paid/free use; Banker and phase-end Axlotl remain separate. Reinforcements seals exact normal-first native sources and excludes an own-World fee from physical dial/casualties while preserving original face/support. Suk rescues committed losses, not fees. Harass returns actual visitors through native custody and is forbidden on every own World. Native E3, Nexus/Discovery and other effect-specific guards remain.',
'Native reserves determine high or low population. Salusa counts Sardaukar, while the other cards count the faction’s reserves there. Reaching the high face’s minimum restores high population. Occupation also applies the low penalty.',
'Low population normally grants one additional free force revival and one additional bank spice when collecting CHOAM Charity. Salusa grants neither bonus; CHOAM’s Tupile reverses the usual pattern by granting an advantage while low and a penalty while high.',
'A qualifying charity claim separates its ordinary payer from the extra bank spice. Inflation doubles both portions or prevents the whole collection. Canceling Bene Gesserit charity prevents both portions of that claim.',
@@ -4927,12 +4927,12 @@ export const RULE_TOPICS: RuleTopic[] = [
developmentStage: 'Prototyped',
summary: 'Fourteen physical skills, private assignment choices, five battle disciplines, Planetologist movement/battle effects and Suk Graduate rescues, Mentat/Bureaucrat scoring and Bureaucrat payment redirection, Sandmaster victory spice, Rihani exchanges, optional Smuggler shipping and provisional modifier-inclusive battle collection, Sandmaster route and worm-ride collection, sealed Spice Banker battle spending and optional Diplomat base-defense copying in development tables. Other effects and combined-module acceptance remain unfinished.',
steps: [
'Fresh all14 Leader Skills preserves original classic, supported E1/E2 or standalone Ecaz OR Moritani setup with Homeworlds/Discovery/Tech3+/Advanced Strongholds under each envelope. Explicit --nexus-cards additionally admits single/paired one-family E1/E2, BOTH selected Ix+CHOAM native families/union47 and standalone OR paired Ecaz/Moritani/ecaz33 with classics. Basic/Advanced2–6, original Ix pre-training offer, ordinary native discs and actual hands remain; Auditor/shared Duke never train. Winning normal/trained Suk uses source-labelled native, visitor or nested fixed-loss pools; native saved counters stay at that home and external Emperor returns allocate original homes. Original phase-end industry, held benefits, cleanup/Tech before Face Dance and native assassination remain; unreconciled bands, mixed E3/three-family, public starts and played-save conversion stay separate.',
'Fresh all14 uses one selected-deck capability for registered base/E1/E2 seats, Basic/Advanced, without requiring an expansion faction, independent cards or Nexus merely to use a selected ordinary deck. Native E3 retains its dedicated roster boundaries. Existing World/phase and no-card Nexus/Discovery envelopes keep actual setup and original component custody. Ix chooses its starting card before training; Auditor/shared Duke never train. Native World Suk saves and external Emperor typed destinations stay source-labelled. No new Advanced power, income, module owner or played-save history is created by this configuration cutover.',
'Explicit guild-betrayal --leader-skills retains the original classic native-Guild Nexus profile without Homeworlds, Tech, Strongholds, Discovery, Semuta or other overlays. All14 training remains native. Ordinary skill quotes now admit the composition, restoring actual Mentat private questions before posture and Sandmaster ground collection rather than only enabling Bureaucrat. Native card custody, paid forces, original Betrayal Use/Pass and movement/plan continuation stay unchanged. Other combinations and complete-mode acceptance remain separate.',
'Basic Moritani retains classic opponents including Harkonnen. Standalone or paired Ecaz/Moritani Skills retains original Tech3+ and Advanced Strongholds2+, optionally independent cards, with the original Advanced non-Harkonnen assassination roster. Winner Suk and Rihani finish before an eligible different trained disc dies, returns one skill and pays printed bounty. No casualties repeat; original set-aside and one Mentat replacement remain. Shared-Duke training, mixed families and other module envelopes stay guarded.',
'Fresh Advanced profiles compose native Ixians, Tleilaxu, CHOAM and/or Richese with classic opponents and distinct required family decks. All fourteen skills and native starts remain. Auditor stays unskilled; cyborg casualties, original CHOAM support and Richese capped marker revelation remain physical. Foreign revival creates no new skill. Supplied Advanced p34 excludes Richese auctions from Ixian Technology; own mixed No-Field, captured replacement, Advanced Atreides Suk/KH and unrelated overlays retain their guards.',
'The independent Recruits, Reinforcements and Harass & Withdraw cards compose all14 Skills in fresh classic, selected Ix/CHOAM native/base or standalone/paired Ecaz/Moritani/classic Basic/Advanced games, optionally original Tech3+ and Advanced Strongholds2–6. Original36/38/50, Richese cache, native setup and revival prices stay. Card fee/returns/Suk and Smuggler, Planetologist and Sandmaster share admission. Earned support is not personal spice or reserve fee funding; phase-end Tech and actual-Mentat Banker remain separate. Advanced E3/Harkonnen, mixed E3, World/Nexus/Discovery and other guards remain.',
'Fresh all14 Skills retains original Tech3–6 Basic/Advanced for classic factions, supported E1/E2 or standalone/paired Ecaz/Moritani with their actual selected decks. Cards are optional within the independent-card envelope. Starting hands/cache, skill/Traitor choices and printed/first-Storm owners remain genuine. No token owner, income or victory credit is assigned to simulate earned play. Existing World/Nexus envelopes and mixed E3 or unrelated guards stay separate; played games are not converted.',
'Basic and Advanced selected-deck profiles admit actual Ixians, Tleilaxu, CHOAM/Richese and base seats only from their selected families; unused faction availability never creates a seat or requires one. All14 and native setup remain. Auditor is Advanced and unskilled; foreign-ghola authorization still explicitly requires Advanced, and foreign revival creates no new skill. Cyborg casualties, native funding and capped markers remain physical. Supplied Advanced p34 excludes Richese auctions from Ixian Technology; unrelated captured/KH/copy/role guards retain their own rules.',
'Independent Recruits, Reinforcements and Harass compose all14 in supported classic/E1/E2 and standalone/paired E3 Basic/Advanced, with original Tech3+/Advanced Strongholds2+. Classic/E1/E2 Worlds also retain the cards and phase modules. Original36/38/50, cache, setup and native prices stay. Shared admission feeds card/skill controls; own World fee/dial pools stay disjoint, visitor returns keep typed native homes and Suk cannot rescue fees. Earned support is not personal money or reserve funding. Native E3 card Worlds, Nexus/Discovery, actual mixed E3 and special-role guards remain.',
'Fresh all14 keeps original Tech3–6 Basic/Advanced with actual selected decks, optional independent cards and supported World envelopes. Starting hands/cache, original offers/Traitors and printed/first-Storm owners remain genuine. Native rates use actual stock/population on each accepted request; normal Banker records the accepted Bank invoice, not a net wallet change after separate native income. No token owner, premature spendable grant or victory credit is assigned to simulate earned play. Other Nexus/Discovery, native E3 and effect-specific envelopes stay separate; played games are not converted.',
'Fresh Advanced supported classic/native all14 tables retain six original Stronghold Cards, optional Tech3+, and independent cards within their own envelope. Actual end-Mentat earns the holder; benefit stays local to the selected holder-plan. Arrakeen changes actual payer debit, not physical commitment, Suk entitlement or Banker threshold. Native E1/E2 aftercare and standalone/paired E3 coalition/assassination retain original order. Shared Duke never trains; mixed E3, unsupported copied defenses and active skill/Stone retain their guards.',
'Fresh classic Leader Skills may explicitly add Nexus through local leader-skills --nexus-cards, Basic/Advanced two through six players, retaining selected original Tech at three or more seats and/or Advanced Strongholds. --discoveries additionally composes original Discovery7/8 in this classic profile. Saved hands/offers remain authoritative; the actual end-Spice closing draw follows Maker votes/typed rides, both Advanced piles and settled alliance. Free-return ledgers, bank purchase and Traitor Deck declarations stay distinct from training. Original phase-end industry, held payer support/physical defenses, physical Suk rescue and subsequent mandatory winner Tech rewards retain their own timing. Homeworlds, Banker/Mentat previews, borrowed Smuggler arithmetic and unresolved interactions remain separate.',
'The same fresh entry also adds --nexus-cards --discoveries to paired Ixians+Tleilaxu, paired CHOAM+Richese or standalone Ecaz OR Moritani with classics, original all14/all12/Discovery7/8, Basic/Advanced two through six with optional Tech3+ and Advanced Strongholds. Original offers/hands/native components remain authoritative. E1 Suboid Cunning settles typed Suk rescue before one equal Cyborg Tank substitution, then original cleanup and mandatory winner Tech precede a matching Face Dance; E2 keeps its signed one-invoice pair; Ecaz keeps quiet living/unclaimed Duke then a real owner-labelled mandatory Occupy; Moritani keeps skill-first assassination and one private Mentat replacement. Mixed/E3 pairs, shared Duke, borrowed Smuggler/pair companions, native free returns, captured/foreign training, Basic odd Ecaz, Advanced Harkonnen and other pending rulings stay guarded.',
@@ -4985,7 +4985,7 @@ export const RULE_TOPICS: RuleTopic[] = [
'Clean classic2–6 Basic/Advanced Homeworlds compose through the fresh independent36-card setup. Double current native free rates including low-population bonuses, within the seven-force total. Provisionally recheck population and recorded free use on each separate request: low Fremen may take7 together, but1 crossing high leaves5 further free and cannot buy a seventh without Tleilaxu. Original typed destinations and special-force limits stay. Other overlays/rosters, public activation and whole-mode acceptance remain unfinished.',
'Classic or selected Ix/CHOAM native/base rosters, including Homeworlds, may retain original unused Tech Tokens3–6 and/or Stronghold Cards2–6 Advanced. Setup, first-Storm Tech and actual end-Mentat custody remain original. Recruits changes current native free rates, not the once-per-phase Axlotl trigger/delayed payout. Harass returns are not free Revival.',
'Selected Ix/CHOAM native/base Basic/Advanced Worlds use original38/50 independent-card setup with optional original phase modules. Current native bonuses, typed deposits and accepted paid/free classifications stay. Ix keeps its multiple-Cyborg allowance; Tleilaxu and CHOAM remain unlimited rather than being reduced to seven. Other card/overlay/public-start gates remain.',
'Fresh supported classic, selected Ix/CHOAM or standalone/paired Ecaz/Moritani all14 Skills may retain these cards with original Tech3+ and Advanced Strongholds2+. Current native free allowance still doubles after recorded use; paid Cyborg surcharges and any Tleilaxu recipient remain, and native unlimited allowances are not reduced to seven. Axlotl accrues once and waits for phase end; mandatory normal Banker uses the actual final Bank payer and waits for Mentat. No revival ledger, refund, token owner or spendable premature income is invented.',
'Supported original all14/card rosters retain Tech3+ and Advanced Strongholds2+, including classic/E1/E2 Worlds. Current native free allowance doubles after recorded use; separate World groups re-observe native population. Typed elite caps, unlimited native allowances, paid Cyborg surcharges and any Tleilaxu recipient stay. Axlotl accrues once and waits for phase end; normal Banker uses the accepted final Bank invoice and waits for Mentat, not a net wallet delta after a separate native payout. No ledger, refund, owner or premature spendable income is invented.',
],
related: ['revival', 'homeworlds', 'ecaz-modules', 'expansion-faction-games', 'implementation-checklist'],
checklist: [
@@ -5012,7 +5012,7 @@ export const RULE_TOPICS: RuleTopic[] = [
'Classic and selected Ix/CHOAM Basic/Advanced Worlds retain exact native normal-first sources, sealed when ambiguous; unique sources may derive. Own-World fees cannot also fund dial/casualties; original face/support stays, including explosion thresholds. Original phase modules preserve their own prerequisites and earned custody. Native-only World Traitors, typed Tanks and fee-before-Harass stay provisional composition, not a new card FAQ.',
'One canonical physical-name registry now includes the independent cards for current facts and named battle conditions. Naming Reinforcements in a weapon slot does not make it a weapon category. Native questions use actual combat-location labels. Source-aware legal completion, private full-plan/read-only review and the fill button retain exact native sources.',
'Selected Ix/CHOAM Worlds retain original38/50 setup and native stock, optionally with original Tech3+ and Advanced Strongholds2+. Cyborg substitution and Face Dance use their actual physical pools, never a duplicate fee origin. Native Richese must retain three World reserves AFTER its own projected No-Field reveal before R seals; rejection moves no counter or marker. Original phase rewards and earned held-card support stay; admitted Stone compositions retain their separate guards.',
'Supported all14 Skills profiles, including original phase modules, keep the same physical fee and score. Trained Suk rescues only actual committed casualties, never reserve fee counters. Earned Arrakeen pays eligible support, not the fee or personal spice. A native Richese marker must leave the full fee after materialization; future Harass cannot fund a refused seal. Fixed Ecaz and variable ally ownership, mandatory disposal and original winner rewards stay separate.',
'Supported all14/card World/phase profiles keep the same physical fee and score. An own-World fee cannot fund the same physical dial/casualty; pre-fee native traits/face remain original. Suk rescues actual committed losses, never fee counters, keeping native saves at that home or using original typed external destinations. Earned Arrakeen never subsidizes a World or reserve fee. A Richese marker must leave three after materialization; future Harass cannot fund a refused seal. Native E3 card Worlds and unrelated guards remain.',
],
related: ['battle-cards', 'battle', 'homeworlds', 'card-recruits', 'card-harass-withdraw', 'card-truthtrance', 'implementation-checklist'],
checklist: [
@@ -5041,7 +5041,7 @@ export const RULE_TOPICS: RuleTopic[] = [
'With an own concealed No-Field, this prototype provisionally uses the original materialization-first order. Before sealing, privately forecast its actual ordinary counters at the original marker sector; do not move them early. Both plans seal before native revelation, then any return allocation uses actual counters. Marker0 remains legal with a leader/cards, reserve shortage caps materialization, and withdrawal does not return/reset the token. Opposing successful Traitor cancels Harass, not that native reveal.',
'Classic and selected Ix/CHOAM Basic/Advanced Worlds may choose the independent cards before original setup. Harass works on Arrakis or a foreign World, never an own World. Return actual undialed board/visitor types through native custody: normal/special to the original primary World except Advanced Emperor normal to Kaitain and Sardaukar to Salusa. Original commitment stays across thresholds; native-only World Traitors/Face Dancers, late defense/explosion and disposal stay.',
'Classic or selected Ix/CHOAM native/base rosters, including Homeworlds, compose original Tech3+ and/or Advanced Strongholds2+. An earned held Stronghold affects only its original eligible plan/actual support; +2 R adds no supported counters. Harass deposits are not off-planet shipment/free Revival. Original winner card cleanup/Tech reward and native queues retain their order.',
'Supported all14 Skills with original Tech/Advanced Strongholds keeps the same typed undialed complement and selected-trainer effects. Ix may return Suboids/Cyborgs, then rescue only committed losses. Native E3 keeps fixed/variable owners separate. Earned held support belongs only to its original eligible selected plan; it creates no reserves or fee funding. A capped Richese marker may legally use Harass when Reinforcements is unfunded; unique single-sector returns stay automatic.',
'Supported all14/card World/phase profiles keep actual typed undialed complements and selected-trainer effects. Ix returns Suboids/Cyborgs, then rescues only committed losses before original aftercare/Face Dance. Visitor returns use original native custody; Advanced Emperor normals go to Kaitain and elites to Salusa. Every own World still forbids native Harass. Earned held support is local to its eligible holder-plan, not a World subsidy or fee funding. Capped Richese may use legal Harass when R is unfunded; no token or reserve pool resets.',
],
related: ['battle-cards', 'battle', 'card-recruits', 'homeworlds', 'ecaz-modules', 'implementation-checklist'],
checklist: [