diff --git a/AGENTS.md b/AGENTS.md index e44d3b49..47fbacd6 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -41,7 +41,9 @@ for the in-memory SQLite tests. `tsx` is a pinned development dependency. checkpoints under standing authorization. No user-imposed usage cutoff or routine account-usage check remains. - Keep material rulings explicit and prototype independent work while pending. - Prototype evidence does not open mode or publication gates. + The user-authorized Advanced preview permits unfinished base-faction starts + with a visible warning; see `docs/ADVANCED_PREVIEW.md`. Prototype evidence does + not certify complete modes or open expansion/publication gates. ## Implement and verify diff --git a/README.md b/README.md index f4519f4b..81bc34b0 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Dune — Arrakis Table -An unofficial multiplayer adaptation of Gale Force Nine’s classic 2019 Dune, built with React, TypeScript, Vinext, and Cloudflare Workers/D1. **Development is ongoing; this is not yet a complete rules implementation.** Advanced and unfinished expansion starts remain disabled. Start with [current status](docs/CURRENT_STATUS.md) for implemented systems, remaining requirements and release gates; detailed historical evidence remains in the [implementation log](docs/IMPLEMENTATION_STATUS.md). +An unofficial multiplayer adaptation of Gale Force Nine’s classic 2019 Dune, built with React, TypeScript, Vinext, and Cloudflare Workers/D1. **Development is ongoing; this is not yet a complete rules implementation.** The six classic factions can use a clearly labeled **Advanced preview**; unfinished expansion starts remain disabled. Start with [current status](docs/CURRENT_STATUS.md) for implemented systems, remaining requirements and release gates; detailed historical evidence remains in the [implementation log](docs/IMPLEMENTATION_STATUS.md). ## Run locally @@ -14,6 +14,11 @@ npm run dev -- --host 0.0.0.0 Open `http://localhost:3000`. Create a room, share its eight-character invitation, and add human or AI seats. The host can configure Easy, Medium, Hard and Brutal AI opponents. Current calibration demonstrates a substantially weaker Easy policy; it does not yet demonstrate a consistent ordering among the upper three levels. +For Advanced play, choose **Rules → Advanced preview** before creating a room, +or use the same selector as host in an existing base-game lobby. Everyone must +ready again after changing rules, then the host chooses **Begin Advanced preview**. +This mode is unfinished; see [preview scope and limits](docs/ADVANCED_PREVIEW.md). + Before starting, open **Configure** on an AI seat to change its difficulty, faction or player circle without replacing it. Changes save immediately and clear human readiness. See [lobby AI configuration](docs/LOBBY_AI_CONFIGURATION.md). diff --git a/app/globals.css b/app/globals.css index 157ed743..0a88451b 100644 --- a/app/globals.css +++ b/app/globals.css @@ -473,6 +473,10 @@ input[data-slot='input'] { line-height: 1.8; color: #a8af9c; } +.development-note.advanced-preview-note { + font-size: 0.875rem; + line-height: 1.5; +} .development-note { font-size: 11px; line-height: 1.6; diff --git a/app/page.tsx b/app/page.tsx index ed502013..5a6ac215 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -3,6 +3,7 @@ import Link from 'next/link'; import { useState, useEffect, useCallback, useRef } from 'react'; import { TableTalk } from '@/components/table-talk'; import { GameTable } from '@/components/game-table'; +import { RulesetControls } from '@/components/ruleset-controls'; import { SeatHandoverSetup, SeatHandoverClaim, @@ -68,6 +69,7 @@ export default function Home() { const [busy, setBusy] = useState(false); const [connection, setConnection] = useState(''); const [selected, setSelected] = useState('atreides'); + const [advanced, setAdvanced] = useState(false); const [expansions, setExpansions] = useState([]); const [name, setName] = useState(''); const [code, setCode] = useState(''); @@ -423,7 +425,7 @@ export default function Home() { let attempt: RoomEntryAttempt; try { attempt = createRoomEntry( - { name, faction: selected, expansions, advanced: false }, + { name, faction: selected, expansions, advanced }, join ? code : undefined, ); } catch { @@ -1014,10 +1016,17 @@ export default function Home() { placeholder="Enter your name" maxLength={32} /> -
- Rules - BASIC -
+ { + setAdvanced(value); + if (value) { + setExpansions([]); + if (f.expansion !== 'base') setSelected('atreides'); + } + }} + />

2–6 players · up to 10 turns

Expansions @@ -1028,7 +1037,7 @@ export default function Home() {
+ {g.advanced && g.status !== 'lobby' && } {g.status !== 'lobby' && (