Files
chenmoranzhiandCursor 06eb360fbf 把规则、架构与实现路线写成仓库文档。
后续改内容或结算顺序时有冻结依据,不必再翻原始稿才能对齐。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-09 02:04:20 +08:00

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`