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

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

106 lines
3.1 KiB
Markdown

# CONTENT_SCHEMA
Draft formats. Change this file together with JSON Schema and any validator.
Ordinary cards are data + standard effects. `customEffect` is an escape hatch.
## Identity
- `id`: stable string, unique in its catalog
- `name`: display name
- `tags`: string array, `kebab-case`
## Cards (`content/cards/*.json`)
```json
{
"id": "card.example.spark",
"name": "Spark",
"type": "Spell",
"cost": 1,
"tags": ["damage"],
"effects": [
{ "op": "Damage", "amount": 1, "target": "ChosenEnemy" }
]
}
```
`type`: `Creature` | `Spell` | `Field`.
Creatures/fields may add `attack`, `health`, `countdown`, `triggers`, `activate`.
### Activate
```json
"activate": [{ "op": "TransferStatsThenDie" }],
"activateNeedsFriendly": true
```
`activateNeedsEnemy` for targeted enemy activates. Default: once per own turn; usable the turn the creature enters.
### Play targeting flags
`playNeedsFriendly`, `playNeedsEnemy` (e.g. Vile Fire needs both).
### Tags (v1, partial)
Only these are recognized by rules/content checks. Extra kebab-case tags may exist as data and are ignored by the engine.
`damage`, `heal`, `creature`, `field`, `supply`, `countdown`
Do not grow this list unless a rule actually reads the new tag.
### Triggers
`when`: `TurnStart` | `OnDestroyed`. Effects use the same `op` list as play effects.
`effects` on a card are on-play / on-cast. Do not duplicate them as `OnEnter` yet.
## Standard `op` values
`Damage`, `Heal`, `Draw`, `Discard`, `Destroy`, `Summon`, `MoveCard`, `ModifyStat`, `ModifyCountdown`, `AddKeyword`, `RemoveKeyword`, `GenerateEnergy`, `AddStatus`, `RemoveStatus`.
Unknown `op` is a content error unless `customEffect` names a registered C# handler.
## Characters (`content/characters/*.json`)
Each character is **starting deck + skill** (see `docs/DESIGN.md`). `coreActions` / `bridge` are design metadata.
```json
{
"id": "char.example.ash",
"name": "Ash",
"coreActions": ["Damage", "Heal"],
"bridge": "Damage+Heal",
"skill": { "id": "skill.ash.ember", "summary": "..." },
"startingDeck": ["card.example.spark"]
}
```
## Packs (`content/packs/*.json`)
In-run reward pools. `base: true` is always available this run. Other packs unlock when **all** `allOf` conditions are true. Evaluation is live against current run stats and current owned cards (not sticky, not meta).
```json
{
"id": "pack.example.vitality",
"name": "Vitality",
"base": false,
"coreActions": ["Heal"],
"cards": ["card.example.salve"],
"allOf": [{ "kind": "HealReceivedAtLeast", "amount": 2 }]
}
```
`kind`: `HealReceivedAtLeast`, `AttacksAtLeast`, `FriendlyDestroyedAtLeast`, `FatigueAtLeast`, `DeckTagAtLeast` (+ `tag`), `KillTagAtLeast` (+ `tag`).
World tags such as `cult` may appear in `KillTagAtLeast` without being v1 rules tags.
## Enemies / encounters
Same effect language as cards where possible. AI weights live in enemy data (`docs/AI.md`), not in the engine.
## Validation (Phase G)
Unique ids, existing references, required fields, numeric ranges, tag shape, effect arguments. PT report is optional and must not block load of contextual cards.