Execution Order

If a response has an item:...:true requirement (consume on use), items are removed before actions execute. Actions themselves run in the order they appear in the list. A page:pageId action navigates immediately — place it last in the list.

Auto-Triggered Pages

Every page has an optional AutoTrigger boolean field (default false). When set to true, QuestLines checks the page's requirements on every HUD tick for all online players. As soon as requirements pass, the page's LoadActions are executed automatically — no NPC interaction required and no dialogue UI is shown.

Typical use cases:

  • Auto-start intro quests — trigger a quest start the first time a new player connects.
  • Passive milestones — detect when a player reaches a kill count or level and award a bonus quest.
  • World-event gates — fire effects when a global:hastag world flag is set.
  • Location-based triggers — combine with nearPosition or zone requirements to fire when a player enters an area.
Prevent Re-Firing Every Tick

An auto-triggered page fires every tick while its requirements pass. You must prevent this from looping. The standard pattern is to add a !hastag:someflag (or notTag:someflag) requirement and an addTag:someflag load action so it fires exactly once per player. You can also use setTimestamp: + cooldown: for time-gated repeatable triggers.

Example — auto-start an intro quest on first login

{
  "Id":           "auto_welcome",
  "AutoTrigger": true,
  "Requirements": ["questNotStarted:intro_quest", "!hastag:intro_fired"],
  "LoadActions":  ["addTag:intro_fired", "questStarted:intro_quest", "chat:Welcome to the server, {username}!"]
}

Example — location-based trigger (fires once when player enters area)

{
  "Id":           "dungeon_entrance_trigger",
  "AutoTrigger": true,
  "Requirements": [
    "questStarted:dungeon_quest",
    "nearPosition:450:64:-210:20",
    "!hastag:dungeon_entered"
  ],
  "LoadActions": [
    "addTag:dungeon_entered",
    "setMarker:dungeon_exit:Exit:460:64:-250:Portal",
    "sound:world.dungeon_ambience"
  ]
}
Tick Rate & Scope

Auto-trigger checks run at the same interval as the Quest Goal HUD refresh (configurable via hud_refresh_rate in QuestLines.conf, default 500 ms). The check runs independently for every online player — it starts when a player connects and stops when they disconnect. Auto-trigger pages do not open a dialogue UI and are never reachable via NPC interaction.

Commands

Runs a server command either from the console or as the interacting player. This allows bridging QuestLines with any other plugin that supports commands.

