Admit fresh public Basic Ecaz starts with selected native E1/E2 families while retaining roster, inventory, seat and optional-profile guards. Keep actual coalition battle assertions. Include allied marker-only and mixed Richese presence, zero and capped materialization after both seals, and owner-specific casualties. Extend the explicitly provisional additive mixed-marker interpretation to Basic without new arithmetic or FAQ ruling. Use the current physical force pool for battle-wheel half steps so Ecaz can commit Ixian Suboids; cancellation restores Ecaz-only whole steps. Preserve Basic free support, zero funding/income, native Ix substitution, lead-owned cards and original Collection. Verify related Basic/Advanced rules, types/lint/build, nine actual-control/rendered-table programmes after genuine public Basic setup, explicit controlled board/budget/card staging and four existing profiles with legal lead/plan/native-substitution proposals. Full modes, wider optional configurations, comprehensive assurance and deployed acceptance remain unfinished. No strategic calibration, saved-room operation, reset, restart or deployment.
30 lines
1.8 KiB
TypeScript
30 lines
1.8 KiB
TypeScript
import assert from 'node:assert/strict';
|
|
import test from 'node:test';
|
|
import { applyAction, createGame, joinGame, newPlayer } from '../game/engine';
|
|
import { faction, type FactionId } from '../game/catalog';
|
|
|
|
function lobby(roster: FactionId[]) {
|
|
const expansions = [...new Set(roster.map(id => faction(id).expansion).filter(id => id !== 'base'))];
|
|
let game = createGame('BASICECAZNATIVEENTRY', newPlayer(roster[0], roster[0], roster[0]), false, expansions);
|
|
for (const id of roster.slice(1)) joinGame(game, newPlayer(id, id, id));
|
|
for (const p of game.players) game = applyAction(game, p.id, { type: 'ready' });
|
|
return game;
|
|
}
|
|
for (const native of ['ixians', 'choam', 'richese'] as const)
|
|
void test(`a fresh public Basic Ecaz/${native} lobby starts with its actual native selected family`, () => {
|
|
const source = lobby(['ecaz', native, 'guild']), before = structuredClone(source);
|
|
const game = applyAction(source, source.host, { type: 'start' });
|
|
assert.equal(game.status, 'setup'); assert.equal(game.advanced, false);
|
|
assert.equal(game.ecazOccupyPreview, true);
|
|
assert.deepEqual(game.expansions, source.expansions);
|
|
assert.deepEqual(game.players.map(p => p.faction), source.players.map(p => p.faction));
|
|
assert.equal(game.leaderSkills, undefined); assert.equal(game.ecazTreachery, undefined);
|
|
assert.deepEqual(source, before);
|
|
});
|
|
void test('the fresh six-native Basic lobby preserves all three selected families through public start', () => {
|
|
const source = lobby(['ecaz', 'ixians', 'choam', 'richese', 'moritani', 'tleilaxu']);
|
|
const game = applyAction(source, source.host, { type: 'start' });
|
|
assert.equal(game.status, 'setup'); assert.equal(game.advanced, false);
|
|
assert.equal(game.players.length, 6); assert.deepEqual(new Set(game.expansions), new Set(['ecaz', 'ix', 'choam']));
|
|
});
|