Connect source-ordered Advanced Ecaz new-ally Duke grant
This commit is contained in:
1 parent
5e293f567a
commit
59a406830c
9 files changed
+95
-22
No files matched your search
@@ -23,7 +23,7 @@ import { TERRITORIES } from '@/game/board';
|
||||
import { faction } from '@/game/catalog';
|
||||
|
||||
export const AMBASSADOR_COVERAGE =
|
||||
'Development coverage: Ambassador placement, Ecaz’s direct Duke acquisition and consensual alliance, Emperor, Atreides, Harkonnen, CHOAM, Ixian, Richese, Fremen, Guild and Tleilaxu entry effects are supported, plus Bene Gesserit copies. The Tleilaxu effect offers physical force returns or a first-death own-leader revival. Basic Ecaz can optionally lend Duke to a newly accepted ally, with provisional one-battle/turn-end tenure. Ordinary revival accounting, repeat-death/shared-leader cases, Advanced loans and competing arrival reactions remain for refinement; full Ecaz starts remain disabled.';
|
||||
'Development coverage: Ambassador placement, Ecaz’s direct Duke acquisition and consensual alliance, Emperor, Atreides, Harkonnen, CHOAM, Ixian, Richese, Fremen, Guild and Tleilaxu entry effects are supported, plus Bene Gesserit copies. The Tleilaxu effect offers physical force returns or a first-death own-leader revival. Basic offers an optional new-ally Duke loan; Advanced automatically grants the available Duke after accepted alliance consent. One-battle loan tenure is provisional; an unused living loan is set aside at turn end. Ordinary revival accounting, repeat-death/shared-leader cases and competing arrivals remain for refinement; full Ecaz starts remain disabled.';
|
||||
function tokenLocation(token: AmbassadorToken) {
|
||||
if (token.zone === 'placed')
|
||||
return `Placed in ${TERRITORIES.find((t) => t.id === token.location)?.name ?? 'a stronghold'}`;
|
||||
|
||||
@@ -72,6 +72,13 @@ export function EcazEntry({
|
||||
{game.players.find((p) => p.id === entry.entrant)?.name} entered this
|
||||
stronghold. {guide.gameplay}
|
||||
</p>
|
||||
{game.advanced && entry.effect === 'ecaz' && (
|
||||
<p className="fine">
|
||||
Advanced source override: supplied rulebook, physical page 30, adds an
|
||||
available Duke after accepted alliance consent automatically. The
|
||||
publisher token guide’s optional loan wording above remains Basic guidance.
|
||||
</p>
|
||||
)}
|
||||
{token && <AmbassadorInspector token={token} />}
|
||||
{entry.stage === 'offer' ? (
|
||||
<>
|
||||
@@ -141,8 +148,10 @@ export function EcazEntry({
|
||||
<p className="m-0 text-sm leading-6">
|
||||
Both factions must be unallied. The entrant chooses whether to
|
||||
accept. The triggered Ambassador returns to supply even if the
|
||||
offer is refused. In Basic, an accepted alliance can be followed
|
||||
by an optional Duke loan when the disc is available.
|
||||
offer is refused.{' '}
|
||||
{game.advanced
|
||||
? 'In Advanced, accepting also adds an available Duke to the entrant’s pool automatically. The first version uses one-battle tenure and sets an unused living Duke aside at turn end.'
|
||||
: 'In Basic, an accepted alliance can be followed by an optional Duke loan when the disc is available.'}
|
||||
</p>
|
||||
</>
|
||||
) : (
|
||||
@@ -195,8 +204,11 @@ export function EcazEntry({
|
||||
<p className="m-0 text-sm leading-6">
|
||||
{game.players.find((p) => p.id === entry.owner)?.name} offers you an
|
||||
alliance. Accepting activates both factions’ alliance abilities
|
||||
immediately. In Basic, Ecaz can then optionally lend an available
|
||||
Duke Vidal. Your remaining actions resume after those choices.
|
||||
immediately.{' '}
|
||||
{game.advanced
|
||||
? 'An available Duke Vidal is added to your pool automatically, without a second acknowledgement. One-battle tenure is provisional; an unused living Duke is set aside at turn end.'
|
||||
: 'In Basic, Ecaz can then optionally lend an available Duke Vidal.'}{' '}
|
||||
Your remaining actions then resume.
|
||||
</p>
|
||||
<Button
|
||||
className={buttonClass}
|
||||
|
||||
@@ -20,6 +20,11 @@ open mode gates.
|
||||
requests usable first versions for every faction before refinement. Administration
|
||||
is deferred. Broad suites and capture-resumption campaigns are deferred; rule
|
||||
delivery uses brief changed-path smoke only, with batched compiler feedback.
|
||||
**Active pass — Advanced first versions.** Basic standalone core-function
|
||||
inventory is closed at prototype level, with its stated provisional policies.
|
||||
This does not certify Basic timing variants, combinations or public expansion
|
||||
starts. Those remain after the Advanced function pass.
|
||||
|
||||
|
||||
**Richese cache cancellation connected.** The printed Karama cancellation
|
||||
now reaches the restore-one-ordinary-lot policy selected on 7 October. First/last
|
||||
@@ -77,6 +82,12 @@ paths; Advanced-only powers and deferred combinations were kept separate.
|
||||
Compact faction guides now describe connected Basic Richese/Ecaz prototypes
|
||||
and bounded Moritani effects rather than stale blanket absence. This is an
|
||||
inventory result, not comprehensive rules or complete-mode acceptance.
|
||||
**Advanced Ecaz new-ally Duke grant.** Supplied PDF physical p30 adds an available
|
||||
shared Duke automatically after Ambassador alliance consent. The accepting action
|
||||
now grants the original disc and resumes the entrant without another loan choice.
|
||||
Basic remains optional. One-battle tenure stays provisional; unavailable/captured
|
||||
scope remains guarded. One actual grant-and-battle smoke and three changed
|
||||
contract cases pass; types pass. No broad suite or deployed acceptance was run.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ The [base Harkonnen capture rules, p. 17](https://www.gf9games.com/dunegame/wp-c
|
||||
| Moritani acquisition from captured or ghola custody | Ecaz’s Ambassador explicitly excludes both; Moritani’s acquisition excludes only Tanks and says to take Duke from any controller. Do not silently copy the Ecaz exclusions as a confirmed Moritani rule. The interaction with concealed capture and the apparent ghola restriction needs an explicit supported policy. |
|
||||
| Duke used in a lost battle against Harkonnen | One-battle tenure and postbattle capture both apply. No retrieved Duke-specific text orders release versus selection into the capture pool. Removing him first changes the random pool; keeping him first can change custody. Gate this combination until resolved rather than choosing by handler order. |
|
||||
| Returning a captured Duke | Native identity is Ecaz, but temporary prior custody may be Moritani or a loaned ally. Base capture return plus Duke’s special acquisition restrictions do not explicitly settle active-control versus set-aside destination in every combination. Preserve prior custody rather than discarding that information. |
|
||||
| Loan to the new Ecaz ally | The printed loan lasts this turn. The 8 October Basic-first prototype now offers the loan after an accepted Ambassador alliance, with the same physical disc. One-battle tenure and unused living turn-end set-aside are explicitly provisional implementation policies. Advanced, capture and alliance-break interactions remain for refinement; no publisher clarification is claimed. |
|
||||
| Loan to the new Ecaz ally | Basic has an optional same-disc first version after accepted Ambassador alliance consent. The authorized supplied Advanced PDF, physical p30 Ecaz A, instead adds an available Duke automatically after consent and sets an unused disc aside at turn end; that path is now connected without another acknowledgement. One-battle release is still provisional. Capture and alliance-break interactions remain for refinement. |
|
||||
| Ecaz co-occupied battles | Ecaz’s Occupy rules distinguish participating forces from the faction chosen to fight. Duke eligibility excludes battles involving Ecaz, but no direct combined example decides every Ecaz-ally designation case. Ordinary faction-pair battle lists alone do not certify the full Occupy interaction. |
|
||||
| Revival alternatives | Ecaz’s Tleilaxu Ambassador effect and sharing an Ambassador benefit may interact with the absolute Ecaz-only restriction. No retrieved specific exception permits another faction to revive Duke. Keep that restriction unless a primary clarification establishes otherwise. |
|
||||
|
||||
|
||||
@@ -15,9 +15,32 @@ Private decision ownership and a minimal legal bot choice are connected.
|
||||
The first version uses one-battle tenure and sets an unused living loan aside
|
||||
at turn end. These are labelled implementation policies under the Basic-first
|
||||
instruction, not a publisher clarification of return destination or mid-loan
|
||||
alliance changes. Advanced loans and exceptional custody remain for later work.
|
||||
alliance changes. Exceptional custody and wider combinations remain for refinement.
|
||||
A direct Basic arrival → consent → legal bot loan → resumed entrant smoke passes.
|
||||
|
||||
## Advanced accepted-alliance Duke grant — 8 October 2026
|
||||
|
||||
The authorized supplied `UNOFFICIAL_Revised_Dune_Rulebook_v.2.3_web.pdf`,
|
||||
physical **page 30, Ecaz A**, says “Then, add Duke Vidal to the triggering
|
||||
faction’s leader pool” after alliance consent, and sets an unused disc
|
||||
aside at turn end. Advanced therefore grants an available canonical Duke
|
||||
automatically in the accepting action, with **no separate Ecaz loan choice
|
||||
or acknowledgement**. Basic keeps its existing optional prototype choice.
|
||||
|
||||
The same disc changes controller/source, preserving identity and death
|
||||
history without appending a native leader or Traitor. Existing dead,
|
||||
captured/ghola and Advanced-Harkonnen scope guards remain; unavailable
|
||||
Duke does not veto alliance consent. One-battle release remains the
|
||||
explicit provisional tenure policy, not an additional supplied-text ruling.
|
||||
The entrant’s original arrival suffix resumes once after consent/grant.
|
||||
|
||||
One direct Advanced smoke reproduces the missing grant, then uses Easy's
|
||||
real consent, the automatic same-disc grant, a real Duke Battle Plan and
|
||||
surviving release through native aftermath. Three changed alliance
|
||||
contract cases pass, including Basic decline and dead/shared custody.
|
||||
Actual SSR consent controls were observed in Chromium with automatic
|
||||
grant wording. Types pass; no broad suite or deployed acceptance was run.
|
||||
|
||||
## Rules and authoritative execution
|
||||
|
||||
`game/ecaz-duke-acquisition.ts` quotes a detached next `DukeState` using the existing custody helper. It requires a current seated Ecaz owner and the existing canonical shared disc. It preserves identity, death history and `usedAt`; it never appends a leader to a native roster, adds a Traitor card, manufactures a replacement disc, samples randomness or grants new battle-use permissions. Starting-force initialization remains the normal disc-creation boundary.
|
||||
|
||||
@@ -23,6 +23,18 @@ They supersede earlier software-absence claims only within their named scope.
|
||||
No publication or faction/mode gate is opened. The exact 7 October user
|
||||
rulings below remain distinct from these prototype choices.
|
||||
|
||||
## Advanced prototype pass — 8 October 2026
|
||||
|
||||
The Basic standalone core-function inventory is closed at first-version
|
||||
level, not complete-mode acceptance; Advanced function delivery now precedes
|
||||
timing/combination refinement. Ecaz's supplied physical PDF **p30, A**
|
||||
requires an available Duke grant after accepted Ambassador alliance consent.
|
||||
The accepting action now performs that same-disc transfer automatically,
|
||||
without a new loan acknowledgement. Basic keeps its optional prototype.
|
||||
Turn-end set-aside is supplied text; one-battle loan release remains the
|
||||
explicit provisional implementation policy. Existing exceptional custody and
|
||||
Advanced Harkonnen guards remain. [Current Duke grant contract](ECAZ_DUKE_ACQUISITION.md).
|
||||
|
||||
## User rulings — 7 October 2026
|
||||
|
||||
Five previously pending questions were answered directly by the user. These are
|
||||
|
||||
+12
-5
@@ -16449,7 +16449,8 @@ function ecazAllianceQuote(g: Game, owner: string, entrant: string) {
|
||||
}
|
||||
}
|
||||
function ecazAmbassadorLoanBlock(g: Game, owner: Player, entrant: Player) {
|
||||
if (g.advanced) return 'This first-version Duke loan is available in Basic.';
|
||||
if (g.advanced && byFaction(g, 'harkonnen'))
|
||||
return 'Advanced Duke loans with Harkonnen capture remain guarded.';
|
||||
if (owner.ally !== entrant.id || entrant.ally !== owner.id)
|
||||
return 'The new Ecaz alliance is no longer current.';
|
||||
const duke = g.dukeVidal;
|
||||
@@ -16555,10 +16556,16 @@ function decideAmbassador(g: Game, p: Player, action: Action) {
|
||||
{ faction: 'ecaz', name: 'Ambassador alliance' },
|
||||
);
|
||||
if (!ecazAmbassadorLoanBlock(g, owner, entrant)) {
|
||||
entry.stage = 'loan';
|
||||
entry.beneficiary = owner.id;
|
||||
g.decision = { kind: 'ecazAmbassador', player: owner.id };
|
||||
return;
|
||||
if (g.advanced) {
|
||||
g.dukeVidal = acquireDuke(g.dukeVidal!, entrant.id, g.turn, 'ally');
|
||||
log(g, `${entrant.name} received the available Duke Vidal as part of accepting the Ecaz Ambassador alliance. No separate loan acknowledgement is required. The first version uses one-battle tenure; an unused living Duke is set aside at turn end.`,
|
||||
{ faction: 'ecaz', name: 'Ambassador Duke grant' });
|
||||
} else {
|
||||
entry.stage = 'loan';
|
||||
entry.beneficiary = owner.id;
|
||||
g.decision = { kind: 'ecazAmbassador', player: owner.id };
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else
|
||||
log(
|
||||
|
||||
+6
-6
@@ -1319,9 +1319,9 @@ export const RULE_TOPICS: RuleTopic[] = [
|
||||
'The current closing order is CHOAM market, deferred technology income, then Ecaz placement. Income received at that point can fund placement. This combined order is an implementation choice, not a priority established by a combined official FAQ.',
|
||||
'The first placement costs one spice, the second two, and so on that turn. A declaration opens a Karama response before spice is paid or the token moves. Canceling stops the remaining placement opportunity for that turn; previous placements and payments remain.',
|
||||
'Finish Ambassador placement advances the phase. On a later turn the price begins at one again and the earlier placement block expires. Pending declarations survive reload without charging twice.',
|
||||
'Destroyed tokens return to supply; triggered regular tokens are set aside, Bene Gesserit is permanently removed, and replenishment waits for all five random tokens. Storm crossings and resolved explosions use destruction rather than trigger accounting. The reusable Ecaz token returns to supply after Duke acquisition or an alliance proposal. Basic now also offers a provisional new-ally Duke loan after consent.',
|
||||
'When an eligible entrant reaches the reusable Ecaz token, Ecaz may acquire the available shared Duke. The token returns to supply and its five companions are unchanged. Unused Ecaz control persists until battle use or Moritani acquisition. Basic also connects the separate optional new-ally loan after an accepted Ambassador alliance; standing ally assignment and exceptional capture remain unfinished.',
|
||||
'Unallied Ecaz can instead propose an alliance to an unallied entrant. The entrant accepts or refuses; the token returns to supply either way. Acceptance activates alliance abilities immediately. In Basic, Ecaz may then lend an available Duke to this newly allied faction or continue without a loan. The first-version loan allows one battle and sets an unused living Duke aside at turn end; those return/tenure details are provisional, not a resolved publisher ruling. An unavailable Duke never prevents alliance consent.',
|
||||
'Destroyed tokens return to supply; triggered regular tokens are set aside, Bene Gesserit is permanently removed, and replenishment waits for all five random tokens. Storm/explosion destruction remains separate. The reusable Ecaz token returns to supply after acquisition or alliance proposal. Basic has an optional new-ally Duke loan; the supplied Advanced p30 automatically grants an available Duke after accepted consent.',
|
||||
'When an eligible entrant reaches the reusable Ecaz token, Ecaz may acquire the available shared Duke. The token returns to supply and its companions are unchanged. Unused Ecaz control persists until battle use or Moritani acquisition. Basic optional and Advanced automatic new-ally grants are connected; standing ally assignment and exceptional capture remain unfinished.',
|
||||
'Unallied Ecaz may propose an alliance to an unallied entrant. Acceptance activates alliance abilities immediately. Basic then offers an optional Duke loan; Advanced automatically adds an available Duke under supplied PDF p30, without another acknowledgement. The first version releases a surviving loan after one battle, provisionally; an unused living loan is set aside at turn end. Unavailable Duke never prevents consent.',
|
||||
'When another eligible faction enters a marked stronghold, Ecaz may trigger its Ambassador for itself or its current ally, or leave the token in place. Ecaz itself, its ally, advisors and the faction matching the physical Ambassador do not trigger it. Entries with competing arrival reactions remain blocked until their ordering is implemented; a rejected entry does not spend or move its pieces.',
|
||||
'Emperor grants five bank spice. Atreides records the entrant’s current Treachery hand privately for the beneficiary; Harkonnen records one randomly selected held Traitor identity, or Face Dancer identity for a Tleilaxu entrant. These snapshots remain in the recipient’s private inspection history, identify when they were taken, and do not become a live view of later changes. Opening, enlarging or closing them needs no game acknowledgement.',
|
||||
'CHOAM lets the beneficiary choose any available hand cards, including none, for three spice each. Ixians require one available card to discard before drawing its replacement. Card controls respect projected reservations. After committing an Ixian exchange, a voluntary interruption must leave a card available for its required discard; a queued Truthtrance counts as already committed. A Bene Gesserit trigger permanently removes its token, then the beneficiary chooses an available effect outside the original supply for this group; unsupported copies remain visibly blocked.',
|
||||
@@ -1357,7 +1357,7 @@ export const RULE_TOPICS: RuleTopic[] = [
|
||||
area: 'Documentation',
|
||||
status: 'Partial',
|
||||
detail:
|
||||
'Placement, entry choices, private inspections, token inventory and all eleven effect guides are available. The Basic new-ally Duke loan and its provisional tenure policy are distinguished from Advanced and exceptional-custody work. Complete timing and interaction refinement remains open.',
|
||||
'Placement, entry choices, private inspections and all eleven guides are available. Basic optional new-ally loan and source-ordered Advanced automatic Duke grant are distinguished from exceptional custody and provisional one-battle tenure. Complete timing/interaction refinement remains open.',
|
||||
},
|
||||
{
|
||||
area: 'Verification',
|
||||
@@ -2841,9 +2841,9 @@ export const RULE_TOPICS: RuleTopic[] = [
|
||||
'Duke Vidal is separate from both factions’ five ordinary leaders. His Ecaz identity does not mean Ecaz currently controls him. Inspect the shared disc to see its current controller, whether it is set aside, or whether it is in the Tanks.',
|
||||
'At the end of Shipping and Movement, Moritani gains Vidal if it faces battles in at least two strongholds, excluding battles involving Ecaz, and Vidal is not in the Tanks. The printed rule takes him from the current controller. Moritani has him for one battle; it may acquire him again on a later turn by meeting the condition again. At turn end, set him aside unless he is in the Tanks or captured.',
|
||||
'Karama can prevent Moritani from acquiring Vidal. That cancellation does not remove him once Moritani already controls him.',
|
||||
'Ecaz gains Vidal through its Ecaz Ambassador if he is neither in the Tanks, captured nor a ghola. Ecaz keeps him until battle use or Moritani takes him. The Ambassador can instead form a consensual alliance when both factions are unallied; Ecaz may then lend Vidal to that new ally for the turn.',
|
||||
'Ecaz acquires Vidal through its Ambassador outside Tanks/captured/ghola custody. The alternative forms a consensual alliance while both factions are unallied. Basic can then lend Duke optionally; the supplied Advanced physical p30 adds an available Duke to the new ally automatically and sets an unused disc aside at turn end.',
|
||||
'Only Ecaz may revive Vidal, including with Ghola Treachery. Ecaz may revive him for five spice regardless of how many of its leaders are in the Tanks. Five spice is his special revival cost; his printed battle strength is six. Ecaz may begin ordinary leader revival when five leaders are in the Tanks, counting Vidal, even if it still holds another leader.',
|
||||
'Current development support includes Moritani acquisition, Ecaz Ambassador self-acquisition, consensual alliances, a Basic optional new-ally loan, one-battle use, and Ecaz-only revival to living set-aside custody. The new loan uses provisional one-battle and unused-living turn-end set-aside policies. Native ordinary-disc skills coexist with Duke without assigning him a skill. Advanced loans, shared skill assignment and captured-leader interactions remain for later work; this does not certify complete modes.',
|
||||
'Development support includes Moritani acquisition, Ecaz self-acquisition, consensual alliances, Basic optional loan, Advanced automatic new-ally grant, one-battle use and Ecaz-only revival to living set-aside custody. Loan one-battle release is provisional. Native ordinary-disc skills coexist without assigning Duke a skill. Shared skills, capture and wider interactions remain for refinement; complete modes are not certified.',
|
||||
],
|
||||
related: [
|
||||
'faction-ecaz',
|
||||
|
||||
@@ -122,7 +122,7 @@ function conserved(g: Game) {
|
||||
}
|
||||
|
||||
for (const advanced of [false, true])
|
||||
void test(`${advanced ? 'Advanced' : 'Basic'} actual shipment allows bilateral Ecaz alliance and resumes the paid entrant without changing Duke`, () => {
|
||||
void test(`${advanced ? 'Advanced grants the available Duke' : 'Basic can decline the loan'} while bilateral Ecaz alliance resumes the paid entrant`, () => {
|
||||
const initial = fixture(advanced);
|
||||
const token = initial.ecazAmbassadors!.tokens.find(
|
||||
(t) => t.effect === 'ecaz',
|
||||
@@ -157,7 +157,11 @@ for (const advanced of [false, true])
|
||||
assert.equal(seat(done, 'in').ally, 'ec');
|
||||
assert.equal(seat(done, 'ec').allySinceTurn, 2);
|
||||
assert.equal(seat(done, 'in').allySinceTurn, 2);
|
||||
assert.deepEqual(done.dukeVidal, duke);
|
||||
if (advanced) {
|
||||
assert.equal(done.dukeVidal!.controller, 'in');
|
||||
assert.equal(done.dukeVidal!.source, 'ally');
|
||||
assert.deepEqual(done.dukeVidal!.leader, duke!.leader);
|
||||
} else assert.deepEqual(done.dukeVidal, duke);
|
||||
assert.equal(done.pendingAmbassador, null);
|
||||
assert.equal(done.decision, null);
|
||||
assert.equal(done.active, 'in');
|
||||
@@ -256,7 +260,7 @@ void test('acceptance clears obsolete offers involving the new pair and leaves u
|
||||
);
|
||||
});
|
||||
|
||||
void test('a dead or previously controlled Duke cannot gate the no-loan alliance or be moved by it', () => {
|
||||
void test('Advanced new-ally Duke grant transfers available shared custody while a dead Duke never blocks the alliance', () => {
|
||||
for (const dead of [false, true]) {
|
||||
const g = fixture(true);
|
||||
g.dukeVidal = acquireDuke(g.dukeVidal!, 'a', 1, 'moritani');
|
||||
@@ -271,7 +275,11 @@ void test('a dead or previously controlled Duke cannot gate the no-loan alliance
|
||||
null,
|
||||
);
|
||||
const done = answer(propose(entered), true);
|
||||
assert.deepEqual(done.dukeVidal, duke);
|
||||
if (dead) assert.deepEqual(done.dukeVidal, duke);
|
||||
else {
|
||||
assert.equal(done.dukeVidal!.controller, 'in');
|
||||
assert.deepEqual(done.dukeVidal!.leader, duke!.leader);
|
||||
}
|
||||
}
|
||||
const g = fixture(true);
|
||||
g.players[2] = newPlayer('a', 'Harkonnen', 'harkonnen');
|
||||
|
||||
Reference in new issue
Block a user