Custom NPCs, Dialogues, and Quests
Custom NPCs, dialogue trees, and quests are the foundation of Unturned™ roleplay and story-driven server experiences. A fully functional NPC encounter requires four separate authoring layers that work together: the NPC asset (character appearance and placement), the Dialogue asset (conversation tree with messages and responses), the Quest asset (conditions, objectives, and rewards), and the Vendor asset (items available for purchase or sale). Each layer is a separate .dat file with its own GUID, its own field set, and its own cross-links to the other layers.
This article is the cohort-validated end-to-end reference for authoring all four layers. It covers every significant field in each .dat format, explains how quest flags persist across sessions, and provides a complete worked example of a supply-run quest chain that demonstrates all four asset types working together. The article also documents the cross-links between NPC assets and the item system, so quest rewards can reference custom items from the throwable asset reference and other item categories.
57 Studios™ uses the patterns in this article for NPC encounters on the Horizon Life RP server and for standalone story-mode content published through Workshop.

Prerequisites
- A working Unturned™ dedicated server or a single-player environment with Workshop content enabled.
- Notepad++. See How to Install Notepad++.
- Familiarity with GUIDs and the mod folder structure. See Project Folder Structure and GUIDs.
- An understanding of how Unturned loads asset files at runtime. See Workshop Content on Dedicated Servers.
- Approximately 2–6 hours for a first NPC quest chain authoring pass.
What you'll learn
- How Unturned's NPC system relates the four asset types to each other.
- How to author the NPC asset
.datwith appearance, pose, equipped item, and dialogue GUID. - How to author the Dialogue asset
.datwith messages, responses, and conditional flags. - How to author the Quest asset
.datwith types, conditions, and rewards. - How to author the Vendor asset
.datwith buying and selling item lists. - How quest flags persist across sessions and how to use them for conditional branching.
- How to reference custom items from other mod categories as quest rewards.
- How to test NPC encounters in single-player and on a dedicated server.
System architecture
The four NPC system asset types connect in a directed graph. The NPC asset is the entry point. It holds the character's appearance and a reference to the Dialogue asset's GUID. The Dialogue asset holds the conversation tree: each response the player can choose advances to another Dialogue asset, starts a Quest, or opens a Vendor. The Quest asset defines what the player must do and what they receive. The Vendor asset defines what the NPC will buy or sell.
The system is entirely data-driven. No scripting is required to author a standard NPC quest chain. Every behavior is encoded in the .dat files and the flag system.
NPC asset authoring
Folder structure
Each NPC is a separate folder inside your mod's Objects/ or NPCs/ directory. The cohort-validated folder structure is:
Workshop/Content/304930/<ModID>/
└── NPCs/
└── ExampleTrader/
├── ExampleTrader.dat ← NPC asset definition
└── English.dat ← localization (display name)The NPC asset's GUID must be unique across all loaded mods. Generate a new GUID for each NPC. See Project Folder Structure and GUIDs for the GUID generation workflow.
NPC .dat fields
| Field | Type | Example | Purpose |
|---|---|---|---|
ID | uint16 | 5001 | Unique NPC ID. Use IDs above 50000 to avoid collision with vanilla and established mods. |
GUID | uint128 | a1b2c3d4e5f6478aab1c2d3e4f5a6b7c | Globally unique identifier for this NPC asset. |
Type | enum | NPC | The asset type. Always NPC for character NPCs. |
Name | string | ExampleTrader | Internal name. Not shown to players. |
Dialogue | uint128 | d4e5f6a7b8c9410dabc1d2e3f4a5b6c7 | GUID of the Dialogue asset shown when the player interacts with this NPC. |
Pose | enum | Stand | Idle pose. Values: Stand, Sit, Lean, Rest. |
Equipped | uint16 | 0 | ID of an item the NPC visually holds. 0 = nothing. |
Face | uint8 | 5 | Face index (0–31 matching vanilla face palette). |
Hair | uint8 | 3 | Hair style index. |
Beard | uint8 | 0 | Beard style index. |
Skin | color | 255,204,153 | RGB skin color. |
Color_Hair | color | 80,40,10 | RGB hair color. |
Hat | uint16 | 0 | ID of a clothing item placed on the head slot. |
Glasses | uint16 | 0 | ID of a glasses item. |
Vest | uint16 | 300 | ID of a vest/jacket item. |
Shirt | uint16 | 15 | ID of a shirt item. |
Pants | uint16 | 51 | ID of a pants item. |
Shoes | uint16 | 145 | ID of shoes. |
NPC item appearance
The Equipped, Hat, Glasses, Vest, Shirt, Pants, and Shoes fields accept vanilla Unturned item IDs. They control the visual appearance of the NPC. The items are display-only — the NPC does not use them functionally. Equipping vanilla items on an NPC is a quick way to establish character identity without authoring a custom clothing mod.
Seasonal variant fields
Unturned™ supports Christmas and Halloween variant overrides on NPCs. When the server is running during the seasonal event period, these fields override the base fields:
| Field | Purpose |
|---|---|
Christmas_Dialogue | GUID of the dialogue to show during the Christmas event. |
Halloween_Dialogue | GUID of the dialogue to show during the Halloween event. |
Christmas_Hat | Item ID for the hat worn during the Christmas event. |
Halloween_Hat | Item ID for the hat worn during the Halloween event. |
If seasonal variant fields are not defined, the NPC uses the base fields year-round.
NPC placement
Placement requires level editing
NPCs cannot be spawned at runtime through the standard .dat system. Placement requires the Unturned™ level editor. If you are adding NPCs to an existing community map you do not own, you need to author a separate custom map that copies the layout and adds the NPC placements. Confirm the map license terms before copying community map content.
NPCs are placed in the level editor or in a map's Objects.dat. For server-side NPC placement without a custom map, the cohort approach is to place NPCs in a custom map loaded by the server. NPCs cannot be spawned at runtime through the standard .dat system; placement requires level editing.
Example NPC .dat
ID 5001
GUID a1b2c3d4e5f6478aab1c2d3e4f5a6b7c
Type NPC
Name ExampleTrader
Dialogue d4e5f6a7b8c9410dabc1d2e3f4a5b6c7
Pose Stand
Face 5
Hair 3
Beard 0
Skin 255,204,153
Color_Hair 80,40,10
Shirt 15
Pants 51
Shoes 145
Vest 300
Equipped 0English.dat for NPCs
Name Example TraderThe Name field is the display name shown above the NPC's head and in the dialogue window header.
Dialogue asset authoring
A Dialogue asset defines the conversation structure. Each Dialogue asset represents a single conversation node: it shows one or more messages from the NPC and presents a set of responses the player can choose. Choosing a response can advance to another Dialogue node, start a Quest, open a Vendor, or close the dialogue window.
Folder structure
Workshop/Content/304930/<ModID>/
└── Dialogues/
└── ExampleTraderDialogue/
├── ExampleTraderDialogue.dat
└── English.datDialogue .dat fields
Identity fields:
| Field | Type | Example | Purpose |
|---|---|---|---|
ID | uint16 | 6001 | Unique Dialogue ID. |
GUID | uint128 | d4e5f6a7b8c9410dabc1d2e3f4a5b6c7 | Globally unique identifier. Must match the GUID referenced in the NPC asset. |
Type | enum | Dialogue | Always Dialogue. |
Message fields:
A Dialogue asset can show 1–8 messages. Each message is conditionally shown based on quest flag conditions. The first message whose conditions are satisfied is shown to the player. This allows a single Dialogue node to present different text depending on quest state.
| Field | Type | Example | Purpose |
|---|---|---|---|
Messages | uint8 | 2 | Total count of messages defined in this dialogue node. |
Message_0_Conditions | uint8 | 1 | Number of conditions that must be true for Message_0 to show. |
Message_0_Condition_0_Type | enum | Quest_Flag_Bool | Type of condition. See condition types below. |
Message_0_Condition_0_ID | uint16 | 100 | The quest flag ID to check. |
Message_0_Condition_0_Value | bool/int | True | The expected value of the flag. |
Message_0_Condition_0_Logic | enum | Equal | Comparison logic: Equal, Not_Equal, Greater_Than, Less_Than. |
Message_0_English | string | Thanks for completing the supply run! | The message text for this condition. |
Response fields:
Each Dialogue node can have 1–8 responses. Responses are the choices presented to the player. Like messages, responses can be conditionally shown based on quest flags.
| Field | Type | Example | Purpose |
|---|---|---|---|
Responses | uint8 | 3 | Total count of responses. |
Response_0_Conditions | uint8 | 0 | Number of conditions for this response to be shown. 0 = always shown. |
Response_0_Dialogue | uint128 | ... | GUID of the next Dialogue node if the player selects this response. Leave blank if not advancing to another dialogue. |
Response_0_Quest | uint16 | 7001 | Quest ID to start when this response is selected. Leave 0 if no quest starts. |
Response_0_Vendor | uint16 | 8001 | Vendor ID to open when this response is selected. Leave 0 if no vendor opens. |
Response_0_OpenEffect | uint16 | 0 | Effect ID to play when this response is selected. |
Response_0_English | string | Tell me about the supply run. | The response text shown to the player. |
Condition types
| Condition type | Checks |
|---|---|
Quest_Flag_Bool | Whether a boolean quest flag equals a given value |
Quest_Flag_Short | Whether a short integer quest flag meets a numeric comparison |
Quest_Status | Whether a specific quest is None, Active, or Completed |
Time_Of_Day | Whether the in-game time is within a range |
Player_Is_Full | Whether the player's inventory is full |
Currency | Whether the player has enough of a currency item |
English.dat for Dialogues
Unlike other asset types, Dialogue English.dat files can hold multiple keyed entries — one per message and one per response:
Message_0 Thanks for completing the supply run!
Message_1 I have a job for you, if you're up for it.
Response_0 Tell me about the supply run.
Response_1 What are you buying?
Response_2 Goodbye.The key format is Message_N and Response_N matching the index in the .dat file.

