Quest Givers
NPCs serve as quest givers in the Alegacy Quest Framework. This page covers the quest giver entity behavior and the dialogue system used for NPC conversations.
How It All Connects
A quest giver NPC is made of three files working together:
graph TD
A([Player right-clicks NPC]) -->|conversable
behavior| B[Dialogue
config/dialogue/priest.json]
B -->|NPC says 'Hello'| C([Player sees greeting])
C -->|Player clicks
'I need work'| D[Dialogue trigger:
openquests]
D -->|opens quest UI| E[Quest
config/quests/priest.json]
E -->|shows objectives
& rewards| F([Player accepts quest])
A -.->|questgiver behavior
lists quest IDs| EHow the flow works:
- Player right-clicks NPC → The
conversablebehavior loads the dialogue file. - NPC says 'Hello' → The player sees the greeting text.
- Player clicks 'I need work' → The dialogue reaches the
trigger: "openquests"step. - Quest UI opens → The framework loads the quest file and displays it.
- Player accepts → The quest becomes active and objectives start tracking.
The questgiver behavior (dotted line) tells the framework which quest IDs this NPC can offer, so the quest appears in the selection UI.
Minimal Quest Giver (Copy-Paste)
A complete quest-giving NPC needs exactly two behaviors:
{
"code": "villager-helper",
"class": "EntityAgent",
"server": {
"behaviors": [
{ "code": "nametag", "selectFromRandomName": ["Helper"] },
{ "code": "conversable", "dialogue": "config/dialogue/helper" },
{
"code": "questgiver",
"quests": ["yourmod:helper-quest"],
"noAvailableQuestDescLangKey": "yourmod:no-quests"
}
]
}
}And the matching dialogue file config/dialogue/helper.json:
{
"components": [
{
"code": "start",
"owner": "npc",
"type": "talk",
"text": [{ "value": "yourmod:helper-greeting" }],
"jumpTo": "main"
},
{
"code": "main",
"owner": "player",
"type": "talk",
"text": [
{ "value": "yourmod:helper-ask", "jumpTo": "quests" },
{ "value": "yourmod:helper-bye", "jumpTo": "close" }
]
},
{
"code": "quests",
"owner": "npc",
"type": "talk",
"trigger": "openquests",
"text": [{ "value": "yourmod:helper-opening" }]
},
{
"code": "close",
"owner": "npc",
"type": "talk",
"text": [{ "value": "yourmod:helper-goodbye" }]
}
]
}That's it. Three files (entity + dialogue + quest) and a lang file and you have a working quest giver. See Getting Started for the full walkthrough.
Quest Giver Behavior
Add the questgiver entity behavior to any NPC entity to make it offer quests. Configure it in the entity's behavior list:
{
"code": "questgiver",
"quests": ["yourmod:intro", "yourmod:gather-herbs"],
"alwaysquests": ["yourmod:daily-task"],
"priorityquests": ["yourmod:main-story-1"],
"rotationpool": ["yourmod:side-a", "yourmod:side-b", "yourmod:side-c"],
"reputationnpc": "innkeeper",
"singlequestatatime": true,
"maxavailablequests": 3,
"chaincooldowndays": 1.0,
"bosshuntactiveonly": false,
"trialactiveonly": false
}Fields
| Field | Description |
|---|---|
quests | Array of quest IDs this NPC can offer |
alwaysquests | Quests always shown regardless of rotation or cooldown |
priorityquests | Quests shown first, before regular pool |
rotationpool | Quests that rotate availability (only a subset shown at a time) |
reputationnpc | NPC identifier for the reputation system |
singlequestatatime | If true, player can only have one active quest from this NPC |
maxavailablequests | Maximum number of quests shown in the quest selection UI |
chaincooldowndays | Days before a completed chain quest becomes available again |
bosshuntactiveonly | Only show quests when Boss Hunt is active |
trialactiveonly | Only show quests when Hollow Trials are active |
Dialogue System
Dialogues are part of the vanilla EntityBehaviorConversable system. NPCs with this behavior can have conversations with players through a dialogue UI. Alegacy VS Quest extends this by intercepting the trigger property to execute quest actions.
Dialogue files are placed in config/dialogue/.json within your mod's assets folder. Each file contains an array of components — individual steps in a conversation.
{
"components": [
{ "code": "intro", "owner": "npc", "type": "talk", "text": [{ "value": "modid:greeting" }], "jumpTo": "main" },
{ "code": "main", "owner": "player", "type": "talk", "text": [
{ "value": "modid:option-quests", "jumpTo": "openquests" },
{ "value": "modid:option-leave", "jumpTo": "close" }
]},
{ "code": "openquests", "owner": "npc", "type": "talk", "trigger": "openquests", "text": [{ "value": "modid:quests-opening" }] }
]
}Component Properties
| Property | Description |
|---|---|
code | Unique identifier for this component |
owner | npc or player |
type | talk or condition |
text | Array of text entries |
jumpTo | Next component code to jump to |
trigger | Action string to execute |
setVariables | Variables to set when this component is entered |
sound | Sound to play when this component is entered |
NPC Speech (owner: npc)
Displays the NPC's lines and automatically advances via jumpTo:
{
"code": "greeting",
"owner": "npc",
"type": "talk",
"text": [{ "value": "modid:dialogue-greeting" }],
"jumpTo": "main"
}Player Choices (owner: player)
Text entries become clickable options, each with its own jumpTo:
{
"code": "main",
"owner": "player",
"type": "talk",
"text": [
{ "value": "modid:option-quests", "jumpTo": "openquests" },
{ "value": "modid:option-shop", "jumpTo": "shop" },
{ "value": "modid:option-leave", "jumpTo": "close" }
]
}Condition Check (type: condition)
Checks a variable and branches the dialogue:
{
"code": "checkfirstmeet",
"owner": "npc",
"type": "condition",
"variable": "entity.hasmet",
"isNotValue": "true",
"thenJumpTo": "firstmeet",
"elseJumpTo": "welcomeback"
}Conditional Text Options
Show or hide player choices based on conditions. All conditions in the array must be met:
{
"value": "modid:special-option",
"jumpTo": "special",
"conditions": [
{ "variable": "entity.unlocked", "isValue": "true" },
{ "variable": "player.haskey", "isValue": "true" }
]
}Variables & Scopes
Variables are stored with different scopes:
entity.— Stored on the NPC entity (per-NPC)player.— Stored on the player entity (per-player)global.— Global scope (shared across all)
Setting Variables
{
"setVariables": {
"entity.hasmet": "true",
"player.talkedtoinnkeeper": "true"
}
}Triggers
The trigger property executes Alegacy VS Quest action strings when the component is entered:
{
"code": "openquests",
"owner": "npc",
"type": "talk",
"trigger": "openquests",
"text": [{ "value": "modid:dialogue-quests-opening" }]
}Multiple actions separated by ;:
{
"trigger": "playsound 'sounds/effect/writing' 0.5;addjournalentry yourmod:questid yourmod:lorecode 'Title' 'Text'"
}Per-Entry Triggers
Individual player choices can have their own trigger field:
{
"code": "choices",
"owner": "player",
"type": "talk",
"text": [
{ "value": "modid:accept", "jumpTo": "accepted", "trigger": "playsound 'sounds/effect/receptionbell' 0.5" },
{ "value": "modid:decline", "jumpTo": "close" }
]
}💡 For a complete deep dive into the dialogue system with full examples, see the Dialogues page.