Objectives
Objectives are conditions the player must complete to finish a quest. They are continuously checked while the quest is active. Objectives are different from Actions: objectives are things the player must do, actions are things that happen.
Objective Format
Each objective in a quest's objectives array follows this structure:
{
"id": "unique_objective_id",
"objectiveId": "kill",
"args": ["validCode1", "validCode2", "5"],
"onCompleteActions": [
{ "id": "notify", "args": ["Objective complete!"] }
]
}id— A unique identifier for this objective instance within the quest.objectiveId— The type of objective (e.g.kill,gather,walkdistance).args— An array of string arguments specific to the objective type.onCompleteActions— (Optional) Actions to execute when this objective is completed.
Mega Example: All Objective Types in One Quest
This is the most complex realistic example. It shows how to combine kill, gather, reach, check variable, land gate, sequence, and timer in a single quest:
{
"id": "yourmod:epic-quest",
"cooldown": -1,
"perPlayer": true,
"onAcceptedActions": [
{ "id": "playsound", "args": ["game:sounds/quest-accept", "0.8"] },
{ "id": "resetwalkdistance", "args": ["yourmod:epic-quest"] },
{ "id": "resettimer", "args": ["yourmod:epic-quest", "timer1"] }
],
"killObjectives": [
{ "validCodes": ["wolf-*"], "demand": 5 }
],
"gatherObjectives": [
{ "validCodes": ["game:herb-*"], "demand": 10 }
],
"actionObjectives": [
{
"id": "walk_500m",
"objectiveId": "walkdistance",
"args": ["yourmod:epic-quest", "500", "0"]
},
{
"id": "reach_temple",
"objectiveId": "reachwaypoint",
"args": ["5120,68,5340", "5"]
},
{
"id": "check_blessing",
"objectiveId": "checkvariable",
"args": ["blessed", "==", "true"]
},
{
"id": "enter_village",
"objectiveId": "landgate",
"args": ["derevnia", "enter_village", "Enter: ", "false"]
},
{
"id": "do_steps_in_order",
"objectiveId": "sequence",
"args": [
"yourmod:epic-quest",
"seq1",
"kill_5_wolves",
"gather_10_herbs",
"reach_temple"
]
},
{
"id": "timer1",
"objectiveId": "timer",
"args": ["yourmod:epic-quest", "timer1", "300"]
}
]
}What each part does:
| Objective | What the player must do |
|---|---|
kill | Kill 5 wolves |
gather | Collect 10 herbs |
walkdistance | Walk 500 meters total |
reachwaypoint | Reach the temple at 5120,68,5340 (radius 5) |
checkvariable | Have the blessed attribute set to true |
landgate | Stand inside the derevnia land claim |
sequence | Complete kill, then gather, then reach in that exact order |
timer | Complete everything within 300 seconds (5 minutes) |
Objective-Level Actions
Each objective can fire its own onCompleteActions when it is finished. This is useful for updating the quest state or notifying the player:
{
"id": "reach_north",
"objectiveId": "reachwaypoint",
"args": ["5200,70,5400", "10"],
"onCompleteActions": [
{ "id": "playsound", "args": ["game:sounds/quest-step", "0.8"] },
{ "id": "notify", "args": ["yourmod:checkpoint-reached"] }
]
}What happens:
- When the player reaches the waypoint, a sound plays and a notification is sent.
- This is independent of the quest's
actionRewards— it fires immediately when the objective is done, not when the whole quest completes.
Complete Example
Here is a full quest that uses multiple objective types together. This is the pattern you copy when you want a quest with several steps:
{
"id": "yourmod:multi-step-quest",
"cooldown": -1,
"perPlayer": true,
"onAcceptedActions": [
{ "id": "playsound", "args": ["game:sounds/quest-accept", "0.8"] }
],
"killObjectives": [
{ "validCodes": ["wolf-male", "wolf-female"], "demand": 3 }
],
"gatherObjectives": [
{ "validCodes": ["game:herb-*"], "demand": 5 }
],
"actionObjectives": [
{
"id": "reach_temple",
"objectiveId": "reachwaypoint",
"args": ["5120,68,5340", "5"]
},
{
"id": "check_blessing",
"objectiveId": "checkvariable",
"args": ["blessed", "==", "true"]
}
]
}How the objectives work together:
killObjectives— the player must kill 3 wolves.gatherObjectives— the player must collect 5 herbs.reachwaypoint— the player must reach the temple at5120,68,5340(radius 5 blocks).checkvariable— the player must have the attributeblessedset totrue(usually set by a dialogue action).
All four must be completed before the quest becomes completable.
Quest with a Gate
A gate is an objective that must be satisfied before the quest can be completed, even if all other objectives are done. The most common gate is landgate — requiring the player to be inside a specific land claim.
{
"id": "yourmod:gate-example",
"cooldown": -1,
"perPlayer": true,
"onAcceptedActions": [
{ "id": "playsound", "args": ["game:sounds/quest-accept", "0.8"] }
],
"gatherObjectives": [
{ "validCodes": ["game:ingot-*"], "demand": 3 }
],
"actionObjectives": [
{
"id": "must_be_in_town",
"objectiveId": "landgate",
"args": ["town", "must_be_in_town", "Return to town: ", "false"]
}
]
}What happens:
- The player collects 3 ingots anywhere.
- The quest cannot be completed until the player walks back into the
townland claim. - The HUD shows:
Return to town: must_be_in_town
Gates and Sequences
Some objectives are designed to block progress until other conditions are met.
Sequence + Land Gate Combined
This example shows how to force the player to complete objectives in order, and then return to a safe zone:
{
"id": "yourmod:patrol-quest",
"cooldown": -1,
"perPlayer": true,
"actionObjectives": [
{
"id": "patrol_steps",
"objectiveId": "sequence",
"args": [
"yourmod:patrol-quest",
"patrol1",
"reach_north",
"reach_east",
"reach_south",
"return_base"
]
},
{
"id": "reach_north",
"objectiveId": "reachwaypoint",
"args": ["5200,70,5400", "10"]
},
{
"id": "reach_east",
"objectiveId": "reachwaypoint",
"args": ["5300,70,5400", "10"]
},
{
"id": "reach_south",
"objectiveId": "reachwaypoint",
"args": ["5300,70,5300", "10"]
},
{
"id": "return_base",
"objectiveId": "landgate",
"args": ["base", "return_base", "Return to base: ", "false"]
}
]
}How it works:
sequenceforces the player to visit the 4 waypoints in order.- The last step (
return_base) is alandgate— the player must enter thebaseland claim. - The quest cannot be completed until all 4 sequence steps are done and the player is inside
base.
Sequence
Forces objectives to be completed in order. The next objective only becomes active after the previous one is done:
{
"id": "quest_01",
"objectiveId": "sequence",
"args": [
"myquest",
"seq1",
"step1_kill",
"step2_gather",
"step3_reach"
]
}step1_killmust be completed first- Then
step2_gatherbecomes active - Then
step3_reachbecomes active
💡 Sequence works with any objective type. The objective IDs in args can be killObjectives, gatherObjectives, or actionObjectives — the sequence controller finds them by their id field.
Land Gate
Blocks a quest until the player is standing inside a specific land claim:
{
"id": "gate_village",
"objectiveId": "landgate",
"args": ["derevnia", "enter_village", "Enter: ", "false"]
}args[0]— the land claim nameargs[1]— the objective ID this gate is blockingargs[2]— HUD prefix (e.g.Enter:)args[3]— hide the prefix (true/false)
Kill Objectives
Track creature kills by entity code. The player must kill a certain number of matching entities.
{
"id": "kill_wolves",
"objectiveId": "kill",
"args": ["wolf-male", "wolf-female", "5"]
}args[0..n-1]— `One or more entity codes to match (supports wildcard*`).args[n]— `` The number of kills required (last element in args).
Gather Objectives
Track item collection. The player must have a certain number of matching items in their inventory.
{
"id": "gather_flax",
"objectiveId": "gather",
"args": ["flaxfibers", "10"]
}args[0..n-1]— `One or more item/block codes to match (supports wildcard*`).args[n]— `` The number of items required (last element in args).
Action Objectives
Action objectives cover a wide range of specialized conditions beyond simple kill/gather tracking. Each uses a unique objectiveId and its own argument format.
walkdistance
Requires the player to walk a certain distance in meters while the quest is active.
args[0]— `` The quest this objective belongs to (required).args[1]— `` Distance in meters the player must walk (required).args[2]— `` Tracking slot index (optional, default 0).
💡 Use the resetwalkdistance action to reset the distance counter if the quest is restarted or the objective needs to be re-tracked.
randomkill
Assigns a random kill target from a predefined slot. The target entity is selected randomly when the quest starts.
args[0]— `` The quest this objective belongs to (required).args[1]— `` The random kill slot identifier (required).
checkvariable
Checks a player attribute (variable) against a value using a comparison operator. Completes when the condition is true.
args[0]— `` The attribute/variable name to check (required).args[1]— `Comparison operator (required). Valid operators:=,==,>,>=,args[2]— `` The value to compare against (required).args[3]— `` Action string to execute on completion (optional).
timeofday
Completes when the in-game time matches the specified mode. Useful for quests that require waiting for day or night.
args[0]— `Time mode (required). Values:day,night, orstartHour,endHour(e.g.6,18` for daytime hours).
interactat
Completes when the player interacts (right-clicks) at one of the specified coordinates.
args[0]— `First coordinate inx,y,z` format (required).args[1..n]— `` Additional coordinates (optional). Any one match completes the objective.
interactcount
Counts the number of interactions at specified coordinates. Completes when the player has interacted the required number of times.
args[0..n-1]— `Coordinates inx,y,z` format (required).args[n]— `` Localization key for the HUD display text (last element).
plantflowers
Checks if a certain number of flowers are planted nearby the player.
args[0]— `` Number of flowers required nearby (required).
hasattribute
Checks if the player has a specific attribute set to a specific value. Completes when the attribute matches.
args[0]— `` The attribute key name (required).args[1]— `` The expected value (required).
reachwaypoint
Completes when the player reaches a specific coordinate within a given radius.
args[0]— `` Target coordinate (required).args[1]— `Detection radius in blocks (optional, default2`).
hasitem
Checks if the player currently has a certain number of items in their inventory.
args[0]— `Item code to match, supports wildcard*` (required).args[1]— `` Number of items required (required).
wearing
Checks if the player is wearing a specific item in their equipment slots.
args[0]— `Item code to match, supports wildcard*` (required).args[1]— `` Specific equipment slot index to check (optional, checks all slots if omitted).
interactwithentity
Tracks interactions with a specific entity. Completes after the required number of interactions.
args[0]— `` The quest this objective belongs to (required).args[1]— `` The entity code or ID to interact with (required).args[2]— `` Number of interactions required (required).
inland
Completes when the player is standing inside a specific land claim area.
args[0]— `` The name of the land claim to check (required).
landgate
A progress gate tied to a land claim. Used to block quest progression until the player has completed objectives within a claimed area.
args[0]— `` The land claim name (required).args[1]— `` The objective to gate behind (optional).args[2]— `` Display prefix for the HUD (optional).args[3]— `Whether to hide the prefix (true/false`, optional).
killnear
Tracks kills near a specific coordinate. Only kills within the radius count toward completion.
args[0]— `` The quest this objective belongs to (required).args[1]— `` Unique objective identifier (required).args[2]— `` Center coordinate (required).args[3]— `` Detection radius in blocks (required).args[4]— `Entity code to match, supports wildcard*(optional, default*` matches all).args[5]— `` Number of kills required (required).
killactiontarget
Requires the player to kill a target that was marked by a previous action (e.g. a spawned boss or marked entity).
args[0]— `` The quest this objective belongs to (required).args[1]— `` Unique objective identifier (required).args[2]— `` The target identifier set by the marking action (required).args[3]— `` Number of kills required (required).
sequence
Defines an ordered sequence of objectives that must be completed in order. The next objective only activates after the previous one is done.
args[0]— `` The quest this objective belongs to (required).args[1]— `` Unique identifier for this sequence (required).args[2..n]— `` Ordered list of objective IDs to complete in sequence (required).
temporalstorm
Requires the player to survive a number of temporal storms while the quest is active.
args[0]— `` The quest this objective belongs to (required).args[1]— `` Unique objective identifier (required).args[2]— `` Number of storms to survive (required).
Experimental Objectives
⚠️ These objectives are experimental and may change or be removed in future versions. Use them with caution in production quest packs.
Timed Challenge Example
Combine timer with other objectives to create a time-limited challenge:
{
"id": "yourmod:timed-hunt",
"cooldown": 24,
"perPlayer": true,
"onAcceptedActions": [
{ "id": "playsound", "args": ["game:sounds/quest-accept", "0.8"] },
{ "id": "resettimer", "args": ["yourmod:timed-hunt", "timer1"] }
],
"killObjectives": [
{ "validCodes": ["bear-male"], "demand": 1 }
],
"actionObjectives": [
{
"id": "timer1",
"objectiveId": "timer",
"args": ["yourmod:timed-hunt", "timer1", "120"]
},
{
"id": "reach_cave",
"objectiveId": "reachwaypoint",
"args": ["5000,60,5000", "5"]
}
]
}What the player must do:
- Kill 1 bear.
- Reach the cave at
5000,60,5000. - Do it all within 120 seconds (2 minutes).
If the timer expires before both objectives are done, the quest fails (or resets depending on your quest logic).
killwithweapon
Tracks kills made with a specific weapon type.
args[0]— `` The quest this objective belongs to (required).args[1]— `` Unique objective identifier (required).args[2]— `Weapon item code, supports wildcard*` (required).args[3]— `` Number of kills required (required).
harvestcrop
Tracks crop harvesting.
args[0]— `` The quest this objective belongs to (required).args[1]— `` Unique objective identifier (required).args[2]— `Crop block code, supports wildcard*` (required).args[3]— `` Number of crops to harvest (required).
mineblock
Tracks block mining/breaking.
args[0]— `` The quest this objective belongs to (required).args[1]— `` Unique objective identifier (required).args[2]— `Block code, supports wildcard*` (required).args[3]— `` Number of blocks to mine (required).
placeblock
Tracks block placement.
args[0]— `` The quest this objective belongs to (required).args[1]— `` Unique objective identifier (required).args[2]— `Block code, supports wildcard*` (required).args[3]— `` Number of blocks to place (required).
fishcatch
Tracks fish caught.
args[0]— `` The quest this objective belongs to (required).args[1]— `` Unique objective identifier (required).args[2]— `Fish item code, supports wildcard*` (required).args[3]— `` Number of fish to catch (required).
timer
A time-limit gate. The objective completes (or fails) after the specified number of seconds. Useful for timed challenges.
args[0]— `` The quest this objective belongs to (required).args[1]— `` Unique objective identifier (required).args[2]— `` Time limit in seconds (required).
💡 Use the resettimer action to reset the timer if the quest is restarted or the objective needs to be re-tracked.
craftitem
Tracks items crafted on the crafting grid.
args[0]— `` The quest this objective belongs to (required).args[1]— `` Unique objective identifier (required).args[2]— `Item code, supports wildcard*` (required).args[3]— `` Number of items to craft (required).
smeltitem
Tracks items smelted in a furnace or similar device.
args[0]— `` The quest this objective belongs to (required).args[1]— `` Unique objective identifier (required).args[2]— `Item code, supports wildcard*` (required).args[3]— `` Number of items to smelt (required).
Escort Quest Example
> ⚠️ EXPERIMENTAL — Requires EscortObjectiveEnabled: true in config.
A complete escort quest with a merchant:
{
"id": "yourmod:escort-merchant",
"cooldown": -1,
"perPlayer": true,
"onAcceptedActions": [
{ "id": "playsound", "args": ["game:sounds/quest-accept", "0.8"] },
{ "id": "spawnentity", "args": ["npc-merchant", "5200,70,5400", "merchant1"] }
],
"actionObjectives": [
{
"id": "escort_merchant",
"objectiveId": "escort",
"args": [
"yourmod:escort-merchant",
"escort1",
"npc-merchant",
"waypoint",
"5300",
"70",
"5500",
"5",
"failondeath=true",
"maxleashbreaks=5",
"timelimit=300",
"leashrange=25",
"warndistance=20"
]
}
]
}What happens:
- A merchant NPC spawns at
5200,70,5400. - The player must escort the merchant to
5300,70,5500. - The player must stay within 25 blocks (
leashrange). - The merchant must survive (
failondeath=true). - The player has 5 minutes (
timelimit=300). - If the player gets too far 5 times (
maxleashbreaks=5), the quest fails.
escort
> ⚠️ EXPERIMENTAL — Requires EscortObjectiveEnabled: true in config.
Escort a target entity. Two modes: proximity (stay near for N seconds) and waypoint (escort to destination).
Proximity Mode
Player must stay near a target entity for N seconds total. Leaving range pauses progress.
args[0]— `` The quest this objective belongs to (required).args[1]— `` Unique objective identifier (required).args[2]— `Entity code to escort, supports wildcard*` (required).args[3]— `` Total seconds to stay near the entity (required).args[4+]— `` Optional key=value options (see below).
{
"id": "escort_merchant",
"objectiveId": "escort",
"args": ["myquest", "escort1", "npc-merchant", "60", "failondeath=true", "maxleashbreaks=3"]
}Waypoint Mode
Entity moves toward a destination. Player must stay near until arrival.
args[0]— `` The quest this objective belongs to (required).args[1]— `` Unique objective identifier (required).args[2]— `Entity code to escort, supports wildcard*` (required).args[3]— `Literal string"waypoint"` to activate this mode (required).args[4]— `` Destination X coordinate (required).args[5]— `` Destination Y coordinate (required).args[6]— `` Destination Z coordinate (required).args[7]— `` Arrival radius in blocks (optional, default 5).args[8+]— `` Optional key=value options (see below).
{
"id": "escort_refugee",
"objectiveId": "escort",
"args": ["myquest", "escort1", "npc-refugee", "waypoint", "5120", "68", "5340", "5",
"failondeath=true", "ambushchance=0.05", "ambushentity=game:wolf-male", "ambushcount=3"]
}Options
Append as key=value strings after the main arguments:
| Option | Default | Description |
|---|---|---|
failondeath | true | Fail if escort target dies |
maxleashbreaks | 3 | Max times player can be too far. -1 = unlimited |
timelimit | 0 | Time limit in seconds. 0 = no limit |
leashrange | 20.0 | Distance at which leash breaks |
warndistance | 15.0 | Distance for warning message |
speedmult | 1.0 | NPC movement speed (waypoint mode) |
ambushchance | 0.0 | Chance (0-1) per tick of enemy ambush |
ambushentity | — | Entity code to spawn during ambushes |
ambushcount | 2 | Enemies per ambush |
Failure Conditions
The escort fails if:
- Leash broken — Player too far too many times (
maxleashbreaks) - Target died — Escort entity killed (if
failondeath=true) - Time expired — Time limit reached (if
timelimitset)
💡 Waypoint mode uses simple direct movement. For complex pathfinding, configure the entity's AI tasks and use proximity mode instead.
defendpoint
Tracks waves survived at a defend point. Completes when N waves are cleared.
args[0]— `` The quest this objective belongs to (required).args[1]— `` Unique objective identifier (required).args[2]— `` Number of waves to survive (required).
💡 Requires external system to signal wave completion via DefendPointObjective.TryIncrement.
timedkill
Kill N entities within a time limit. Timer starts on first kill, resets if time expires before reaching the target.
args[0]— `` The quest this objective belongs to (required).args[1]— `` Unique objective identifier (required).args[2]— `Entity code, supports wildcard*` (required).args[3]— `` Number of kills required within the time window (required).args[4]— `` Time limit in seconds (required).