Example: two-node dialogue chain
Node 1 (ExampleTraderDialogue_Root.dat) — the first node the player sees:
ID 6001
GUID d4e5f6a7b8c9410dabc1d2e3f4a5b6c7
Type Dialogue
Messages 1
Message_0_Conditions 0
Message_0_English I need someone to run supplies to the outpost. Are you in?
Responses 2
Response_0_Conditions 0
Response_0_Quest 7001
Response_0_English I'll do it.
Response_1_Conditions 0
Response_1_English Not right now. Maybe later.Node 2 (ExampleTraderDialogue_Complete.dat) — shown when quest is done:
ID 6002
GUID e5f6a7b8c9d0421eabc2d3e4f5a6b7c8
Type Dialogue
Messages 2
Message_0_Conditions 1
Message_0_Condition_0_Type Quest_Status
Message_0_Condition_0_ID 7001
Message_0_Condition_0_Value Completed
Message_0_Condition_0_Logic Equal
Message_0_English Excellent work. Here's your payment.
Message_1_Conditions 0
Message_1_English Safe travels out there.
Responses 1
Response_0_Conditions 0
Response_0_English Thanks.Message ordering and fallback
Messages are evaluated in order from Message_0 to Message_N. The first message whose conditions are all satisfied is the one shown. The last message should have zero conditions to act as a guaranteed fallback — if no earlier message's conditions are met, the fallback message is shown. This prevents a dialogue node from displaying nothing to the player if all conditional messages fail.
Quest asset authoring
A Quest asset defines what the player must do (conditions), what triggers quest completion, and what the player receives when it completes (rewards). Quest assets are separate .dat files referenced by response fields in Dialogue assets.
Folder structure
Workshop/Content/304930/<ModID>/
└── Quests/
└── ExampleSupplyRun/
├── ExampleSupplyRun.dat
└── English.datQuest .dat identity and type fields
| Field | Type | Example | Purpose |
|---|---|---|---|
ID | uint16 | 7001 | Unique Quest ID. |
GUID | uint128 | f6a7b8c9d0e1432fabc3d4e5f6a7b8c9 | Globally unique identifier. |
Type | enum | Quest | Always Quest. |
Name | string | ExampleSupplyRun | Internal name. |
Quest condition fields
::: note Conditions are evaluated on dialogue interaction, not continuously Quest conditions are not checked in real time as the player collects items. They are evaluated at the moment the player interacts with the NPC and the dialogue checks whether the quest can be completed. The player must return to the NPC to trigger the evaluation — the quest does not auto-complete when the last item enters the inventory. :::
Conditions define what must be true for the quest to be considered complete. Conditions are evaluated at runtime when the player opens the relevant dialogue or when the server checks quest state.
| Field | Type | Example | Purpose |
|---|---|---|---|
Conditions | uint8 | 2 | Total number of conditions for this quest. |
Condition_0_Type | enum | Item | The condition type. |
Condition_0_ID | uint16 | 14 | The item ID to check (for Item conditions). |
Condition_0_Amount | uint16 | 5 | The required item count. |
Condition_0_Reset | bool | True | Whether to remove the items from inventory on quest completion. |
Quest condition types:
| Type | What it checks | Key fields |
|---|---|---|
Item | Player holds a minimum quantity of a specific item | ID (item ID), Amount, Reset (remove on complete) |
Quest_Flag_Bool | A boolean quest flag equals a value | ID (flag ID), Value |
Quest_Flag_Short | A short integer flag meets a comparison | ID, Value, Logic |
Quest_Status | Another quest is in a specific state | ID (quest ID), Value (None / Active / Completed) |
Skillset | Player's skillset matches | Value (skillset name) |
Experience | Player has a minimum XP amount | Amount |
Reputation | Player's reputation meets a threshold | Amount, Logic |
Time_Of_Day | In-game time is within a range | Value (time range) |
Player_Life_Food | Player's food stat meets a threshold | Amount, Logic |
Player_Life_Water | Player's water stat meets a threshold | Amount, Logic |
Quest reward fields
Rewards are given to the player when all conditions are satisfied and the quest is completed. Multiple reward types can be combined in a single quest.
| Field | Type | Example | Purpose |
|---|---|---|---|
Rewards | uint8 | 3 | Total number of rewards. |
Reward_0_Type | enum | Item | Reward type. |
Reward_0_ID | uint16 | 253 | For Item rewards: the item ID to give. |
Reward_0_Amount | uint16 | 1 | For Item rewards: quantity to give. |
Quest reward types:
| Type | What it gives | Key fields |
|---|---|---|
Item | One or more copies of an item | ID (item ID), Amount |
Quest_Flag_Bool | Sets a boolean quest flag to a value | ID (flag ID), Value |
Quest_Flag_Short | Sets or modifies an integer quest flag | ID, Value, Modification (Assign / Increment / Decrement) |
Experience | Grants XP | Amount |
Reputation | Adjusts player reputation | Amount (positive or negative) |
Hint | Shows a hint message to the player | Text |
Effect | Plays an effect | ID (effect ID) |
Teleport | Teleports the player to a named location | Spawnpoint |
Currency | Gives a currency item | GUID (currency GUID), Amount |
Item reward GUID requirement
When referencing custom modded items as quest rewards, use the item's GUID in the Reward_N_GUID field rather than its ID. GUID references are stable across mod updates; ID references can collide if another mod uses the same ID. See Project Folder Structure and GUIDs for the distinction.
English.dat for Quests
Name Supply Run
Description Deliver 5 Medical Kits to the northern outpost.
Reward_0 Reward: Emergency Kit x1The Reward_N keys are optional. If provided, they appear in the quest log as human-readable reward descriptions.
Example Quest .dat
ID 7001
GUID f6a7b8c9d0e1432fabc3d4e5f6a7b8c9
Type Quest
Name ExampleSupplyRun
Conditions 1
Condition_0_Type Item
Condition_0_ID 394
Condition_0_Amount 5
Condition_0_Reset True
Rewards 3
Reward_0_Type Item
Reward_0_ID 255
Reward_0_Amount 1
Reward_1_Type Experience
Reward_1_Amount 500
Reward_2_Type Quest_Flag_Bool
Reward_2_ID 100
Reward_2_Value TrueIn this example: the player must carry 5 units of item 394 (Medical Kit). Upon completion, those 5 items are removed, the player receives item 255 (Emergency Kit), 500 XP, and flag 100 is set to True. The flag can then be checked in the dialogue's conditions to show the post-completion message.
Condition_Reset and inventory management
Setting Condition_0_Reset True removes the required items from the player's inventory at the moment of quest completion. If the player's inventory is full when the reward item is granted, the reward may fail to place — it will drop on the ground near the NPC. Inform players of this in the quest description so they clear inventory space before turning in item-delivery quests.
Vendor asset authoring
A Vendor asset defines the items an NPC will buy from or sell to the player. Vendors are opened from a dialogue response with a non-zero Response_N_Vendor field.
Folder structure
Workshop/Content/304930/<ModID>/
└── Vendors/
└── ExampleTraderVendor/
├── ExampleTraderVendor.dat
└── English.datVendor .dat identity fields
| Field | Type | Example | Purpose |
|---|---|---|---|
ID | uint16 | 8001 | Unique Vendor ID. Referenced in Dialogue responses. |
GUID | uint128 | g7h8i9j0k1l2453mabc4d5e6f7a8b9c0 | Globally unique identifier. |
Type | enum | Vendor | Always Vendor. |
Name | string | ExampleTraderVendor | Internal name. |
Currency | uint128 | `` | GUID of the currency item. Leave blank to use the default experience-as-currency system. |
Disable_Sorting | bool | False | If True, items appear in definition order instead of sorted by name. |
Custom currency items
The Currency field accepts the GUID of any item defined in a loaded mod. This allows server operators to create custom in-game currencies (tokens, faction credits, barter goods) separate from the default experience system. Author the currency item as a standard item .dat with a unique GUID, then reference that GUID in the Vendor's Currency field.
Selling items (NPC sells to player)
Selling entries define what the NPC has available for the player to purchase.
| Field | Type | Example | Purpose |
|---|---|---|---|
Selling | uint8 | 3 | Total count of items the NPC sells. |
Selling_0_Type | enum | Item | Entry type: Item or Vehicle. |
Selling_0_ID | uint16 | 255 | Item ID of the item being sold. |
Selling_0_Cost | uint32 | 100 | Cost in experience points (or currency item units if Currency is set). |
Selling_0_Conditions | uint8 | 1 | Number of conditions that must be true for this listing to appear. 0 = always visible. |
Selling_0_Condition_0_Type | enum | Quest_Flag_Bool | Condition type for unlocking this listing. |
Selling_0_Condition_0_ID | uint16 | 100 | Flag ID to check. |
Selling_0_Condition_0_Value | bool | True | Required flag value for the listing to appear. |
Buying items (NPC buys from player)
Buying entries define what the NPC will purchase from the player.
| Field | Type | Example | Purpose |
|---|---|---|---|
Buying | uint8 | 2 | Total count of items the NPC buys. |
Buying_0_Type | enum | Item | Entry type: Item. |
Buying_0_ID | uint16 | 394 | Item ID the NPC will purchase. |
Buying_0_Cost | uint32 | 25 | Amount paid to the player per unit. |
Buying_0_Conditions | uint8 | 0 | Conditions for this buying entry to appear. |
Example Vendor .dat
ID 8001
GUID g7h8i9j0k1l2453mabc4d5e6f7a8b9c0
Type Vendor
Name ExampleTraderVendor
Selling 2
Selling_0_Type Item
Selling_0_ID 255
Selling_0_Cost 200
Selling_1_Type Item
Selling_1_ID 56
Selling_1_Cost 50
Selling_1_Conditions 1
Selling_1_Condition_0_Type Quest_Flag_Bool
Selling_1_Condition_0_ID 100
Selling_1_Condition_0_Value True
Selling_1_Condition_0_Logic Equal
Buying 1
Buying_0_Type Item
Buying_0_ID 394
Buying_0_Cost 25In this example: the NPC always sells item 255 (Emergency Kit) for 200 experience. Item 56 (Bandage) is unlocked for sale only after flag 100 is True (i.e., after the supply run quest completes). The NPC buys Medical Kits at 25 experience each.
The following diagram shows how the vendor evaluates which items to display when a player opens it:
English.dat for Vendors
Name Example Trader ShopThe display name is shown in the vendor window header.
Quest flag persistence
Quest flags are short integer or boolean values stored in the player's save file. They persist across server restarts and across sessions. Flags are keyed by a numeric ID (1–65535) that is shared across all quests and dialogues within the same mod. Flags from different mods do not conflict because Unturned scopes them to the mod's Workshop content ID.
Flag types
| Type | Storage | Range | Use case |
|---|---|---|---|
| Boolean flag | bool | True / False | Quest completion state, binary unlock gates |
| Short integer flag | short | -32768 to 32767 | Quest step counters, reputation scores, item delivery counts |
Flag ID management
Flag ID collisions are silent and destructive
If two quests use the same flag ID with different intentions — for example, Quest A uses flag 100 as a completion gate and Quest B uses flag 100 as a kill counter — the quests will corrupt each other's state. The system does not report this conflict at load time. All validation is on the author. Maintain the flag registry document described below before authoring the second quest in any mod.
The cohort's convention for flag ID management is to maintain a flags.md document within the mod's source folder that lists every flag ID, its type, its name, and the quests that read and write it. This prevents two quests from accidentally using the same flag ID with different semantics.
Example flags.md:
Flag 100 (Bool) — supply_run_complete
Written True by: Quest 7001 (ExampleSupplyRun) on completion
Read by: Dialogue 6002 (ExampleTraderDialogue_Complete), Vendor 8001 (ExampleTraderVendor)
Flag 101 (Short) — supply_runs_completed_count
Incremented by: Quest 7001 on each completion (if repeatable)
Read by: Dialogue 6003 (ExampleTraderDialogue_Repeat) for unlocking new quests
Flag 102 (Bool) — advanced_trader_unlocked
Written True by: Quest 7002 (AdvancedSupplyRun) on completion
Read by: Vendor 8001, Selling_2 (advanced item unlocked after this quest)Using flags for quest chaining
Quest chains are built by using a completion quest's Reward_N_Type Quest_Flag_Bool to set a flag, and then using that flag as a condition in the next quest's dialogue or in an unlocked vendor entry. This pattern supports arbitrarily deep quest chains without requiring plugin code.
Repeatable quests
A quest is repeatable if the server resets the completion flag when the quest is turned in. Author a repeatable quest by using a Quest_Flag_Short counter instead of a Quest_Flag_Bool completion flag, and not gating the quest offer on the flag value. The quest remains available after each completion because there is no Quest_Status = Completed gate blocking re-entry.
For economy-critical quests (supply runs, material delivery), the cohort recommendation is to use a repeatable short-counter flag to track the number of completions and to use that counter to unlock higher-tier quests at specific completion thresholds.
Cross-linking to custom item assets
Quest rewards can reference custom modded items by GUID. The item must be in the same Workshop mod or in a mod that is loaded before the quest mod. Cross-references to custom items follow the same pattern as the throwable asset reference: use the item's GUID in the reward field, not its numeric ID.
Reward cross-linking example — giving a custom modded item as a quest reward:
Reward_0_Type Item
Reward_0_GUID a9b8c7d6e5f4321a987654321fedcba01
Reward_0_Amount 1The GUID a9b8c7d6e5f4321a987654321fedcba01 is the GUID from the custom item's own .dat file. Because GUIDs are stable across ID renumbering, this cross-reference remains valid even if the item's numeric ID changes during a mod update.
Load order for cross-mod reward references
If the reward item is in a separate mod from the quest, the item mod must be loaded before the quest mod. Unturned resolves GUID cross-references at load time, not at runtime. If the item mod loads after the quest mod, the reward item will be unresolved and the reward will silently fail to grant.
Complete worked example: supply run quest chain
The following section summarizes all four asset files for a minimal but complete supply run quest chain. Each file's content is shown in its final form.
Asset GUID register
| Asset | GUID |
|---|---|
| NPC: ExampleTrader | a1b2c3d4e5f6478aab1c2d3e4f5a6b7c |
| Dialogue: Root | d4e5f6a7b8c9410dabc1d2e3f4a5b6c7 |
| Dialogue: Complete | e5f6a7b8c9d0421eabc2d3e4f5a6b7c8 |
| Quest: ExampleSupplyRun | f6a7b8c9d0e1432fabc3d4e5f6a7b8c9 |
| Vendor: ExampleTraderVendor | g7h8i9j0k1l2453mabc4d5e6f7a8b9c0 |
System flow
Testing NPC encounters
Single-player testing
- Copy the mod's
Bundles/folder to the local Unturned™ install's Workshop directory. - Launch Unturned™ in single-player on a map that includes the NPC placement.
- Approach the NPC and press
F(or the configured interaction key) to open the dialogue. - Confirm the root dialogue message appears.
- Select the quest-start response. Confirm the quest appears in the quest log.
- Collect the required items and return to the NPC.
- Confirm the completion dialogue appears and the reward items appear in inventory.
- Confirm the quest is removed from the active quest log.
- Re-open the dialogue. Confirm the post-completion message appears (flag 100 = True condition).
- Open the vendor. Confirm conditional items are now visible.
Common single-player test failures
| Symptom | Cause | Resolution |
|---|---|---|
| NPC shows no dialogue on interact | NPC Dialogue GUID does not match any loaded Dialogue asset | Confirm GUID in NPC .dat matches GUID in Dialogue .dat header |
| Dialogue shows wrong message | Message condition flags are in unexpected state | Check flag state with a debug plugin or reset player save to test from a clean state |
| Quest does not appear in log | Dialogue response does not reference a valid Quest ID | Confirm Response_N_Quest matches Quest ID and Quest .dat is loaded |
| Quest conditions never met | Item ID in Condition does not match the item the player is carrying | Confirm item ID with @give command and inspect what the player receives |
| Reward item not received | Reward GUID not resolved | Confirm reward item mod is loaded before quest mod |
| Vendor shows no items | Vendor ID in dialogue response does not match loaded Vendor asset | Confirm Response_N_Vendor matches Vendor ID field |
| Conditional vendor items not visible | Flag condition uses wrong flag ID or value | Inspect flag state; confirm Quest reward sets the flag with the correct ID |
| Quest repeats when it should not | Completion flag not set or flag gate not in dialogue conditions | Add Quest_Status = Completed condition to quest-offer dialogue response |
Test with a clean player save
When testing NPC quests in single-player, the player save file accumulates flag state from previous test runs. A flag set to True in a prior session will remain True in the next session, which can cause conditional dialogues to show the post-completion state before you have completed the quest in the current test run. Keep a clean backup of the player save file and restore it at the start of each full test cycle.
Dedicated server testing
After single-player testing passes, deploy the mod to a dedicated server and repeat the test with at least two client connections:
- Client A completes the quest chain. Confirm flag persistence across a server restart.
- Client B joins fresh and completes the quest independently. Confirm flags are per-player, not global.
- Both clients open the vendor simultaneously. Confirm no inventory conflict.
- Restart the server. Confirm Client A's completed flag is still True on reconnect.
Flag persistence across restarts
Quest flags are saved in the player's .player save file on the server. They persist across server restarts automatically. If flag state is not persisting, the most likely cause is that the player save directory is being wiped on restart by a server management script. Confirm the save directory is excluded from any wipe scripts.

