后续改内容或结算顺序时有冻结依据,不必再翻原始稿才能对齐。 Co-authored-by: Cursor <cursoragent@cursor.com>
122 lines
4.6 KiB
Markdown
122 lines
4.6 KiB
Markdown
# Surfaces
|
|
|
|
How the project ships two usable fronts on **one** rules engine.
|
|
|
|
This is product/engineering framing, not a second ruleset.
|
|
|
|
## Verdict
|
|
|
|
Yes. We maintain **two surfaces**:
|
|
|
|
| # | Surface | Who uses it | Job |
|
|
| --- | --- | --- | --- |
|
|
| 1 | **Headless** | Dev, AI, batch sims, CI, balance | Fast, no UI (or terminal-only). Same rules as the player game. |
|
|
| 2 | **Interactive** | Human players (and playtesters) | Click/type legal actions; see `GameState` and play `GameEvent`s. |
|
|
|
|
They are not two games. They are two **adapters** over `Game.Core` (+ in-run progression such as `RunProgress`).
|
|
|
|
```
|
|
┌─────────────────────┐
|
|
│ Game.Core │
|
|
│ rules · RNG · AI │
|
|
│ RunProgress · packs │
|
|
└──────────┬──────────┘
|
|
┌───────────────┼───────────────┐
|
|
▼ ▼
|
|
Headless surface Interactive surface
|
|
tools / tests / batch playtest client → later Godot
|
|
```
|
|
|
|
## 1. Headless surface
|
|
|
|
**Purpose:** AI search, auto fights, full-run loops, regression tests, future balance batches. Anything that must be cheap to run and easy to pin with a seed.
|
|
|
|
**Today:**
|
|
|
|
- `tools/HeadlessBattle` — single fight and `--run` full run (terminal I/O is convenience, not a second rules layer)
|
|
- `tests/Game.Core.Tests` — pinned scenarios
|
|
- In-process AI (`TurnBeamSearch`) calling `GetLegalActions` / `Execute` / `Clone`
|
|
|
|
**Later (same surface family):**
|
|
|
|
- Batch sims / PT reports / seed sweeps
|
|
- Headless full-run without printing every step
|
|
- Replay from `seed + action log`
|
|
|
|
**Must:**
|
|
|
|
- Depend only on Core (and content JSON), never on Godot or browser UI
|
|
- Stay deterministic: same seed + choices → same result
|
|
- Be the path AI and automated tests use in production of balance data
|
|
|
|
**Must not:**
|
|
|
|
- Reimplement card text, pack unlocks, or combat resolution “for speed”
|
|
- Become a simplified AI-only ruleset
|
|
|
|
## 2. Interactive surface
|
|
|
|
**Purpose:** What a human actually plays. Input becomes `GameAction`; screen shows state and events. Presentation only.
|
|
|
|
**Today:**
|
|
|
|
- `Game.Client` — browser playtest (emoji/SVG placeholders)
|
|
- Optional: interactive mode of `HeadlessBattle` (numbered legal actions) as a thin terminal client — still surface 2 in spirit, but not the player-facing target
|
|
|
|
**Later:**
|
|
|
|
- Godot .NET desktop / Steam presentation
|
|
- Art pass replaces placeholders; rules stay in Core
|
|
|
|
**Must:**
|
|
|
|
- Call the same Core APIs as headless (`GetLegalActions`, `Execute`, …)
|
|
- Own layout, input, animation, audio, UX copy
|
|
- Refuse to “fix” rules bugs in the UI
|
|
|
|
**Must not:**
|
|
|
|
- Encode damage formulas, pack conditions, legal-move filters, or win checks locally
|
|
- Drift into a parallel progression model for “the real game”
|
|
|
|
## Shared core (the only rules owner)
|
|
|
|
Both surfaces consume:
|
|
|
|
- Combat: `GameState`, `GameAction`, `GameEvent`, `GameRng`
|
|
- Progression: `RunProgress`, rewards, Holder, simple upgrades, in-run packs
|
|
- AI: evaluation + current-turn search that **reads** Core, does not own it
|
|
|
|
If a feature matters for “how the game works,” it lands in Core (and tests) first. Surfaces only expose or automate it.
|
|
|
|
## How work usually splits
|
|
|
|
| Change type | Land in | Headless | Interactive |
|
|
| --- | --- | --- | --- |
|
|
| New rule / card effect / pack condition | Core + tests | exercise via CLI/tests | render/input only if needed |
|
|
| Faster AI / batch balance | Core + tools | primary | optional “show AI candidates” |
|
|
| UX, targeting UX, animation, art | Client (later Godot) | no | primary |
|
|
| Full-run loop (reward → upgrade → next fight) | Core + headless first | prove it | then wire the same loop in the client |
|
|
|
|
Default order stays **simulation first**: headless (or tests) prove the loop; interactive follows.
|
|
|
|
## Roadmap mapping
|
|
|
|
1. CLI combat / CLI full run → headless surface (also a crude interactive terminal)
|
|
2. Playtest client → interactive surface v1
|
|
3. Art pass / Godot → interactive surface v2 (same Core)
|
|
4. Expansion packs → content + Core; both surfaces pick them up automatically
|
|
|
|
## Non-goals
|
|
|
|
- Two rulebooks (player vs AI)
|
|
- Meta / cross-run unlocks on either surface
|
|
- Making the browser client a permanent architecture requirement (it is a playtest skin; Godot may replace it)
|
|
|
|
## Related docs
|
|
|
|
- Principles: `docs/FOUNDATION.md` (simulation vs presentation)
|
|
- Layout & phases: `docs/ARCHITECTURE.md`
|
|
- AI constraints: `docs/AI.md`
|
|
- Run / Holder grammar: `docs/RULES.md`
|