Adding Quests¶
Status: Current Last reviewed: 2026-07-07
Quests are JSON. They live in server/data/quests/starter_quests.json, seeded from DEFAULT_QUESTS in shared/src/quests.ts. Edit them in the /admin Quests modal (then Save Quests) or in the file directly (then restart the server). Players load the current definitions on their next join.
Anatomy¶
{
"id": "clear_the_well",
"title": "Clear the Well",
"giverNpcId": "npc_mera",
"description": "Healer Mera says something has fouled the village well. Deal with it and bring back proof.",
"objectives": [
{ "id": "kill", "type": "kill_mob", "description": "Kill goblin slingers", "target": "slinger", "count": 2 },
{ "id": "ears", "type": "loot_item", "description": "Loot goblin ears", "target": "goblin_ear", "count": 2 }
],
"rewards": {
"items": [{ "itemId": "healing_draught", "qty": 2 }],
"skillUses": [{ "skill": "defense", "uses": 3 }]
},
"requires": ["goblins_at_fenline"],
"repeatable": false
}
giverNpcIdmust match an NPC'snpcId, and that NPC'squestIdsmust include this quest'sidfor it to appear in dialogue. See Adding NPCs.requiresis a list of quest ids that must be turned in first.rewards.skillUsesfeed the normal use-based progression, so a reward can nudge a skill without a fake XP grant.
Objective Types and Event Keys¶
Each objective matches a gameplay event key of the form type:target.
| Type | Target format | Example |
|---|---|---|
talk_to_npc |
npcId |
talk_to_npc:npc_rusk |
kill_mob |
variant | kill_mob:scrapper |
collect_item |
itemId |
collect_item:goblin_coin |
loot_item |
itemId |
loot_item:goblin_ear |
reach_area |
trigger id | reach_area:shrine_area |
interact_object |
object/prefab id | interact_object:loot_container |
hit_target_weapon |
<prefab>:<weaponId> |
hit_target_weapon:training_dummy:mace |
hit_target_spell |
<prefab>:<spellId> |
hit_target_spell:magic_target:fireball |
hit_target_arrow |
prefab | hit_target_arrow:archery_target |
raise_ember |
level | raise_ember:awakened |
defeat_boss |
variant | defeat_boss:champion |
count is how many times the event must fire (or, for collect_item, the inventory count to reach).
Testing¶
- Save the quest and make sure its NPC lists the id in
questIds. - In
/admin, use Reset Quests to clear your own log, then rejoin as a player. - Talk to the giver, accept, and complete the objectives. The HUD tracker and combat log show progress; the quest flips to ready when all objectives are met, and turning it in at the giver grants the rewards.
The questtest.mjs bot in tools/ is a working example of driving a quest end to end over the protocol.