From a82b6b0685c7c032f6e4bba5d7975ad8d156659c Mon Sep 17 00:00:00 2001 From: hyper Date: Sun, 19 Apr 2026 18:36:10 +0800 Subject: [PATCH] docs: fleshed out agents.md --- AGENTS.md | 35 +++++++++--- src/samples/slay-the-spire-like/AGENTS.md | 68 +++++++++++++++++++++++ 2 files changed, 96 insertions(+), 7 deletions(-) create mode 100644 src/samples/slay-the-spire-like/AGENTS.md diff --git a/AGENTS.md b/AGENTS.md index e51392b..af98ae1 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -36,15 +36,36 @@ Run tests matching a name: `npx vitest run -t "should create"` ``` src/ - core/ # game.ts, game-host.ts, part.ts, part-factory.ts, region.ts - samples/ # tic-tac-toe.ts, boop/, onitama/, regicide/, slay-the-spire-like/ - utils/ # mutable-signal.ts, rng.ts, async-queue.ts, command/ (8 files) - index.ts # barrel export - global.d.ts # *.yarnproject module declaration -tests/ # mirrors src/ with *.test.ts + index.ts # Barrel export (single public API) + core/ + game.ts # Game core logic + game-host.ts # GameHost lifecycle manager + part.ts # Part entity + part-factory.ts # Part factory + region.ts # Region/space management + utils/ + mutable-signal.ts # MutableSignal (extends Preact Signal) + rng.ts # Mulberry32 seeded PRNG + async-queue.ts # Async queue + middleware.ts # Middleware chain + command/ # CLI-style command system (7 files) + types.ts, command-parse.ts, command-registry.ts + command-runner.ts, command-validate.ts, command-apply.ts, schema-parse.ts, index.ts + samples/ + tic-tac-toe.ts # Simple sample game + boop/ # Boop board game + onitama/ # Onitama card game + regicide/ # Regicide card game + slay-the-spire-like/ # Roguelike deckbuilder (see samples/slay-the-spire-like/AGENTS.md) +tests/ # Mirrors src/ with *.test.ts (20 files) + core/ # game-host, game, part, part-factory, region + samples/ # Each sample + slay-the-spire-like submodules + utils/ # mutable-signal, rng, async-queue, middleware, command ``` -`src/utils/command/` is a directory: types.ts, command-parse.ts, command-registry.ts, command-runner.ts, command-validate.ts, command-apply.ts, schema-parse.ts, index.ts. +`src/global.d.ts` — `*.yarnproject` module declaration. + +`testsgames/` and `testsrules/` — empty directories (reserved). ## Samples Build diff --git a/src/samples/slay-the-spire-like/AGENTS.md b/src/samples/slay-the-spire-like/AGENTS.md new file mode 100644 index 0000000..6d6cca2 --- /dev/null +++ b/src/samples/slay-the-spire-like/AGENTS.md @@ -0,0 +1,68 @@ +# AGENTS.md - slay-the-spire-like + +Roguelike deckbuilder combining Slay the Spire combat with Backpack Hero grid inventory. + +## Architecture + +Three-layer design: **system** (content-agnostic) → **data** (CSV content) → **dialogues** (Yarn Spinner). + +### System Layer (`system/`) + +| Module | Files | Responsibility | +|---|---|---| +| `combat/` | types.ts, effects.ts, triggers.ts, prompts.ts | Combat state, effects pipeline, middleware triggers | +| `deck/` | types.ts, factory.ts, index.ts | Deck state management | +| `grid-inventory/` | types.ts, transform.ts, index.ts | Grid backpack, shape collision, adjacency | +| `map/` | types.ts, generator.ts, index.ts | Procedural node generation (point crawl) | +| `progress/` | types.ts, encounter.ts, index.ts | Adventure progress, node traversal | +| `utils/` | parse-shape.ts, shape-collision.ts | Shape parsing and collision detection | +| `types.ts` | — | `EffectData`, `EffectLifecycle`, `EnemyData`, `CardData`, `IntentData`, `EncounterData`, `ItemData` | + +### Data Layer (`data/desert/`) + +All content via CSV (loaded by `inline-schema`): + +| File | Content | +|---|---| +| `card.csv` | Card definitions | +| `effect.csv` | Effect definitions | +| `enemy.csv` | Enemies + intents | +| `intent.csv` | Intent definitions | +| `item.csv` | Equipment items | +| `encounter.csv` | Encounter nodes | + +### Triggers (`data/desert/triggers/`) + +Middleware hooks extending the base trigger system: + +| File | Hooks | +|---|---| +| `effect.ts` | Orchestrator — calls all sub-modules | +| `instant.ts` | `onEffectApplied` — attack, draw, gainEnergy, removeWound, summon, etc. | +| `damage.ts` | `onDamage` — block, spike, expose, aim, roll, charge, molt, tailSting, energyDrain | +| `turn-start.ts` | `onTurnStart` — discard, defendNext, energyNext, drawNext | +| `card-events.ts` | `onEnemyIntent`, `onCardPlayed`, `onCardDiscarded`, `onDamage` — storm, crossbow, burnForEnergy, sandwormKing, vulture | + +### Dialogue Layer (`data/desert/dialogues/`) + +`story.yarn` — branching encounter dialogues (inside `dialogues.yarnproject`). Commands resolve via `tryAnswerPrompt`. + +## Key Mechanics + +- **Energy**: 3/turn, spent on weapon/armor/tool cards +- **Uses**: Consumable cards use `uses` cost type instead of energy; tracked as `depletion` on `GameItemMeta` +- **Grid adjacency**: Items buff adjacent items (e.g. burnForEnergy consumes adjacent item on card play) +- **Effect lifecycles**: `instant`, `temporary`, `lingering`, `permanent`, `posture`, `item`, `itemTemporary`, `itemUntilPlay`, `itemUntilDiscard`, `itemPermanent` +- **Trigger pipeline**: `createMiddlewareChain` with `use(async (ctx, next) => ...)` pattern +- **Cards from items**: `GameCard` instances are generated from `GameItem` inventory items via deck factory + +## Testing + +Tests live in `tests/samples/slay-the-spire-like/`: +- `combat/effects.test.ts` — effect application, upkeep, posture damage +- `combat/triggers.test.ts` — full desert trigger integration tests +- `deck/factory.test.ts` — deck creation +- `grid-inventory.test.ts` — placement, adjacency, collision +- `map/generator.test.ts` — procedural generation +- `utils/shape-utils.test.ts` — shape parsing +- `data/index.test.ts` — data loading validation