How It Works

QuestLines Icons reads NPC quest assignments from QuestLines’ mods/QuestLines/npcs.json and displays a floating item above each NPC. The icon shown is determined per player based on their quest state for the quests assigned to that NPC. Icons are updated on every server tick and are invisible to players who are not in range.

Requires QuestLines Core

Icons reads quest assignments directly from QuestLines’ npcs.json. QuestLines Core must be installed and configured for Icons to show anything.

Quest States

Each NPC is evaluated against the player’s quest data to determine which state to show. States are resolved in priority order: the highest-priority state that applies wins.

State Key Default Icon Default Animation Description
Available available Icons_Exclamation Ping + Bob The NPC has a quest the player has not yet started.
In Progress inprogress Icons_Dots Rotate The player has the quest and it is currently in progress.
Objectives Complete objectives_complete Icons_DownArrow Bob + Ping The player’s current page on a started quest has all of its required objectives satisfied — a “come back to me” turn-in cue. Resolved automatically; can also be forced via the iconState: action (see Per-Player Overrides).
Completed completed Icons_Checkmark Rotate The player has completed every quest this NPC offers.
Locked locked Icons_Lock Bob (slow) The NPC has at least one quest the player has not started, but every offered quest’s requirements currently fail — a prerequisite is missing. Distinguishes “come back when you’re ready” from unknown.
Waiting waiting Icons_Clock Bob Every quest this NPC offers is a completed repeatable, and at least one is still on cooldown / waiting for its repeat condition.
Repeatable Ready repeatable_ready Icons_Clock Bob + Ping Quest is repeatable, the player has completed it before, and it is ready to be done again (cooldown over). Visually distinguishes a daily/weekly that’s back in rotation from a fresh first-time quest.
Story story Icons_Exclamation Bob + Ping (fast) Override-only. Not auto-resolved — quest authors set it via the iconState: action to mark a main-story / critical-path NPC so its icon visibly outranks regular side content.
Custom custom Icons_QuestionMark None Override-only. No built-in semantics — pair a per-NPC NpcQuestIconStates entry and animation override with the iconState: action to bind any visual to a name of your choosing.
Unknown unknown Icons_QuestionMark Orbit Quest state is not yet resolved for this player / NPC pair.

Commands

All configuration is done via /icons (alias: /i) using a wand-style workflow: run the command, then click an NPC in-world to apply the setting. Every /icons subcommand requires the questlinesicons.admin permission.

Command Description
/icons reload Reload icons.json and re-sync NPC assignments from npcs.json.
/icons icon <itemId> Click an NPC to set its floating icon item. Use none to disable the icon for that NPC entirely.
/icons offset <offset> Click an NPC to set the Y-offset of its icon in blocks (e.g. 0.5 to raise it). Default is 0.0.
/icons scale <scale> Click an NPC to set the icon scale multiplier (e.g. 1.5 for 50% larger). Default is 1.0.
/icons rotation <degrees> Click an NPC to set a fixed Y-axis rotation for the icon in degrees. Default is 0.
/icons animate <animation> [state] Click an NPC to apply an animation. Optionally target a specific quest state (e.g. available). See Animations for format.
/icons list List all NPC IDs that have explicit icon configuration in icons.json.

Animations

Animations are applied via /icons animate <animation>. Multiple animation types can be active simultaneously on the same NPC icon. Each animation takes an optional speed and amplitude parameter.

Animation Format Speed Amplitude Description
bob bob[:speed[:amp]] Hz (cycles/sec) Max Y displacement (blocks) Bobs the icon up and down.
rotate rotate[:speed] Degrees/sec Continuously spins the icon on the Y axis.
pulsate pulsate[:speed[:amp]] Hz Max scale delta added to base scale Smoothly oscillates the icon’s size.
sway sway[:speed[:amp]] Hz Max rotation in degrees Rocks the icon side-to-side on the Z axis.
orbit orbit[:speed[:amp]] Hz Orbit radius (blocks) Circles the icon horizontally around the NPC.
ping ping[:speed[:amp]] Hz (pops/sec) Max scale delta per pop Brief sharp scale pop — attention-grabbing.
ring ring[:speed[:amp]] Hz (burst freq) Max lateral displacement (blocks) Rapid side-to-side shake in periodic bursts.
float float[:speed[:amp]] Hz Drift radius (blocks) Organic figure-8 Lissajous XZ drift.
stamp stamp[:speed[:amp]] Hz (stamps/sec) Drop distance (blocks) Periodic sharp downward drop; idles high.
none none or none:<type> Clears all animations, or clears only the specified type.

Animation Examples

// Bob at default speed (1 Hz) and amplitude (0.2 blocks)
/icons animate bob

// Spin at 90 degrees per second
/icons animate rotate:90

// Orbit slowly at 0.5 Hz with a 1.5-block radius
/icons animate orbit:0.5:1.5

// Ping animation only on the "available" state icon
/icons animate ping:0.5:0.4 available

// Remove only the rotate animation
/icons animate none:rotate

// Clear all animations
/icons animate none
💡
Tip: State-targeted animations

Add an optional state name after the animation to apply it only when the icon is showing that quest state — e.g. /icons animate ping:0.5:0.4 available. This lets you have the “available” icon draw more attention than the “completed” one.

