Connect supplied Advanced Fremen Ecaz two-sietch victory allowance
This commit is contained in:
1 parent
d438d923a3
commit
0315917987
7 files changed
+54
-17
No files matched your search
@@ -96,6 +96,11 @@ cleanup. Both have owned live controls and minimum legal AI; numeric/custody
|
||||
precedence interpretations are explicit. Two direct battle smokes and types pass;
|
||||
live isolated React declarations/selectors submit exact native payloads in Chromium.
|
||||
No broad suite, deployed acceptance or strategic AI work was run.
|
||||
**Advanced Fremen/Ecaz protected sietches cutover.** Supplied physical p32
|
||||
permits cooccupation in Habbanya as well as Tabr. The shared quote now feeds
|
||||
both public progress and actual turn-ten victory. Basic stays Tabr-only;
|
||||
solitary Ecaz and third-party blockers remain. One before/after native ending
|
||||
smoke and three Habbanya contract cases pass; no broad suite was run.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,30 @@
|
||||
# Ecaz victory implementation contract
|
||||
|
||||
The [14 September runtime follow-up](#fremen-final-turn-runtime-follow-up) connects
|
||||
the explicit Fremen/Ecaz Sietch Tabr exception. The original audit and its
|
||||
unimplemented Habbanya inference remain below as source context.
|
||||
Basic retains the [14 September Tabr-only runtime](#fremen-final-turn-runtime-follow-up).
|
||||
Advanced now follows the authorized supplied revision's physical p32 allowance
|
||||
in both protected sietches. The publisher audit below remains historical context.
|
||||
|
||||
## Authorized Advanced two-sietch allowance — 8 October 2026
|
||||
|
||||
`UNOFFICIAL_Revised_Dune_Rulebook_v.2.3_web.pdf`, physical **p32,
|
||||
Fremen I**, permits “Fremen forces (± coexisting Ecaz forces) or no one”
|
||||
in **Sietch Tabr and Habbanya Sietch**. This is an explicit Advanced
|
||||
source cutover, not a newly located publisher symmetry ruling.
|
||||
|
||||
The shared `fremenSpecialVictory` quote now ignores reciprocal allied
|
||||
Ecaz cooccupation in either protected sietch when both factions actually
|
||||
have fighters there. Basic stays Tabr-only. Solitary/nonallied Ecaz and
|
||||
third-faction fighters still block; other Tuek/final-turn/ordinary-winner/
|
||||
prediction/fallback conditions do not change. Public progress and real
|
||||
victory evaluation consume the same quote without another decision.
|
||||
|
||||
One native Collection-to-Mentat smoke reproduces the old Guild fallback,
|
||||
then awards Fremen/Ecaz on the same Advanced board while preserving
|
||||
Basic and solitary-Ecaz exclusions. Three Habbanya contract cases pass.
|
||||
No broad suite or deployed acceptance was run.
|
||||
|
||||
**Superseded for Advanced:** the Habbanya rows below predate the authorized
|
||||
supplied p32 cutover above. Basic still follows the Tabr-only audit.
|
||||
|
||||
Primary-source review, 2026-09-07. This separates the explicit three-stronghold rule from its ordinary control and prediction consequences. No combat-rounding decision is needed for a victory predicate operating on an already-settled board. The unrelated rounding conflict remains as corrected in [Ecaz Occupy rules](ECAZ_OCCUPY_RULES.md).
|
||||
|
||||
@@ -38,7 +60,7 @@ Stronghold Cards are benefits held between end-turn settlements, not additional
|
||||
|
||||
Base p.16 requires Sietch Tabr and Habbanya Sietch to be empty or occupied only by Fremen for its last-turn special victory. The November FAQ p.5 expressly says ordinary allied forces do not count as Fremen for this restriction. E3 p.15 then specifically allows **Ecaz and Fremen co-occupying Sietch Tabr**. [Base p.16](https://www.gf9games.com/dunegame/wp-content/uploads/Dune-Rulebook.pdf#page=16), [November FAQ p.5](https://www.gf9games.com/dune/wp-content/uploads/2020/11/Dune-FAQ-Nov-2020.pdf#page=5), [E3 p.15](https://www.gf9games.com/dune/wp-content/uploads/EcazMoritani-Rulebook-LOWRES.pdf#page=15)
|
||||
|
||||
The supported narrow implementation requires an actual reciprocal Ecaz/Fremen alliance and Fremen presence **in that same territory** before ignoring Ecaz's additional presence. Ecaz alone in Sietch Tabr does not meet the stated co-occupation exception. Presence of any further faction remains disqualifying. A blanket `p.faction === 'ecaz'` exemption would permit non-allied or solitary Ecaz and is not justified by the FAQ.
|
||||
The supported narrow implementation requires an actual reciprocal Ecaz/Fremen alliance and Fremen presence **in that same territory** before ignoring Ecaz's additional presence. Ecaz alone in Sietch Tabr does not meet the stated co-occupation exception. Presence of any further faction remains disqualifying. A blanket `p.faction === 'ecaz'` exemption would permit non-allied or solitary Ecaz and is not justified by the FAQ. Advanced supersedes the Tabr-only scope above.
|
||||
|
||||
| Protected territory occupants | Result and evidence |
|
||||
| ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
|
||||
@@ -371,7 +371,7 @@ dedicated retrieved worked FAQs. [Contract and remaining limits](HOMEWORLD_OCCUP
|
||||
| Moritani Advanced assassination preview | After an eligible battle loss, a different opposing-faction Traitor Card may be revealed even if its leader is already dead (zero bounty). Face-up set-aside and one private replacement occur during Mentat; one use per faction. Normal-call duration, uniform hidden-eligibility UX and exceptional combinations remain explicit. | [Runtime/source contract](MORITANI_ASSASSINATE_LEADERS.md) |
|
||||
| Moritani Extortion at Mentat | The user selected normal Terror placement/relocation first, including any Karama response; only then collect the reserved five bank spice and approach other players in storm order for a possible three-spice payment. Payment removes the token; all declines recover it with rotated hidden supply IDs. The relative placement timing is a user-selected interpretation, not a publisher ruling. | [Publisher sequence and selected timing](MORITANI_EXTORTION_RULES.md#mentat-ordering-selected-interpretation-not-a-publisher-ruling) |
|
||||
| Ecaz Ambassador / Moritani Terror shared entry | In bounded classic plus Ecaz/Moritani Basic/Advanced games and the exact original paired native Nexus envelopes, both originally eligible owners resolve optional reactions in current storm order; committed entry, payment and counters do not replay. Later alliances do not erase the original trigger; physical effect prerequisites are rechecked. This remains an explicit provisional interpretation, not a located publisher priority ruling. An original accompanying counter joining existing BG fighters creates its own qualifying entry only after earlier Intrusion/income finish; exempt advisors, competing live reactions, unsupported children and Atomics retain guards. The Terror entry itself is now deferred behind the arrival's own interaction (Guild income, BG fighter Intrusion or BG advisor choice, Fremen storm protection) in an additive pending record that never replays payment or force transfer; a Terror entry already in flight and every Ambassador combination still reject. | [Primary-source gap and selected policy](MORITANI_ENTRY_TIMING.md#selected-bounded-overlap-order--29-september-2026), [exact paired composition](MORITANI_ENTRY_TIMING.md#paired-native-nexus-composition--7-october-2026), [deferred arrival entry](MORITANI_ENTRY_TIMING.md#deferred-arrival-entry-behind-the-arrivals-own-interactions--7-october-2026), [movement recovery](DEFERRED_MOVEMENT_ARRIVAL.md#bounded-storm-order-continuation--29-september-2026) |
|
||||
| Fremen/Ecaz final-turn victory | Reciprocal allied Ecaz and Fremen with fighters in Sietch Tabr do not block the Fremen special victory. Ecaz alone/non-allied or a third faction still blocks. The Habbanya extension remains unsupported; ordinary winner/prediction and fallback order are preserved. | [Explicit FAQ and runtime](ECAZ_VICTORY_RULES.md#fremen-final-turn-runtime-follow-up) |
|
||||
| Fremen/Ecaz final-turn victory | Basic keeps reciprocal cooccupation at Tabr only. Authorized supplied Advanced physical p32 Fremen I permits both Tabr and Habbanya when Fremen/Ecaz actually coexist. Solitary/nonallied Ecaz and third parties still block; ordinary winner/prediction/fallback order is preserved. | [Current source cutover](ECAZ_VICTORY_RULES.md) |
|
||||
| Truthtrance recorded knowledge | Questions compare an already recorded BG prediction, active submitted storm dial or actually known native Fremen forecast. Missing knowledge is unknown; only the aggregate answer is published. No future promise or unknown deck peek is created. | [Connected predicates and evidence](TRUTHTRANCE_KNOWLEDGE.md) |
|
||||
| Nexus lifecycle | Twelve physical cards, phase draw/replacement and alliance forfeiture; native Cunning, absent-faction Secret Ally and Betrayal have separate effects. No blanket Karama immunity. | [Common source contract](NEXUS_CARD_RULES.md), [lifecycle runtime](NEXUS_CARD_RUNTIME.md) |
|
||||
| Nexus faction effects | Preserve physical custody, original faction identity and durable effect receipts; use each printed family instead of borrowing another faction's rules by analogy. | [Atreides](NEXUS_ATREIDES_RULES.md), [Harkonnen](NEXUS_HARKONNEN_RULES.md), [BG](NEXUS_BENE_GESSERIT_RULES.md), [Emperor](NEXUS_EMPEROR_RULES.md), [Fremen](NEXUS_FREMEN_RULES.md), [Guild](NEXUS_GUILD_RULES.md) |
|
||||
|
||||
@@ -102,7 +102,7 @@ export const FACTION_RULES: Record<
|
||||
'Bring reserves to the Great Flat or one territory within two territories of it for no spice, subject to storm and occupancy restrictions. Ordinary movement has range two, or three when eligible for ornithopters.',
|
||||
'Worms do not devour Fremen. After the Nexus, move some or all forces from the worm territory to a legal destination. The destination’s existing forces survive.',
|
||||
'You choose whether a worm spares your ally and whether to grant your ally three free force revivals. These benefits are optional.',
|
||||
'At the final turn, the special victory requires Sietch Tabr and Habbanya Sietch to be empty or occupied by Fremen, with no Atreides, Harkonnen or Emperor in Tuek’s Sietch. The specific Ecaz alliance exception permits Fremen and Ecaz to share Sietch Tabr; it does not waive the other conditions or extend to Habbanya Sietch. Advanced Richese also prevents this victory while occupying Tuek’s Sietch.',
|
||||
'Basic final-turn victory requires protected sietches empty or occupied by Fremen and no Atreides/Harkonnen/Emperor in Tuek. Reciprocal allied Ecaz cooccupation is permitted at Sietch Tabr only; other conditions remain. Advanced follows the separate supplied two-sietch allowance below.',
|
||||
],
|
||||
advanced: [
|
||||
'Once per game during Spice Blow and Nexus, spend Karama to call Shai-Hulud in sand. Resolve destruction and optional protections immediately; Nexus follows at the end of the blow, with eligible Fremen rides afterward. The called worm consumes no spice-deck card.',
|
||||
@@ -110,6 +110,7 @@ export const FACTION_RULES: Record<
|
||||
'Additional worms after the first in a spice blow can be placed in a sand territory chosen by Fremen.',
|
||||
'Fremen loses half its forces, rounded up, to storm exposure. Reserves may arrive under storm at half loss. Ordinary movement and worm rides may not enter or leave storm.',
|
||||
'Three Fedaykin tokens count as two forces in battle and casualties. Only one may be revived per turn. All Fremen forces fight at full strength without spice support.',
|
||||
'Supplied Advanced p32 permits reciprocal Ecaz/Fremen cooccupation in both Sietch Tabr and Habbanya Sietch for the final-turn special victory. Ecaz without Fremen still blocks. Richese also blocks Tuek in Advanced; prior ordinary victory and Guild fallback ordering remain unchanged.',
|
||||
],
|
||||
},
|
||||
guild: {
|
||||
|
||||
@@ -18,10 +18,10 @@ export type FremenVictoryProgress = {
|
||||
tueksBlockers: string[];
|
||||
};
|
||||
|
||||
/** Public current-board facts for the Fremen final-turn victory condition.
|
||||
* Turn timing, prior stronghold winners and the Guild fallback belong to the
|
||||
* victory quote. The only Ecaz exception established here is co-occupied
|
||||
* Sietch Tabr; the same forces still block Habbanya Ridge Sietch. */
|
||||
/** Public settled-board facts. Basic keeps the publisher's Tabr-only Ecaz
|
||||
* exception; supplied Advanced PDF p32 permits coexisting allies in both
|
||||
* protected sietches. Timing, earlier winners and Guild fallback remain
|
||||
* the victory quote's responsibility. */
|
||||
export function fremenSpecialVictory(
|
||||
g: BoardContext,
|
||||
): FremenVictoryProgress | null {
|
||||
@@ -58,7 +58,7 @@ export function fremenSpecialVictory(
|
||||
if (player.id === fremen.id || fighterCount(player, territory) === 0)
|
||||
return false;
|
||||
return !(
|
||||
territory === 'sietch_tabr' &&
|
||||
(g.advanced || territory === 'sietch_tabr') &&
|
||||
ecazCooccupation &&
|
||||
player.id === ecaz!.id
|
||||
);
|
||||
|
||||
+4
-4
@@ -146,7 +146,7 @@ const phaseDetails = [
|
||||
'A Fremen move using the two-territory advantage has a Karama response. Cancellation leaves the forces in place and limits this move to one territory; city ornithopters and a later extra move keep their normal rules.',
|
||||
'Guild transport can move one exact physical group across the planet or return it to reserves. In classic games its normal half-price rate can be canceled separately from its transport permission. Ordinary movement is checked against range, storm and stronghold occupancy.',
|
||||
'You may pass through an ally’s territory on a legal route that ends elsewhere. Basic ordinary physical reserve shipments may also enter allied territory before movement, provided the visiting group departs during that turn. Storm and stronghold capacity remain binding. The table visibly labels its provisional no-exit policy: excess new visitors still present when the turn ends go to Tanks, without destroying the ally or granting an extra move. Concealed No-Fields, optional arrivals and Advanced entry remain separate.',
|
||||
'Ecaz and its reciprocal ally may share territories permanently and count as one faction toward stronghold capacity. This applies to normal shipment, ground routes and Ambassador arrivals. It does not grant extra movement, bypass storm or mobile-stronghold entry rules, or apply to homeworlds. Their three jointly occupied stronghold victory and shared desert allocation are supported. Allied Ecaz and Fremen together in Sietch Tabr do not block the Fremen final-turn victory; its other conditions still apply. Combined combat and the Habbanya extension remain unfinished.',
|
||||
'Ecaz and its reciprocal ally may share territories and count as one faction toward stronghold capacity, without extra movement or storm/Homeworld exceptions. Their three-joint-stronghold victory and desert allocation are connected. Fremen/Ecaz cooccupation permits the Fremen special win in Sietch Tabr in Basic; supplied Advanced p32 permits both Tabr and Habbanya Sietch. Other victory conditions and exceptional combined interactions remain separate.',
|
||||
'A restored pending physical shipment is checked again before forces or spice are committed. If its saved turn, force allocation, destination, price or authorized contribution no longer matches the table, it is rejected without changing the saved declaration.',
|
||||
'Finish shipment and movement explicitly. Any Bene Gesserit free-shipment decision and its response must finish first.',
|
||||
'In Advanced, finishing your turn sends your own fighters in territories shared with your ally to Tanks, even if your ally acts later or the alliance formed this turn. Polar Sink, Bene Gesserit advisor coexistence in either direction and native Ecaz peaceful coexistence are exempt. The finish warning names affected territories without revealing concealed forces. Loss is mandatory, not a separate confirmation; finishing remains legal if you cannot escape.',
|
||||
@@ -3177,7 +3177,7 @@ export const RULE_TOPICS: RuleTopic[] = [
|
||||
'On turn ten, a normal stronghold victory comes first. Otherwise, check Fremen’s special condition, then award the game to Guild and its ally if present. If Guild is absent, Fremen and its ally win even when the usual Fremen special condition fails.',
|
||||
'When neither Guild nor Fremen is playing and nobody has reached the normal target, compare individual qualifying stronghold counts. Every player tied for the highest count wins. A correct Bene Gesserit prediction can replace this stronghold win.',
|
||||
'With tech tokens enabled, owning all three adds one stronghold. One player must hold all three, even in an alliance. If several sides reach their target at the same check, they share a normal win before any correct prediction replaces it.',
|
||||
'The table’s Stronghold victory progress shows current qualifying territories, a complete Tech Token set, Ecaz joint occupation and Fremen’s final-turn conditions. Allied Ecaz and Fremen may co-occupy Sietch Tabr without blocking that special win; solitary or non-allied Ecaz does not receive this exception. Tech Tokens cannot supply a jointly occupied territory. These public counts do not resolve a private prediction or award victory before the proper checkpoint.',
|
||||
'Stronghold victory progress shows current territories, a complete Tech Token set, Ecaz joint occupation and Fremen final-turn conditions. Basic permits reciprocal Fremen/Ecaz cooccupation at Tabr; supplied Advanced p32 permits both protected sietches. Solitary/nonallied Ecaz still blocks. Public counts do not award victory before the proper checkpoint; Tech Tokens cannot supply joint occupation.',
|
||||
'Other expansion additions to victory remain in development. Advanced preview supports the six classic factions; expansion starts remain disabled.',
|
||||
],
|
||||
example:
|
||||
@@ -3204,10 +3204,10 @@ export const RULE_TOPICS: RuleTopic[] = [
|
||||
'The public victory guide lists the three territories and any blocking factions. It uses the same settled-board facts as automatic victory resolution. No extra confirmation is required; the table chronicle explains a successful special victory.',
|
||||
],
|
||||
checklist: [
|
||||
{ area: 'Implementation', status: 'Partial', detail: 'The source-confirmed Sietch Tabr exception is connected in Basic and Advanced. Habbanya symmetry and broader expansion acceptance remain incomplete.', evidence: ['game/fremen-victory.ts', 'game/victory-quote.ts', 'game/engine.ts'] },
|
||||
{ area: 'Implementation', status: 'Partial', detail: 'Basic Tabr-only and supplied Advanced p32 two-sietch cooccupation allowances share public progress and the real final-turn quote. Broader expansion acceptance remains separate.', evidence: ['game/fremen-victory.ts', 'game/victory-quote.ts', 'game/engine.ts'] },
|
||||
{ area: 'Player controls', status: 'Implemented', detail: 'Read-only public territory conditions and blockers; victory resolves at the existing checkpoint without a new decision.', evidence: ['components/victory-progress.tsx', 'components/game-table.tsx'] },
|
||||
{ area: 'AI', status: 'Partial', detail: 'All four profiles reach the automatic outcome through legal final-turn actions. Strategic defense of this allied exception is not separately calibrated.', evidence: ['tests/fremen-ecaz-victory-engine.test.ts'] },
|
||||
{ area: 'Documentation', status: 'Implemented', detail: 'The explicit FAQ exception is separated from the unsupported Habbanya extension.', evidence: ['docs/ECAZ_VICTORY_RULES.md', 'game/reference.ts'] },
|
||||
{ area: 'Documentation', status: 'Implemented', detail: 'Publisher Basic Tabr exception and authorized Advanced two-sietch cutover are distinguished.', evidence: ['docs/ECAZ_VICTORY_RULES.md', 'game/reference.ts'] },
|
||||
{ area: 'Verification', status: 'Partial', detail: 'Public presence, precedence, all-profile continuation, JSON and authenticated SQLite recovery are covered. Final-turn positions are explicitly staged after genuine setup.', evidence: ['tests/fremen-victory.test.ts', 'tests/fremen-victory-controls.test.tsx', 'tests/fremen-ecaz-victory-engine.test.ts', 'tests/fremen-ecaz-victory-recovery.test.ts'] },
|
||||
],
|
||||
related: ['victory', 'faction-fremen', 'faction-ecaz'],
|
||||
|
||||
@@ -27,7 +27,7 @@ function place(g: BoardContext, id: string, key: string) {
|
||||
player.forces = { ...player.forces, [key]: 1 };
|
||||
}
|
||||
|
||||
void test('allied Ecaz co-occupation is ignored only at Sietch Tabr in Basic and Advanced', () => {
|
||||
void test('allied Ecaz co-occupation at Sietch Tabr permits Fremen victory in Basic and Advanced', () => {
|
||||
for (const advanced of [false, true]) {
|
||||
const g = fixture(advanced);
|
||||
place(g, 'f', 'sietch_tabr:14');
|
||||
@@ -80,7 +80,7 @@ void test('solitary, nonallied and third-party Ecaz presence do not receive the
|
||||
assert.equal(fremenSpecialVictory(third)!.qualifies, false);
|
||||
});
|
||||
|
||||
void test('Ecaz co-occupation at Habbanya remains a blocker', () => {
|
||||
void test('Basic Ecaz co-occupation at Habbanya remains a blocker', () => {
|
||||
const g = fixture();
|
||||
place(g, 'f', 'habbanya_ridge_sietch:17');
|
||||
place(g, 'e', 'habbanya_ridge_sietch:17');
|
||||
@@ -90,6 +90,15 @@ void test('Ecaz co-occupation at Habbanya remains a blocker', () => {
|
||||
assert.equal(result.qualifies, false);
|
||||
});
|
||||
|
||||
void test('supplied Advanced Ecaz cooccupation permits Habbanya while preserving Basic and solitary Ecaz blockers', () => {
|
||||
const g = fixture(true);
|
||||
place(g, 'f', 'habbanya_ridge_sietch:17');
|
||||
place(g, 'e', 'habbanya_ridge_sietch:17');
|
||||
assert.equal(fremenSpecialVictory(g)!.qualifies, true);
|
||||
seat(g, 'f').forces = {};
|
||||
assert.deepEqual(fremenSpecialVictory(g)!.sietches[1].blockers, ['e']);
|
||||
});
|
||||
|
||||
void test('accompanied BG advisors do not block, while mandatory lone-advisor release restores fighter presence', () => {
|
||||
const accompanied = fixture(true);
|
||||
place(accompanied, 'f', 'habbanya_ridge_sietch:17');
|
||||
|
||||
Reference in new issue
Block a user