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

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

4.6 KiB

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 GameEvents.

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)
  • Principles: docs/FOUNDATION.md (simulation vs presentation)
  • Layout & phases: docs/ARCHITECTURE.md
  • AI constraints: docs/AI.md
  • Run / Holder grammar: docs/RULES.md