Configuration File

All icon settings are persisted in mods/QuestLinesIcons/icons.json. You can edit this file directly or use the /icons commands to update it in-game. Below is the full structure.

{
  // Global fallback item shown on any NPC that has no per-NPC override
  "DefaultIconItemId": "Recipe_Page",
  "DefaultIconOffset":  0.0,

  // Global item overrides per quest state (used for all QuestLines NPCs)
  "DefaultQuestStateIcons": {
    "available":           "Icons_Exclamation",
    "inprogress":          "Icons_Dots",
    "objectives_complete": "Icons_DownArrow",
    "completed":           "Icons_Checkmark",
    "locked":              "Icons_Lock",
    "waiting":             "Icons_Clock",
    "repeatable_ready":    "Icons_Clock",
    "story":               "Icons_Exclamation",
    "custom":              "Icons_QuestionMark",
    "unknown":             "Icons_QuestionMark"
  },

  // Global default animations per quest state
  "DefaultQuestStateAnimations": {
    "available": {
      "ping": { "speed": 0.5, "amplitude": 0.4 },
      "bob":  { "speed": 0.5, "amplitude": 0.12 }
    }
  },

  // Per-NPC item override (any item ID or "none" to disable)
  "NpcQuestIcons": {
    "citizen_42": "Custom_Star",
    "citizen_07": "none"
  },

  // Per-NPC per-state item overrides
  "NpcQuestIconStates": {
    "citizen_42": {
      "available": "Icons_Exclamation",
      "completed": "Icons_Checkmark"
    }
  },

  // Per-NPC Y-offsets in blocks
  "NpcQuestIconOffsets": {
    "citizen_42": 0.5
  },

  // Per-NPC scale multipliers
  "NpcQuestIconScales": {
    "citizen_42": 1.25
  },

  // Per-NPC fixed Y rotation in degrees
  "NpcQuestIconRotations": {
    "citizen_42": 45.0
  },

  // Per-NPC animations (multiple types active at once)
  "NpcAnimations": {
    "citizen_42": {
      "bob":    { "speed": 1.0, "amplitude": 0.2 },
      "rotate": { "speed": 60.0, "amplitude": 0.0 }
    }
  },

  // Per-NPC per-state animation overrides
  "NpcStateAnimations": {
    "citizen_42": {
      "available": {
        "ping": { "speed": 0.5, "amplitude": 0.3 }
      }
    }
  }
}
Cloned NPCs share icon configuration

When multiple NPCs share the same citizen ID (e.g. cloned HyCitizens spawned via spawnCitizen:), they share an iconKey and therefore the same icon, scale, rotation, and animation settings. Each cloned NPC still renders its own dedicated icon entity above its head, and command-issued changes (/icons icon, scale, rotation) propagate to every clone on the next tick.

Configuration Override Priority

When determining which icon and animation to show for a given NPC and player, the plugin uses the following priority chain:

Icon item

  1. Per-NPC entry in NpcQuestIcons (static override, ignores quest state)
  2. Per-NPC per-state entry in NpcQuestIconStates for the player’s current state
  3. Global per-state entry in DefaultQuestStateIcons
  4. Built-in default for the state (e.g. Icons_Exclamation for available)

Animation

  1. Per-NPC per-state entry in NpcStateAnimations
  2. Global per-state entry in DefaultQuestStateAnimations
  3. Built-in defaults per state (see Quest States table above)
  4. Per-NPC entry in NpcAnimations (NPC-level, state-agnostic)

Per-Player Overrides

Quest authors can force a specific icon state for a single player from QuestLines Core, bypassing the auto-computed state for that player only. Useful for narrative beats — e.g. force unknown on a fallen NPC the player just discovered until they read a clue, or hold an NPC at objectives_complete after a scripted cutscene.

Format Type Description
iconState:npcId:state Action Set a per-player icon state override for the named NPC. state must be one of available, inprogress, objectives_complete, completed, locked, waiting, repeatable_ready, story, custom, unknown. Invalid state names silently no-op. story and custom are override-only (no auto-resolution) — useful for narrative beats and admin-defined visuals.
iconState:npcId:state:clear Action Guarded clear — removes the override only if it currently equals state. This prevents one quest’s cleanup from stomping another quest’s override.
iconState:npcId:state Requirement True iff the player’s override for that NPC is currently set to state.
Override resolution priority

The override is read at the very top of resolveIconState and wins over the auto-computed state. The action and requirement are only registered when the QuestLines Icons plugin is active — on installs without Icons they no-op and pass through validation.

Example

// Mark the smith as "ready to turn in" while a quest is gated on a scene
"Actions": ["iconState:smith_id:objectives_complete"]

// On turn-in, only clear if our quest set it -- another quest may have
// since switched the icon to its own override.
"Actions": [
  "questCompleted:trial",
  "iconState:smith_id:objectives_complete:clear"
]

// Gate dialogue on the override being active
"Requirements": ["iconState:smith_id:objectives_complete"]

Permissions

Permission Default Description
questlinesicons.admin false Required for all /icons subcommands (icon, offset, scale, rotation, animate, list, reload).