NPC Dialogue & Quest Givers
Characters who hold real conversations and hand out quests
Overview
Quest givers actually talk to you. They greet you, change what they say as you progress, offer options to pick from, share a bit of lore, and occasionally hand over a one-time gift. You accept a quest, return later to hand it in, and claim your reward right inside the conversation, without ever leaving the chat.
This is built in. There is no third-party requirement: a dialogue mod such as HyCitizens is optional, not required. If you already run one and prefer it, it still works - point a dialogue button at the quest UI command (see Optional integration).
How a conversation works
Walk up to a quest giver and press the interact key. The character opens a dialogue panel with a greeting and a set of options. Each option can move the conversation to another line, fire a quest action, open a screen, or close the chat.
Which greeting you get is decided on a fixed ladder, so a conversation never has to hand-sort its own lines: a beat the author marked as coming first, then a quest that is ready to hand in here, then one this character can offer you, then one that is in progress, then a steady-state line, then the fallback screen. The player's quest log is the state machine, so the same character greets a newcomer, a player mid-quest, and a player coming back to deliver, all from one file.
- Accept in conversation - pick the offer option to start a quest, no separate menu needed
- Hand in and claim in conversation - return when your objectives are done and the character hands over the reward
- Branching options - lore, side replies, and follow-up lines, with options that appear or hide based on your quest progress
- One-time gifts - a character can grant a reward once (for example a starter item), tracked so it only fires the first time
Accepting or completing a quest in conversation fires the same feedback as the Quests page - a toast and a sound - so the moment reads clearly no matter which surface triggered it.

