Skip to main content

NPC Integration

The Achievement System integrates with the KyuubiSoft Citizens (NPC) system to provide two powerful features:

  1. Achievement Triggers -- unlock achievements when players interact with NPCs or complete dialogs
  2. Dialog Conditions -- show or hide dialog options based on a player's achievement progress

Achievement Trigger Types

npc_interact

Fires when a player interacts (right-clicks) with a citizen NPC. The target field matches the citizen's ID.

Use cases:

  • "Talk to 5 different NPCs"
  • "Visit the Blacksmith for the first time"
  • "Interact with all town NPCs"
{
"id": "meet_the_blacksmith",
"category": "social",
"iconItem": "Tool_Hammer_Iron",
"difficulty": "normal",
"trigger": {
"type": "npc_interact",
"target": "blacksmith_gorn",
"count": 1
},
"title": {
"id": "smiths_friend",
"color": "#FF8C00"
}
}

To track interactions with any NPC (regardless of citizen ID), use "target": "any":

{
"id": "social_butterfly",
"category": "social",
"iconItem": "Decoration_Banner_Blue",
"difficulty": "hard",
"trigger": {
"type": "npc_interact",
"target": "any",
"count": 20
},
"title": {
"id": "social_butterfly",
"color": "#FF69B4"
}
}
Multi-Target

You can use comma-separated citizen IDs to match specific NPCs:

{ "type": "npc_interact", "target": "merchant_sol,smith_gorn,cook_mira", "count": 3 }

This counts one interaction per matching NPC towards the total.

dialog_complete

Fires when a player finishes a dialog tree with an NPC. The target field matches the dialog ID.

Use cases:

  • "Complete the Elder's story"
  • "Finish 10 NPC dialogs"
  • "Hear the legend of the ancient ruins"
{
"id": "elders_wisdom",
"category": "social",
"iconItem": "Ingredient_Scroll",
"difficulty": "normal",
"trigger": {
"type": "dialog_complete",
"target": "elder_story_dialog",
"count": 1
},
"title": {
"id": "wise_listener",
"color": "#9370DB"
}
}

For tracking any dialog completion:

{
"id": "chatterbox_npc",
"category": "social",
"iconItem": "Ingredient_Scroll",
"difficulty": "hard",
"trigger": {
"type": "dialog_complete",
"target": "any",
"count": 10
},
"title": {
"id": "chatterbox",
"color": "#44AAFF"
}
}

Dialog Conditions

Dialog conditions let you control NPC dialog options based on a player's achievement status. This creates dynamic conversations where NPCs react differently depending on what the player has accomplished.

achievement_unlocked

Checks whether the player has unlocked a specific achievement.

FieldValue
type"achievement_unlocked"
valueThe achievement ID to check
negatefalse = require it, true = require it to NOT be unlocked

Example: NPC offers a reward dialog only if the player has a specific achievement

{
"id": "blacksmith_special_dialog",
"nodes": [
{
"id": "start",
"text": "Welcome, traveler. What brings you here?",
"choices": [
{
"text": "I heard you have a special blade for dragon slayers.",
"next": "special_blade",
"condition": {
"type": "achievement_unlocked",
"value": "dragon_slayer",
"negate": false
}
},
{
"text": "Just browsing your wares.",
"next": "shop"
}
]
},
{
"id": "special_blade",
"text": "Ah, so the rumors are true! You really slew the dragon. Here, take this -- you've earned it.",
"action": "give_reward"
}
]
}

In this example, the "special blade" dialog choice only appears for players who have unlocked the dragon_slayer achievement.

achievement_count

Checks whether the player has unlocked at least a certain number of total achievements.

FieldValue
type"achievement_count"
valueMinimum number of achievements (as a string, e.g., "10")
negatefalse = require at least this many, true = require fewer

Example: Elder NPC acknowledges dedicated players

{
"choices": [
{
"text": "Tell me about the ancient legends.",
"next": "legends",
"condition": {
"type": "achievement_count",
"value": "25",
"negate": false
}
},
{
"text": "I'm new here. What should I do?",
"next": "beginner_help",
"condition": {
"type": "achievement_count",
"value": "5",
"negate": true
}
}
]
}

In this example:

  • The "ancient legends" option only appears for players with 25+ achievements
  • The "beginner help" option only appears for players with fewer than 5 achievements

Combining Triggers and Conditions

A powerful pattern is combining NPC triggers with dialog conditions to create multi-step experiences:

  1. Step 1: Player interacts with an NPC, earning the meet_the_elder achievement
  2. Step 2: On the next visit, a new dialog option appears (gated by achievement_unlocked: meet_the_elder)
  3. Step 3: Completing that dialog earns the elders_wisdom achievement
  4. Step 4: Future dialogs unlock further options based on achievement_count
custom/custom_achievements.json
{
"achievements": [
{
"id": "meet_the_elder",
"category": "social",
"iconItem": "Decoration_Candle",
"difficulty": "normal",
"trigger": {
"type": "npc_interact",
"target": "kweebec_elder",
"count": 1
},
"title": { "id": "elder_acquaintance", "color": "#98FB98" }
},
{
"id": "elders_full_story",
"category": "social",
"iconItem": "Ingredient_Scroll",
"difficulty": "hard",
"requires": "meet_the_elder",
"trigger": {
"type": "dialog_complete",
"target": "elder_full_story_dialog",
"count": 1
},
"title": { "id": "lorekeeper", "color": "#DDA0DD" }
}
]
}
tip

Remember to add localization entries for your custom achievements:

localization/en-US.json
{
"achievements.name.meet_the_elder": "Meet the Elder",
"achievements.desc.meet_the_elder": "Speak with the Kweebec Elder for the first time",
"achievements.title.elder_acquaintance": "Elder's Acquaintance",
"achievements.name.elders_full_story": "The Full Story",
"achievements.desc.elders_full_story": "Listen to the Elder's complete tale",
"achievements.title.lorekeeper": "Lorekeeper"
}

Negation

Both condition types support the negate field. When set to true, the condition is inverted:

Conditionnegate: falsenegate: true
achievement_unlockedPlayer has the achievementPlayer does not have the achievement
achievement_countPlayer has at least N achievementsPlayer has fewer than N achievements

This is useful for showing introductory dialog to new players while hiding it from veterans, or for creating "before and after" dialog trees.


Troubleshooting

NPC Interaction Not Counting

  1. Verify the citizen ID in your achievement config matches the actual NPC's citizen ID exactly (case-sensitive)
  2. Check that the NPC is registered as a citizen through the KyuubiSoft Citizens system
  3. Look for "NPC interact tracked" entries in the server log (fine-level logging)

Dialog Condition Not Working

  1. Confirm the condition type is spelled exactly as achievement_unlocked or achievement_count
  2. For achievement_count, the value must be a number as a string (e.g., "10", not 10)
  3. Check that the Achievement plugin is loaded -- conditions fail silently if the plugin is unavailable
  4. Verify the achievement ID exists in the config (typos are a common cause)

Dialog Complete Not Firing

  1. The player must reach the end of the dialog tree for the trigger to fire
  2. Closing the dialog mid-conversation does not count as completing it
  3. Check that the dialog ID in the achievement config matches the dialog tree ID