后续改内容或结算顺序时有冻结依据,不必再翻原始稿才能对齐。 Co-authored-by: Cursor <cursoragent@cursor.com>
4.3 KiB
ARCHITECTURE
Current prototype implementation. May be rewritten.
Source: AI-First Technical Architecture Plan · v0.1, Layer 2.
Stack
- Godot .NET — later Steam/desktop presentation
Game.Client— current playtest browser; no rules- C# / .NET 8 — rules and tools
- JSON + JSON Schema — content
- xUnit — tests
- First platform: Windows desktop / Steam prototype
Repository layout
src/Game.Core
src/Game.AI
src/Game.Content
src/Game.Client
tests/Game.Core.Tests
tests/Game.AI.Tests
tests/Game.Content.Tests
content/cards
content/characters
content/enemies
content/encounters
schemas
tools
docs
AGENTS.md
Game.Core
Pure C#; no Godot reference.
v1 types: GameState, PlayerState, Entity, CardDefinition, CardInstance, Zone, GameAction, GameEvent, Effect, Condition, Trigger, ResponseWindow, GameRng.
Do not build a universal framework. Implement only what current rules need.
Core API
GetLegalActions(state)
Execute(state, action)
CloneState(state)
ResolveUntilStable(state)
AI and the player client must call this same pair of legal-action and execute paths.
Action vs event
GameAction: intent —PlayCard,Attack,Activate,Respond,EndTurn,ChooseTargetGameEvent: what happened —Damage,Heal,Draw,Discard,Destroy,EnterField,LeaveField,CountdownChanged,SupplyGenerated
Rules process actions. UI plays events.
Atomic resolution and response
Complex effects split into atomic steps. An atomic step is an engine unit, not a player-response unit. Response windows open only at rule-defined timings.
Do not implement free “anywhere second-speed.” Responses bind to events (on attack, before damage, on target, on enter, about to destroy). Response is not a card type. Show a window only if a legal response exists.
Content model
Card types v1: Creature / Spell / Field. Long-lived entities share one battlefield. Board size 10 is a test parameter.
Standard effects
Damage, Heal, Draw, Discard, Destroy, Summon, MoveCard, ModifyStat, ModifyCountdown, AddKeyword, RemoveKeyword, GenerateEnergy, AddStatus, RemoveStatus.
Ordinary cards compose these. Custom C# handlers only when composition is unreasonable. Do not invent a card scripting language.
Validation, RNG, replay
CLI validator (later): unique IDs, dangling refs, structure, required fields, numeric ranges, tags, effect args. PT and dead-ref reports later.
All randomness: GameRng. GameState stores RNG. Tests pin seed. A battle records initial state, seed, and action sequence for 100% replay.
AI v1 (see docs/AI.md)
Current-turn only. No MCTS, minimax, multi-turn planning, opponent-future prediction, response prediction, or LLM AI.
Shallow beam search + near-optimal randomness among scores ≥ BestScore × Threshold.
Performance depends on clone + Execute speed, not algorithm prestige. Deep-copy until it hurts.
PT v1
Linear value table for damage, heal, draw, energy, attack, health. DelayedValue ≈ BaseValue × DelayDiscount. No forced PT for highly contextual effects.
Godot client (Phase F)
Render(GameState) and Input → GameAction → Core.Execute → GameEvents → Animation. Never “fix” a rules bug in animation code.
Prototype order
| Phase | Focus | Deliverable |
|---|---|---|
| A | Core skeleton | Entities, zones, state, action, event, RNG, clone, tests; no UI |
| B | Basic combat | Draw, hand, energy, creatures, fields, attack, damage, heal, destroy, GY, turns |
| C | Special rules | Cost, effect text, trigger, response, countdown, supply, fatigue, tags |
| D | Headless battle | Full fight in CLI |
| E | AI | Random legal → utility → current-turn beam |
| F | Godot client | Hand, board, HP, energy, targeting, response prompt, basic anim |
| G | Content tools | Schema, validator, PT report, load tests |
| H | Vertical slice | First characters, cards, fields, enemies, one boss |
Current milestone: Phase A. Do not start Godot until Core + tests + a CLI fight can draw, play, attack, end turn, and run a simple AI.
Success
Headless full combat; full replay; automated core tests; ordinary new cards usually need no code; AI legal turns and 2–4 card combos; sim fast enough for live decisions; Godot only presents the same simulation.