Badges update automatically and link to the mod page on MineUniverse.
Turn Minecraft villages into living RPG hubs.
Mebahel's RPG: Villager Quests & Companions adds story-driven villager quests, rumors, named enemies, branching choices, quest tracking, RPG-style notifications, and recruitable companions. Villagers are no longer just traders standing near a bell. They can ask for help, warn you about nearby threats, send you toward strange structures, reveal hidden stories through rumors, or pull you into choices that change what happens next.
Some quests are simple village jobs. Others become full story arcs with investigations, moral decisions, ambushes, raids, hidden follow-ups, named targets, and enemies who might not deserve the axe you were sent to bring.
If you like vanilla Minecraft but want villages to give you more reasons to explore, protect, question, and return, this mod is built for that.
You arrive at a village. A farmer heard something moving near an old portal. A smith remembers smoke below a mine. Someone claims a celebrated hero may be wearing stolen glory. A witch outside the village might be a threat, or she might be the only person telling the truth.
You talk, choose responses, accept the quest, track it in your journal, follow coordinates or structure clues, and return for rewards. Some targets fight immediately. Some talk first. Some can be spared. Sometimes mercy opens a longer path. Sometimes it brings danger back to the village.
The goal is to make villages feel like places with memory, consequences, and unfinished business.
Investigate a ruined portal guarded by Sir Alaric Ashward, an armed zombie with fragments of a soldier's memory. Kill him to seal the restless gate, or spare him and help recover the identity buried under the undead curse. The mercy path can lead to a recruitable companion.
Rurik, a vindicator without a banner, stands outside the usual raider order. Is he hunting, mourning, hiding, or trying to escape what he used to serve? Your choice can end his story or push him toward a trial that may turn an enemy into an ally.
A village champion may be celebrated for courage that belonged to someone else. Follow the evidence, find the last witness, and decide whether to bury the truth or expose the person the village has been praising.
The village fears a witch. The easy answer is to kill her. The harder answer is to listen. Sparing her can reveal a larger plot involving curses, raiders, undead proxies, and an evoker pushing danger toward the village.
Prepare a village for attack, raise iron golems, survive a raid, and earn a reputation. But fame has consequences. After the bell rings, a hidden follow-up can draw assassins from the Quiet Ledger.
A rumor about a cold forge leads into a darker thread about a smith, an old mine, and a curse tied to the forge's last work.
Trace ash-marked skeletons into the Nether, discover an old bargain beneath the village, recover written evidence, and decide whether to break or renegotiate a debt that may have protected the village for too long.
Not every quest appears the same way.
Some villagers can offer jobs directly. Others may only give you a rumor. Hearing the right rumor can unlock hidden content, such as smoke below an old mine, a stranger among the dead, or trouble that appears only after a village has already survived a raid.
This lets the world reveal stories gradually as you play.
Certain spared characters can eventually become permanent companions.
Companions are designed to be useful without turning villages into chaos. They follow your lead, focus on hostile threats, and avoid randomly attacking peaceful villagers, iron golems, or passive animals.
Some companions also support equipment interaction through the companion inventory screen.
Press J by default to open the quest journal.
The journal and tracker help you follow active objectives with contextual labels such as:
Coordinates in the journal are clickable, and active objectives can be followed through the HUD tracker.
Server/world config file:
config/mebahelrpgrquest.json
Current configurable values:
{
"villagerQuestChance": 0.20,
"villagerRumorChance": 0.33
}
villagerQuestChance is the quest assignment weight for a newly loaded villager.villagerRumorChance is the rumor assignment weight for a newly loaded villager.1.0 means no quest or rumor is assigned.0.0 and 1.0. If their sum is above 1.0, quest and rumor are normalized against each other with no empty outcome.Join the Discord to follow development, report bugs, share quest ideas, or discuss custom quest lines:
https://discord.com/invite/y8uC2NepkB
This tutorial builds a small but complete questline called The Ash Road Oath.
At the end, the player can:
The examples are written as a datapack or addon namespace called example. Replace example with your own namespace.
Important: the real quest id comes from the folder under data/, not from the tutorial text. If you place these files in this mod at data/mebahelrpgrquest/..., every reference must use mebahelrpgrquest:ash_road_..., not example:ash_road_....
Create these files:
data/example/rumors/ash_road_whisper.json
data/example/quests/ash_road_1_old_portal.json
data/example/quests/ash_road_2_iron_record.json
data/example/quests/ash_road_3_trial_by_bell.json
data/example/quests/ash_road_4_oath_companion.json
Quest subfolders are allowed, but the filename is the quest id. For example:
data/example/quests/story/ash_road_1_old_portal.json
still becomes:
example:ash_road_1_old_portal
Keep quest filenames unique inside your namespace.
This rumor can appear on a villager. When the player hears it, the mod adds:
quest_discovered:example:ash_road_1_old_portal
That trait is used to unlock the first quest.
data/example/rumors/ash_road_whisper.json
{
"id": "ash_road_whisper",
"enabled": true,
"weight": 12,
"line": "A trader swears a dead knight is kneeling by an old portal, asking every traveler which road leads home.",
"unlock_quest": "example:ash_road_1_old_portal",
"discovered_line": "Rumor discovered: a dead knight waits beside an old portal.",
"conditions": {
"not_completed_quests": [
"example:ash_road_1_old_portal"
]
}
}
Use weight to control how often this rumor appears compared to other usable rumors. A rumor with weight: 12 is twelve times as likely as one with weight: 1, after conditions are checked.
The first quest sends the player to a ruined portal and spawns a named zombie knight. The player can attack or spare him.
This quest uses:
required_traits from the rumor;kill_entity objective tied to a quest target;threat_target with dialogue;next_quest_on_kill;next_quest_on_spare;offer_summary_line is written as dialogue from the quest giver. It should sound like something the NPC says directly to the player, not like an objective label.
data/example/quests/ash_road_1_old_portal.json
{
"title": "The Knight at the Old Portal",
"offer_intro_line": "You heard the rumor too, then. Good. I was starting to think the whole village had agreed to pretend the road was quiet.",
"offer_dialogue_steps": [
{
"choice": "What waits by the portal?",
"line": "A dead knight, if the trader was sober. It kneels in the ash and asks for the road home."
},
{
"choice": "Why not send the guards?",
"line": "Because the guards remember the last portal sickness. They will defend the bell, but they will not walk toward that frame."
}
],
"offer_summary_line": "Please, go to the old portal and learn whether that knight is a threat before it follows the road back to us.",
"required_traits": [
"quest_discovered:example:ash_road_1_old_portal"
],
"next_quest_on_kill": "example:ash_road_3_trial_by_bell",
"next_quest_on_spare": "example:ash_road_2_iron_record",
"objective": {
"id": "kill_ash_knight",
"type": "kill_entity",
"entity": "minecraft:zombie",
"amount": 1
},
"threat_target": {
"entity": "minecraft:zombie",
"name": "Sir Caelen of the Ash Road",
"structure": "minecraft:ruined_portal",
"search_radius": 4000,
"spawn_radius": 28,
"spawn_min_radius": 8,
"spawn_max_radius": 40,
"spawn_on_accept": true,
"spare_enabled": true,
"glow": true,
"max_health": 120.0,
"equipment": {
"mainhand": {
"item": "minecraft:iron_sword",
"enchantments": [
{
"id": "minecraft:sharpness",
"level": 2
}
]
},
"head": "minecraft:iron_helmet",
"chest": "minecraft:chainmail_chestplate"
},
"offer_line": "The old portal has been marked on your journal.",
"target_line": "The dead knight raises its head. 'Road... bell... home. Which one still stands?'",
"dialogue_steps": [
{
"choice": "Do you remember your name?",
"line": "Caelen. I think. The ash took the rest, but not the oath."
},
{
"choice": "Why are you guarding the portal?",
"line": "Something followed me through. If I leave, it finds the road."
}
],
"attack_choice_label": "Your oath ends here.",
"spare_choice_label": "Give me proof, and I will take it to the village.",
"attack_return_line": "Then the dead knight is finally still. I hope that was the only mercy left.",
"spared_line": "You lower your weapon.",
"post_spare_line": "Take the record. If the bell still knows my name, I may remember the road.",
"villager_spared_line": "You spared him? Then whatever he gave you had better be worth the risk.",
"spare_handoff": {
"item": "minecraft:written_book",
"count": 1,
"name": "Caelen's Iron Record",
"depart_after_spare": true,
"consume_on_claim": true,
"quest_book": {
"title": "Caelen's Iron Record",
"author": "Sir Caelen",
"pages": [
"I held the ash road when the portal opened.",
"If I return without memory, ask the bell whether I died facing away from the village.",
"If the bell still rings, my oath is not finished."
]
}
},
"spare_rewards_from_giver": true,
"spare_rewards": [
{
"type": "xp",
"amount": 160
}
],
"mercy_outcome": {
"offer_quest_chance": 100,
"offered_quest": "example:ash_road_2_iron_record",
"ambush_player": 0,
"nothing_chance": 0,
"offer_line": "The dead knight leaves the ash behind. The book in your hands is warm."
}
},
"return_dialogue_line": "You came back from the portal. Tell me the ash did not follow you.",
"reward_dialogue_line": "Take this. Whether you ended him or trusted him, you walked where we would not.",
"already_completed_line": "The old portal has been quiet since you went there.",
"rewards": [
{
"type": "xp",
"amount": 260
},
{
"type": "item",
"item": "minecraft:emerald",
"count": 9
}
],
"traits_on_attack": [
"ash_road_caelen_attacked"
],
"traits_on_spare": [
"ash_road_caelen_spared"
]
}
What this creates:
next_quest_on_kill.mercy_outcome.offered_quest starts the next quest.consume_on_claim: true makes the book matter when the next quest resolves.The spared route asks the player to read Caelen's book, gather repair materials, deliver the proof to a messenger in another village, and return to the original villager.
This quest uses:
sequential_objectives;read_book;collect_item;talk_to_entity;delivery_objectives;return_to_quest_giver;data/example/quests/ash_road_2_iron_record.json
{
"title": "The Iron Record",
"sequential_objectives": true,
"offer_intro_line": "That book is not a trophy. It is a witness. If the words inside are true, another village once knew his oath.",
"offer_dialogue_steps": [
{
"choice": "Where should I take it?",
"line": "A messenger from the far village waits beyond the road. If their bell remembers Caelen, they will know what to do."
},
{
"choice": "Why bring iron too?",
"line": "If they accept the record, they will need iron to rehang the old bell plate. A name without a bell is only ink."
}
],
"offer_summary_line": "Please, read Caelen's record, gather iron for the bell plate, and carry both to the messenger waiting in another village.",
"required_traits": [
"ash_road_caelen_spared"
],
"next_quest": "example:ash_road_3_trial_by_bell",
"objectives": [
{
"id": "read_caelen_record",
"type": "read_book",
"item": "minecraft:written_book",
"amount": 1,
"quest_item_name": "Caelen's Iron Record",
"quest_item_tag": "caelen_iron_record",
"stage": 0,
"auto_advance": true,
"completion_dialogue_line": "The final page is warm. The book wants to be carried to a bell that remembers its author."
},
{
"id": "collect_bell_iron",
"type": "collect_item",
"item": "minecraft:iron_ingot",
"amount": 12,
"stage": 1
},
{
"id": "deliver_record_to_messenger",
"type": "talk_to_entity",
"entity": "minecraft:villager",
"quest_item_name": "Road Messenger",
"amount": 1,
"stage": 1,
"auto_advance": true,
"completion_dialogue_line": "The messenger accepts the record and the iron. The far bell will ring Caelen's name before dusk."
},
{
"id": "return_after_delivery",
"type": "return_to_quest_giver",
"amount": 1,
"stage": 2
}
],
"threat_target": {
"entity": "minecraft:villager",
"name": "Road Messenger",
"structure": "minecraft:villages",
"search_radius": 4200,
"min_structure_distance": 700,
"spawn_radius": 10,
"spawn_on_accept": true,
"spare_enabled": false,
"glow": false,
"target_line": "If you carry Caelen's record, then hand it over. The bell has waited long enough.",
"delivery_choice_label": "Hand over the record and iron",
"delivery_objectives": [
"read_caelen_record",
"collect_bell_iron"
],
"delivered_line": "This is his hand. I know it. Tell your village the far bell will answer.",
"depart_after_delivery": false
},
"return_dialogue_line": "The messenger knew the name? Then the dead knight was not lying.",
"reward_dialogue_line": "You carried proof farther than fear could reach. Take this before the road asks more of you.",
"already_completed_line": "The far village sent word. Their bell rang once at dusk.",
"rewards": [
{
"type": "xp",
"amount": 220
},
{
"type": "item",
"item": "minecraft:emerald",
"count": 8
}
],
"traits_on_complete": [
"ash_road_record_delivered"
]
}
Important note about read_book: the objective completes when the marked book is opened, not when it is merely picked up.
Now the road answers. This quest is a staged village defense: wait until night, talk to Caelen if he was spared, then survive an ambush around the quest giver.
This quest uses:
wait_time with wait_until;talk_to_entity;threat_targets;spawn_origin: "quest_giver";attack_ambushes;attack_only cleanup objectives;defend_raid style village defense.data/example/quests/ash_road_3_trial_by_bell.json
{
"title": "Trial by Bell",
"sequential_objectives": true,
"offer_intro_line": "The bell rang at dusk, and something on the road answered it. I need you here before night finishes what the portal began.",
"offer_dialogue_steps": [
{
"choice": "What answered the bell?",
"line": "Ash shapes. Men with no names left. They stood beyond the crops and counted the windows."
},
{
"choice": "What if Caelen comes back?",
"line": "Then he stands trial beneath the bell. If he protects the village, the road may still claim him as ours."
}
],
"offer_summary_line": "Stay until night, stand by the bell, and help us survive whatever follows Caelen's name home.",
"required_completed_quests": [
"example:ash_road_1_old_portal"
],
"next_quest": "example:ash_road_4_oath_companion",
"objectives": [
{
"id": "wait_for_ash_night",
"type": "wait_time",
"wait_until": "next_night",
"stage": 0,
"auto_advance": true,
"completion_dialogue_line": "The last daylight leaves the roofs. The bell rope twists though no hand touches it."
},
{
"id": "speak_with_caelen",
"type": "talk_to_entity",
"entity": "minecraft:zombie",
"quest_item_name": "Sir Caelen of the Ash Road",
"amount": 1,
"stage": 1,
"auto_advance": true,
"completion_dialogue_line": "Caelen kneels beneath the bell. The ash outside the village begins to move."
},
{
"id": "kill_ash_callers",
"type": "kill_entity",
"entity": "minecraft:skeleton",
"amount": 4,
"stage": 2,
"threat_target_only": true,
"completion_dialogue_line": "The last ash-caller falls, but the bell still shakes."
},
{
"id": "break_ash_focus",
"type": "break_block",
"block": "minecraft:spawner",
"required_mob": "minecraft:skeleton",
"amount": 1,
"completion_range": 48,
"force_place_block": true,
"stage": 3,
"auto_advance": true,
"spawn_equipment": {
"mainhand": "minecraft:stone_sword",
"head": "minecraft:leather_helmet"
},
"block_patch": {
"radius": 5,
"replace_solid_only": true,
"falloff_start": 0.6,
"palette": [
{
"block": "minecraft:coal_block",
"weight": 2
},
{
"block": "minecraft:blackstone",
"weight": 5
},
{
"block": "minecraft:stone",
"weight": 3
}
]
},
"completion_dialogue_line": "The focus cracks. Ash blows away from the bell."
},
{
"id": "defend_the_bell",
"type": "defend_raid",
"amount": 1,
"completion_range": 128,
"stage": 4
}
],
"threat_targets": [
{
"entity": "minecraft:zombie",
"name": "Sir Caelen of the Ash Road",
"stage": 1,
"spawn_origin": "quest_giver",
"spawn_min_radius": 5,
"spawn_max_radius": 12,
"spare_enabled": false,
"glow": true,
"max_health": 120.0,
"equipment": {
"mainhand": "minecraft:iron_sword",
"head": "minecraft:iron_helmet",
"chest": "minecraft:chainmail_chestplate"
},
"target_line": "The bell knows me. Let the road test the oath."
},
{
"entity": "minecraft:skeleton",
"name": "Ash Caller",
"stage": 2,
"spawn_origin": "quest_giver",
"spawn_min_radius": 18,
"spawn_max_radius": 34,
"spare_enabled": false,
"equipment": {
"mainhand": "minecraft:bow",
"head": "minecraft:leather_helmet"
}
},
{
"entity": "minecraft:skeleton",
"name": "Ash Caller",
"stage": 2,
"spawn_origin": "quest_giver",
"spawn_min_radius": 18,
"spawn_max_radius": 34,
"spare_enabled": false,
"equipment": {
"mainhand": "minecraft:bow",
"head": "minecraft:leather_helmet"
}
},
{
"entity": "minecraft:skeleton",
"name": "Ash Caller",
"stage": 2,
"spawn_origin": "quest_giver",
"spawn_min_radius": 18,
"spawn_max_radius": 34,
"spare_enabled": false,
"equipment": {
"mainhand": "minecraft:bow",
"head": "minecraft:leather_helmet"
}
},
{
"entity": "minecraft:skeleton",
"name": "Ash Caller Captain",
"stage": 2,
"spawn_origin": "quest_giver",
"spawn_min_radius": 24,
"spawn_max_radius": 40,
"spare_enabled": false,
"max_health": 60.0,
"equipment": {
"mainhand": {
"item": "minecraft:bow",
"enchantments": [
{
"id": "minecraft:power",
"level": 2
}
]
},
"head": "minecraft:iron_helmet"
}
}
],
"return_dialogue_line": "The bell still stands. So does the village.",
"reward_dialogue_line": "You held the road when it came looking for us. Take this, and speak with Caelen if he still stands.",
"already_completed_line": "The bell has rung clean since the ash broke.",
"rewards": [
{
"type": "xp",
"amount": 420
},
{
"type": "item",
"item": "minecraft:emerald",
"count": 16
},
{
"type": "item",
"item": "minecraft:shield",
"count": 1,
"enchantments": [
{
"id": "minecraft:unbreaking",
"level": 2
}
]
}
],
"traits_on_complete": [
"ash_road_bell_defended"
]
}
The defend_raid objective is intended for raid defense chains. If you want a smaller custom fight instead, use kill_entity with threat_targets and skip defend_raid.
Use this pattern when choosing "Attack" in a dialogue should spawn extra enemies. This is useful in a quest where the player can provoke a named target.
{
"threat_target": {
"entity": "minecraft:zombie",
"name": "Sir Caelen of the Ash Road",
"spare_enabled": true,
"attack_ambushes": [
{
"entity": "minecraft:zombie",
"name": "Ash-Bound Squire",
"count": 3,
"max_health": 36.0,
"equipment": {
"mainhand": "minecraft:stone_sword",
"head": "minecraft:leather_helmet"
}
},
{
"entity": "minecraft:skeleton",
"name": "Ash-Bound Archer",
"count": 2,
"max_health": 30.0,
"equipment": {
"mainhand": "minecraft:bow"
}
}
]
},
"optional_objectives": [
{
"id": "kill_attack_ambush",
"type": "kill_entity",
"entity": "minecraft:zombie",
"amount": 3,
"attack_only": true,
"threat_target_only": false,
"bonus_rewards": [
{
"type": "xp",
"amount": 80
}
]
}
]
}
attack_only: true means the objective only becomes relevant after the attack path is triggered.
The final quest is short: if the village survived and Caelen was spared, he becomes recruitable.
This quest uses:
required_completed_quests;required_traits;talk_to_entity;recruit_companion;data/example/quests/ash_road_4_oath_companion.json
{
"title": "Oath of the Ash Road",
"offer_intro_line": "Caelen did not leave after the bell. He has been standing on the road since dawn, waiting for your word.",
"offer_dialogue_steps": [
{
"choice": "Does the village trust him?",
"line": "Trust is too large a word for one sunrise. But the bell did not reject him, and neither did the golems."
}
],
"offer_summary_line": "Speak with Caelen one last time. If his oath holds, he may walk beside you instead of haunting the road.",
"required_completed_quests": [
"example:ash_road_3_trial_by_bell"
],
"required_traits": [
"ash_road_caelen_spared",
"ash_road_bell_defended"
],
"recruit_companion": true,
"objective": {
"id": "speak_to_caelen_companion",
"type": "talk_to_entity",
"entity": "minecraft:zombie",
"quest_item_name": "Sir Caelen of the Ash Road",
"amount": 1
},
"threat_target": {
"entity": "minecraft:zombie",
"name": "Sir Caelen of the Ash Road",
"spawn_origin": "quest_giver",
"spawn_min_radius": 6,
"spawn_max_radius": 14,
"spare_enabled": false,
"glow": true,
"max_health": 120.0,
"recruit_companion": true,
"equipment": {
"mainhand": "minecraft:iron_sword",
"head": "minecraft:iron_helmet",
"chest": "minecraft:chainmail_chestplate"
},
"target_line": "The road is quiet. If you still have need of an oath, I will carry mine beside you."
},
"return_dialogue_line": "Then the road has given us back more than it took.",
"reward_dialogue_line": "May his oath guard your steps better than it guarded his grave.",
"already_completed_line": "Caelen walks with you now. The village remembers.",
"rewards": [
{
"type": "xp",
"amount": 300
},
{
"type": "item",
"item": "minecraft:emerald",
"count": 12
}
],
"traits_on_complete": [
"ash_road_caelen_recruited"
]
}
Result: the questline now has a rumor, a named moral choice, a delivery step, a staged defense, and a companion payoff.
This section is a reference for creators after they understand the tutorial flow.
Quest files are loaded from:
data/<namespace>/quests/<quest_id>.json
data/<namespace>/quests/<optional/subfolder>/<quest_id>.json
Common top-level quest fields:
title: quest title shown to the player.offer_summary_line: dialogue line spoken by the quest giver when offering the quest.offer_intro_line: optional opening line before choices.offer_dialogue_steps: optional choice/answer dialogue before accepting.return_dialogue_line: line shown after objectives are done.return_dialogue_steps: optional choice/answer dialogue before reward.reward_dialogue_line: line shown before claiming rewards.already_completed_line: line shown after the quest has already been claimed.objective: single objective object.objectives: objective array.optional_objectives: optional objective array with possible bonus rewards.sequential_objectives: makes mandatory objectives progress by stages.threat_target: one spawned quest entity.threat_targets: several spawned quest entities.next_quest: direct follow-up quest.next_quest_on_kill: follow-up after attack/kill path.next_quest_on_spare: follow-up after spare path.required_completed_quests: quest ids the player must have completed.required_advancements: advancement ids the player must have.required_traits: quest traits the player must have.traits_on_accept: traits added when accepting.traits_on_complete: traits added when completing.traits_on_fail: traits added when failing or abandoning.traits_on_spare: traits added when sparing a target.traits_on_attack: traits added when choosing attack.recruit_companion: allows companion recruitment.companion_recruitable: alias for recruit_companion.rewards: reward array.Supported objective types:
kill_entitybreak_blockdetonate_tntplace_blockcollect_itemread_bookescort_entityreach_structureenter_netherleave_netherbring_entitytalk_to_entityreturn_to_quest_giverdefend_raidwait_timeCommon objective fields:
id: stable id. Use this when another field needs to refer to the objective.type: objective type.amount: required count or seconds for timed waits.mandatory: whether the objective is required.sequential: whether this objective participates in staged progression.stage: stage number for sequential quests.auto_advance: immediately activates the next stage when completed.completion_dialogue_line: dialogue line after this objective/stage completes.attack_only: only active/countable after an attack choice.threat_target_only: for kill objectives, only count quest-spawned targets.completion_range: distance check range.search_radius: structure search radius.entity: required by kill_entity, bring_entity, and talk_to_entity.block: required by break_block, detonate_tnt, and place_block.item: required by collect_item and read_book.required_mob: mob type required for spawner-related objectives.structure: required by escort_entity and reach_structure; also useful for generated block/container objectives.quest_item_name: display name for a quest item or target label.quest_item_tag: stable quest item marker.spawn_in_chest: generate the objective item in a container.container: generated container block id.container_block: alias for container.force_place_block: force generation of a block objective target.wait_until: next_day or next_night.spawn_equipment: equipment for mobs created by forced spawners.quest_book: written book data.block_patch: terrain decoration around generated targets.bonus_rewards: rewards for optional objectives.Threat target fields:
entity: entity id to spawn.name: displayed name.custom_name: alias for name.structure: optional structure target.search_radius: structure search radius.min_structure_distance: minimum distance to the selected structure.spawn_radius: general spawn radius.spawn_min_radius: minimum spawn distance.spawn_max_radius: maximum spawn distance.spawn_y_offset: vertical spawn offset.spawn_origin: player, quest_giver, quest_target, target, or objective.stage: sequential stage where the target appears.spawn_on_accept: spawn when quest is accepted.spare_enabled: enables attack/spare dialogue.glow: gives the target a glowing outline.max_health: custom max health.equipment: equipment map.mount: mounted entity data.offer_line: line spoken by the quest giver before target info.target_line: line spoken by the target.dialogue_steps: target dialogue choices.attack_choice_label: attack button text.spare_choice_label: spare button text.attack_return_line: line after the attack path.spared_line: line when the player spares the target.post_spare_line: line after sparing, spoken by the target.villager_spared_line: line when returning after sparing.spare_rewards: rewards for sparing.spare_rewards_from_giver: whether the quest giver pays spare rewards.drop_on_death: guaranteed reward-format drops.mercy_outcome: random outcome after sparing.spare_handoff: item or book given after sparing.attack_ambush_entity: legacy simple attack ambush entity.attack_ambush_name: legacy simple attack ambush name.attack_ambush_count: legacy simple attack ambush count.attack_ambush_max_health: legacy simple attack ambush health.attack_ambush_equipment: legacy simple attack ambush equipment.attack_ambushes: array of attack ambush groups.recruit_companion: marks this target as recruitable.delivery_choice_label: delivery button text.delivery_objectives: objective ids consumed by delivery.delivered_line: line after successful delivery.depart_after_delivery: whether the target leaves after delivery.mercy_outcome fields:
offer_quest_chanceambush_chanceambush_playerambush_quest_givernothing_chanceoffered_questambush_entityambush_nameambush_targetambush_countambush_max_healthambush_equipmentoffer_linenothing_lineambush_lineambush_player_lineambush_quest_giver_linevillager_ambush_lineChance values can be written as percentages or normalized values. 5 and 0.05 both mean 5%.
quest_book fields:
titleauthorpagesblock_patch fields:
radiusreplace_solid_onlyfalloff_startpaletteblockweightEquipment and item stack fields:
itemcountenchantmentsidlevelCommon equipment slots:
mainhand
offhand
head
chest
legs
feet
Reward fields:
type: xp or item.amount: XP amount.item: item id.count: item count.enchantments: optional enchantment array.Rumor files are loaded from:
data/<namespace>/rumors/<rumor_id>.json
Rumor fields:
id: optional id override.enabled: defaults to true.weight: relative random selection weight.line: spoken rumor text.discovered_line: discovery message.unlock_quest: quest id to unlock.conditions: condition object.required_traits: required player traits.forbidden_traits: blocked player traits.required_completed_quests: required completed quests.not_completed_quests: quests the player must not have completed.required_biomes: biome ids required at the villager's position.A rumor with unlock_quest adds this trait when heard:
quest_discovered:<quest_id>
The matching quest should usually require that trait.
offer_summary_line as spoken NPC dialogue.id values in sequential and delivery quests.threat_target_only: false for ordinary world kill objectives.threat_target_only: true when only spawned quest targets should count.stage and auto_advance to build cinematic multi-step quests.traits_on_spare, traits_on_attack, and traits_on_complete to remember player choices.