Frequently asked questions
How do I create an NPC that gives a quest without any dialogue?
An NPC must have a Dialogue asset — it cannot start a quest directly without dialogue. To create a minimal single-interaction quest-giver, author a Dialogue asset with one message and one response whose Response_0_Quest references the quest. This produces an NPC that shows one line of text and one "Accept" button.
Can a single dialogue node start multiple quests?
No. Each response field can reference at most one Quest ID (Response_N_Quest). To start multiple quests, author a chain of dialogue nodes where each node starts one quest and the response leads to the next node.
How many responses can a dialogue node have?
The Unturned dialogue system supports up to 8 responses per dialogue node. If more than 8 choices are needed, split the content across multiple dialogue nodes with a "More options..." response leading to the continuation node.
Can a vendor be opened from the map editor without an NPC?
No. Vendors are accessed exclusively through NPC dialogue responses. They cannot be opened by interacting with a placed object or environment element through the standard .dat system.
How do I make a quest reward give the player a vehicle?
Reward types include Vehicle in addition to Item. Use Reward_N_Type Vehicle and set Reward_N_ID to the vehicle's ID. The vehicle spawns near the player's position at the reward moment.
What is the maximum number of conditions per quest?
Unturned supports up to 8 conditions per quest. If more conditions are required, consider using a short-integer flag as an intermediate accumulator: a plugin increments the flag as each sub-condition is met, and the quest checks the flag value as its single condition.
How do I reference a custom modded item as a quest reward?
Use the Reward_N_GUID field with the custom item's GUID from its .dat file. Do not use the numeric ID for cross-mod references — numeric IDs are not guaranteed to be stable if the item mod is updated. GUIDs are stable identifiers. See Project Folder Structure and GUIDs for GUID management.
Can I use quests to track player kills or zombie kills?
Not through the standard quest .dat system. Kill tracking requires a plugin that increments a quest flag via the server API. The standard system supports item delivery, flag states, quest status, reputation, and time conditions — not event-based counters. To implement kill-count quests, use a RocketMod or OpenMod plugin that listens to death events and calls the Unturned API to increment a quest flag.
How does quest flag scoping work? Do flags conflict between mods?
Flags are scoped to the Workshop content ID of the mod that defines the quest. Flags used by Mod A do not conflict with flags in Mod B even if they share the same numeric ID. However, within a single mod, every flag ID is shared across all quests and dialogues. Maintain a flag registry (as described in the Flag ID Management section) to prevent intra-mod conflicts.
Can an NPC have different dialogue depending on the time of day?
Yes. Author two message entries in the dialogue node. Set Message_0_Condition_0_Type Time_Of_Day with a day range and Message_1_Conditions 0 as the fallback. The dialogue system evaluates the time-of-day condition at interaction time and shows the appropriate message.
How do I make an NPC disappear or stop responding after a quest is completed?
The standard NPC system does not support conditional NPC visibility through .dat authoring. Making an NPC disappear requires either a plugin that modifies NPC state at runtime, or placing the NPC in a conditional object group that is toggled by a plugin based on flag state.
Can the same NPC have both a Dialogue and a Vendor?
Yes. The NPC's Dialogue field links to a Dialogue asset. That Dialogue asset can have a response with Response_N_Vendor set to the Vendor ID. When the player selects that response, the vendor window opens. The NPC serves as the access point for both the dialogue tree and the vendor through the same interaction.
How do I test flag state during development without completing the full quest chain?
The cohort approach is to author a temporary debug dialogue node that sets flags to specific values via responses (using Response_N_Quest pointing at a debug quest whose only reward is setting the flag). This allows manual flag state control during development. Remove the debug node before publishing.
Appendix A: Complete .dat field reference tables
NPC asset fields — full reference
| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
ID | uint16 | Yes | — | Must be unique across all loaded mods |
GUID | uint128 | Yes | — | Globally unique; generate with a GUID tool |
Type | enum | Yes | — | Always NPC |
Name | string | Yes | — | Internal name; not player-visible |
Dialogue | uint128 | Yes | — | GUID of root Dialogue asset |
Pose | enum | No | Stand | Stand, Sit, Lean, Rest |
Equipped | uint16 | No | 0 | Visually held item ID |
Face | uint8 | No | 0 | 0–31 |
Hair | uint8 | No | 0 | Hair style index |
Beard | uint8 | No | 0 | Beard style index |
Skin | color | No | 255,204,153 | RGB |
Color_Hair | color | No | 80,40,10 | RGB |
Hat | uint16 | No | 0 | Clothing item ID |
Glasses | uint16 | No | 0 | Clothing item ID |
Vest | uint16 | No | 0 | Clothing item ID |
Shirt | uint16 | No | 0 | Clothing item ID |
Pants | uint16 | No | 0 | Clothing item ID |
Shoes | uint16 | No | 0 | Clothing item ID |
Christmas_Dialogue | uint128 | No | — | Seasonal override |
Halloween_Dialogue | uint128 | No | — | Seasonal override |
Quest condition types — full reference
| Type | Field: ID | Field: Value | Field: Amount | Field: Logic |
|---|---|---|---|---|
Item | Item numeric ID | — | Required quantity | — |
Quest_Flag_Bool | Flag numeric ID | True / False | — | Equal / Not_Equal |
Quest_Flag_Short | Flag numeric ID | Numeric | — | Equal / Not_Equal / Greater_Than / Less_Than |
Quest_Status | Quest numeric ID | None / Active / Completed | — | Equal / Not_Equal |
Skillset | — | Skillset name | — | Equal / Not_Equal |
Experience | — | — | XP amount | Greater_Than / Less_Than |
Reputation | — | — | Rep amount | Greater_Than / Less_Than |
Time_Of_Day | — | Time range string | — | — |
Player_Life_Food | — | — | Food stat | Greater_Than / Less_Than |
Player_Life_Water | — | — | Water stat | Greater_Than / Less_Than |
Quest reward types — full reference
| Type | Field: ID | Field: Amount | Field: GUID | Field: Modification |
|---|---|---|---|---|
Item | Item numeric ID or use GUID | Quantity | Optional; use instead of ID for modded items | — |
Quest_Flag_Bool | Flag numeric ID | — | — | — |
Quest_Flag_Short | Flag numeric ID | Value | — | Assign / Increment / Decrement |
Experience | — | XP amount | — | — |
Reputation | — | Rep delta | — | — |
Hint | — | — | — | — |
Effect | Effect numeric ID | — | — | — |
Teleport | — | — | — | Spawnpoint name |
Vehicle | Vehicle numeric ID | — | — | — |
Currency | — | Amount | Currency item GUID | — |
Appendix B: Flag ID reservation template
Copy this template into a flags.md file in each mod's source folder. Fill in entries as quests are authored. This prevents flag ID collisions within the mod.
# Quest Flag Registry — [Mod Name]
# Updated: [Date]
## Boolean Flags (True/False)
Flag ID | Name | Set by Quest | Read by
--------|-----------------------------|--------------|---------
100 | supply_run_complete | Quest 7001 | Dialogue 6002, Vendor 8001
101 | advanced_trader_unlocked | Quest 7002 | Vendor 8001 (Selling_2)
## Short Integer Flags (counter/score)
Flag ID | Name | Modified by | Read by
--------|-----------------------------|--------------|---------
200 | supply_runs_completed_count | Quest 7001 | Dialogue 6003 (threshold gate)
201 | player_reputation_score | Quest 7001/2 | Vendor 8001 (price modifier)
## Reserved Range
IDs 900–999: Reserved for future expansion.
IDs 1000+: Do not use in this mod.Appendix C: Useful references
| Resource | URL | Purpose |
|---|---|---|
| Smartly Dressed Games modding docs | https://docs.smartlydressedgames.com/en/stable/ | Official NPC, dialogue, and quest asset documentation |
| Unturned on Steam | https://store.steampowered.com/app/304930/Unturned/ | Official game page; verify current asset format version |
Cross-references
- RocketMod and OpenMod Plugin Basics — the previous article; plugins that extend quest and NPC functionality.
- Animation Events for Weapons — the next article; animation event system used in weapon mods that accompany quest rewards.
- Project Folder Structure and GUIDs — GUID generation and mod folder layout.
- Workshop Content on Dedicated Servers — deploying NPC mods to a dedicated server.
- Throwable Asset Reference — item asset format for custom items used as quest rewards.
- Smartly Dressed Games Modding Documentation — the primary reference for all asset field definitions.
- Unturned on Steam — game page for version reference.
Document history
| Version | Date | Author | Notes |
|---|---|---|---|
| 1.0 | 2025-05-18 | 57 Studios | Initial publication. NPC, Dialogue, Quest, and Vendor asset authoring; flag persistence; worked example. |