Quest-driven option visibility
Which options a giver shows is driven directly by your quest state, not by a separate set of story flags. An "Accept" option only appears while the quest is available, the hand-in option only appears once you qualify and there is genuinely something to deliver, and a finished quest stops offering itself. The upshot for players: a quest you reset (or that an admin resets) leaves the dialogue in a clean state instead of soft-locking the character, because the conversation reads the live quest, not a stale flag.
Where quest givers appear
A character in the world is a placement file: one file that says who stands there, which worlds they stand in, where in each world, whether they appear at all, and what pressing the interact key opens. The Adventurer's Guide is an ordinary placement authored exactly that way; nothing about it is special-cased.
Where in the world they stand
A placement has five independent ways to say where it stands, and it may use several at once. Every position they resolve to gets its own copy of the character, so "beside world spawn and beside every matching camp" needs nothing new.
| Anchor | Stands at |
|---|---|
| World spawn | The world's own spawn point, nudged by an offset in blocks and a facing angle, so a new player finds them immediately |
| Fixed coordinates | Exact X / Y / Z plus a facing angle. Useful in a world whose layout you control |
| A worldgen structure | Wherever a matching structure or prefab marker generated, so a character appears at every village, camp, or ruin of that kind |
| A discovered zone | Where a named zone was found, so a region's questline introduces itself when a player arrives there |
| A custom provider | Wherever a mod-supplied placement rule says |
Quests can also be scoped to a world zone, so an objective only counts where it is meant to, for example a hunt that only progresses "in the Howling Sands". That pairs naturally with a giver anchored to that same zone.
Which worlds, and whether they appear
- Worlds. A placement names its worlds by name, by name pattern, or by the world's own gameplay-config key. That last one is how a character reaches an instance world such as the Forgotten Temple, which is rebuilt with a fresh name every visit: the config key stays the same, the name does not. Left unsaid, a placement stands in the ordinary persistent world only.
- Gating. A placement can be gated on the server itself, not the player. The Mastery Trainer asks for the mastery feature to be switched on, so on a server without mastery the trainer never appears at all rather than standing there refusing.
- Upkeep. Three opt-in knobs cover a service character who has to stay reachable: keep their chunk loaded, place them again if something removes them, and give them a health pool nothing can chew through. Each one costs something real, so each is off unless a placement asks for it.
The Adventurer's Guide
The Adventurer's Guide is the hub character at world spawn. New players are greeted on arrival and offered a short built-in tutorial or a skip - either way you walk away with the Skill Menu Scroll, so the menu is always one item-use away. The tutorial needs no extra packs; finishing or skipping it flows straight into the first campaign when the free Quest Pack is installed, so the opening tutorial and the campaign read as one continuous start.
Alongside the walkthrough, the Guide also hands out a short jar-bundled homesteader arc of four tutorial side quests - Make Camp, Home Cooking, Prove Your Mettle, and Meet Me at the Forgotten Temple - that teach Building, Cooking, sustained combat, and exploration. The last one stands beside the starter crafting quest so a player who would rather explore than forge has somewhere to go: it points you down to the Guide's temple standing, and it is the doorway to the whole temple arc below. They ship in every language and need no content pack.
One more character standing ships in the jar, in the vanilla Forgotten Temple:
- The Guide, again. The same character stands in the temple. They greet you the first time you meet them down there and remember it per temple, so a rebuilt instance does not start the greeting over. Anything the Guide offers at spawn can be taken and handed in at the temple standing too, because it is one character in two places, and a quest step aimed at the temple standing in particular can only be credited down there.
The temple standing is a quest giver in its own right: it carries a jar-bundled temple arc of four quests that are offered and handed in only down there - What the Stones Remember, The Watch Below, Keeper of the Deep (which asks for total level 150), and The Temple's Due, a daily that resets on the calendar day rather than on a rolling cooldown. The arc pays out its own gear - a delver's pick, a watchman's blade, and the keeper's robe and hood, none of them craftable - and the keeper's set is a deliberate trade rather than a straight upgrade: it gives up health for luck and bonus XP.
With the free MMO Skill Mastery Pack installed, the Mastery Trainer stands across from the temple Guide: taller, darker, staff in hand. The pack ships the whole character - pressing the interact key starts a conversation (the trainer has quests of their own before the mastery menu), and the placement is gated on the mastery feature, so without the pack, or with mastery switched off, no trainer appears at all. See the Mastery Trainer for the owner's view.
For server owners
Characters and their conversations are two kinds of file, both readable inside the mod jar and both overridable by id:
Server/ZiggfreedCommon/NpcPlacements/<id>.json- one file per character standing: who they are, which worlds, where, whether they appear, and what the interact key opens.Server/ZiggfreedCommon/Dialogues/<namespace>/<Name>.json- the conversations. Your own version of any conversation goes inmods/ziggfreedcommon/dialogues.json, a bare map from conversation id to what that id should read differently ({"<id>": { ... } }), read by the same codec and folded over the stored conversation leaf by leaf - so retuning one line means writing that one node, and every other screen, memory and shared option group the pack wrote stays as it was. An id nothing else ships is simply your own conversation.mods/mmoskilltree/dialogues.jsonis retired in 1.6.0: it is renamed in place to.legacyon the first start after upgrading, with one boot warning naming the replacement, and nothing is carried across automatically, so an existing customisation has to be re-authored into the ziggfreedcommon file by hand.
To switch a character off you never edit their file. The owner layer is mods/ziggfreedcommon/npc-placements.json, where {"mypack_sands_guide": {"enabled": false}} takes one character down and "*" takes them all down at once.
| Command | What it does |
|---|---|
/mmonpc list | Every placement targeting the world you are standing in, with its state: standing, pending, or held back with the reason |
/mmonpc enable --arg1=<id|*> | Turn a placement back on and place it immediately |
/mmonpc disable --arg1=<id|*> | Turn one off. It despawns what is already standing, not just what would spawn next |
/mmonpc reconcile [--arg1=<world>] | Force a sweep now instead of waiting for the next one |
/mmonpc list --arg1=structures | List the structure-marker sightings the anchor engine has recorded in this world, which is how you find a real one to anchor to |
/mmonpc list --arg1=markers | Scan the live entity store for spawn-marker entities actually present right now. structures reads the sighting record, markers reads reality, so the two disagreeing tells you which side a missing anchor is on. A marker only exists while its chunk is loaded - stand near the structure and re-run |
/mmonpc list --arg1=channels | Every extension channel a mod has claimed, with its failure count and last message |
See Placed NPCs & the Adventurer's Guide for the full server-owner walkthrough, Quest Configuration for the quest side, and the Commands page for everything else.
Optional dialogue-mod integration
Because the dialogue engine is built in, no integration is needed. If you would rather keep an existing dialogue mod, you can still hand off to the MMO quest screen from one of its buttons by running:
/mmoquestui <player> <npc_id>That opens the named character's quest panel directly, so an external dialogue line can drop the player into the same accept / hand-in / claim view.
One dialogue engine per server
Conversations are run by the shared library every mod on the server uses, and they live in one shared store. That has a concrete payoff for a server running more than one of these mods: a single conversation can mix actions from two different mods. An option can accept an MMO quest and, in the same click, do something another mod registered, because both put their vocabulary into the same engine. Nothing has to know about anything else.
Pack authoring
Content packs author conversations without any Java - drop JSON into Server/ZiggfreedCommon/Dialogues/<YourPack>/ and the engine folds it in at server start, the same way quests and achievements load. Zip the folder (with a manifest carrying "IncludesAssetPack": true and forward-slash entries) and drop the .zip in Mods/ - see Building the zip.
The older Server/MMOSkillTree/Dialogues/ folder still loads exactly as it did, so nothing already there has to move today. Moving a file to the shared folder is optional and preferred: every reader folds the whole shared folder, so one conversation authored there can serve several mods at once. The same id present in both folders logs a collision warning, so move a file rather than copy it. See the Dialogue Authoring reference for the full field list and worked examples.
A conversation file declares which screen it opens on (see the ladder above) and a map of screens. Each screen carries a line of text and a list of options; each option has a label, optional conditions, and one or more actions.
Reuse via native Parent inheritance
Rather than rewrite the same greet / intro / hand-in / lore structure for every giver, a conversation can name another as its Parent and inherit everything it does not mention: an omitted field takes the parent's value, and screens merge by key, so a child can reword one screen and keep every other screen and every other field on that screen.
A reusable base is an ordinary dialogue
Abstract, so it never shows up as content of its own, and any file can name it as its Parent. There is also no parameter substitution and no automatic branch pruning: state-varied beats are authored as conditions on a screen or on an option (most often a quest-state condition), and quest-specific ids are written out in the child.Placements inherit the same way, and it is the reason a second standing of a character is so cheap. The temple Guide names the spawn Guide as its Parent and writes four lines: which world it applies to, its own id, and the id it also answers to. The role, the anchor, the upkeep knobs, and the conversation all come down from the parent, so re-tuning the Guide in one file re-tunes both.
Option keys
Authors do not have to spell out a verbose action list for the common cases. Option-level shorthand expands to the full actions before validation, so a single key handles the usual moves:
| Key | What it does |
|---|---|
Accept | Accept the named quest |
Complete | Force-complete the named quest, even with unmet objectives (the "skip the tutorial" path) |
TurnIn | Hand in the named quest |
MarkTalked | Credit this conversation, which is what a "talk to somebody" objective counts. Written out as a full action rather than a one-word shorthand, on purpose: crediting a visit is a decision worth writing. Leave the target off (or write @self) and it credits whoever the player is facing, aliases included; name an id to credit somebody else |
Reward | Grant a reward (once, by default) |
Remember / Forget | Write or clear a piece of named state this conversation declared (see below) |
Run | Run an arbitrary console command, with {player} substituted - the generic pack escape hatch |
Open | Open a screen (quest list, hub, a shop, a board, a skill tree) |
Goto | Jump to another screen in the conversation |
Close | End the conversation |
Once | Not an action but a knob on the option: offer it until its actions have run, then stop (see below) |
Do | An ordered array of single-key actions, for when order matters or a step repeats - the escape hatch when the bare keys above aren't enough |
An option can also carry a Presentation block (a hex color that tints the button, plus an item-icon or glyph override) and a Style key (accept / turnin / continue / neutral / farewell) that controls the button's color and shape in-game. Leave both off and the button styles itself from its decisive action (accept quests render green, hand-ins render blue, and so on) - set them only to override that default.
Once and memories
Two knobs cover everything a conversation needs to remember, and neither asks an author to invent or spell a key by hand.
A beat that plays once is "Once": true on a greeting entry or an option. Scope it to a set of worlds instead of to the whole character by giving it the same world selector a placement uses, which is what makes "greet me the first time I come down here" survive an instance world being torn down and rebuilt:
"Once": true
"Once": { "Where": { "Match": ["forgotten_temple"] } }
"Once": { "Where": { "GameplayConfig": ["ForgottenTemple"] } }On a greeting entry the beat stops matching once the player finishes it, so leaving mid-beat shows it again. On an option it is remembered by the option's own label rather than its position, so reordering a screen's options can neither resurrect nor spend one.
Named state is declared once at the top of the conversation, with its own scope and lifetime, then used by bare name everywhere else through the Remember / Forget actions and the matching conditions. A declaration can keep the state per world family, tie it to a quest so resetting that quest forgets it too, or share it with every conversation that declares the same name. Because it is declared, a typo is a validation error rather than a second, silent piece of state.
Authored flags are gone
SetFlag, Flag, and NotFlag were removed in 1.6.0. A first-visit greeting is a Once; anything with a name is a declared memory. Quest-driven option visibility should still come from quest state directly, never from a memory mirroring it - a memory outlives a quest reset, and that is exactly how a conversation soft-locks. When a piece of state genuinely must die with a quest, declare it that way and the reset clears it for you.All dialogue text is localized by key and follows the player's game language, the same as every other MMO Skill Tree menu, so a translated pack reads in the player's own language.