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,113 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: system-session-structure
|
|
3
|
+
title: Session Structure
|
|
4
|
+
kind: system
|
|
5
|
+
tags: [session, run, campaign, level, world, pacing, length, structure, container]
|
|
6
|
+
summary: The nesting of play — run / campaign / level / world — and how session length and shape set the game's rhythm and stakes.
|
|
7
|
+
use-when: You need to decide how long a sitting is, what a "run" contains, and how sessions nest into a longer arc.
|
|
8
|
+
composes-with: [system-procgen-design, system-meta-progression, system-save-and-checkpoint, pattern-pacing-and-tension]
|
|
9
|
+
anchors: [anchor-hades, anchor-slay-the-spire]
|
|
10
|
+
verify-with: docs/FUN.md#14-incrementalidle
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Session Structure
|
|
14
|
+
|
|
15
|
+
**What it is.** The **containers** play nests into — a *moment*, a *level* or
|
|
16
|
+
*encounter*, a *run* or *session*, and the *meta* arc across them — and the
|
|
17
|
+
**length and shape** of each. Session structure decides "how long is one sitting,
|
|
18
|
+
what does it contain, and how do sittings add up?" A 3-minute Vampire Survivors
|
|
19
|
+
push and a 40-turn Slay the Spire climb are the same genre-family with wildly
|
|
20
|
+
different session shapes.
|
|
21
|
+
|
|
22
|
+
**Player fantasy / why it's fun.** *A satisfying unit of time.* A good session has
|
|
23
|
+
a clean arc — start, build, climax, resolution — that fits a real sitting and
|
|
24
|
+
leaves a hook. The pull is closure-plus-appetite: "one more run" works because each
|
|
25
|
+
run *finishes* something and *promises* something.
|
|
26
|
+
|
|
27
|
+
## When to use / when NOT
|
|
28
|
+
|
|
29
|
+
This is a **framing** system — every game has a session shape whether or not you
|
|
30
|
+
design it. Reach for it explicitly when:
|
|
31
|
+
|
|
32
|
+
| Design it deliberately when | It's near-trivial when |
|
|
33
|
+
|---|---|
|
|
34
|
+
| Runs/campaigns/roguelite structure is core | A single continuous level (endless arcade) |
|
|
35
|
+
| You're deciding meta vs. per-run persistence | A one-sitting puzzle box |
|
|
36
|
+
| Session length is a selling point (coffee-break vs. epic) | — |
|
|
37
|
+
|
|
38
|
+
## The nesting
|
|
39
|
+
|
|
40
|
+
| Tier | Span | Owns | Ends when |
|
|
41
|
+
|---|---|---|---|
|
|
42
|
+
| **Moment** | seconds | one verb → feedback | the input resolves ([[process-core-loop]]) |
|
|
43
|
+
| **Encounter / level** | 1–5 min | one fight or room | cleared / failed |
|
|
44
|
+
| **Run / session** | 5–60 min | a sequence of encounters + choices | win / death / objective |
|
|
45
|
+
| **Meta / campaign** | many runs | persistent progress, unlocks, story | the long goal ([[system-meta-progression]]) |
|
|
46
|
+
|
|
47
|
+
The two big shape decisions:
|
|
48
|
+
|
|
49
|
+
| Decision | Options | Consequence |
|
|
50
|
+
|---|---|---|
|
|
51
|
+
| **Session length** | coffee-break (3–10 min) · sitting (20–60) · epic (hours) | sets stakes per run and save granularity |
|
|
52
|
+
| **Persistence** | fully reset · roguelite carry-over · fully persistent | resets make death cheap; persistence makes it heavy |
|
|
53
|
+
|
|
54
|
+
## Tuning levers
|
|
55
|
+
|
|
56
|
+
| Lever | Effect | Watch for |
|
|
57
|
+
|---|---|---|
|
|
58
|
+
| **Run length** | stakes & commitment per session | too long = quitting mid-run loses progress; own it in [[system-save-and-checkpoint]] |
|
|
59
|
+
| **Encounters per run** | the run's internal pacing arc | too few = no arc; too many = a slog |
|
|
60
|
+
| **Meta gain per run** | how much a failed run still *earns* | zero = punishing; too much = trivial |
|
|
61
|
+
| **Hook strength** | the pull into the next session | none = the loop doesn't restart |
|
|
62
|
+
|
|
63
|
+
## How it wires to Hayao
|
|
64
|
+
|
|
65
|
+
- **A run is a seed + a snapshot.** Because state is pure JSON in `world.state`
|
|
66
|
+
with `world.rng`, one run is fully described by `(seed, tuning, inputLog)` and
|
|
67
|
+
restorable from a snapshot — this is exactly the Studio session artifact
|
|
68
|
+
([`docs/STUDIO.md`](../../docs/STUDIO.md), FUN.md law 7). Session structure and
|
|
69
|
+
the replay artifact are the *same* nesting.
|
|
70
|
+
- **Runs are generated.** A roguelite run is a `generateLevels`/`generateDungeon`
|
|
71
|
+
sequence over a per-run seed ([[system-procgen-design]],
|
|
72
|
+
[`src/content/generate.ts`](../../src/content/generate.ts)) — the campaign that
|
|
73
|
+
ships is a list of seeds.
|
|
74
|
+
- **Campaigns compose.** `composeCampaign(spec)` (grep `docs/API.md`,
|
|
75
|
+
[`src/content/campaign.ts`](../../src/content/campaign.ts)) assembles proven
|
|
76
|
+
levels into an ordered arc — the meta tier as data.
|
|
77
|
+
- **Between-run persistence** is meta-progression saved across sessions
|
|
78
|
+
([[system-meta-progression]], [[system-save-and-checkpoint]]).
|
|
79
|
+
|
|
80
|
+
## Fails when…
|
|
81
|
+
|
|
82
|
+
- **Length ≠ save granularity.** A 45-minute run with no checkpoint punishes anyone
|
|
83
|
+
who has to stop — respect the player's time ([[system-save-and-checkpoint]]).
|
|
84
|
+
- **No arc per session.** A run with no build-and-climax is texture, not an
|
|
85
|
+
experience ([[pattern-pacing-and-tension]]).
|
|
86
|
+
- **Failed runs earn nothing.** In roguelites, a death that advances *nothing*
|
|
87
|
+
feels like theft — grant meta or knowledge ([[anchor-hades]]).
|
|
88
|
+
- **No hook.** A run that finishes and dead-ends stops the "one more" loop.
|
|
89
|
+
- **Deserts in the meta.** Long stretches with no unlock or new goal
|
|
90
|
+
([FUN.md §14](../../docs/FUN.md#14-incrementalidle) unlock-desert lint).
|
|
91
|
+
|
|
92
|
+
## Verify
|
|
93
|
+
|
|
94
|
+
- **The whole arc paces:** balance-sim the run/campaign; assert pacing windows and
|
|
95
|
+
**no unlock deserts** across the arc ([FUN.md §14](../../docs/FUN.md#14-incrementalidle)).
|
|
96
|
+
- **A run is reproducible:** golden-hash a full scripted run; snapshot→restore→hash
|
|
97
|
+
round-trips (FUN.md law 7; [`docs/STUDIO.md`](../../docs/STUDIO.md)).
|
|
98
|
+
- **Every level in the campaign is winnable:** solver proof per level via the
|
|
99
|
+
generator (FUN.md §10, [`src/content/generate.ts`](../../src/content/generate.ts)).
|
|
100
|
+
|
|
101
|
+
## Composes with
|
|
102
|
+
|
|
103
|
+
- [[system-procgen-design]] — a run's content is generated from its seed.
|
|
104
|
+
- [[system-meta-progression]] — the tier that persists across sessions.
|
|
105
|
+
- [[system-save-and-checkpoint]] — session length dictates save granularity.
|
|
106
|
+
- [[pattern-pacing-and-tension]] — each session tier needs its own arc.
|
|
107
|
+
- [[system-difficulty-and-dda]] — the curve spans a run and the campaign both.
|
|
108
|
+
|
|
109
|
+
## See also
|
|
110
|
+
|
|
111
|
+
- [`src/content/campaign.ts`](../../src/content/campaign.ts) — `composeCampaign` (the meta tier as data).
|
|
112
|
+
- [`docs/STUDIO.md`](../../docs/STUDIO.md) — a session as a replayable artifact.
|
|
113
|
+
- [[anchor-hades]] · [[anchor-slay-the-spire]] — the run as the fundamental unit.
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: system-skill-trees
|
|
3
|
+
title: Skill Trees — Branching Unlocks & Builds
|
|
4
|
+
kind: system
|
|
5
|
+
tags: [skill-tree, builds, unlocks, branching, exclusivity, respec, specialization]
|
|
6
|
+
summary: Branching unlock graphs that turn flat power into a build; meaningful exclusivity is what makes the choice a choice, and respec is its grace.
|
|
7
|
+
use-when: Progression should let the player CHOOSE a shape — a build, a specialization — not just accumulate the same power everyone gets.
|
|
8
|
+
composes-with: [system-progression, system-build-diversity, system-tech-tree, system-economy, system-collectibles]
|
|
9
|
+
anchors: [anchor-dead-cells, anchor-slay-the-spire]
|
|
10
|
+
verify-with: docs/FUN.md#2-skill-delta-proofs
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Skill Trees — Branching Unlocks & Builds
|
|
14
|
+
|
|
15
|
+
**What it is.** A **graph of unlocks** the player buys with a progression
|
|
16
|
+
currency (points, cells, essence). The graph's *branches* — and the fact that you
|
|
17
|
+
can't afford all of them — turn "get stronger" into "become a *kind* of strong."
|
|
18
|
+
|
|
19
|
+
**Player fantasy / why it's fun.** "This build is *mine*." The tree is a canvas;
|
|
20
|
+
the player paints a strategy and then gets to test it. The pull is the road not
|
|
21
|
+
taken — every point spent is a small identity claim.
|
|
22
|
+
|
|
23
|
+
## When to use / when NOT
|
|
24
|
+
|
|
25
|
+
| Use it when | Skip it when |
|
|
26
|
+
|---|---|
|
|
27
|
+
| You want players to express strategy through pre-commitment | There's no meaningful choice — every node is strictly good |
|
|
28
|
+
| Replay value comes from "try a different build" | One optimal path exists; the tree is a formality |
|
|
29
|
+
| Power is horizontal ([[system-progression]]) and needs structure | A flat list of upgrades reads clearer (small games) |
|
|
30
|
+
|
|
31
|
+
A tree with no **exclusivity** is just a shopping list. If the player will
|
|
32
|
+
eventually own every node, the branches are decoration — either add scarcity
|
|
33
|
+
(can't afford all) or opposition (this node locks that one).
|
|
34
|
+
|
|
35
|
+
## Variants
|
|
36
|
+
|
|
37
|
+
| Variant | Structure | The choice is | Example |
|
|
38
|
+
|---|---|---|---|
|
|
39
|
+
| **Prerequisite web** | Nodes gate deeper nodes | *Order & reach* | Path of Exile's lattice |
|
|
40
|
+
| **Point-buy, no gates** | Flat pool, scarce points | *What to skip* | Classic RPG stat spend |
|
|
41
|
+
| **Mutually-exclusive forks** | Pick A xor B at each fork | *Identity* | "Fire OR frost, never both" |
|
|
42
|
+
| **Class/archetype trees** | Separate trees per role | *Which fantasy* | Diablo class trees |
|
|
43
|
+
| **Draft-as-tree** | The run's picks form an implicit build | *Emergent shape* | Hades boons; StS deck |
|
|
44
|
+
|
|
45
|
+
The **fork** variant carries the most meaning per node and the most respec
|
|
46
|
+
pressure — see levers.
|
|
47
|
+
|
|
48
|
+
## Tuning levers
|
|
49
|
+
|
|
50
|
+
| Lever | What it controls | Healthy range / rule |
|
|
51
|
+
|---|---|---|
|
|
52
|
+
| **Point scarcity** | How much you must skip | You should afford ~40–70% of a tree per playthrough — enough to specialise, not complete |
|
|
53
|
+
| **Branch exclusivity** | Whether a choice costs another | At least the *capstones* should be exclusive, or builds converge |
|
|
54
|
+
| **Node granularity** | Fewer big nodes vs many small | Big nodes = legible builds; tiny nodes = fiddly filler |
|
|
55
|
+
| **Capstones** | The payoff that defines a build | Each branch needs a "this is why you went here" node |
|
|
56
|
+
| **Respec cost** | Reversibility | Free in experimental games; costed where commitment is the point |
|
|
57
|
+
| **Gating depth** | Prereqs before the good stuff | Shallow — burying power behind 8 filler nodes reads as grind |
|
|
58
|
+
|
|
59
|
+
**Respec is grace** (**[[FUN.md law 5]]**, the anti-frustration mindset). A tree
|
|
60
|
+
the player is afraid to touch is a tree they don't engage with. Default to
|
|
61
|
+
generous respec unless *permanent commitment* is an explicit pillar.
|
|
62
|
+
|
|
63
|
+
## How it wires to Hayao
|
|
64
|
+
|
|
65
|
+
- **The tree is data.** A node graph (id, cost, prereqs, effect) in `world.state`;
|
|
66
|
+
unlocking is an **input action** that spends a currency and flips a flag. The
|
|
67
|
+
effect is applied by pure logic reading owned-node flags — so a build is a
|
|
68
|
+
reproducible input sequence, and clone-and-score bots can *pilot* builds to
|
|
69
|
+
measure them (**[[FUN.md law 7]]**).
|
|
70
|
+
- **Exclusivity is a solver constraint.** "Can't own A and B" is a rule the pure
|
|
71
|
+
logic enforces and a test asserts. Prove *every* branch is viable by piloting
|
|
72
|
+
each and asserting it beats a null build — the skill-delta proof
|
|
73
|
+
(**[[FUN.md law 2]]**), applied per branch, is your balance instrument for
|
|
74
|
+
[[system-build-diversity]].
|
|
75
|
+
- **The tree UI is chrome.** Draw it with `showScreen()` (DOM menu) — it's not
|
|
76
|
+
sim, so it doesn't belong in `world.hash()`. Grep `docs/API.md`; per CLAUDE.md
|
|
77
|
+
invariant 4, menus are DOM.
|
|
78
|
+
- **Persist unlocks** via `SaveManager` when the tree is meta
|
|
79
|
+
([[system-meta-progression]]).
|
|
80
|
+
|
|
81
|
+
## Fails when…
|
|
82
|
+
|
|
83
|
+
- **A trap node.** A branch that's strictly worse wastes the player's one
|
|
84
|
+
irreversible choice — punishing, not deep. Prove each branch viable.
|
|
85
|
+
- **A God node.** One branch dominates; everyone funnels to it and the tree
|
|
86
|
+
collapses to a line. The win-rate *window* per build catches this.
|
|
87
|
+
- **No exclusivity.** Own-everything trees have no decisions. Add scarcity or forks.
|
|
88
|
+
- **Filler gating.** Prereq chains of dead nodes to reach the good one — grind
|
|
89
|
+
wearing a tree costume.
|
|
90
|
+
- **Respec you fear.** No respec + a trap node = a bricked character. Give an out.
|
|
91
|
+
|
|
92
|
+
## Verify
|
|
93
|
+
|
|
94
|
+
- Per-branch skill delta — each build beats a null build: **[[FUN.md law 2]]**.
|
|
95
|
+
- Build viability as a win-rate *window*, both edges break CI:
|
|
96
|
+
**[[FUN.md §11]]** (deckbuilder's balance instrument).
|
|
97
|
+
- Build as a reproducible pilot (clone-and-score): **[[FUN.md law 7]]**.
|
|
98
|
+
|
|
99
|
+
## Composes with
|
|
100
|
+
|
|
101
|
+
- [[system-progression]] — the tree spends what progression earns.
|
|
102
|
+
- [[system-build-diversity]] — the tree is the machinery that makes many builds real.
|
|
103
|
+
- [[system-tech-tree]] — the same graph shape at the *strategy* scale (a whole faction).
|
|
104
|
+
- [[system-meta-progression]] — persistent trees between runs.
|
|
105
|
+
- [[system-economy]] — skill points are a currency; the tree is a sink.
|
|
106
|
+
|
|
107
|
+
## See also
|
|
108
|
+
|
|
109
|
+
- [`docs/FUN.md`](../../docs/FUN.md) §11, law 2 — build deltas and win-rate windows.
|
|
110
|
+
- `examples/slay-the-spire`-style drafting (**[[anchor-slay-the-spire]]**) — the
|
|
111
|
+
deck IS the tree, built one card at a time.
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: system-status-effects
|
|
3
|
+
title: Status Effects — damage and change over time
|
|
4
|
+
kind: system
|
|
5
|
+
tags: [status, dot, buff, debuff, stacking, poison, burn, legibility]
|
|
6
|
+
summary: DoT, buffs, and debuffs as first-class state — with stacking rules that are legible, bounded, and interact with builds instead of just piling up.
|
|
7
|
+
use-when: You want conditions (poison, burn, slow, shield, rage) that persist across turns/seconds and interact with the rest of combat.
|
|
8
|
+
composes-with: [system-combat-model, system-counter-systems, system-build-diversity, system-telegraphs]
|
|
9
|
+
anchors: [anchor-slay-the-spire, anchor-hades]
|
|
10
|
+
verify-with: docs/FUN.md#11-roguelike-deckbuilder
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Status Effects — damage and change over time
|
|
14
|
+
|
|
15
|
+
**What it is.** **Conditions** that persist: poison ticking each turn, a burn, a
|
|
16
|
+
shield, a slow, a rage buff. Status turns a hit from a one-frame event into a
|
|
17
|
+
*state you carry* — the layer that lets [[system-build-diversity]] and
|
|
18
|
+
[[system-counter-systems]] interact instead of just stacking flat numbers.
|
|
19
|
+
|
|
20
|
+
**Player fantasy / why it's fun.** Setting up. The poison you stacked three turns
|
|
21
|
+
ago finally kills; the shield you pre-cast eats the boss's big hit. Status rewards
|
|
22
|
+
*plans*, not just reactions — it's the memory of combat.
|
|
23
|
+
|
|
24
|
+
## When to use / when NOT
|
|
25
|
+
|
|
26
|
+
| Use status when… | Skip when… |
|
|
27
|
+
|---|---|
|
|
28
|
+
| You want set-up-then-payoff play | Combat is pure twitch reaction |
|
|
29
|
+
| Builds should interact (a synergy engine) | You have < ~4 effects (just make them direct) |
|
|
30
|
+
| Counters need a vocabulary (cleanse, resist) | Legibility budget is already spent |
|
|
31
|
+
|
|
32
|
+
Every status is a rule the player must hold in their head. Ship the fewest that
|
|
33
|
+
carry the most interaction — a bloated status list is unreadable, not deep.
|
|
34
|
+
|
|
35
|
+
## Variants
|
|
36
|
+
|
|
37
|
+
| Kind | Shape | Stacking | Example |
|
|
38
|
+
|---|---|---|---|
|
|
39
|
+
| **DoT** (poison, burn) | damage per tick, N ticks | intensity or duration | Slay the Spire poison (−1/turn, decays) |
|
|
40
|
+
| **Debuff** (slow, weak, vuln) | multiplier on the target | usually duration | weak = −25% dmg dealt |
|
|
41
|
+
| **Buff** (rage, haste, shield) | multiplier / absorb on self | intensity or refresh | block that expires next turn |
|
|
42
|
+
| **CC** (stun, freeze, root) | skips/limits actions | rarely stacks; diminishing | one turn skipped |
|
|
43
|
+
| **Trigger** (mark, curse) | fires on a condition | count-based | "next hit crits" |
|
|
44
|
+
|
|
45
|
+
## Stacking rules — pick one per effect, state it
|
|
46
|
+
|
|
47
|
+
| Rule | Behaviour | Good for |
|
|
48
|
+
|---|---|---|
|
|
49
|
+
| **Intensity** | more applications = bigger effect | poison, bleed |
|
|
50
|
+
| **Duration** | more applications = longer, same size | slow, weak |
|
|
51
|
+
| **Refresh** | re-apply resets the timer, no stack | most buffs |
|
|
52
|
+
| **Independent** | each application is its own timer | rare; hard to read |
|
|
53
|
+
| **Cap** | stacks up to N, then no-op | keep any of the above bounded |
|
|
54
|
+
|
|
55
|
+
Ambiguous stacking is the #1 status bug. Decide intensity-vs-duration *per effect*
|
|
56
|
+
and cap it — an uncapped intensity DoT trivializes the game (FUN.md law 3).
|
|
57
|
+
|
|
58
|
+
## Tuning levers
|
|
59
|
+
|
|
60
|
+
| Lever | Does | Healthy range |
|
|
61
|
+
|---|---|---|
|
|
62
|
+
| **Tick timing** | when DoT resolves | fixed point in the turn/second; deterministic |
|
|
63
|
+
| **Decay** | how stacks fall off | poison −1/turn keeps it self-limiting |
|
|
64
|
+
| **Cap** | max stacks/intensity | always set one |
|
|
65
|
+
| **Cleanse cost** | price to remove a status | real, so statuses are a threat not a nuisance |
|
|
66
|
+
| **Duration** | turns/seconds it lasts | long enough to matter, short enough to plan around |
|
|
67
|
+
|
|
68
|
+
## How it wires to Hayao
|
|
69
|
+
|
|
70
|
+
- **Status is pure state** on the entity in `world.state` — a `{ id, stacks, turns }`
|
|
71
|
+
list, resolved by a pure tick function; all rolls via `world.rng`. That makes
|
|
72
|
+
clone-and-score bots free (FUN.md law 7): pilot the intended build, assert it beats
|
|
73
|
+
the null build (FUN.md law 2, §11 draft-delta).
|
|
74
|
+
- **Legibility is intent honesty.** A shown "poison 6" must deal exactly 6 over its
|
|
75
|
+
ticks (FUN.md §11 — resolve the telegraph, compare to the number). Audit it.
|
|
76
|
+
- **The tick returns choreography** — the number pop and tint are cosmetic
|
|
77
|
+
(`FloatingText`, `FLOAT_PRESETS`; JUICE Part 1), out of `world.hash()`.
|
|
78
|
+
- No special engine primitive is needed — status is *your* data. Grep [`docs/API.md`](../../docs/API.md)
|
|
79
|
+
before citing; there is no `applyStatus` in the surface, and there shouldn't be.
|
|
80
|
+
|
|
81
|
+
## Fails when…
|
|
82
|
+
|
|
83
|
+
- **Uncapped intensity.** One infinite-scaling DoT becomes the only strategy
|
|
84
|
+
(dominant, [[system-build-diversity]] collapses).
|
|
85
|
+
- **Illegible stacking.** The player can't predict the tick, so they stop planning —
|
|
86
|
+
status becomes noise, not depth.
|
|
87
|
+
- **No counter-play.** A status with no cleanse/resist and a long duration is just
|
|
88
|
+
unfair; give the vocabulary a full loop ([[system-counter-systems]]).
|
|
89
|
+
- **Silent resolution.** Ticks with no pop/tint read as HP randomly draining. Answer
|
|
90
|
+
on ≥ 2 senses (JUICE).
|
|
91
|
+
|
|
92
|
+
## Verify
|
|
93
|
+
|
|
94
|
+
- **[FUN.md §11](../../docs/FUN.md)** — draft/build delta (the status build beats the
|
|
95
|
+
null build); intent honesty (shown status == resolved damage).
|
|
96
|
+
- **[FUN.md law 3](../../docs/FUN.md)** — the cap inequality asserted against config.
|
|
97
|
+
- Determinism: golden hash of a scripted fight with statuses; view-on == view-off.
|
|
98
|
+
- Feel: number pops answer on ≥ 2 senses → **[JUICE.md Part 3](../../docs/JUICE.md)**.
|
|
99
|
+
|
|
100
|
+
## Composes with
|
|
101
|
+
|
|
102
|
+
- [[system-combat-model]] — status is damage/change that resolves over the model's clock.
|
|
103
|
+
- [[system-counter-systems]] — cleanse/resist/immunity are the counter vocabulary.
|
|
104
|
+
- [[system-build-diversity]] — status synergies are a primary source of viable builds.
|
|
105
|
+
- [[system-telegraphs]] — a big incoming debuff should itself telegraph.
|
|
106
|
+
|
|
107
|
+
## See also
|
|
108
|
+
|
|
109
|
+
- [`docs/FUN.md`](../../docs/FUN.md) §11 — deckbuilder draft-delta and intent honesty.
|
|
110
|
+
- [`docs/JUICE.md`](../../docs/JUICE.md) Part 1 — `FloatingText` / `FLOAT_PRESETS` for pops.
|
|
111
|
+
- [[anchor-slay-the-spire]] — the reference for legible, capped, build-defining status.
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: system-tech-tree
|
|
3
|
+
title: Tech Tree — Research Gating & the Ramp of Options
|
|
4
|
+
kind: system
|
|
5
|
+
tags: [tech-tree, research, gating, branch-exclusivity, strategy, unlocks, ramp]
|
|
6
|
+
summary: Research-gated unlocks at the strategy scale; branch exclusivity and a widening ramp of options that shape a whole playthrough's arc.
|
|
7
|
+
use-when: The game unlocks strategic capabilities (units, buildings, abilities) over a session and you need the order and exclusivity of those unlocks to matter.
|
|
8
|
+
composes-with: [system-skill-trees, system-resource-loops, system-economy, system-faction-asymmetry, system-progression]
|
|
9
|
+
anchors: [anchor-age-of-empires, anchor-civilization, anchor-factorio]
|
|
10
|
+
verify-with: docs/FUN.md#9-rts-lite
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Tech Tree — Research Gating & the Ramp of Options
|
|
14
|
+
|
|
15
|
+
**What it is.** A **tech tree** is a **[[system-skill-trees]]** at the *strategy*
|
|
16
|
+
scale: a graph of researchable capabilities — units, buildings, upgrades, ages —
|
|
17
|
+
where each unlock widens what the player can *do*, and prerequisites impose an
|
|
18
|
+
order. Where a skill tree shapes a *character*, a tech tree shapes a *civilization's
|
|
19
|
+
whole arc*.
|
|
20
|
+
|
|
21
|
+
**Player fantasy / why it's fun.** "My tech path is my strategy." The order you
|
|
22
|
+
research is a plan; a well-timed unlock is a power spike (**[[anchor-age-of-empires]]**
|
|
23
|
+
age-ups). The pull is the branch just out of reach — the tech that would answer
|
|
24
|
+
what's beating you.
|
|
25
|
+
|
|
26
|
+
## When to use / when NOT
|
|
27
|
+
|
|
28
|
+
| Use it when | Skip it when |
|
|
29
|
+
|---|---|
|
|
30
|
+
| Strategy is expressed through *what you unlock, when* (RTS, 4X) | The game has a fixed toolset from the start |
|
|
31
|
+
| Build orders and tech timing are a skill | Research would just be a passive timer |
|
|
32
|
+
| You want power spikes to punctuate a long session | Sessions are too short to ramp options |
|
|
33
|
+
|
|
34
|
+
The tech tree is the RTS/4X engine of **[[pattern-pacing-and-tension]]**: each age
|
|
35
|
+
or era is a plateau, each unlock a spike. If unlocks don't create *timing decisions*
|
|
36
|
+
(rush this or bank for that?), you have a checklist, not a tree.
|
|
37
|
+
|
|
38
|
+
## Variants
|
|
39
|
+
|
|
40
|
+
| Variant | Structure | The decision is | Example |
|
|
41
|
+
|---|---|---|---|
|
|
42
|
+
| **Age/era gates** | Discrete tiers; advance to unlock a bracket | *When* to age up (spike vs eco) | AoE ages; Civ eras |
|
|
43
|
+
| **Prerequisite web** | Deep dependency graph | *Route* through the tree | Civ tech web; Factorio science |
|
|
44
|
+
| **Exclusive branches** | Pick a path, lock the other | *Identity/commitment* | Civ policy trees; StarCraft tech choices |
|
|
45
|
+
| **Cost-gated flat** | No prereqs, priced by power | *Priority* | Simple upgrade shops |
|
|
46
|
+
| **Faction trees** | Different tree per faction | *Asymmetric strategy* | See [[system-faction-asymmetry]] |
|
|
47
|
+
|
|
48
|
+
## Tuning levers
|
|
49
|
+
|
|
50
|
+
| Lever | What it controls | Healthy range / rule |
|
|
51
|
+
|---|---|---|
|
|
52
|
+
| **Tier/age spacing** | Time between power spikes | Long enough to *feel* the plateau, short enough to keep momentum |
|
|
53
|
+
| **Branch exclusivity** | Whether a path costs another | Some branches exclusive, or every game converges to the same tech |
|
|
54
|
+
| **Research cost curve** | The ramp of options | Rising cost per tier; but each tier's *value* must rise with it |
|
|
55
|
+
| **Gate depth** | Prereqs before a payoff tech | Shallow — burying the fun behind filler tech is grind |
|
|
56
|
+
| **Counter-availability** | Can you tech *into* an answer? | Yes — a tech tree is where RTS counters live; every threat needs a reachable response |
|
|
57
|
+
| **Snowball vs comeback** | Does a tech lead compound? | Add catch-up / comeback techs, or leaders run away ([[pattern-feedback-loops]]) |
|
|
58
|
+
|
|
59
|
+
## How it wires to Hayao
|
|
60
|
+
|
|
61
|
+
- **The tree is a data graph + pure logic.** Nodes (`id, cost, prereqs, unlocks`)
|
|
62
|
+
in `world.state`; researching is an **input action** that spends resources and
|
|
63
|
+
flips availability flags; unit/ability availability is pure logic reading those
|
|
64
|
+
flags. So a *build order* is a reproducible input script a bot can pilot
|
|
65
|
+
(**[[FUN.md law 7]]**).
|
|
66
|
+
- **Strategy is the balance test.** The RTS truth (**[[FUN.md §9]]**): the intended
|
|
67
|
+
line (e.g. turtle → tech → counterpush) must *beat* a naive line (attack-move /
|
|
68
|
+
one-tech rush). Pilot both, assert the delta — that's your proof the tech
|
|
69
|
+
choices matter (law 2).
|
|
70
|
+
- **Counters must be reachable.** Every enemy threat needs a tech-reachable answer;
|
|
71
|
+
assert it the way tower-defense proves counter duels from both sides
|
|
72
|
+
(**[[FUN.md §8]]**) and RTS proves every counter edge wins its NvN
|
|
73
|
+
(**[[FUN.md §9]]**).
|
|
74
|
+
- **The tech panel is chrome** — `showScreen()` DOM; the research *state* is sim
|
|
75
|
+
(CLAUDE.md invariant 4). Generate/ramp the option-unlock curve as content
|
|
76
|
+
(`src/content/`, `assertRamp`).
|
|
77
|
+
|
|
78
|
+
## Fails when…
|
|
79
|
+
|
|
80
|
+
- **A dominant path.** One tech order is always best; the tree collapses to a line.
|
|
81
|
+
Skill-delta between *paths* should be small; each viable path should beat null.
|
|
82
|
+
- **Unreachable counters.** A threat with no tech answer is unfair — the RTS/TD
|
|
83
|
+
counter proof fails from one side.
|
|
84
|
+
- **Filler gating.** Dead prereq techs padding the route to the good one — grind.
|
|
85
|
+
- **Runaway snowball.** A tech lead that compounds into an unbeatable lead with no
|
|
86
|
+
comeback tech ([[pattern-feedback-loops]]).
|
|
87
|
+
- **Spikes with no plateau.** Constant unlocks = no pacing; the age-up thrill needs
|
|
88
|
+
the plateau before it.
|
|
89
|
+
|
|
90
|
+
## Verify
|
|
91
|
+
|
|
92
|
+
- Intended tech line beats naive line (strategy is the test): **[[FUN.md §9]]**,
|
|
93
|
+
law 2.
|
|
94
|
+
- Every counter edge wins its duel, both sides: **[[FUN.md §9]]** (RTS) /
|
|
95
|
+
**[[FUN.md §8]]** (TD).
|
|
96
|
+
- Build order as a reproducible pilot: **[[FUN.md law 7]]**.
|
|
97
|
+
- Option ramp shape as a test: `assertRamp`/`rampIssues` over the unlock curve.
|
|
98
|
+
|
|
99
|
+
## Composes with
|
|
100
|
+
|
|
101
|
+
- [[system-skill-trees]] — the same graph shape at the character scale.
|
|
102
|
+
- [[system-resource-loops]] — research consumes the production chain's output.
|
|
103
|
+
- [[system-economy]] — research points/cost are a currency and a sink.
|
|
104
|
+
- [[system-faction-asymmetry]] — different trees are a core asymmetry lever.
|
|
105
|
+
- [[system-counter-systems]] — the tree is where reachable counters live.
|
|
106
|
+
- [[pattern-pacing-and-tension]] — ages/eras are the plateau-and-spike engine.
|
|
107
|
+
|
|
108
|
+
## See also
|
|
109
|
+
|
|
110
|
+
- [`docs/FUN.md`](../../docs/FUN.md) §9 (RTS strategy-as-test) · §8 (counter duels)
|
|
111
|
+
— the tech-tree proofs.
|
|
112
|
+
- **[[anchor-age-of-empires]]** (age spikes) · **[[anchor-civilization]]** (deep web).
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: system-telegraphs
|
|
3
|
+
title: Telegraphs — readable threat
|
|
4
|
+
kind: system
|
|
5
|
+
tags: [telegraph, tells, windup, readability, reaction, threat, combat]
|
|
6
|
+
summary: The wind-up that makes a threat readable — every hitbox announces itself long enough to react, and the tell is stored as a direction, not a guess.
|
|
7
|
+
use-when: Any threat can hurt the player in real time or resolve on a turn; you need the danger to be reactable, not a surprise.
|
|
8
|
+
composes-with: [system-combat-model, system-boss-design, system-enemy-ai, system-grace, pattern-readability]
|
|
9
|
+
anchors: [anchor-into-the-breach, anchor-shadow-of-mordor]
|
|
10
|
+
verify-with: docs/FUN.md#4-top-down-action-adventure-zelda-like
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Telegraphs — readable threat
|
|
14
|
+
|
|
15
|
+
**What it is.** The **tell**: the flash, wind-up, or warning tile that fires *before*
|
|
16
|
+
a threat can hurt you, giving a window to react. A telegraph is the contract that
|
|
17
|
+
makes reactive play possible — without it, damage is a dice roll disguised as a
|
|
18
|
+
fight. It is the readable half of every [[system-combat-model]].
|
|
19
|
+
|
|
20
|
+
**Player fantasy / why it's fun.** "I saw it coming and I moved." Every dodged blow
|
|
21
|
+
is the player's skill, not the game's mercy. A death after a telegraph is *fair* —
|
|
22
|
+
you read it or you didn't; a death with no telegraph is the designer's fault.
|
|
23
|
+
|
|
24
|
+
## When to use / when NOT
|
|
25
|
+
|
|
26
|
+
| Telegraph when… | Skip when… |
|
|
27
|
+
|---|---|
|
|
28
|
+
| A threat can kill/hurt in real time | Damage is player-initiated only (you hit them) |
|
|
29
|
+
| Perfect information is the promise (tactics) | The threat is a slow, always-visible hazard (lava) |
|
|
30
|
+
| A boss/elite has committal, punishable moves | The genre's fun is *not* reacting (idle, puzzle) |
|
|
31
|
+
|
|
32
|
+
Turn-based games still telegraph — they just do it as **shown intent on the board**
|
|
33
|
+
(the arrow, the highlighted tiles), not a timed flash.
|
|
34
|
+
|
|
35
|
+
## Variants
|
|
36
|
+
|
|
37
|
+
| Telegraph | Channel | Window | Anchor | Note |
|
|
38
|
+
|---|---|---|---|---|
|
|
39
|
+
| **Flash / color wind-up** | visual | ~0.45s (§4) | Zelda-likes | the default reactive tell |
|
|
40
|
+
| **Wind-up animation** | visual | scales to move weight | brawlers, [[anchor-shadow-of-mordor]] | big moves telegraph longer |
|
|
41
|
+
| **Audio cue** | audio | leads the visual | rhythm, horror | a growl before the lunge |
|
|
42
|
+
| **Ground marker / AoE** | visual | fills over the window | ARPGs, bosses | the red circle grows, then fires |
|
|
43
|
+
| **Shown intent (turn)** | visual, static | until next turn | [[anchor-into-the-breach]] | the arrow you rewrite |
|
|
44
|
+
| **Charge / meter** | visual | fills to threshold | bosses | commit-punish window |
|
|
45
|
+
|
|
46
|
+
## Tuning levers
|
|
47
|
+
|
|
48
|
+
| Lever | Does | Healthy range |
|
|
49
|
+
|---|---|---|
|
|
50
|
+
| **Reaction window** | telegraph frames before the hitbox | **~0.45s** flash floor (FUN.md §4); scale up for heavier moves |
|
|
51
|
+
| **Salience** | how loud the tell reads | brightest thing after the avatar (JUICE salience gate) |
|
|
52
|
+
| **Recovery** | punish window after the move whiffs | long enough to answer; short enough to stay dangerous |
|
|
53
|
+
| **Overlap budget** | simultaneous telegraphs | few enough that each still reads (bullet-hell coherence, §7) |
|
|
54
|
+
| **Channels** | senses the tell fires on | ≥ 2 for the big ones (sfx + flash) |
|
|
55
|
+
|
|
56
|
+
The window is a **derived inequality** (FUN.md law 3): reaction window ≥ human
|
|
57
|
+
reaction floor + the frames the dodge costs. Don't vibe it — compute it.
|
|
58
|
+
|
|
59
|
+
## How it wires to Hayao
|
|
60
|
+
|
|
61
|
+
- **The gate is real.** `telegraphIssues(timeline, minFrames)` (in `@hayao`) walks a
|
|
62
|
+
per-frame `TelegraphFrame[]` (`{ telegraphing, active }`) and flags any hitbox that
|
|
63
|
+
goes live after fewer than `minFrames` of contiguous wind-up. This is the direct
|
|
64
|
+
proof that reactive play is possible.
|
|
65
|
+
- **Store tells as DIRECTIONS, not target tiles.** FUN.md §12: a tactics telegraph is
|
|
66
|
+
a *direction on the unit*, so a shove/redirect rewrites the outcome for free — the
|
|
67
|
+
future is editable, which is the whole fun of the genre. Encode the intent, resolve
|
|
68
|
+
it late.
|
|
69
|
+
- **The tell is cosmetic; the timing is sim time.** The flash/marker are view; the
|
|
70
|
+
*window* is `world.time` and fixed `dt` (FUN.md law 6). Wire the flash to the sim
|
|
71
|
+
event, never to wall-clock — a replay reproduces the exact tell.
|
|
72
|
+
- Reference: the top-down §4 pattern (kiting bot reads flashes); [[anchor-into-the-breach]]
|
|
73
|
+
DNA for shown-intent telegraphs.
|
|
74
|
+
|
|
75
|
+
## Fails when…
|
|
76
|
+
|
|
77
|
+
- **No wind-up.** A hitbox that goes live cold is an unfair death — `telegraphIssues`
|
|
78
|
+
fails and it *should*.
|
|
79
|
+
- **The tell is illegible.** Too dim, too brief, or buried under five other flashes.
|
|
80
|
+
If the salience gate can't find it, neither can the player ([[pattern-readability]]).
|
|
81
|
+
- **The telegraph lies.** The flash points left, the hit lands right. Perfect
|
|
82
|
+
information demands perfect honesty (FUN.md §12) — shown must equal resolved.
|
|
83
|
+
- **Uniform windows.** Every move telegraphs 0.45s regardless of weight, so nothing
|
|
84
|
+
reads as *scary*. Scale the tell to the threat.
|
|
85
|
+
|
|
86
|
+
## Verify
|
|
87
|
+
|
|
88
|
+
- **[FUN.md §4](../../docs/FUN.md)** — ~0.45s flash makes reactive play possible;
|
|
89
|
+
kiting-bot telemetry with an hp floor.
|
|
90
|
+
- **[FUN.md §12](../../docs/FUN.md)** — telegraphs as directions; intent honesty
|
|
91
|
+
(resolve each telegraph, compare to the shown number/arrow).
|
|
92
|
+
- `telegraphIssues(timeline, minFrames)` → **[VERIFICATION Channel 4](../../docs/VERIFICATION.md)**.
|
|
93
|
+
- Salience: `salienceIssues` proves the tell out-contrasts scenery (JUICE Part 2/3).
|
|
94
|
+
|
|
95
|
+
## Composes with
|
|
96
|
+
|
|
97
|
+
- [[system-combat-model]] — the telegraph is the reactive half of the resolution rule.
|
|
98
|
+
- [[system-boss-design]] — bosses live or die on legible, escalating tells across phases.
|
|
99
|
+
- [[system-enemy-ai]] — the AI must *commit* to a telegraphed move, not cancel it.
|
|
100
|
+
- [[pattern-readability]] — signposting and salience are how a tell gets read.
|
|
101
|
+
|
|
102
|
+
## See also
|
|
103
|
+
|
|
104
|
+
- [`docs/FUN.md`](../../docs/FUN.md) §4 (flash window), §7 (pattern coherence), §12 (directions).
|
|
105
|
+
- [`docs/JUICE.md`](../../docs/JUICE.md) — salience gate; the avatar/threat contrast floor.
|
|
106
|
+
- [`src/verify/gates.ts`](../../src/verify/gates.ts) — `telegraphIssues`, `TelegraphFrame`.
|