@kiberon-labs/quests
v1.0.2
Published
Composable graph-grammar modules for grounded, procedural quest generation — 14 archetypes, branching, and a corpus of world-matched beats.
Maintainers
Readme
@kiberon-labs/quests
Generate side quests that read like a designer wrote them, without hand-authoring thousands of them.
Most procedural quests are filler. Go somewhere, fetch a thing, come back. Players spot the pattern fast, and the quest never touches the wider world. This library takes the harder route. It builds quests as graph grammars (rewrite rules over a graph) and grounds every one in your live world state. A "slay" quest becomes a foe that is already menacing a giver who already wants it gone, with complications drawn from relationships that exist. The result reads authored, and no one hand-wrote it.
You get 14 quest archetypes (rescue, fetch, slay, heist, escort, and more) and a corpus of composable beats: small rules that match real world state and add branches, skill checks, rival NPCs, and concrete world changes.
What this is, and what it is not
It is a usable library and a worked reference. Install it, generate quests, read the graphs. It ships a demo world, so quests come out grounded and coherent from the first run.
It will not model your game one to one. Quest logic binds to a game's specific mechanics, so no corpus drops in unchanged. That is why the package is composable. The archetypes and beats are independent, you pull in the ones that fit, and you ground the rest in your own mechanics. Where a module is not an exact fit, take the idea and extend it.
It does not replace handmade quests. A designer with a specific idea still wins on the set piece a whole game bends around. This raises the floor instead. It keeps the "always something to do" layer alive and interactive, at a fraction of the authoring cost.
Install
npm install @kiberon-labs/quests graph-grammargraph-grammar is the engine that runs the grammars. Install it alongside.
Use it two ways
1. Compose in TypeScript
Pick an archetype, compose it with the layers that fit it, and run it into a quest graph:
import { composeQuest, coreFor } from '@kiberon-labs/quests'
// Pass a seed for a reproducible quest; omit it for a different one each call.
const quest = composeQuest(coreFor('heist'), 42)
// quest.nodes / quest.edges: a grounded quest graph (Steps, Choices, an End, and the
// world entities the quest binds to). Walk it from the Start to drive your game's side
// effects: spawn entities, set flags, present exposition.
console.log(quest.nodes.length, quest.edges.length)Want the runnable grammar instead of a finished graph (to pick a strategy, or generate the quest as the player arrives at each beat)?
import { composeGrammar, coreFor } from '@kiberon-labs/quests'
import { Engine } from 'graph-grammar'
const engine = new Engine(composeGrammar(coreFor('slay')))
engine.run()
console.log(engine.graph)Inspect the library, or pick a subset of layers, through the registry:
import { REGISTRY, modulesForCore, QUEST_ARCHETYPES } from '@kiberon-labs/quests'
QUEST_ARCHETYPES // the 14 archetypes
REGISTRY // every core and beat, with its key, folder, and capability requirements
modulesForCore('rescue') // the layers that compose onto a rescue2. Load a pre-built JSON grammar
Every archetype also ships as a compiled grammar JSON. Run it with the engine and nothing else from this package:
import { Engine, importGrammar } from 'graph-grammar'
import heist from '@kiberon-labs/quests/grammars/heist.grammar.json' with { type: 'json' }
const engine = new Engine(importGrammar(heist))
engine.run()
console.log(engine.graph) // a generated heist questThe grammars live at @kiberon-labs/quests/grammars/<archetype>.grammar.json for compete, defend, escape, escort, explore, fetch, heist, hunt, investigate, negotiate, provision, rescue, slay, and survive. The raw per-beat data (one JSON per beat, plus index.json and manifest.json) is under @kiberon-labs/quests/data/*.
3. Author your own beats
The module DSL is exported, so you can write beats that match your world and mechanics and compose them beside (or instead of) the built-in ones:
import { matchModule } from '@kiberon-labs/quests'The integration guide covers the full DSL.
How it is organized
Modules live in src/modules/, grouped by the quest stage they act on (the number prefix is load order):
| Folder | Provides |
| ------------------------------- | --------------------------------------------------------------------- |
| 0-core | The seeded quest archetypes (rescue, fetch, slay, escort, heist, …) |
| 1-exposition … 7-denouement | Per-stage beats that fill out the quest |
| 8-structure | Cross-cutting structure: branches, prerequisites, parallel objectives |
A core lays down the spine. The stage and structure beats then compete (weighted-random) to fill it in, so each run produces a different quest, and rare, world-gated beats surface now and then to break the pattern.
Documentation
Start with the docs. They cover why the system works this way, both integration paths in depth, and the archetype reference: gg.kiberonlabs.com → Quests.
- The quest generation system: the design reasoning.
- Integrate quests into your game: both integration paths in depth.
- Quest archetypes and exports: the reference.
License
MIT © Kiberon Labs
