gamedev-skills/awesome-gamedev-agent-skills已通过检查
SKILL DETAIL
rpg
gamedev-skills/awesome-gamedev-agent-skills/rpg
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.
安装量 · 292查看来源
Installation
npx skills add https://github.com/gamedev-skills/awesome-gamedev-agent-skills --skill rpg
技能文件
SKILL.md
最近同步 · 2026年10月22日
references/stats-combat-quests.md›
# RPG stats, combat, and quests (depth)
Formulas and data shapes behind `SKILL.md`. Engine-neutral pseudocode. Treat every number
as a starting point to tune against playtests, not a law.
## 1. Stat block: base, derived, and modifiers
Separate **base** attributes from **derived** combat stats so a single attribute change
ripples predictably, and keep **modifiers** in their own layer so buffs/equipment are
reversible without corrupting base values.
```python
# Base attributes (what leveling/allocation changes)
base = { "STR": 10, "AGI": 10, "INT": 10, "VIT": 10 }
# Derived stats are pure functions of base (+ modifiers). Recompute; never store as truth.
def derive(base, mods):
s = sum_layers(base, mods) # base + flat + percent modifiers
return {
"max_hp": 20 + s["VIT"] * 8,
"attack": s["STR"] * 2,
"defense": s["VIT"] * 1 + s["AGI"] * 0.5,
"crit": min(0.05 + s["AGI"] * 0.005, 0.50), # cap it
"speed": s["AGI"],
}
```
Modifier layers (apply in this order): **base → flat adds → percent multipliers → clamp**.
Equipping an item pushes a modifier; unequipping pops the same one. This avoids the classic
"buff wore off and left me at the wrong HP" bug.
## 2. Damage formulas
Two common families — pick one and stay consistent:
```python
# (a) Subtractive: defense flatly reduces damage. Simple; high defense can trivialize hits.
dmg = max(1, attacker.attack - defender.defense) # floor at 1 so nothing is immune
# (b) Ratio/mitigation: defense gives diminishing % reduction. Scales smoothly to high numbers.
mitigation = defender.defense / (defender.defense + K) # K ~ 100; tune the curve
dmg = attacker.attack * (1 - mitigation)
# Layer on: random variance (±10%), crit multiplier, and type effectiveness.
dmg *= rng.range(0.9, 1.1)
if is_crit: dmg *= 1.5
dmg *= type_multiplier(attacker.element, defender.element) # 0.5 / 1.0 / 2.0
```
Subtractive feels "tactical" at low numbers; ratio scales better for big late-game values.
## 3. Leveling curves
XP-to-next-level shapes the whole pace. Three common curves:
```python
# Linear-ish (gentle): next = base * level
# Quadratic (classic JRPG):next = base * level^2
# Exponential (steep): next = base * growth^level # growth ~1.2–1.5
def xp_to_next(level, base=100, kind="quadratic", growth=1.3):
if kind == "linear": return base * level
if kind == "quadratic": return base * level * level
if kind == "exponential": return int(base * (growth ** level))
```
Guidance: keep early levels fast (reward in minutes) and stretch later ones. Grant stat gains
and/or skill points on level-up; telegraph the next unlock to pull players forward.
## 4. Turn-based vs. action combat timelines
| | Turn-based | Action |
|---|---|---|
| Time | Discrete; pause to choose | Real-time; reflexes matter |
| Initiative | Speed stat / ATB gauge orders turns | Cooldowns / attack timing |
| Strength | Deep tactics, accessible | Visceral, skill-expressive |
| Build with | A turn scheduler (see `roguelike` Pattern 2) | The engine movement/physics skill |
ATB ("active time battle") is a hybrid: a gauge fills by `speed`; when full, the actor may act.
## 5. Inventory and equipment data
```python
# Items are data, not code. Define them as resources/assets (see godot-resources /
# unity-scriptableobjects) and reference by id.
item = {
"id": "iron_sword", "name": "Iron Sword", "slot": "weapon",
"stackable": False, "max_stack": 1,
"modifiers": [ {"stat": "STR", "type": "flat", "value": 3} ],
"value": 50,
}
# Inventory = list of (item_id, count). Equipment = slot -> item_id.
# Equipping applies the item's modifiers (push); unequipping removes them (pop).
```
## 6. Quest state model
```python
# A quest is a small state machine with objectives. Persist its state in the save.
quest = {
"id": "missing_cat", "state": "available", # available -> active -> complete -> turned_in
"objectives": [ {"id": "find_cat", "done": False, "count": 0, "needed": 1} ],
"rewards": { "xp": 150, "gold": 30, "items": ["iron_sword"] },
}
# Game events (kill, pickup, talk) update matching objectives; when all done, state=complete.
# Dialogue conditions read quest state; turning in grants rewards and advances dependent quests.
```
Keep quest *definitions* as data and quest *progress* in the save. Gate dialogue lines and
NPC behavior on quest state via `dialogue-systems` conditions/variables.
SKILL.md›
---
name: rpg
description: >
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.
---
# 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
1. **Stats + leveling** — base attributes, derived combat stats, XP curve, level-up gains.
2. **Inventory + equipment** — data-defined items, stacking, slots, stat modifiers.
3. **Combat** — turn-based or action; damage formula, status effects, win/loss.
4. **Quests** — objectives, state machine (available→active→complete→turned-in), rewards.
5. **Dialogue** — branching lines, conditions on game state, choices that matter.
6. **Save/load** — persist character, inventory, quest progress, world flags, with versioning.
7. **Economy + progression gating** — gold/shops; gate power behind level/quest/region.
8. **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)
```python
# 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
```python
# 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
```python
# 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`.