Skip to main content

NPC Quest Profiles

NPC Quest Profiles connect Citizens (NPCs) to quests. Each profile defines which quests an NPC offers, what dialog they show in different phases, and how they behave when a player is nearby. Profiles are JSON files stored in the quest_npc_profiles/ folder.

Overview

When a player interacts with an NPC that has a quest profile, the system determines which dialog to show based on a priority algorithm:

  1. Complete -- If the player has finished all objectives for a quest this NPC can turn in, show the completion dialog.
  2. Offer -- If the NPC has an available quest the player has not started or completed, show the offer dialog. If multiple quests are available, a selection page opens.
  3. Active -- If the player has an active quest from this NPC but has not finished yet, show the active/reminder dialog.
  4. Not Ready -- If quests exist but prerequisites are not met, show the "not ready" dialog.
  5. Default -- Fallback dialog when no quests are relevant.

Profile JSON Structure

Each profile is a single JSON file per NPC:

{
"citizenId": "smith_gorn",
"quests": [
{
"questId": "story_iron_forge",
"priority": 10,
"requires": ["tutorial_sustainability"],
"offer": { "speaker": "Gorn", "nodes": [/* ... */] },
"active": { "speaker": "Gorn", "lines": ["npc.smith_gorn.active.1"] },
"complete": { "speaker": "Gorn", "lines": ["..."], "action": "complete_quest" }
}
],
"proximityMessages": {
"offer": "npc.smith_gorn.proximity.offer",
"active": "npc.smith_gorn.proximity.active",
"complete": "npc.smith_gorn.proximity.complete",
"defaultMsg": "npc.smith_gorn.proximity.default"
},
"proximityRange": 20,
"proximityCooldown": 300,
"defaultDialog": { "speaker": "Gorn", "lines": ["npc.smith_gorn.default.1"] },
"notReadyDialog": { "speaker": "Gorn", "lines": ["npc.smith_gorn.not_ready.1"] }
}

Top-Level Fields

FieldRequiredDescription
citizenIdYesMust match the Citizen ID from the Citizens system
_config_versionNoSchema version for auto-update detection (current: "2")
questsYesArray of quest dialog entries (at least one)
defaultDialogNoFallback dialog when no quests are relevant
notReadyDialogNoShown when quests exist but prerequisites are unmet
proximityMessagesNoChat whisper messages for proximity detection
proximityRangeNoDetection range in blocks (default: 20)
proximityCooldownNoSeconds between proximity whispers (default: 300)

Quest Dialog Entry

Each entry in the quests array ties a quest to this NPC with phase-specific dialogs:

FieldRequiredDescription
questIdYesQuest definition ID to link
priorityNoLower number = checked first (default: 10)
requiresNoArray of quest IDs that must be completed first
offerNoDialog shown when quest is available to accept
activeNoDialog shown while quest is in progress
completeNoDialog shown when objectives are done and quest can be turned in
tip

Not every NPC needs all three phases. You can split quests across NPCs -- for example, NPC A has the offer phase while NPC B has the complete phase. This lets players pick up a quest from one NPC and turn it in at another.

Dialog Formats

Simple Format

Uses a flat list of text lines. For offer dialogs, add acceptButton/declineButton:

{
"speaker": "Gorn",
"lines": ["Would you like to help me forge some iron?"],
"acceptButton": "Sure!",
"declineButton": "Maybe later.",
"action": "start_quest"
}

Full Format (Nodes)

Uses a tree of dialog nodes for branching conversations. Node types: TEXT (shows lines, advances to next) and CHOICE (shows clickable options):

{
"speaker": "Gorn",
"nodes": [
{ "id": "greeting", "type": "TEXT", "lines": ["Welcome!"], "next": "accept" },
{
"id": "accept", "type": "CHOICE", "lines": ["Will you help me?"],
"choices": [
{ "text": "Of course!", "macro": "start_quest" },
{ "text": "Not now." }
]
}
]
}

Actions and Macros

ActionDescription
start_questStarts the linked quest for the player
complete_questCompletes the linked quest and grants rewards

In the full format, macros are set on individual nodes or choices via the "macro" field.

info

Dialog text values can be literal strings or localization keys (e.g., npc.smith_gorn.default.1). If a matching key exists in the localization files, the translated text is shown.

Multiple Quests Per NPC

A single NPC can offer multiple quests. The requires field controls ordering and priority determines check order. When two or more quests are available simultaneously, a Quest Selection Page opens letting the player choose.

Example of a sequential quest chain (quests unlock one after another):

{
"citizenId": "guide_finn",
"quests": [
{ "questId": "tutorial_awakening", "priority": 1, "requires": [] },
{ "questId": "tutorial_first_steps", "priority": 2, "requires": ["tutorial_awakening"] },
{ "questId": "tutorial_workbench", "priority": 3, "requires": ["tutorial_first_steps"] }
]
}

Proximity Detection

Chat Whispers

When a player enters the proximityRange, a colored chat whisper is sent based on the current quest phase. The message appears as [NPC Name] text in light blue. The NPC plays a wave animation when a quest is available. Placeholders {PlayerName} and {CitizenName} are replaced automatically. The cooldown prevents spam (default: 300 seconds per NPC per player).

Proximity Toast HUD

Nearby quest NPCs also appear in a Proximity Toast HUD showing the NPC's avatar, a quest indicator (! gold = available, ? green = turn-in ready), distance in blocks, and compass direction. Up to 5 NPCs display simultaneously and are removed when the player moves out of range.

Configure the toast in config.json:

{ "proximityToast": { "enabled": true, "toastRange": 20.0, "durationMs": 0 } }

Set durationMs to 0 for persistent display while in range, or a positive value for auto-hide.

World Map Markers

Quest NPCs automatically receive world map markers based on the player's quest status:

MarkerMeaning
quest_availableNPC has a quest the player can accept
quest_turn_inNPC can receive a completed quest
quest_progressPlayer has an active quest from this NPC

Markers update automatically when a player accepts, completes, or abandons a quest. They are per-player, so different players see different markers on the same NPC.

File Location

Profile files are stored in configs/kyuubisoft_questbook/quest_npc_profiles/. Default profiles are extracted from the mod JAR on first startup. You can edit existing profiles or add new ones by creating additional JSON files in this folder.

warning

The citizenId in the profile must match an existing Citizen in the Citizens system. If the Citizen does not exist, the profile is loaded but has no effect.