Skip to content

Quests

TalesMUD’s quest system is data-driven. Every quest is a JSON/YAML document with objectives, rewards, prerequisites, and optional Lua completion scripts. Progress is tracked automatically for Kill, Collect, Deliver, Visit, and Talk objectives.

Terminal window
curl -X POST http://localhost:8010/api/quests \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Rat Problem",
"description": "The cellars are overrun with rats. Clear them out.",
"category": "side",
"level": 1,
"source": {
"type": "npc",
"npcId": "NPC0001"
},
"objectives": [
{
"id": "obj1",
"type": "kill",
"description": "Kill 5 Catacomb Rats",
"targetId": "ENM0001",
"targetName": "Catacomb Rat",
"amount": 5,
"order": 1
}
],
"rewards": {
"xp": 50,
"gold": 10
},
"acceptDialogText": "Those rats are getting bold. Kill five of them.",
"completeDialogText": "Good work. Here is your payment."
}'
FieldRequiredDescription
nameYesDisplay name in quest log
descriptionYesJournal text describing the quest
categoryNomain, side, or daily
levelNoRecommended level (display only)
repeatableNoIf true, can be accepted again after completion
sourceYesHow the quest is obtained
objectivesYesArray of objectives (at least one)
rewardsNoXP, gold, and item rewards
requiredQuestIdsNoQuest IDs that must be completed first
requiredLevelNoMinimum character level
onCompleteScriptIdNoLua script ID to run on completion
acceptDialogTextNoNPC speech when offering the quest
progressDialogTextNoNPC speech while quest is in progress
completeDialogTextNoNPC speech when turning in the quest

Track how many NPCs matching a template are killed:

{
"id": "kill_rats",
"type": "kill",
"description": "Kill 5 Catacomb Rats",
"targetId": "ENM0001",
"targetName": "Catacomb Rat",
"amount": 5,
"order": 1
}

targetId must be the template ID (e.g., ENM0001), not a spawned instance ID.

Track how many items matching a template are picked up:

{
"id": "collect_pelts",
"type": "collect",
"description": "Collect 3 Wolf Pelts",
"targetId": "ITM0013",
"targetName": "Wolf Pelt",
"amount": 3,
"order": 1
}

Note: The tracker counts pickup events, not current inventory. Items dropped and re-picked still count.

Bring an item to a specific NPC:

{
"id": "deliver_letter",
"type": "deliver",
"description": "Deliver the Sealed Letter to Captain Aldric",
"targetId": "ITM0025",
"targetName": "Sealed Letter",
"deliverToNpcId": "NPC0004",
"deliverToNpcName": "Captain Aldric",
"amount": 1,
"order": 1
}

Enter a specific room:

{
"id": "visit_marsh",
"type": "visit",
"description": "Travel to Gloomfen Marsh",
"targetId": "R0301",
"targetName": "Marsh Gate Trail",
"amount": 1,
"order": 1
}

Talk to an NPC (optionally reaching a specific dialog node):

{
"id": "talk_archivist",
"type": "talk",
"description": "Speak with Archivist Maren",
"targetId": "NPC0007",
"targetName": "Archivist Maren",
"dialogNodeId": "ruins_info",
"amount": 1,
"order": 1
}

Progress managed by a Lua script:

{
"id": "solve_puzzle",
"type": "custom",
"description": "Solve the Ancient Rune Puzzle",
"checkScriptId": "SCR0007",
"amount": 1,
"order": 1
}

In your script:

local charID = ctx.character.id
if tales.quests.isActive(charID, "QST0005") then
tales.quests.setProgress(charID, "QST0005", "solve_puzzle", 1)
end
SourceDescription
npc + npcIdQuest offered by an NPC via auto-injected dialog
item + itemIdQuest granted via item pickup/use (needs Lua script)
autoQuest is always available in the player’s quest list
scriptQuest granted via tales.quests.grantQuest() from any script

When source.type = "npc", dialog options are automatically injected when players talk to the source NPC:

StateInjected Option
Available (not started)[Quest] {quest name} using acceptDialogText
Active (in progress)[Quest] {quest name} (in progress) using progressDialogText
Active (objectives complete)[Quest] Turn in: {quest name} using completeDialogText
Completed (non-repeatable)Nothing injected
"requiredQuestIds": ["quest-uuid-1", "quest-uuid-2"],
"requiredLevel": 5

All listed quests must have completed status. Use captured UUIDs when creating chains programmatically.

"rewards": {
"xp": 100,
"gold": 25,
"itemTemplateIds": ["ITM0012", "ITM0015"]
}

Items are created from templates and added to the player’s inventory on completion.

Quests can be authored as YAML files in data/quests/QST####.yaml:

id: QST0201
name: Sewer Sweep
description: >
Clear the creatures from Oldtown's sewer system.
category: side
level: 2
source:
type: npc
npcId: NPC0004
objectives:
- id: kill_rats
type: kill
description: Kill 8 Sewer Rats
targetId: ENM0001
amount: 8
order: 1
rewards:
xp: 75
gold: 25
acceptDialogText: Clear out whatever is in the sewers. I'll pay.
completeDialogText: Good work. Here's your payment.