FormatDescription
command:commandText:server Runs commandText as the server console (op-level permissions).
command:commandText:player Runs commandText as the interacting player (player's permission level).
command:commandText:player:elevated Runs commandText as the player with a transient wildcard permission grant. Requires VaultUnlocked; falls back to normal player execution if unavailable.
No Colons in Command Text

The command text is parsed by splitting on :. If your command contains a colon (e.g. a plugin command like myplugin:subcmd), the parser will break. Use an alias or a wrapper command instead.

Example

// Teleport the player via console command
"Actions": ["command:tp Steve 100 64 -200:server"]

// Player runs a command (e.g. to join a minigame)
"Actions": ["command:joinqueue arena:player"]

Chat

Sends a plain chat message directly to the interacting player. Supports all TextFormatter variables (e.g. {username}, {variable:name}). Everything after chat: is the message — colons in the message text are allowed.

FormatDescription
chat:message text here Sends the message to the triggering player's chat. Colons in the message are preserved.

Example

// Simple confirmation message
"Actions": ["chat:Your quest has been recorded, {username}."]

// Used in an if: branch to inform the player of a condition
"Actions": [
  "if:hasTag:quest_started::chat:You already have this quest!::startquest:my_quest"
]

Cooldown & Timer

FormatDescription
setTimestamp:key Records the current server time under key in the player's timestamps. Used with the cooldown:key:seconds requirement.
timedStart:key Records the current server time under key. Use with timedActive:key:seconds / timedExpired:key:seconds.
timedStart:key:durationSeconds Same as above, but also stores the duration so the requirements can be written as just timedActive:key / timedExpired:key (without repeating the seconds). The stored duration is used when no seconds argument is given to those requirements.
setTimestamp vs timedStart

Both actions write to the same timestamps map. The names differ only for readability: use setTimestamp for cooldown gates (reward timers, NPC chat limits) and timedStart for countdown timers (timed quests, races). Do not reuse the same key for both purposes.

Example

// Grant daily reward and reset the cooldown clock
"Actions": [
  "item:daily_chest:1",
  "setTimestamp:daily_reward"
]

// Start a 5-minute countdown timer
"Actions": [
  "startquest:courier_run",
  "timedStart:courier_timer"
]

Dialogue Navigation

Immediately navigates the player to a different dialogue page without closing the UI. This enables branching conversations, sub-menus, and multi-step dialogue trees that don't require NPC re-interaction.

FormatDescription
page:pageId Navigates the player's open dialogue to the specified page. Place this last in the actions list.
💡
Use for Branching Dialogue

Hub pages with no quest logic can use page:pageId exclusively to route players to topic-specific sub-pages. The sub-pages can themselves have actions or further navigation. See Quest Patterns → Branching Dialogue.

Example

// Hub page response routes to a lore sub-page
"Responses": [{ "Text": "Tell me about the ancient war.", "Actions": ["page:elder_lore_war"] }]

Economy (VaultUnlocked optional dependency)

Give or take currency from the player's economy account. Requires VaultUnlocked with a compatible economy provider. Actions are silently ignored if VaultUnlocked is not installed.

FormatDescription
economy:give:amount Deposits amount into the player's economy account.
economy:take:amount Withdraws amount from the player's economy account. Use economy:canafford:amount as a requirement to guard this.
💡
Always Guard economy:take with a Requirement

Pair economy:take with an economy:canafford:amount requirement on the same response. This prevents the action from firing if the player's balance is insufficient.

Example

// Quest reward — deposit gold into the player's account
"Actions": [
  "completequest:merchant_errand",
  "economy:give:250"
]

// Purchase response — require funds, then deduct them
"Responses": [{
  "Text":         "I'll buy the map for 100 gold.",
  "Requirements": ["economy:canafford:100"],
  "Actions":      ["economy:take:100", "item:treasure_map:1"]
}]

Global State (server-wide)

Manage server-wide tags and variables stored in GlobalData. Unlike per-player tags and variables, these affect and are visible to all players. Changes are persisted to QuestLines/global.json immediately.

FormatDescription
global:addtag:tagName Adds tagName to the server-wide global tag list. No effect if already present.
global:removetag:tagName Removes tagName from the server-wide global tag list.
global:variable:name:set:value Sets the global variable to value exactly.
global:variable:name:add:value Adds value to the global variable.
global:variable:name:subtract:value Subtracts value from the global variable.
global:variable:name:multiply:value Multiplies the global variable by value.
global:variable:name:divide:value Divides the global variable by value. Division by zero is ignored.

Example

// Start a world event by setting a global tag
"Actions": ["global:addtag:world_event_active"]

// Increment a server-wide boss kill counter
"Actions": ["global:variable:boss_kills:add:1"]

Items

FormatDescription
item:itemId:qty Gives qty of the specified item to the player and shows an item-received notification.

Example

// Reward the player for completing a quest
"Actions": [
  "completequest:bounty_hunter",
  "item:gold_coin:50",
  "item:health_potion:3"
]

If Action

Executes actions conditionally based on whether a set of requirements passes. Uses :: as a delimiter between the requirements, the then-branch actions, and an optional else-branch. Each section is a comma-separated list. Brackets [] around lists are accepted but optional.

FormatDescription
if:req::thenAction Runs thenAction when the requirement passes. No else branch.
if:req::thenAction::elseAction Runs thenAction when the requirement passes; elseAction when it fails.
if:req1,req2::[thenA,thenB]::[elseA,elseB] All requirements must pass (AND logic). Brackets optional around comma-separated action lists.
page: not supported inside if:

The page:pageId navigation action cannot be used in the then or else branches of an if: action.

Example

// Flag the player only if they haven't been flagged before
"Actions": ["if:notTag:visited::addTag:visited"]

// Grant a bonus quest if a prerequisite is complete, otherwise inform the player
"Actions": [
  "if:questCompleted:main_quest::startquest:bonus_quest::chat:Complete the main quest first!"
]

// Multiple requirements and multiple actions in each branch
"Actions": [
  "if:hasTag:vip,questCompleted:tutorial::[startquest:vip_quest,chat:Welcome VIP!]::[chat:You are not eligible yet.]"
]

Quest Items

Quest items live in the player's virtual quest inventory — a separate storage tracked by QuestLines, not the player's real item pack. They cannot be dropped, lost, or consumed by normal item: requirements. Use questitem:itemId:qty in Requirements to check them, and removequestitem: to take them back. Quest items are visible to the player in the Quest Items tab of the journal.

FormatDescription
givequestitem:itemId:qty Adds qty of the item to the player's virtual quest inventory. The item is not placed in the real pack.
removequestitem:itemId:qty Removes up to qty of the item from the player's virtual quest inventory. Has no effect on the real pack.

Example

// Give the player a quest item on quest start
"Actions": [
  "startquest:artifact_hunt",
  "givequestitem:Ancient_Medallion:1"
]

// Turn in — require the item in Requirements, then remove it in Actions
"Requirements": ["questitem:Ancient_Medallion:1"]
"Actions": [
  "removequestitem:Ancient_Medallion:1",
  "completequest:artifact_hunt"
]

Journal Log Tag

QuestLines automatically maintains a log:questId:pageId tag for every quest a player has interacted with. It records the last dialogue page the player actually saw for that quest and is the data source that powers the Quest Journal (/journal).

You never write this tag yourself. The engine writes it in two places:

  • When a player opens NPC dialogue — the resolved page is logged immediately.
  • When a page:pageId response navigates to a new page — the target page is logged before its load actions run.

At most one log:questId:* tag exists per quest per player at any time; the old entry is replaced automatically. The tag persists after quest completion so the Journal can show the final dialogue for completed quests.

No Action Required

Do not add addTag:log:… to your LoadActions or response Actions. The engine handles this automatically. If you see a stale log: tag in player data during debugging, it is always safe to remove it manually via /ql player <name> in the admin UI.

Load Actions

In addition to response Actions, every Page has a LoadActions field — a list of action strings that run automatically whenever that page is displayed. This happens both on the initial NPC interaction and whenever a page:pageId response navigates to the page. Load actions fire before the player sees any response buttons and regardless of which button they eventually click.

Use LoadActions for side-effects that should happen once per page view, not once per response click — for example, setting a tag, recording a timestamp, or running a server command that logs the visit.

Old Configs

LoadActions defaults to an empty list if omitted. Existing page configs that predate this field work without any changes.

JSON field

{
  "Id":           "my_quest_hub",
  "Requirements": ["questStarted:my_quest"],
  "LoadActions":  ["setTimestamp:last_visit_hub"],
  "Dialog":      "Welcome back, {username}.",
  "Responses": [{ "..." }]
}
💡
Supported Actions

Any action string that works in a response Actions list also works in LoadActions. The same execution rules apply: actions run in order, and page:pageId navigation is supported but should be placed last.

Objectives

Every Page has an optional Objectives list — an array of requirement strings (same format as Requirements). When non-empty, the Quest Goal HUD and Journal display an auto-generated pass/fail objectives list.

Which page's objectives are shown?

The HUD and journal always show objectives for the player's current page — determined by page resolution. The engine walks the quest's Pages list in order and picks the first page whose Requirements pass for that player. That page's Objectives are what appear on screen. As the player completes steps and requirements start passing, page resolution advances automatically and the displayed objectives update with it — no extra configuration needed.

Each objective is evaluated live and rendered as a labelled line with a progress counter where applicable:

// HUD / journal output
✓ Kill zombie: 5/5
· Break oak_log: 2/10
· Have iron_sword x1

The pass indicator is (green) when the requirement passes and · (grey) when it does not. Requirements that have a tracked progress counter (kills, breaks, places, talk, travel, fish, etc.) show current/required alongside the label. Requirements with no counter (e.g. item:, questCompleted:) show only the label.

Contextual Requirements Skipped

Contextual requirements (e.g. npcname:) are skipped during objective evaluation because they depend on the active NPC interaction, which is not available in the HUD or journal context.

Backwards Compatibility

Objectives defaults to an empty list if omitted. Pages without Objectives show nothing in the HUD goal area.

JSON field

{
  "Id":           "collect_wood",
  "Requirements": ["questStarted:lumber_run"],
  "Objectives":   [
    "break:oak_log:10",
    "item:iron_axe:1"
  ],
  "Dialog":      "Come back when you have the wood."
}
💡
Objectives vs Requirements

Objectives are purely display — they do not gate the page. If you also want to block navigation until the objectives are complete, add the same strings to the page Requirements or to the relevant response's Requirements.

MMO Skill XP (MMOSkillTree optional dependency)

Gives XP to a player's MMO skill. Requires the MMOSkillTree plugin to be active; silently ignored if not installed. Skill IDs are case-insensitive.

FormatDescription
mmo:xp:skillId:give:amount Awards amount XP to the player in the specified skill (e.g. MINING, CRAFTING).

Example

// Give 500 Mining XP as a quest reward
"Actions": [
  "completequest:miners_task",
  "mmo:xp:MINING:give:500"
]

Named Variables

Named variables are numeric values stored per-player. They can be used to track arbitrary numeric state — scores, choices, counters, or anything that doesn't fit a kill/break counter. Variables default to 0 if never set. Fractional values are supported.

FormatDescription
variable:name:set:value Sets the variable to value exactly. Use this to initialise a variable at quest start.
variable:name:add:value Adds value to the variable.
variable:name:subtract:value Subtracts value from the variable.
variable:name:multiply:value Multiplies the variable by value.
variable:name:divide:value Divides the variable by value. Division by zero is ignored.
Initialise Before Use

Always use variable:name:set:0 (or another initial value) in your quest-start actions before any add, subtract, or multiply operations. While variables default to 0, being explicit avoids surprises if a player repeats a quest.

💡
Variables in Action Strings

{variable:name} substitution works inside action strings, not just dialog text. This lets named variables drive action parameters at runtime.

// Spawn count and delay are taken from named variables
"spawn:Zombie:~0:~0:~0:{variable:delay}:{variable:amount}"

Example

// Quest start — initialise a score variable
"Actions": [
  "startquest:my_quest",
  "variable:score:set:0"
]

// Response that increments the counter
"Actions": ["variable:score:add:1"]

// Response that doubles it
"Actions": ["variable:score:multiply:2"]

Use {variable:name} in dialog text to show the current value to the player. Use variable:name:comparison:value requirements to gate pages or responses on the variable's value. See Requirements → Named Variables and Text Variables.

NPC Spawning

Spawn NPCs in the world as a result of player actions — useful for scripted events, quest escorts, ambushes, and environmental storytelling. Spawned NPCs are not persisted to disk; they exist only until the server restarts or they are killed.

FormatDescription
spawnCitizen:citizenName:x:y:z Spawns a visual clone of the HyCitizens NPC with that display name at the given world coordinates. Copies model, skin, scale, and appearance. Spawns in the player's current world.
spawnCitizen:citizenName:x:y:z:delaySeconds Same as above, but waits delaySeconds (integer) before spawning. Useful for dramatic timing.
spawnCitizen:citizenName:x:y:z:delaySeconds:quantity Spawns quantity clones simultaneously (minimum 1). Combine with a delay as needed.
spawn:npcRoleId:x:y:z Spawns a standard Hytale NPC by role ID at the given coordinates. Default rotation (0, 0, 0).
spawn:npcRoleId:x:y:z:delaySeconds Same as above with an optional spawn delay in seconds.
spawn:npcRoleId:x:y:z:delaySeconds:quantity Spawns quantity NPCs simultaneously. Combine with a delay as needed.
spawnCitizen Lookup

spawnCitizen matches by the display name of an existing HyCitizens NPC. If multiple NPCs share the same display name, the first match is used. The spawned copy has no quest linkage — it is purely visual.

💡
Relative Coordinates

Coordinates for both spawnCitizen and spawn support a ~ prefix to specify a position relative to the player. For example, ~5 means 5 units ahead on that axis, and ~ or ~0 means exactly at the player's position on that axis.

// Spawn 3 units in front of and 1 unit above the player
"spawnCitizen:Bandit Guard:~3:~1:~0"

Example

// Spawn a bandit immediately at a fixed position
"Actions": [
  "startquest:ambush",
  "spawnCitizen:Bandit Guard:120:64:-340"
]

// Spawn after a 3-second dramatic pause
"Actions": [
  "startquest:ambush",
  "track:bandit_kills:killcitizen:Bandit Guard",
  "spawnCitizen:Bandit Guard:120:64:-340:3"
]

// Spawn a standard Hytale NPC by role
"Actions": ["spawn:goblin_warrior:200:70:100"]

OrbisGuard Regions (OrbisGuard optional dependency)

Add or remove the interacting player as a member of an OrbisGuard region. Requires OrbisGuard to be active; silently ignored if not installed.

FormatDescription
regionaddmember:regionId Adds the player as a member of the named OrbisGuard region.
regionremovemember:regionId Removes the player from the named OrbisGuard region's member list.

Example

// Grant access to the guild hall region on quest complete
"Actions": [
  "completequest:guild_initiation",
  "regionaddmember:guild_hall"
]

Player Tags

Tags are free-form string labels stored on a player's data. They can represent any custom boolean state — visited locations, made choices, unlocked content, etc. Adding a tag that already exists is a no-op (idempotent).

FormatDescription
addTag:tagName Adds the tag to the player's tag list. No effect if already present.
removeTag:tagName Removes the tag. If the tag is a tracking flag, also resets the associated counter (see Tracking Flags below).

Example

// Record that the player chose a path in branching dialogue
"Actions": ["addTag:chose_merchant_path"]

// Remove a tag when a condition is no longer relevant
"Actions": ["removeTag:pending_escort"]

Quest State

FormatDescription
startquest:questId Adds the quest to the player's started quests list and displays a "Quest Started" notification on screen.
completequest:questId Adds the quest to completed quests, removes it from started quests, and shows a "Quest Completed" notification.
removequest:questId Removes the quest from both started and completed lists. Useful for resettable or repeatable quests.

Example

// Accept the quest and begin tracking kills (Goblin* matches Goblin_Duke, Goblin_Miner, etc.)
"Actions": [
  "startquest:lost_sword",
  "track:goblin_kills:kill:Goblin*"
]

// Complete the quest and tear down tracking
"Actions": [
  "completequest:lost_sword",
  "untrack:goblin_kills"
]

Random

Picks one action at random from a bracket-delimited comma-separated list and executes it. Each option in the list is an action string. Only one option is chosen and run per execution. The selection is uniformly random.

FormatDescription
random:[action1,action2,action3] Picks one of the listed actions at random and executes it. Enclose the list in [ and ], comma-separated.
page: not supported inside random

The page:pageId navigation action cannot be used inside a random: bracket list. Use separate responses with different page actions if you need random navigation.

Example

// Give one of three random item rewards
"Actions": [
  "completequest:loot_chest",
  "random:[item:gold_coin:10,item:health_potion:3,item:rare_gem:1]"
]

RPG Leveling XP (RPGLeveling optional dependency)

Gives XP to a player's global RPG level. Requires the RPGLeveling plugin to be active; silently ignored if not installed.

FormatDescription
rpgxp:give:amount Awards amount XP to the player's global RPG level.

Example

// Give 200 RPG XP as a quest reward
"Actions": [
  "completequest:training_quest",
  "rpgxp:give:200"
]

Sound

Plays a sound event. Use /sound in-game to browse all available sound event names. Supports 2D (player-relative) and 3D (world-positioned) playback. Coordinates support ~ prefix for player-relative values.

FormatDescription
sound:soundName Plays the named sound event to the interacting player only (2D).
sound:soundName:true Plays the named sound event to all online players (2D broadcast).
sound:soundName:x:y:z Plays a 3D positional sound at the given world coordinates. Broadcasts to all nearby players within the sound's natural max distance. Coordinates support ~ prefix (e.g. ~0:~5:~0).
sound:soundName:x:y:z:player Same as above but only plays to the triggering player (still distance-checked from the specified position).

Example

// Play a quest-complete fanfare for the player
"Actions": [
  "completequest:lost_sword",
  "sound:ui.quest_complete"
]

// Announce a world event to all players
"Actions": ["sound:world.boss_roar:true"]

Title

Shows a large event title on screen. Supports all TextFormatter variables in both the primary and secondary text.

FormatDescription
title:primary Shows the primary message to the triggering player.
title:primary:secondary Primary message with a subtitle below it.
title:primary:secondary:server Broadcasts to all players in the world instead of just the triggering player.
title:primary:secondary:player Explicit player-only (default). Same as omitting the third segment.
title:primary:secondary:server:true Server broadcast with major (large) title style.

Example

// Show a dramatic boss-intro title to all players
"Actions": [
  "title:The Lich Awakens:Prepare for battle:server:true"
]

// Personal quest-complete message
"Actions": [
  "completequest:main_quest",
  "title:Quest Complete!:Well done, {username}"
]

World Map Markers

Place and remove markers on a player's world map. Markers persist across sessions until explicitly removed. Sending the same id again replaces the existing marker.

FormatDescription
setMarker:id:label:x:y:z Place a map marker. id uniquely identifies this marker (used for updates/removal). label is the display text. x:y:z are world coordinates (support ~ relative prefix).
setMarker:id:label:x:y:z:image Same with a custom icon. image is the marker image name — .png is appended automatically. Marker images live in Common/UI/WorldMap/MapMarkers/.
setMarker:id:label:x:y:z:image:RRGGBB Same with a hex tint color applied to the icon (e.g. FF0000 for red).
removeMarker:id Remove the marker with the given id. The marker clears from the client on reconnect.
Built-in marker icons

Default icons available out of the box: Home, Spawn, Portal, Warp, Death, Campfire, Coordinate, Temple_Gateway, PortalInvasion, UserAUserF. Add custom icons to Common/UI/WorldMap/MapMarkers/ in your resource pack.

Example

// Mark an objective location when a quest starts
"Actions": [
  "questStarted:lost_sword",
  "setMarker:goblin_cave:Goblin Cave:450:64:-210:Coordinate:FF6600"
]

// Remove the marker on quest completion
"Actions": [
  "questCompleted:lost_sword",
  "removeMarker:goblin_cave"
]

Macro

Executes a named macro defined in QuestLines/macros/. Each macro is stored as its own <name>.json file. Action macros reuse common action sequences; requirement macros group reusable conditions. Circular references are detected and logged as a warning.

FormatDescription
macro:name Runs every action in the named action macro in order. If used in a requirement list, evaluates the named requirement macro. Unknown macro names are silently ignored (actions) or pass by default (requirements).
Macro file format (QuestLines/macros/<name>.json)

Each macro is a separate JSON file. "Type" is "action" or "requirement". Requirement macros AND all entries by default; add "AnyMode": true to use OR logic (at least one must pass).

// macros/give_rewards.json — action macro
{
  "Type": "action",
  "Entries": ["economy:give:500", "item:Gold_Coin:5", "addTag:rewarded"]
}

// macros/is_vip.json — requirement macro with AnyMode (OR)
{
  "Type": "requirement",
  "AnyMode": true,
  "Entries": ["hasTag:vip", "permission:has:server.vip"]
}

Macros can be created and edited from the in-game editor under the Macros tab in /ql quest. Legacy macros.json files are automatically migrated to per-file format on load.

Example

// Complete the quest and give rewards using a macro
"Actions": [
  "completequest:main_quest",
  "macro:give_rewards"
]

// Gate a response on a VIP requirement macro (OR logic)
"Requirements": ["macro:is_vip"]

Delay

Pauses execution of the remaining actions for a given number of seconds, then resumes. Player data is re-fetched after the delay so variable checks stay current. Decimal values are supported for sub-second precision.

FormatDescription
delay:N Wait N seconds before continuing. N may be a decimal (e.g. 0.5, 2.5).
Not supported inside random:

delay: cannot be used inside a random:[...] bracket list.

Example

// Give a reward then show a title 1.5 seconds later
"Actions": [
  "item:Health_Potion:3",
  "delay:1.5",
  "title:Potions received!"
]

Named Trackers

Named trackers are the preferred way to set up progress counting. Instead of adding a tag, writing a separate requirement, and using a separate variable, a single ID ties everything together. Old tracking flags continue to work.

FormatDescription
track:id:type:[target1,target2] Creates (or resets) a named tracker. id is a unique name you choose. type is one of: kill, killcitizen, block, place, playerkill, travel, craft, harvest, pickup, catchfish, catchfishbiome, catchfishrarity, catchfishzone, releasefish. Targets use a comma-separated bracket list or a bare single value; * matches any.
track:id:type:[targets]:exclude:[excl1,excl2] Same as above with an exclusion filter. Events whose value matches an exclude pattern are ignored even if they matched a target.
track:[id1,id2]:type:[targets] Bracket list on the ID creates multiple trackers with the same config in one action.
untrack:id / untrack:[id1,id2] Removes the named tracker(s) and resets the count to zero.

Example — kill 10 undead:

// Setup (on quest-start response)
"track:undead:kill:[zombie,skeleton,phantom]"

// Requirement (on completion page)
"track:undead:10"

// Variable in dialogue
"You have slain {track:undead} undead so far."

// Objective entry
"track:undead:10::Kill Undead"

// Reset (on quest-complete response)
"untrack:undead"

Open GUI (QuestLines GUI companion plugin)

Opens a custom GUI screen for the player. Requires the QuestLines GUI companion plugin. The screen is defined by a .gui.json file in mods/QuestLinesGUI/. When QuestLines GUI is present, it registers this action with Core automatically at startup.

FormatDescription
opengui:guiId Open the screen with the given ID for the triggering player.
// In a response — open a shop when the player clicks
"opengui:blacksmith_shop"

// In LoadActions — auto-open a welcome screen once per player
// (requires: notTag:seen_welcome)
"addTag:seen_welcome"
"opengui:welcome_screen"

Quick Reference

FormatCategoryDescription
startquest:idQuest StateAdd to started quests + notification
completequest:idQuest StateMove to completed + notification
removequest:idQuest StateRemove from both lists
addTag:tagNameTagsAdd a tag (idempotent)
removeTag:tagNameTagsRemove a tag
track:id:type:[targets]TrackingStart a named tracker (see Named Trackers section)
track:id:type:target:loc:x:y:z:radiusTrackingStart a location-gated named tracker
track:id:type:target:world:worldNameTrackingStart a world-gated named tracker
untrack:idTrackingRemove named tracker and reset its count to zero
untrack:[id1,id2]TrackingRemove multiple named trackers at once
setTimestamp:keyCooldownRecord time for cooldown gate
timedStart:keyTimerRecord time for countdown timer
timedStart:key:durationSecondsTimerRecord time + store duration (allows timedActive/timedExpired without repeating seconds)
item:itemId:qtyItemsGive item + notification
command:text:serverCommandsRun as server console
command:text:player[:elevated]CommandsRun as player (add :elevated to grant temp wildcard perm)
page:pageIdNavigationNavigate to another page
spawnCitizen:name:x:y:z[:delay[:qty]]SpawningClone HyCitizens NPC at position (coords may use ~)
spawn:npcRoleId:x:y:z[:delay[:qty]]SpawningSpawn Hytale NPC by role ID (coords may use ~)
variable:name:set:valueVariableSet named variable to value
variable:name:add:valueVariableAdd to named variable
variable:name:subtract:valueVariableSubtract from named variable
variable:name:multiply:valueVariableMultiply named variable
variable:name:divide:valueVariableDivide named variable
economy:give:amountEconomyDeposit amount into player account (requires VaultUnlocked)
economy:take:amountEconomyWithdraw amount from player account (requires VaultUnlocked)
sound:soundNameSoundPlay 2D sound to player
sound:soundName:trueSoundBroadcast 2D sound to all players
sound:soundName:x:y:zSoundPlay 3D positional sound at coordinates (~ relative ok); broadcasts to nearby players
sound:soundName:x:y:z:playerSoundSame as above but only to the triggering player
title:primary[:secondary[:server|player[:isMajor]]]TitleShow an event title screen; server=broadcast to world, player=self only (default); isMajor=true for large format
setMarker:id:label:x:y:z[:image[:RRGGBB]]Map MarkerPlace a marker on the player's world map. Repeating the same id updates it.
removeMarker:idMap MarkerRemove the map marker with the given id (clears on reconnect)
macro:nameMacroExecute a named action macro from macros/<name>.json in order
delay:NFlowPause for N seconds (decimals ok, e.g. 0.5) then continue remaining actions
mmo:xp:skillId:give:amountMMO SkillGive skill XP to player (requires MMOSkillTree)
rpgxp:give:amountRPG LevelingGive RPG XP to player (requires RPGLeveling)
regionaddmember:regionIdOrbisGuardAdd player as member of OrbisGuard region (requires OrbisGuard)
regionremovemember:regionIdOrbisGuardRemove player from OrbisGuard region's member list (requires OrbisGuard)
opengui:guiIdGUIOpen a custom GUI screen for the player (requires QuestLines GUI plugin)
global:addtag:tagNameGlobal StateAdd tag to server-wide global tag list
global:removetag:tagNameGlobal StateRemove tag from server-wide global tag list
global:variable:name:op:valueGlobal StateMutate server-wide variable (ops: add, subtract, multiply, divide, set)
random:[action1,action2,...]RandomPick one action at random from bracket list (page: not supported inside)
The actions above work in both Response.Actions and Page.LoadActions. Load actions fire automatically when the page is shown, before the player clicks any button.
log:questId:pageIdSystem (auto)Last-seen page tag — written automatically by the engine; powers the Quest Journal. Do not write manually.