hayao 0.4.1 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/design/00-process/README.md +49 -0
- package/design/00-process/composition.md +148 -0
- package/design/00-process/core-loop.md +146 -0
- package/design/00-process/intent-to-brief.md +128 -0
- package/design/00-process/pillars.md +139 -0
- package/design/00-process/refine-and-handoff.md +156 -0
- package/design/00-process/the-twist.md +108 -0
- package/design/10-anchors/README.md +99 -0
- package/design/10-anchors/age-of-empires.md +103 -0
- package/design/10-anchors/baba-is-you.md +127 -0
- package/design/10-anchors/balatro.md +132 -0
- package/design/10-anchors/celeste.md +136 -0
- package/design/10-anchors/civilization.md +101 -0
- package/design/10-anchors/dead-cells.md +125 -0
- package/design/10-anchors/factorio.md +100 -0
- package/design/10-anchors/hades.md +127 -0
- package/design/10-anchors/into-the-breach.md +125 -0
- package/design/10-anchors/it-takes-two.md +104 -0
- package/design/10-anchors/loop-hero.md +131 -0
- package/design/10-anchors/nuclear-throne.md +130 -0
- package/design/10-anchors/outer-wilds.md +107 -0
- package/design/10-anchors/overcooked.md +102 -0
- package/design/10-anchors/peggle.md +133 -0
- package/design/10-anchors/reigns.md +99 -0
- package/design/10-anchors/return-of-the-obra-dinn.md +108 -0
- package/design/10-anchors/rimworld.md +101 -0
- package/design/10-anchors/shadow-of-mordor.md +106 -0
- package/design/10-anchors/slay-the-spire.md +127 -0
- package/design/10-anchors/starcraft.md +98 -0
- package/design/10-anchors/stardew-valley.md +103 -0
- package/design/10-anchors/tetris.md +122 -0
- package/design/10-anchors/vampire-survivors.md +122 -0
- package/design/20-genres/README.md +62 -0
- package/design/20-genres/action-adventure.md +126 -0
- package/design/20-genres/auto-battler.md +121 -0
- package/design/20-genres/bullet-hell.md +123 -0
- package/design/20-genres/city-builder.md +124 -0
- package/design/20-genres/coop-chaos.md +124 -0
- package/design/20-genres/deckbuilder.md +122 -0
- package/design/20-genres/exploration.md +131 -0
- package/design/20-genres/farming-sim.md +122 -0
- package/design/20-genres/grid-puzzle.md +126 -0
- package/design/20-genres/horde-survival.md +128 -0
- package/design/20-genres/incremental.md +120 -0
- package/design/20-genres/match3.md +120 -0
- package/design/20-genres/metroidvania.md +132 -0
- package/design/20-genres/narrative-decisions.md +122 -0
- package/design/20-genres/physics-arcade.md +124 -0
- package/design/20-genres/precision-platformer.md +127 -0
- package/design/20-genres/racing.md +126 -0
- package/design/20-genres/rhythm.md +125 -0
- package/design/20-genres/roguelike.md +122 -0
- package/design/20-genres/rts.md +169 -0
- package/design/20-genres/stealth.md +125 -0
- package/design/20-genres/survival-horror.md +124 -0
- package/design/20-genres/tactics.md +123 -0
- package/design/20-genres/tower-defense.md +120 -0
- package/design/30-systems/README.md +69 -0
- package/design/30-systems/accessibility.md +110 -0
- package/design/30-systems/boss-design.md +126 -0
- package/design/30-systems/build-diversity.md +120 -0
- package/design/30-systems/collectibles.md +108 -0
- package/design/30-systems/combat-model.md +113 -0
- package/design/30-systems/coop-and-competition.md +118 -0
- package/design/30-systems/counter-systems.md +115 -0
- package/design/30-systems/crafting.md +115 -0
- package/design/30-systems/difficulty-and-dda.md +114 -0
- package/design/30-systems/economy.md +117 -0
- package/design/30-systems/emergent-systems.md +114 -0
- package/design/30-systems/encounter-design.md +107 -0
- package/design/30-systems/enemy-ai.md +121 -0
- package/design/30-systems/enemy-archetypes.md +117 -0
- package/design/30-systems/faction-asymmetry.md +144 -0
- package/design/30-systems/grace.md +124 -0
- package/design/30-systems/mastery-curve.md +116 -0
- package/design/30-systems/meta-progression.md +114 -0
- package/design/30-systems/onboarding.md +115 -0
- package/design/30-systems/procgen-design.md +118 -0
- package/design/30-systems/progression.md +120 -0
- package/design/30-systems/resource-loops.md +112 -0
- package/design/30-systems/reward-schedules.md +124 -0
- package/design/30-systems/save-and-checkpoint.md +113 -0
- package/design/30-systems/session-structure.md +113 -0
- package/design/30-systems/skill-trees.md +111 -0
- package/design/30-systems/status-effects.md +111 -0
- package/design/30-systems/tech-tree.md +112 -0
- package/design/30-systems/telegraphs.md +106 -0
- package/design/30-systems/unit-rosters.md +123 -0
- package/design/40-worldbuilding/README.md +49 -0
- package/design/40-worldbuilding/aesthetic-direction.md +155 -0
- package/design/40-worldbuilding/faction-identity.md +136 -0
- package/design/40-worldbuilding/naming-and-tone.md +130 -0
- package/design/40-worldbuilding/narrative-delivery.md +129 -0
- package/design/40-worldbuilding/theme-vectors.md +134 -0
- package/design/40-worldbuilding/worldbuilding-scaffold.md +132 -0
- package/design/50-patterns/README.md +54 -0
- package/design/50-patterns/anti-frustration.md +121 -0
- package/design/50-patterns/emergence.md +121 -0
- package/design/50-patterns/feedback-loops.md +121 -0
- package/design/50-patterns/juice-choreography.md +124 -0
- package/design/50-patterns/mastery-and-flow.md +121 -0
- package/design/50-patterns/pacing-and-tension.md +120 -0
- package/design/50-patterns/readability.md +121 -0
- package/design/50-patterns/risk-reward.md +120 -0
- package/design/CONTRIBUTING.md +183 -0
- package/design/INDEX.md +133 -0
- package/design/README.md +86 -0
- package/design/_TEMPLATE.md +69 -0
- package/design/index.json +2720 -0
- package/package.json +2 -1
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: system-economy
|
|
3
|
+
title: Economy — Faucets, Sinks & the Pacing Window
|
|
4
|
+
kind: system
|
|
5
|
+
tags: [economy, currency, faucets, sinks, inflation, balance, pacing, incremental]
|
|
6
|
+
summary: Currencies flowing in through faucets and out through sinks; keeping the two in tension so the player is always almost-able-to-afford the next thing.
|
|
7
|
+
use-when: The design has resources or currency the player earns and spends, and you need them to stay meaningful instead of trivial or crushing.
|
|
8
|
+
composes-with: [system-resource-loops, system-progression, system-crafting, system-reward-schedules, system-meta-progression]
|
|
9
|
+
anchors: [anchor-factorio, anchor-stardew-valley, anchor-civilization]
|
|
10
|
+
verify-with: docs/FUN.md#14-incrementalidle
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Economy — Faucets, Sinks & the Pacing Window
|
|
14
|
+
|
|
15
|
+
**What it is.** Every currency is a bucket with **faucets** (where it flows in)
|
|
16
|
+
and **sinks** (where it drains out). The economy is the *ratio* between them over
|
|
17
|
+
time. Get the ratio right and the player lives in a productive tension — always
|
|
18
|
+
almost able to afford the next thing. Get it wrong and money is either worthless
|
|
19
|
+
or a wall.
|
|
20
|
+
|
|
21
|
+
**Player fantasy / why it's fun.** "I can *almost* afford it — one more run."
|
|
22
|
+
A good economy makes desire renewable: the moment you can buy the thing, a better
|
|
23
|
+
thing is just out of reach. The pull is the **pacing window** itself.
|
|
24
|
+
|
|
25
|
+
## When to use / when NOT
|
|
26
|
+
|
|
27
|
+
| Use it when | Skip it when |
|
|
28
|
+
|---|---|
|
|
29
|
+
| Earning and spending is a core loop (RPG, sim, incremental) | The game has no persistent resource (pure arcade, puzzle) |
|
|
30
|
+
| You want the player pacing themselves via what they can afford | A flat unlock list reads clearer than a currency |
|
|
31
|
+
| Multiple currencies segment progress into tracks | One currency would do — don't invent five |
|
|
32
|
+
|
|
33
|
+
**Currency count is a tax.** Each currency the player must track is cognitive
|
|
34
|
+
overhead. Add a second only when it *segments* meaningfully (soft vs premium,
|
|
35
|
+
common vs prestige, run vs meta). Civilization's gold/science/culture each gate a
|
|
36
|
+
different track; that earns its complexity.
|
|
37
|
+
|
|
38
|
+
## Variants
|
|
39
|
+
|
|
40
|
+
| Variant | Shape | Best for | Watch for |
|
|
41
|
+
|---|---|---|---|
|
|
42
|
+
| **Single currency** | One in, one out | Small games; clarity | Boredom if one sink dominates |
|
|
43
|
+
| **Multi-currency** | Parallel buckets, separate tracks | Sims, 4X, gacha | Confusion; conversion loopholes |
|
|
44
|
+
| **Convertible chain** | A → B → C ([[system-resource-loops]]) | Crafting, production | Bottleneck placement is the whole game |
|
|
45
|
+
| **Closed loop** | Fixed total, only moves | Auto-battler gold; poker chips | No growth fantasy |
|
|
46
|
+
| **Open (growth)** | Faucets > sinks by design | Incrementals, idlers | Inflation → late-game money is meaningless |
|
|
47
|
+
|
|
48
|
+
## Tuning levers
|
|
49
|
+
|
|
50
|
+
| Lever | What it controls | Healthy range / rule |
|
|
51
|
+
|---|---|---|
|
|
52
|
+
| **Faucet rate** | Income per unit time/effort | Tie to *effort/skill*, not idle time, or you've built a clock |
|
|
53
|
+
| **Sink appetite** | How fast money leaves | Sinks must scale *with* faucets or inflation eats meaning |
|
|
54
|
+
| **Payback ratio** (cost ÷ production) | Time to recoup a purchase | Keep ~flat per tier (**~15–25s** in idlers). Rising payback strangles the late game (**[[FUN.md §14]]**) |
|
|
55
|
+
| **First-buy time** | The onboarding hook | Fast — the first affordable purchase within the first minute |
|
|
56
|
+
| **Inflation control** | Whether late money matters | New, costlier sinks per era; or a prestige reset ([[system-meta-progression]]) |
|
|
57
|
+
| **Currency count** | Cognitive load | As few as segment the game meaningfully |
|
|
58
|
+
|
|
59
|
+
The discipline that defines a healthy economy is the **pacing window**: state the
|
|
60
|
+
payback inequality as a law-3 constraint and *assert it holds across the whole
|
|
61
|
+
arc* — no tier where the next purchase is a desert, none where it's instant
|
|
62
|
+
(**[[FUN.md §14]]**, law 3).
|
|
63
|
+
|
|
64
|
+
## How it wires to Hayao
|
|
65
|
+
|
|
66
|
+
- **The ledger is state.** Balances live in `world.state`; every earn and spend is
|
|
67
|
+
an **input action** (`input.press`), *never* a direct mutation — this is the
|
|
68
|
+
exact rule incremental/idle lives by so replays don't lie (**[[FUN.md §14]]**).
|
|
69
|
+
- **Balance-sim the whole arc.** Because state is pure JSON and rng flows through
|
|
70
|
+
`world.rng`, script a bot that plays the economy start-to-finish and assert the
|
|
71
|
+
pacing windows, monotone production, and *no unlock deserts* — the incremental
|
|
72
|
+
verify pattern. Grep `docs/API.md` for the ramp/pacing helpers
|
|
73
|
+
(`assertRamp`/`rampIssues`).
|
|
74
|
+
- **The HUD is cosmetic.** Balance labels, floating "+N", coin sprites render on
|
|
75
|
+
`LAYER_HUD` and are `cosmetic = true` — deletable without changing
|
|
76
|
+
`world.hash()` (**[[FUN.md law 6]]**). The city-builder truth applies: the live
|
|
77
|
+
"+N under the cursor" is a *pure* score serving sim, bot, test, and label at
|
|
78
|
+
once (**[[FUN.md §17]]**).
|
|
79
|
+
- **Shops/upgrade menus are chrome** — `showScreen()` DOM (CLAUDE.md invariant 4).
|
|
80
|
+
|
|
81
|
+
## Fails when…
|
|
82
|
+
|
|
83
|
+
- **Inflation.** Faucets outrun sinks; late-game money is meaningless and every
|
|
84
|
+
purchase is trivial. Scale sinks with faucets; add prestige resets.
|
|
85
|
+
- **A desert.** A tier where the next thing costs far more than income can reach in
|
|
86
|
+
a fun span — the player grinds a solved loop. The payback assertion catches it.
|
|
87
|
+
- **Idle-not-effort faucets.** Income from waiting, not playing, turns the game
|
|
88
|
+
into a timer. Tie faucets to skill/effort.
|
|
89
|
+
- **Currency soup.** Five currencies where one would do; players lose the thread.
|
|
90
|
+
- **A conversion loophole.** A → B → A at profit breaks a multi-currency economy —
|
|
91
|
+
prove no cycle nets positive.
|
|
92
|
+
|
|
93
|
+
## Verify
|
|
94
|
+
|
|
95
|
+
- Pacing windows, monotone production, no deserts, no click-softlock — the
|
|
96
|
+
incremental balance-sim: **[[FUN.md §14]]**.
|
|
97
|
+
- Payback ratio as an asserted law-3 inequality across tiers: **[[FUN.md law 3]]**.
|
|
98
|
+
- The exposed score as one pure function (sim = bot = test = label):
|
|
99
|
+
**[[FUN.md §17]]** (city-builder).
|
|
100
|
+
- Reinvest-vs-hoard skill delta (740 vs 236): **[[FUN.md §15]]** (farming).
|
|
101
|
+
|
|
102
|
+
## Composes with
|
|
103
|
+
|
|
104
|
+
- [[system-resource-loops]] — the gather→convert→spend cycles the economy prices.
|
|
105
|
+
- [[system-progression]] — XP/levels are one faucet–sink pair among many.
|
|
106
|
+
- [[system-crafting]] — recipes are structured sinks with combinatorial payoff.
|
|
107
|
+
- [[system-reward-schedules]] — the drip that fills the faucet.
|
|
108
|
+
- [[system-meta-progression]] — prestige/meta currency as an inflation reset.
|
|
109
|
+
- [[pattern-feedback-loops]] — income→buy→more income is the runaway loop to tame.
|
|
110
|
+
|
|
111
|
+
## See also
|
|
112
|
+
|
|
113
|
+
- [`docs/FUN.md`](../../docs/FUN.md) §14 (incremental pacing) · §15 (farming
|
|
114
|
+
solvency) · §17 (exposed score) — the three economy proofs.
|
|
115
|
+
- `src/content/` + `assertRamp` — pace-as-data; balance-sim the arc, don't vibe it.
|
|
116
|
+
- **[[anchor-factorio]]** (production economy) · **[[anchor-civilization]]**
|
|
117
|
+
(multi-currency tracks).
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: system-emergent-systems
|
|
3
|
+
title: Emergent Systems
|
|
4
|
+
kind: system
|
|
5
|
+
tags: [emergence, nemesis, memory, relationships, reputation, systemic-story, story-generator, second-order]
|
|
6
|
+
summary: Nemesis-style memory, relationships, and reputation — systemic story generators where the game remembers you and interactions author drama.
|
|
7
|
+
use-when: You want stories the designer didn't script — rivalries, grudges, and reputations that arise from the player's own play.
|
|
8
|
+
composes-with: [system-enemy-ai, system-faction-asymmetry, pattern-emergence, world-narrative-delivery]
|
|
9
|
+
anchors: [anchor-shadow-of-mordor, anchor-rimworld]
|
|
10
|
+
verify-with: docs/FUN.md#7-pure-data-state-pays-compound-interest
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Emergent Systems
|
|
14
|
+
|
|
15
|
+
**What it is.** Systems that **remember and relate** so the game authors stories no
|
|
16
|
+
designer wrote. The exemplar is Shadow of Mordor's **nemesis system**: an orc that
|
|
17
|
+
kills you gets promoted, scars, and a grudge — and when you meet again, *the game
|
|
18
|
+
remembers*. The family includes relationships (who likes whom), reputation (how the
|
|
19
|
+
world treats you), and any **systemic memory** that turns a one-off event into an
|
|
20
|
+
ongoing thread.
|
|
21
|
+
|
|
22
|
+
**Player fantasy / why it's fun.** *A story that's mine because it happened to me.*
|
|
23
|
+
Emergent drama beats scripted drama on ownership: the rival who humiliated you three
|
|
24
|
+
runs ago carries weight no cutscene can. The pull is a world that reacts to your
|
|
25
|
+
history, not a script that ignores it.
|
|
26
|
+
|
|
27
|
+
## When to use / when NOT
|
|
28
|
+
|
|
29
|
+
| Use it when | Skip it when |
|
|
30
|
+
|---|---|
|
|
31
|
+
| Replayability + memorable specific antagonists/allies | A tight linear story — scripting owns it |
|
|
32
|
+
| The world should react to *your* history | Pure skill games where memory adds noise, not meaning |
|
|
33
|
+
| You want stories from interaction, not authoring | You can't afford the systemic-consequence budget (it must *ripple*) |
|
|
34
|
+
|
|
35
|
+
> **Memory only matters if it changes play.** A tracked grudge that never alters an
|
|
36
|
+
> encounter is a stat, not a story. The nemesis is fun because the promoted orc is
|
|
37
|
+
> genuinely *tougher and taunts you* — the memory has mechanical teeth
|
|
38
|
+
> ([[process-the-twist]]: cosmetic signatures don't carry a game).
|
|
39
|
+
|
|
40
|
+
## Variants
|
|
41
|
+
|
|
42
|
+
| Variant | Remembers | Expresses as | Anchor |
|
|
43
|
+
|---|---|---|---|
|
|
44
|
+
| **Nemesis / rival** | who bested/fled whom | promoted, scarred, taunting foes | [[anchor-shadow-of-mordor]] |
|
|
45
|
+
| **Relationship web** | who likes/loathes whom | mood, cooperation, feuds | [[anchor-rimworld]] pawns |
|
|
46
|
+
| **Reputation** | your deeds toward a group | prices, aggression, access | RPG factions |
|
|
47
|
+
| **World state memory** | choices & consequences | changed places, remembered NPCs | narrative games |
|
|
48
|
+
| **Ecology / rivalry** | predator/prey, territory | shifting balance you disturbed | sim sandboxes |
|
|
49
|
+
|
|
50
|
+
## Tuning levers
|
|
51
|
+
|
|
52
|
+
| Lever | Effect | Watch for |
|
|
53
|
+
|---|---|---|
|
|
54
|
+
| **Memory salience** | how much the game references history | too little = forgettable; too much = nagging |
|
|
55
|
+
| **Consequence magnitude** | how hard memory hits play | cosmetic memory = no story; brutal = punishing |
|
|
56
|
+
| **Promotion/decay rules** | how relationships evolve | no decay = the web ossifies |
|
|
57
|
+
| **Legibility of memory** | can the player *see* the history? | invisible memory reads as randomness |
|
|
58
|
+
|
|
59
|
+
## How it wires to Hayao
|
|
60
|
+
|
|
61
|
+
- **Memory is pure data.** Grudges, relationships, and reputation are plain JSON in
|
|
62
|
+
`world.state`, advanced through `dmath`, rolled through `world.rng` — so a
|
|
63
|
+
nemesis roster is part of `world.hash()`, saves, and replays for free (FUN.md
|
|
64
|
+
law 7). "Pure-data state pays compound interest": the *same* property that makes
|
|
65
|
+
a story generator deterministic makes it save/loadable and testable.
|
|
66
|
+
- **The behavior hangs off [[system-enemy-ai]].** A promoted rival is an archetype
|
|
67
|
+
with a memory-derived stat block and a targeting bias toward *you* — same brain,
|
|
68
|
+
history-tuned numbers.
|
|
69
|
+
- **Ordered iteration is mandatory.** Relationship/promotion resolution must iterate
|
|
70
|
+
in a deterministic order (by id), never by insertion or hash order, or the story
|
|
71
|
+
diverges between machines (CLAUDE.md invariant 2).
|
|
72
|
+
- **Expression is often systemic narrative** — the memory shows up in the world,
|
|
73
|
+
not a text dump ([[world-narrative-delivery]]).
|
|
74
|
+
- **A director can dramatize it.** `pollDirector` ([[system-difficulty-and-dda]])
|
|
75
|
+
can weight spawns toward a remembered rival's return.
|
|
76
|
+
|
|
77
|
+
## Fails when…
|
|
78
|
+
|
|
79
|
+
- **Memory with no mechanical consequence.** A tracked history that never changes an
|
|
80
|
+
encounter is a spreadsheet, not a saga.
|
|
81
|
+
- **Non-deterministic resolution.** Iteration-order or wall-clock in the memory
|
|
82
|
+
update breaks `world.hash()` and desyncs the story.
|
|
83
|
+
- **Illegible memory.** If the player can't perceive *why* a foe hates them, the
|
|
84
|
+
emergent story reads as random difficulty ([[pattern-readability]]).
|
|
85
|
+
- **Runaway feuds.** No decay or bounds and relationships spiral into an unreadable
|
|
86
|
+
tangle ([[pattern-feedback-loops]]).
|
|
87
|
+
- **Over-narration.** The system reminding you of every past event constantly kills
|
|
88
|
+
the surprise it exists to create.
|
|
89
|
+
|
|
90
|
+
## Verify
|
|
91
|
+
|
|
92
|
+
- **Determinism of the story:** golden-hash a scripted multi-run sequence; the
|
|
93
|
+
nemesis/relationship state must replay bit-exactly
|
|
94
|
+
([FUN.md law 7](../../docs/FUN.md#part-1--universal-laws)).
|
|
95
|
+
- **Save round-trip:** snapshot→restore→hash the memory state — a rivalry survives a
|
|
96
|
+
save intact (CONVENTIONS; [[system-save-and-checkpoint]]).
|
|
97
|
+
- **Consequence delta:** assert a remembered rival is measurably harder / behaves
|
|
98
|
+
differently than a fresh spawn — memory has teeth (FUN.md law 2 skill-delta shape).
|
|
99
|
+
- **Bounded evolution:** relationship/reputation values stay inside bounds across a
|
|
100
|
+
long sim (no runaway, per [[pattern-feedback-loops]]).
|
|
101
|
+
|
|
102
|
+
## Composes with
|
|
103
|
+
|
|
104
|
+
- [[system-enemy-ai]] — the behavior a memory-tuned rival runs.
|
|
105
|
+
- [[system-faction-asymmetry]] — reputation and relationships across distinct groups.
|
|
106
|
+
- [[pattern-emergence]] — the second-order design this is the flagship case of.
|
|
107
|
+
- [[world-narrative-delivery]] — how the remembered story reaches the player.
|
|
108
|
+
- [[system-difficulty-and-dda]] — a director can stage a rival's return.
|
|
109
|
+
|
|
110
|
+
## See also
|
|
111
|
+
|
|
112
|
+
- [`docs/FUN.md` law 7](../../docs/FUN.md#part-1--universal-laws) — pure-data state as the enabler.
|
|
113
|
+
- [[anchor-shadow-of-mordor]] — the nemesis system, distilled.
|
|
114
|
+
- [[anchor-rimworld]] — relationships + a director as a story engine.
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: system-encounter-design
|
|
3
|
+
title: Encounter Design
|
|
4
|
+
kind: system
|
|
5
|
+
tags: [encounter, combat, pacing, pressure, safe-pocket, exit-lane, waves, composition]
|
|
6
|
+
summary: Composing archetypes into a fight — pressure and safe pockets, exit lanes, and a wave curve that breathes.
|
|
7
|
+
use-when: You have enemy roles and need to arrange them into a specific fight that reads, pressures, and resolves fairly.
|
|
8
|
+
composes-with: [system-enemy-archetypes, system-enemy-ai, system-difficulty-and-dda, system-boss-design]
|
|
9
|
+
anchors: [anchor-into-the-breach, anchor-vampire-survivors]
|
|
10
|
+
verify-with: docs/FUN.md#5-stealth
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Encounter Design
|
|
14
|
+
|
|
15
|
+
**What it is.** The **arrangement** of enemies, space, and time into a single
|
|
16
|
+
fight. If [[system-enemy-archetypes]] is the alphabet, an encounter is the
|
|
17
|
+
*sentence*: which roles, in what count, entering from where, with what geometry —
|
|
18
|
+
and crucially, where the player can **breathe**. A fight is a rhythm of **pressure
|
|
19
|
+
and pocket**, not a constant scream.
|
|
20
|
+
|
|
21
|
+
**Player fantasy / why it's fun.** The satisfaction of *reading a room and solving
|
|
22
|
+
it live*. A great encounter poses a legible problem, ramps the pressure, gives one
|
|
23
|
+
honest window to recover, then peaks. FUN.md §5's "plannable danger" is the whole
|
|
24
|
+
ideal: the player should be able to route the fight, not just survive noise.
|
|
25
|
+
|
|
26
|
+
## When to use / when NOT
|
|
27
|
+
|
|
28
|
+
| Use it when | Skip it when |
|
|
29
|
+
|---|---|
|
|
30
|
+
| Hand-authoring set-piece fights or rooms | Endless horde — that's a *pressure curve* (§6), tune the director not the room |
|
|
31
|
+
| A boss arena with adds | The fight IS one entity — go to [[system-boss-design]] |
|
|
32
|
+
| Roguelike rooms assembled from parts | Pure puzzle levels — that's solver-authored (§1) |
|
|
33
|
+
|
|
34
|
+
## The anatomy of an encounter
|
|
35
|
+
|
|
36
|
+
| Element | The design question | Failure mode |
|
|
37
|
+
|---|---|---|
|
|
38
|
+
| **Composition** | which archetypes, how many? | all-tank slog / all-swarm noise |
|
|
39
|
+
| **Ingress** | where do they enter, in what order? | everything at once → no read |
|
|
40
|
+
| **Pressure curve** | does intensity rise, then peak? | flat = boring; monotone-hard = unfair |
|
|
41
|
+
| **Safe pocket** | where can the player recover mid-fight? | none = a war of attrition, not a fight (§5) |
|
|
42
|
+
| **Exit lanes** | are doors/escape routes obstacle-free? | cover in the door row = **softlock** (§4) |
|
|
43
|
+
| **Resolution** | how does it end — clear, timer, objective? | ambiguous end = the fight overstays |
|
|
44
|
+
|
|
45
|
+
## Tuning levers
|
|
46
|
+
|
|
47
|
+
| Lever | Turns up… | Watch for |
|
|
48
|
+
|---|---|---|
|
|
49
|
+
| **Enemy budget** (a points cost per role) | raw difficulty | cheap way to overshoot — cap it |
|
|
50
|
+
| **Ingress cadence** | how fast the room fills | dumping all at frame 0 kills the read |
|
|
51
|
+
| **Pocket size / duration** | recovery generosity | zero pocket = frustration; huge pocket = no tension |
|
|
52
|
+
| **Arena geometry** (pillars, funnels) | kiting arcs & LoS breaks | a pillar in an exit lane softlocks (§4) |
|
|
53
|
+
| **Composition ratio** | the *kind* of pressure | shift ratios to reface a reused arena |
|
|
54
|
+
|
|
55
|
+
## How it wires to Hayao
|
|
56
|
+
|
|
57
|
+
- **Encounters are data.** A room is a list of spawns + positions in `world.state`,
|
|
58
|
+
fed to the shared archetype behaviors. Timed ingress rides
|
|
59
|
+
`pollDirector(waves, state, world.time, world.rng)` — a repeating wave with an
|
|
60
|
+
`end` is a controlled trickle, a one-shot wave is an ambush
|
|
61
|
+
([`src/content/dsl.ts`](../../src/content/dsl.ts)).
|
|
62
|
+
- **Geometry legibility** is a lint, not a vibe: `astarGrid`/`connectedComponents`
|
|
63
|
+
(grep `docs/API.md`) prove exit lanes stay traversable and every enemy can reach
|
|
64
|
+
the player — cover in a door row shows up as an unreachable path.
|
|
65
|
+
- **Procedural rooms** compose from proven parts: `generateDungeon` /
|
|
66
|
+
`generateLevels` (see [[system-procgen-design]]) with a per-room accept rule that
|
|
67
|
+
every spawn is reachable and a pocket exists.
|
|
68
|
+
- **Wave curve** shares the tower-defense breather math — see
|
|
69
|
+
[[system-difficulty-and-dda]] for `assertRamp`/`rampIssues`.
|
|
70
|
+
|
|
71
|
+
## Fails when…
|
|
72
|
+
|
|
73
|
+
- **No safe pocket.** A long fight with nowhere to recover is attrition, not
|
|
74
|
+
skill — FUN.md §5 requires a pocket at the *midpoint* of any long traversal.
|
|
75
|
+
- **Blocked exit lanes.** A pillar or an enemy parked in a door row is a softlock;
|
|
76
|
+
keep door rows/columns clear (§4).
|
|
77
|
+
- **Everything at once.** Simultaneous ingress erases the read — the player never
|
|
78
|
+
gets to *solve* the room, only flail.
|
|
79
|
+
- **Flat pressure.** No rise, no peak → the fight is texture, not an arc
|
|
80
|
+
([[pattern-pacing-and-tension]]).
|
|
81
|
+
- **Joint-phase waits** (stealth): chaining two guard windows that must *both*
|
|
82
|
+
align makes wait times explode (§5) — chain single windows.
|
|
83
|
+
|
|
84
|
+
## Verify
|
|
85
|
+
|
|
86
|
+
- **Both-ways affordance / safe pocket:** the stealth proof pattern — punished
|
|
87
|
+
exposure AND concealment-holds AND a mid-path pocket
|
|
88
|
+
([FUN.md §5](../../docs/FUN.md#5-stealth)).
|
|
89
|
+
- **Beatable:** a bot clears the encounter deathless with hp floor ≥ comfortable
|
|
90
|
+
([FUN.md §4](../../docs/FUN.md#4-top-down-action-adventure-zelda-like)).
|
|
91
|
+
- **Curve breathes:** assert the pressure *shape* (each wave ≥ ~55% of prior,
|
|
92
|
+
finale peaks) with `rampIssues`, not monotonicity ([FUN.md §8](../../docs/FUN.md#8-tower-defense)).
|
|
93
|
+
- **Exit lanes clear:** reachability lint over the actual room geometry (FUN.md Part 3).
|
|
94
|
+
|
|
95
|
+
## Composes with
|
|
96
|
+
|
|
97
|
+
- [[system-enemy-archetypes]] — the letters this arranges into sentences.
|
|
98
|
+
- [[system-enemy-ai]] — the behaviors that animate each spawn.
|
|
99
|
+
- [[system-difficulty-and-dda]] — encounters are the units a director sequences.
|
|
100
|
+
- [[system-boss-design]] — a boss arena is an encounter with a super-archetype.
|
|
101
|
+
- [[pattern-pacing-and-tension]] — pressure/pocket is pacing at fight scale.
|
|
102
|
+
|
|
103
|
+
## See also
|
|
104
|
+
|
|
105
|
+
- [`docs/FUN.md` §4/§5/§8](../../docs/FUN.md) — readable combat, plannable danger, breathing waves.
|
|
106
|
+
- [`src/content/dsl.ts`](../../src/content/dsl.ts) — director-driven ingress.
|
|
107
|
+
- [[anchor-into-the-breach]] — the perfectly legible, fully telegraphed encounter.
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: system-enemy-ai
|
|
3
|
+
title: Enemy AI
|
|
4
|
+
kind: system
|
|
5
|
+
tags: [ai, behavior, aggro, threat, steering, flow-field, pathfinding, kiting, telegraph]
|
|
6
|
+
summary: Readable, beatable enemy minds — aggro/threat, steering, and pathing that the player can predict, route around, and outplay.
|
|
7
|
+
use-when: A design needs enemies that move and decide, and you want them to feel intelligent without being unfair or opaque.
|
|
8
|
+
composes-with: [system-enemy-archetypes, system-encounter-design, system-telegraphs, system-difficulty-and-dda]
|
|
9
|
+
anchors: [anchor-nuclear-throne, anchor-shadow-of-mordor]
|
|
10
|
+
verify-with: docs/FUN.md#4-top-down-action-adventure-zelda-like
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Enemy AI
|
|
14
|
+
|
|
15
|
+
**What it is.** The **decision + movement** an enemy runs each tick: who to
|
|
16
|
+
target, whether to press or retreat, and how to get there without walking into a
|
|
17
|
+
wall. Good enemy AI is not *smart* — it is **legible**. The player must be able to
|
|
18
|
+
read its intent, predict its next move, and beat it with position and timing.
|
|
19
|
+
|
|
20
|
+
**Player fantasy / why it's fun.** The fantasy is *outwitting a mind*. That only
|
|
21
|
+
lands if the mind is knowable: a shark that telegraphs its lunge is thrilling; one
|
|
22
|
+
that teleports behind you is cheap. The skill the player buys is *reading and
|
|
23
|
+
routing* — FUN.md §4's kiting bot exists because "the enemy is beatable by
|
|
24
|
+
positioning" is a provable claim.
|
|
25
|
+
|
|
26
|
+
## When to use / when NOT
|
|
27
|
+
|
|
28
|
+
| Use it when | Skip it / go simpler when |
|
|
29
|
+
|---|---|
|
|
30
|
+
| Enemies must chase, flank, or hold ground | Bullet-hell foes: they emit **patterns**, not decisions (§7) — script the pattern, not a brain |
|
|
31
|
+
| The player's skill is spacing & threat-reading | Pure puzzle enemies: they're **rules**, deterministic and solver-legible (§1, §12) |
|
|
32
|
+
| You want emergent pressure from a few archetypes | A single scripted boss: hand-author phases ([[system-boss-design]]), don't build a general AI |
|
|
33
|
+
| Mass units under command (RTS) | One enemy, one behavior: a state flag beats a behavior tree |
|
|
34
|
+
|
|
35
|
+
> **Never build a mind the player can't read.** Perfect aim, wall-hacks, and
|
|
36
|
+
> reaction-time-zero are the difficulty of a slot machine. Difficulty comes from
|
|
37
|
+
> *count, geometry, and telegraph windows* — not from the AI cheating.
|
|
38
|
+
|
|
39
|
+
## Variants
|
|
40
|
+
|
|
41
|
+
| Variant | The mind | Reads as | Best for |
|
|
42
|
+
|---|---|---|---|
|
|
43
|
+
| **Direct seeker** | steer straight at the target | "it wants me" | swarms, zombies (§6) |
|
|
44
|
+
| **Flow-field mass** | one BFS per goal, every unit follows the field | "the tide is coming" | RTS-lite, hordes (§9) |
|
|
45
|
+
| **Kiter / spacer** | hold a preferred range, back off when close | "keep your distance" | archers, ranged skirmishers (§4) |
|
|
46
|
+
| **Ambusher** | wait in a state until a trigger, then commit | "don't step there" | stealth, traps (§5) |
|
|
47
|
+
| **State-machine bruiser** | idle → aggro → windup → attack → recover | "here comes the swing" | melee bosses, mini-bosses (§4) |
|
|
48
|
+
| **Threat-driven** | pick target by an aggro/threat score, not proximity | "I pulled it" | party fights, taunt play |
|
|
49
|
+
|
|
50
|
+
## Tuning levers
|
|
51
|
+
|
|
52
|
+
| Lever | Turns up… | Watch for |
|
|
53
|
+
|---|---|---|
|
|
54
|
+
| **Aggro radius** | when the enemy notices you | too large = no safe pockets ([[system-encounter-design]]) |
|
|
55
|
+
| **Threat weights** | *who* it targets (damage dealt, distance, taunt) | must be deterministic & ordered — ties break by entity id, never by iteration order |
|
|
56
|
+
| **Preferred range** (kiters) | the spacing the fight settles at | range < player reach = it's just a melee foe |
|
|
57
|
+
| **Windup / telegraph frames** | the reaction window before a hit | too short = unreadable; own this in [[system-telegraphs]] |
|
|
58
|
+
| **Steering deadzone** | jitter vs. commitment near the target | too tight = enemies vibrate on the spot |
|
|
59
|
+
| **Repath cadence** | how fast it reacts to you moving | every frame = twitchy & expensive; every N frames = readable |
|
|
60
|
+
|
|
61
|
+
## How it wires to Hayao
|
|
62
|
+
|
|
63
|
+
- **Pathing:** `astarGrid` and `floodFill` (grep `docs/API.md`) give per-enemy
|
|
64
|
+
paths and wall-aware reachability. For **mass** pathing, one BFS per goal tile
|
|
65
|
+
cached *outside* `world.state` is the flow field (FUN.md §9) — hundreds of units
|
|
66
|
+
share it. `connectedComponents` proves a goal is even reachable before you spawn
|
|
67
|
+
a chaser that would path into nothing.
|
|
68
|
+
- **Steering:** `steer2D(px,py,tx,ty,out,dead)` emits the same action strings a
|
|
69
|
+
human would press, so an enemy and a bot driver share one movement path — and
|
|
70
|
+
the enemy replays deterministically. The `dead` deadzone is your jitter lever.
|
|
71
|
+
- **Threat/aggro:** plain data in `world.state` — a per-enemy target id and score,
|
|
72
|
+
advanced through `dmath`, ordered iteration for ties. No wall-clock, all rolls
|
|
73
|
+
through `world.rng`.
|
|
74
|
+
- **See it in isolation:** [`sandboxes/pathfinding-demo`](../../sandboxes/pathfinding-demo/)
|
|
75
|
+
— `astarGrid`/`floodFill` with paintable walls and a movable goal, no genre
|
|
76
|
+
attached. Learn the primitive there, not from a whole game.
|
|
77
|
+
|
|
78
|
+
## Fails when…
|
|
79
|
+
|
|
80
|
+
- **The mind cheats.** Perfect prediction, seeing through walls, or homing that
|
|
81
|
+
can't be dodged. The FUN.md §7 dodge-bot exists precisely to prove a human
|
|
82
|
+
*can* survive; an enemy that beats the bot is unfair to people too.
|
|
83
|
+
- **No safe pocket.** Every enemy aggros at once with no gap to breathe → it's a
|
|
84
|
+
wall of pressure, not a fight ([[system-encounter-design]], FUN.md §5).
|
|
85
|
+
- **Iteration-order targeting.** Picking a target by array order leaks
|
|
86
|
+
non-determinism into the sim and breaks `world.hash()`. Order by an explicit
|
|
87
|
+
key.
|
|
88
|
+
- **Repathing every frame** — cost spikes and the enemy twitches; humans read
|
|
89
|
+
*committed* motion, not a gradient-follower recomputing constantly.
|
|
90
|
+
- **Melee foes that outrun you with no telegraph** — the fight becomes a coin
|
|
91
|
+
flip, not a read.
|
|
92
|
+
|
|
93
|
+
## Verify
|
|
94
|
+
|
|
95
|
+
- **Beatable by positioning:** the kiting-bot telemetry pattern — win time, hp
|
|
96
|
+
floor ≥ comfortable, **0 deaths** — is the proof an enemy roster is fair
|
|
97
|
+
([FUN.md §4](../../docs/FUN.md#4-top-down-action-adventure-zelda-like)).
|
|
98
|
+
- **Reachability first:** `connectedComponents` / flow-field over the actual
|
|
99
|
+
geometry before spawning chasers ([FUN.md §9](../../docs/FUN.md#9-rts-lite)).
|
|
100
|
+
- **Feel floor:** every attack telegraphs before its hitbox goes live — the
|
|
101
|
+
readability gate in [`src/verify/gates.ts`](../../src/verify/gates.ts) checks it.
|
|
102
|
+
- **Determinism:** golden-hash a scripted encounter; targeting and steering must
|
|
103
|
+
replay bit-exactly (FUN.md law 6/7).
|
|
104
|
+
|
|
105
|
+
## Composes with
|
|
106
|
+
|
|
107
|
+
- [[system-enemy-archetypes]] — AI is the *how it moves*; archetypes are the
|
|
108
|
+
*what role it plays*. Same brain, different stats, different feel.
|
|
109
|
+
- [[system-telegraphs]] — a readable mind is mostly a well-telegraphed one; the
|
|
110
|
+
windup frames live here.
|
|
111
|
+
- [[system-encounter-design]] — one enemy is a behavior; a fight is a *composition*
|
|
112
|
+
of them with pressure and pockets.
|
|
113
|
+
- [[system-difficulty-and-dda]] — aggro radius and count are the director's dials.
|
|
114
|
+
- [[pattern-readability]] — the salience floor that makes a mind knowable.
|
|
115
|
+
|
|
116
|
+
## See also
|
|
117
|
+
|
|
118
|
+
- [`docs/FUN.md` §4/§7/§9](../../docs/FUN.md) — kiting, dodge-bot fairness, flow fields.
|
|
119
|
+
- [`sandboxes/pathfinding-demo`](../../sandboxes/pathfinding-demo/) — the pathing primitive alone.
|
|
120
|
+
- [[anchor-nuclear-throne]] — tight-loop enemies whose danger is *count + read*, never cheating.
|
|
121
|
+
- [[anchor-shadow-of-mordor]] — where a readable mind grows a *history* ([[system-emergent-systems]]).
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: system-enemy-archetypes
|
|
3
|
+
title: Enemy Archetypes
|
|
4
|
+
kind: system
|
|
5
|
+
tags: [enemy, archetypes, roles, tank, skirmisher, artillery, swarm, support, roster]
|
|
6
|
+
summary: The enemy alphabet — tank/skirmisher/artillery/swarm/support — a small set of roles that combine into fights bigger than their parts.
|
|
7
|
+
use-when: You need a legible enemy roster where each foe demands a different answer and pairs interact.
|
|
8
|
+
composes-with: [system-enemy-ai, system-encounter-design, system-unit-rosters, system-counter-systems]
|
|
9
|
+
anchors: [anchor-vampire-survivors, anchor-into-the-breach]
|
|
10
|
+
verify-with: docs/FUN.md#4-top-down-action-adventure-zelda-like
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Enemy Archetypes
|
|
14
|
+
|
|
15
|
+
**What it is.** A **role vocabulary** for enemies, not a bestiary. Five roles cover
|
|
16
|
+
almost every action game: **tank** (soaks, blocks lanes), **skirmisher** (fast,
|
|
17
|
+
flanks, punishes greed), **artillery** (ranged, forces you to close or break line
|
|
18
|
+
of sight), **swarm** (individually trivial, dangerous in numbers), **support**
|
|
19
|
+
(buffs/heals/shields others — the *priority* target). The alphabet is small on
|
|
20
|
+
purpose: a player learns five answers, then every fight is a *sentence* of them.
|
|
21
|
+
|
|
22
|
+
**Player fantasy / why it's fun.** Recognition, then adaptation. Seeing an
|
|
23
|
+
artillery unit behind a tank behind a swarm is a *puzzle you read at a glance* —
|
|
24
|
+
the fun is choosing the order to solve it. FUN.md §4's whole claim is "readable
|
|
25
|
+
combat"; archetypes are how a fight becomes readable before it becomes hard.
|
|
26
|
+
|
|
27
|
+
## When to use / when NOT
|
|
28
|
+
|
|
29
|
+
| Use it when | Skip it when |
|
|
30
|
+
|---|---|
|
|
31
|
+
| Combat has ≥3 enemy types and you want them to *combine* | A single-enemy game (one boss, one rival) — design that fight directly |
|
|
32
|
+
| You need difficulty from *composition*, not stat inflation | Puzzle "enemies" that are really rules ([[genre-grid-puzzle]], §12) |
|
|
33
|
+
| The player should learn one answer per role | Pure horde where the enemy is *count itself* — one type, superlinear spawn (§6) |
|
|
34
|
+
|
|
35
|
+
## Variants
|
|
36
|
+
|
|
37
|
+
The five roles and what each *demands*:
|
|
38
|
+
|
|
39
|
+
| Role | Job in the fight | Player answer | Signature knob |
|
|
40
|
+
|---|---|---|---|
|
|
41
|
+
| **Tank** | control space, absorb, block a lane | reposition or burst; don't trade | HP + a lane it denies |
|
|
42
|
+
| **Skirmisher** | punish overextension, flank | spacing, patience, don't chase | speed > player, low HP |
|
|
43
|
+
| **Artillery** | force movement, deny camping | close the gap or break LoS | range + a telegraph ([[system-telegraphs]]) |
|
|
44
|
+
| **Swarm** | overwhelm, chip, cover others | AoE, funnels, kiting arcs (§6) | trivial each, superlinear count |
|
|
45
|
+
| **Support** | multiply everyone else | **kill it first** — it's the priority | a buff radius you can see |
|
|
46
|
+
|
|
47
|
+
**Compositions** are where the alphabet earns its keep:
|
|
48
|
+
|
|
49
|
+
| Pair | Emergent problem |
|
|
50
|
+
|---|---|
|
|
51
|
+
| Tank + artillery | the tank buys the artillery time; you're pressured while you dig |
|
|
52
|
+
| Support + swarm | the swarm won't die until the support does — inverts your target order |
|
|
53
|
+
| Skirmisher + tank | the tank pins you where the skirmisher wants you |
|
|
54
|
+
| Artillery + skirmisher | ranged forces motion, flanker punishes it — a positioning vice |
|
|
55
|
+
|
|
56
|
+
## Tuning levers
|
|
57
|
+
|
|
58
|
+
| Lever | Effect | Watch for |
|
|
59
|
+
|---|---|---|
|
|
60
|
+
| **Role stat ratios** (HP/speed/range) | how sharply a role reads | roles that overlap muddy the read — keep silhouettes distinct |
|
|
61
|
+
| **Threat priority** (support first) | the target-order puzzle | if killing in any order works, the roles aren't interacting |
|
|
62
|
+
| **Count per role** | swarm-ness vs. elite-ness | one "swarm" unit is just a weak melee foe |
|
|
63
|
+
| **Telegraph length by role** | reaction budget | artillery needs the longest tell; skirmishers the shortest |
|
|
64
|
+
|
|
65
|
+
## How it wires to Hayao
|
|
66
|
+
|
|
67
|
+
- An archetype is **data**: a stat block in `world.state` (`hp`, `speed`, `range`,
|
|
68
|
+
`role`) driving the shared behaviors from [[system-enemy-ai]]. Same brain,
|
|
69
|
+
different numbers — a tank is a seeker with high HP and a wide body; a kiter is
|
|
70
|
+
the ranged archetype.
|
|
71
|
+
- **Spawning by role** rides the director: `WaveDef.spawn` takes a weighted set,
|
|
72
|
+
so `pollDirector(waves, state, world.time, world.rng)` (grep `docs/API.md`) can
|
|
73
|
+
roll "2 swarm + 1 support" per firing, deterministically. See
|
|
74
|
+
[`src/content/dsl.ts`](../../src/content/dsl.ts).
|
|
75
|
+
- **Silhouette & palette** carry the read — distinct shapes and Kentō-palette
|
|
76
|
+
hues per role ([[world-aesthetic-direction]], JUDGE). The player must name the
|
|
77
|
+
role from the silhouette alone.
|
|
78
|
+
- **Roster legibility** shares the design of [[system-unit-rosters]] — the enemy
|
|
79
|
+
roster is a roster with the same "one glance, one role" bar.
|
|
80
|
+
|
|
81
|
+
## Fails when…
|
|
82
|
+
|
|
83
|
+
- **Stat-only enemies.** Five foes that differ only in HP are one enemy with a
|
|
84
|
+
slider. Roles must demand *different answers*, not different patience.
|
|
85
|
+
- **No priority target.** Without support (or an equivalent "kill this first"),
|
|
86
|
+
every fight is a spray — order stops mattering.
|
|
87
|
+
- **Illegible silhouettes.** If you can't tell artillery from tank at a glance,
|
|
88
|
+
the read collapses ([[pattern-readability]], JUDGE).
|
|
89
|
+
- **Swarm that isn't a swarm.** Too few, too tanky, and it's just chip damage with
|
|
90
|
+
extra steps — swarm fun is *many trivial* (§6).
|
|
91
|
+
|
|
92
|
+
## Verify
|
|
93
|
+
|
|
94
|
+
- **Each role beatable with its answer:** kiting-bot telemetry per archetype —
|
|
95
|
+
0 deaths, hp floor ≥ comfortable
|
|
96
|
+
([FUN.md §4](../../docs/FUN.md#4-top-down-action-adventure-zelda-like)).
|
|
97
|
+
- **Composition, not inflation:** assert a *skill delta* — the correct target
|
|
98
|
+
order clears far faster than a naive one (FUN.md law 2). If order doesn't
|
|
99
|
+
matter, the roles don't interact.
|
|
100
|
+
- **Swarm pressure holds:** `peak alive ≥ N` so the horde feel can't silently
|
|
101
|
+
regress ([FUN.md §6](../../docs/FUN.md#6-twin-stick-horde-survival-vampire-survivors-like)).
|
|
102
|
+
- **Readability gate:** telegraph-before-hitbox in [`src/verify/gates.ts`](../../src/verify/gates.ts).
|
|
103
|
+
|
|
104
|
+
## Composes with
|
|
105
|
+
|
|
106
|
+
- [[system-enemy-ai]] — the shared brain each archetype re-skins with stats.
|
|
107
|
+
- [[system-encounter-design]] — archetypes are letters; encounters are the words.
|
|
108
|
+
- [[system-counter-systems]] — roles imply near-hard counters (AoE vs. swarm).
|
|
109
|
+
- [[system-unit-rosters]] — the same legibility discipline, player-side.
|
|
110
|
+
- [[system-boss-design]] — a boss is often a super-archetype with phases.
|
|
111
|
+
|
|
112
|
+
## See also
|
|
113
|
+
|
|
114
|
+
- [`docs/FUN.md` §4/§6](../../docs/FUN.md) — readable combat; horde pressure.
|
|
115
|
+
- [`src/content/dsl.ts`](../../src/content/dsl.ts) — `WaveDef`/`pollDirector` role spawning.
|
|
116
|
+
- [[anchor-vampire-survivors]] — the swarm archetype as the *whole* game.
|
|
117
|
+
- [[anchor-into-the-breach]] — every enemy role telegraphed as a solvable board.
|