Quests
Edit tabs/quests.json.
Required Fields
| Field | Requirement |
|---|---|
name | Must match object key exactly |
questSource | Where the quest originates (NPC name, location, object) |
questStatement | One-sentence description of the situation |
mainObjective | What the player must accomplish (shown in quest log) |
completionCondition | Semantic query text for auto-trigger completion detection |
questDesignBrief | 2-4 sentence internal design guidance for the AI — drives NPC, location, and trigger generation for this quest |
detailType | basic for AI-generated locations, detailed for specific locations |
Conditional Fields
| Field | When to Include |
|---|---|
spatialRelationship | Required when detailType: 'basic' - defines where quest takes place |
questLocation | Required when detailType: 'detailed' - key from locations.json |
questGiverNPC | Only when a specific NPC gives the quest |
Never Include
Omit these fields (auto-set or runtime-only):
id,creationTick,status,detectionTick,acceptedTickexpiryTick,completedTick,abandonedTick,rejectedTickstartingArea,connectingAreaName,questAreasquestStepPhase,hasVisitedLocation,hasVisitedStartingArea,objectiveCompletedofferedAtLocation,questGiverNPCKey,arcQuestOrdinalconclusive,arcId,arcEscalationAtCreation
detailType Selection
| Type | Use When | Location Handling |
|---|---|---|
basic | Quest location should be AI-generated | Uses spatialRelationship to generate dynamically |
detailed | Quest has a specific predefined location | Uses exact questLocation from locations.json |
Use detailed for hand-crafted narrative quests. Use basic for procedural or emergent quests.
spatialRelationship Values
For basic quests only - defines where the AI generates the quest location:
| Value | Description |
|---|---|
existingLocalArea | Current location, existing area |
newLocalArea | Current location, new area created |
nearbyNewLocation | New location generated nearby |
distantNewLocation | New location generated far away |
existingLocationNewAreas | Existing location, new areas added |
mainObjective Format
Write as a player action in imperative form. Shown in the quest log UI.
Format: “[Verb] the [target]” or “[Verb] [what] from/in/at [where]”
completionCondition Format
The semantic text the trigger system matches against the story to detect quest completion. Write as a natural-language description of what “done” looks like.
If left empty, no auto-trigger is generated.
questStatement Format
One sentence describing the situation that creates the quest.
Format: “[Subject] [situation that creates urgency or motivation]”
Making Quests Available
Quests always start as hidden. To make them available:
Via Story Start (recommended for starting quests):
"storyStarts": {
"adventure": {
"startingQuests": ["rescue-princess", "investigate-ruins"]
}
}
Note: firstQuest is a separate freeform text field for AI quest generation - it doesn’t reference predefined quests. See the story-starts skill for details.
Via Trigger (for unlockable quests):
"triggers": {
"unlock-quest": {
"conditions": [{ "type": "story", "query": "Player speaks to the king" }],
"effects": [{ "type": "quest-init", "operator": "set", "value": "rescue-princess" }]
}
}
Quest Lifecycle
Definition -> hidden -> available -> accepted -> completed
| \ |
| rejected |
| abandoned
|
expired
When an available quest is offered, the player accepts or rejects it as a single step. An available quest expires when its expiry tick is reached (3 ticks after offer), the party leaves the location where the quest was offered, or the quest giver dies/leaves the scene.
Detailed quests auto-generate a completion trigger from completionCondition. Basic quests need manual triggers. If completionCondition is empty, no auto-trigger is created for either type.
Schema
interface QuestDefinition {
name: string
questSource: string
questStatement: string
mainObjective: string
completionCondition: string
questDesignBrief?: string
detailType: 'basic' | 'detailed'
spatialRelationship?: SpatialRelationship // Required for basic
questLocation?: string // Required for detailed
questGiverNPC?: string
}
type SpatialRelationship =
| 'existingLocalArea'
| 'newLocalArea'
| 'nearbyNewLocation'
| 'distantNewLocation'
| 'existingLocationNewAreas'
Reference
For detailed documentation, see quests-reference.md.