后续改内容或结算顺序时有冻结依据,不必再翻原始稿才能对齐。 Co-authored-by: Cursor <cursoragent@cursor.com>
106 lines
3.1 KiB
Markdown
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.
|