RPG
A playbook for role-playing games — stats and progression, inventory/equipment, quests,
dialogue, and combat. This is a compositional skill: it ties data-driven content,
dialogue, and saving together. It does not re-teach those primitives; it defines the systems
that make growth and choice feel meaningful, and points to the skills that implement each.
When to use
- Use when building an RPG/JRPG/action-RPG: the player has stats that grow, an
inventory, quests, dialogue, and persistent progress.
- Use when designing a leveling curve, a damage formula, an inventory/equipment model, or a
quest state machine.
When not to use: permadeath dungeon runs with no persistent character → roguelike.
Pure conversation/branching story → visual-novel. Open-world needs/crafting/base-building →
survival-crafting. For the dialogue engine itself, use dialogue-systems.
Core loop
Explore → encounter (fight / talk / solve) → earn rewards (XP, loot, story) → grow
(level up, gear up, unlock) → take on harder content. The fantasy is getting stronger and
shaping who your character is; every system should feed that growth-and-choice loop.
Must-have systems
- Stats + leveling — base attributes, derived combat stats, XP curve, level-up gains.
- Inventory + equipment — data-defined items, stacking, slots, stat modifiers.
- Combat — turn-based or action; damage formula, status effects, win/loss.
- Quests — objectives, state machine (available→active→complete→turned-in), rewards.
- Dialogue — branching lines, conditions on game state, choices that matter.
- Save/load — persist character, inventory, quest progress, world flags, with versioning.
- Economy + progression gating — gold/shops; gate power behind level/quest/region.
- UI — HUD, inventory, quest log, dialogue box, character sheet.
Design knobs
| Knob |
Effect |
Notes |
| XP curve shape |
pacing of power |
Fast early, slow late (see refs). |
| Stat→derived scaling |
build diversity |
One attribute shouldn't dominate. |
| Damage formula |
tactical feel |
Subtractive vs. ratio mitigation (refs). |
| Random variance / crit |
swinginess |
±10% and ~1.5× crit are safe defaults. |
| Drop rates / economy |
reward cadence |
Avoid trivializing shops with loot. |
| Power gating |
difficulty gating |
Level/region/quest locks. |
| Reversible modifiers |
buff/gear correctness |
Layer mods; never edit base stats. |
| Choice consequence |
role-play weight |
Quest/dialogue flags should branch outcomes. |
Patterns
1. Derived stats from base attributes (recompute, never store as truth)
# Pseudocode. Base attributes are the only "truth"; combat stats are derived each time.
def derive(base, mods):
s = apply_modifiers(base, mods) # base + flat adds + percent, then clamp
return {
"max_hp": 20 + s["VIT"] * 8,
"attack": s["STR"] * 2,
"defense": s["VIT"] + s["AGI"] * 0.5,
}
# Equipping pushes a modifier; unequipping pops it. HP/attack recompute automatically.
2. XP curve + level-up
# Pseudocode. Quadratic curve: fast early levels, long late ones.
def xp_to_next(level, base=100): return base * level * level
def gain_xp(actor, amount):
actor.xp += amount
while actor.xp >= xp_to_next(actor.level):
actor.xp -= xp_to_next(actor.level)
actor.level += 1
actor.base["STR"] += 2; actor.base["VIT"] += 2 # grant gains / skill points
on_level_up(actor) # heal, unlock, notify
3. Quest objective update driven by game events
# Pseudocode. Game events advance matching objectives; completion grants rewards.
def on_event(kind, data):
for q in active_quests:
for obj in q.objectives:
if obj.event == kind and matches(obj, data) and not obj.done:
obj.count += 1
if obj.count >= obj.needed: obj.done = True
if all(o.done for o in q.objectives):
q.state = "complete" # turn-in grants xp/gold/items
Pitfalls / failure modes
- Editing base stats for buffs/gear → values drift and corrupt on save/reload. Keep a
modifier layer; push/pop it (Pattern 1).
- Storing derived stats as truth → desync after a stat change. Recompute from base.
- Runaway XP/damage numbers → either an exponential curve with no cap or a subtractive
formula at huge values. Pick a curve and a formula family deliberately (refs).
- Content as code → every item/quest hardcoded. Define items, enemies, and quests as
data (
godot-resources / unity-scriptableobjects).
- Save format with no version field → old saves break on update. Add a
version and a
migration path from day one (see save-systems).
- Choices without consequences → dialogue branches that reconverge immediately feel hollow.
Set flags that actually change later quests/world state.
- Quest progress not persisted → reloading loses mid-quest state. Save quest state, not
just completion.
Composition (build it from these skills)
- Dialogue:
dialogue-systems (Yarn Spinner / Ink) — branching lines, conditions, variables.
- Persistence:
save-systems — character, inventory, quest flags, world state, versioning.
- Content data:
godot-resources / unity-scriptableobjects — items, enemies, quests, skills as assets.
- Combat AI:
game-ai for enemy behavior; for turn order reuse the scheduler idea in roguelike.
- UI:
game-ui-ux for HUD/menu layout, resolution scaling, and controller/keyboard nav; godot-ui-control for the concrete inventory, quest log, character sheet, and dialogue box.
- World:
level-design plus your engine's tilemap/3D skill (godot-tilemap, godot-3d-essentials).
References
- For stat/damage formulas, leveling curves, turn-vs-action combat timelines, inventory/equipment
data shapes, and the quest state model, read
references/stats-combat-quests.md.
1---2name: rpg3description: Build an RPG: stats and leveling, inventory and equipment, quests, branching dialogue, save/load, and combat. Use for an RPG/JRPG, or designing stat, inventory, quest, or combat systems.4---5
6# RPG
7
8A playbook for role-playing games — stats and progression, inventory/equipment, quests,
9dialogue, and combat. This is a **compositional** skill: it ties data-driven content,
10dialogue, and saving together. It does not re-teach those primitives; it defines the systems
11that make growth and choice feel meaningful, and points to the skills that implement each.
12
13## When to use
14
15- Use when building an RPG/JRPG/action-RPG: the player has **stats that grow**, an
16 **inventory**, **quests**, **dialogue**, and persistent progress.
17- Use when designing a leveling curve, a damage formula, an inventory/equipment model, or a
18 quest state machine.
19
20**When *not* to use:** permadeath dungeon runs with no persistent character → `roguelike`.
21Pure conversation/branching story → `visual-novel`. Open-world needs/crafting/base-building →
22`survival-crafting`. For the dialogue engine itself, use `dialogue-systems`.
23
24## Core loop
25
26**Explore → encounter (fight / talk / solve) → earn rewards (XP, loot, story) → grow
27(level up, gear up, unlock) → take on harder content.** The fantasy is *getting stronger and
28shaping who your character is*; every system should feed that growth-and-choice loop.
29
30## Must-have systems
31
321. **Stats + leveling** — base attributes, derived combat stats, XP curve, level-up gains.
332. **Inventory + equipment** — data-defined items, stacking, slots, stat modifiers.
343. **Combat** — turn-based or action; damage formula, status effects, win/loss.
354. **Quests** — objectives, state machine (available→active→complete→turned-in), rewards.
365. **Dialogue** — branching lines, conditions on game state, choices that matter.
376. **Save/load** — persist character, inventory, quest progress, world flags, with versioning.
387. **Economy + progression gating** — gold/shops; gate power behind level/quest/region.
398. **UI** — HUD, inventory, quest log, dialogue box, character sheet.
40
41## Design knobs
42
43| Knob | Effect | Notes |
44|------|--------|-------|
45| XP curve shape | pacing of power | Fast early, slow late (see refs). |
46| Stat→derived scaling | build diversity | One attribute shouldn't dominate. |
47| Damage formula | tactical feel | Subtractive vs. ratio mitigation (refs). |
48| Random variance / crit | swinginess | ±10% and ~1.5× crit are safe defaults. |
49| Drop rates / economy | reward cadence | Avoid trivializing shops with loot. |
50| Power gating | difficulty gating | Level/region/quest locks. |
51| Reversible modifiers | buff/gear correctness | Layer mods; never edit base stats. |
52| Choice consequence | role-play weight | Quest/dialogue flags should branch outcomes. |
53
54## Patterns
55
56### 1. Derived stats from base attributes (recompute, never store as truth)
57
58```python
59# Pseudocode. Base attributes are the only "truth"; combat stats are derived each time.
60def derive(base, mods):
61 s = apply_modifiers(base, mods) # base + flat adds + percent, then clamp
62 return {
63 "max_hp": 20 + s["VIT"] * 8,
64 "attack": s["STR"] * 2,
65 "defense": s["VIT"] + s["AGI"] * 0.5,
66 }
67# Equipping pushes a modifier; unequipping pops it. HP/attack recompute automatically.
68```
69
70### 2. XP curve + level-up
71
72```python
73# Pseudocode. Quadratic curve: fast early levels, long late ones.
74def xp_to_next(level, base=100): return base * level * level
75
76def gain_xp(actor, amount):
77 actor.xp += amount
78 while actor.xp >= xp_to_next(actor.level):
79 actor.xp -= xp_to_next(actor.level)
80 actor.level += 1
81 actor.base["STR"] += 2; actor.base["VIT"] += 2 # grant gains / skill points
82 on_level_up(actor) # heal, unlock, notify
83```
84
85### 3. Quest objective update driven by game events
86
87```python
88# Pseudocode. Game events advance matching objectives; completion grants rewards.
89def on_event(kind, data):
90 for q in active_quests:
91 for obj in q.objectives:
92 if obj.event == kind and matches(obj, data) and not obj.done:
93 obj.count += 1
94 if obj.count >= obj.needed: obj.done = True
95 if all(o.done for o in q.objectives):
96 q.state = "complete" # turn-in grants xp/gold/items
97```
98
99## Pitfalls / failure modes
100
101- **Editing base stats for buffs/gear** → values drift and corrupt on save/reload. Keep a
102 modifier layer; push/pop it (Pattern 1).
103- **Storing derived stats as truth** → desync after a stat change. Recompute from base.
104- **Runaway XP/damage numbers** → either an exponential curve with no cap or a subtractive
105 formula at huge values. Pick a curve and a formula family deliberately (refs).
106- **Content as code** → every item/quest hardcoded. Define items, enemies, and quests as
107 **data** (`godot-resources` / `unity-scriptableobjects`).
108- **Save format with no version field** → old saves break on update. Add a `version` and a
109 migration path from day one (see `save-systems`).
110- **Choices without consequences** → dialogue branches that reconverge immediately feel hollow.
111 Set flags that actually change later quests/world state.
112- **Quest progress not persisted** → reloading loses mid-quest state. Save quest state, not
113 just completion.
114
115## Composition (build it from these skills)
116
117- **Dialogue:** `dialogue-systems` (Yarn Spinner / Ink) — branching lines, conditions, variables.
118- **Persistence:** `save-systems` — character, inventory, quest flags, world state, versioning.
119- **Content data:** `godot-resources` / `unity-scriptableobjects` — items, enemies, quests, skills as assets.
120- **Combat AI:** `game-ai` for enemy behavior; for turn order reuse the scheduler idea in `roguelike`.
121- **UI:** `game-ui-ux` for HUD/menu layout, resolution scaling, and controller/keyboard nav; `godot-ui-control` for the concrete inventory, quest log, character sheet, and dialogue box.
122- **World:** `level-design` plus your engine's tilemap/3D skill (`godot-tilemap`, `godot-3d-essentials`).
123
124## References
125
126- For stat/damage formulas, leveling curves, turn-vs-action combat timelines, inventory/equipment
127 data shapes, and the quest state model, read `references/stats-combat-quests.md`.