Mineuniverse
Mods

Mebahel's RPG - Villager Quests and Companions

MOD
Mebahel's RPG: Villager Quests & Companions adds story-driven villager quests, branching choices, named enemies, rumors, quest tracking, companion recruitment, and RPG-style notifications to your world.
by Mebahel
Download Claim this project
Add a badge to your pageLink to Mebahel's RPG - Villager Quests and Companions from a README, website or forum post.
Preview: Badge

Badges update automatically and link to the mod page on MineUniverse.

20,179 downloads
0 likes
0 followers
Updated Oct 14, 2026
0 hypes
Follow0
Adventure and RPG Map and Information Mobs
Advertisement Remove ads with Premium →

Mebahel's RPG: Villager Quests & Companions

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.


Dependencies

Forge / NeoForge

Fabric


What This Mod Adds

  • Over 40 included quests built around villages, roads, mines, raids, ruined portals, witches, raiders, skeletons, undead soldiers, false heroes, strange survivors, and hidden contracts.
  • Branching storylines where killing, sparing, exposing, defending, escorting, delivering, or investigating can lead to different follow-up quests.
  • Named quest targets with custom dialogue, equipment, locations, health, mounts, drops, ambushes, and spare/attack choices.
  • Recruitable companions from selected mercy paths, including restored enemies who can later fight beside you.
  • Villager rumors that unlock hidden quests gradually instead of dumping every story on day one.
  • Quest journal and HUD tracking for active objectives, coordinates, structures, destinations, and threat targets.
  • RPG-style quest notifications with custom sounds when quests start, update, or complete.
  • Many objective types: kill, collect, deliver, read, escort, bring back, reach a structure, break blocks, place blocks, detonate TNT, enter or leave the Nether, defend raids, wait for time to pass, talk to entities, and return to the quest giver.
  • Datapack and mod support so creators can add quests and rumors with JSON files.

How It Feels In Game

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.


Included Story Arcs

The Armed Dead

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.

No-Banner Vindicator

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.

The False Hero

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 Witch at the Hut

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.

Village Defense and the Quiet Ledger

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.

The Cold Forge

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.

The Ash Court

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.


Rumors and Discovery

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.


Companions

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.


Quest Journal and HUD

Press J by default to open the quest journal.

The journal and tracker help you follow active objectives with contextual labels such as:

  • Threat location for named enemy targets.
  • Destination for escort quests.
  • Structure location for exploration objectives.
  • Target location when no more specific label applies.

Coordinates in the journal are clickable, and active objectives can be followed through the HUD tracker.


Configuration

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.
  • The two values compete in one roll. Any remaining weight up to 1.0 means no quest or rumor is assigned.
  • Values are clamped between 0.0 and 1.0. If their sum is above 1.0, quest and rumor are normalized against each other with no empty outcome.

Community

Join the Discord to follow development, report bugs, share quest ideas, or discuss custom quest lines:

https://discord.com/invite/y8uC2NepkB


Creator Tutorial: Build a Complete Questline

This tutorial builds a small but complete questline called The Ash Road Oath.

At the end, the player can:

  • hear a rumor that unlocks the story;
  • investigate a ruined portal;
  • talk to a named zombie knight;
  • choose to attack or spare him;
  • receive a written book from the spared target;
  • deliver that proof to another village;
  • trigger an attack ambush;
  • defend the village;
  • recruit the former enemy as a companion.

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_....

Folder Layout

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.

Step 1: A Rumor Unlocks the Questline

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.

Step 2: First Quest, Named Target, Choice, and Branch

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;
  • a kill_entity objective tied to a quest target;
  • threat_target with dialogue;
  • custom equipment and health;
  • attack/spare labels;
  • next_quest_on_kill;
  • next_quest_on_spare;
  • a mercy outcome that offers the next quest if the target is spared;
  • a spare handoff book.

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:

  • If the player attacks and kills Caelen, the quest can continue through next_quest_on_kill.
  • If the player spares him, the handoff book is created and mercy_outcome.offered_quest starts the next quest.
  • consume_on_claim: true makes the book matter when the next quest resolves.

Step 3: Second Quest, Read Book, Delivery, and Return

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;
  • a non-hostile spawned target.

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.

Step 4: Third Quest, Attack Ambush and Village Defense

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;
  • multiple 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.

Optional Variant: Attack Ambush on a Choice

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.

Step 5: Final Quest, Recruit a Companion

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;
  • a spawned named target that acts as the companion candidate.

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.


Field Reference

This section is a reference for creators after they understand the tutorial flow.

Quest Files

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.

Objective Types

Supported objective types:

  • kill_entity
  • break_block
  • detonate_tnt
  • place_block
  • collect_item
  • read_book
  • escort_entity
  • reach_structure
  • enter_nether
  • leave_nether
  • bring_entity
  • talk_to_entity
  • return_to_quest_giver
  • defend_raid
  • wait_time

Common 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

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

mercy_outcome fields:

  • offer_quest_chance
  • ambush_chance
  • ambush_player
  • ambush_quest_giver
  • nothing_chance
  • offered_quest
  • ambush_entity
  • ambush_name
  • ambush_target
  • ambush_count
  • ambush_max_health
  • ambush_equipment
  • offer_line
  • nothing_line
  • ambush_line
  • ambush_player_line
  • ambush_quest_giver_line
  • villager_ambush_line

Chance values can be written as percentages or normalized values. 5 and 0.05 both mean 5%.

Books, Patches, Equipment, and Rewards

quest_book fields:

  • title
  • author
  • pages

block_patch fields:

  • radius
  • replace_solid_only
  • falloff_start
  • palette
  • block
  • weight

Equipment and item stack fields:

  • item
  • count
  • enchantments
  • id
  • level

Common 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 Fields

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.

Practical Advice

  • Write offer_summary_line as spoken NPC dialogue.
  • Use stable objective id values in sequential and delivery quests.
  • Use threat_target_only: false for ordinary world kill objectives.
  • Use threat_target_only: true when only spawned quest targets should count.
  • Use stage and auto_advance to build cinematic multi-step quests.
  • Use rumors to hide story arcs until the player discovers them.
  • Use traits_on_spare, traits_on_attack, and traits_on_complete to remember player choices.
  • Put quests that reference other mods in optional datapacks or mods so missing registry ids do not break unrelated setups.
mebahelrpgrquest-3.5.2-fabric-1.21.1
MC 1.21, Client, Fabric, Forge, 1.21.1, NeoForge, Server, Quilt
Release 2026-10-16 Get
mebahelrpgrquest-3.5.2-fabric-1.20.1
MC Client, Fabric, 1.20.1, Forge, 1.20, NeoForge, Server, Quilt
Release 2026-10-16 Get
mebahelrpgrquest-3.5.1-fabric-1.20.1
MC Client, Fabric, 1.20.1, Forge, 1.20, NeoForge, Server, Quilt
Release 2026-10-15 Get
mebahelrpgrquest-3.5.1-fabric-1.21.1
MC 1.21, Client, Fabric, Forge, 1.21.1, NeoForge, Server, Quilt
Release 2026-10-15 Get
mebahelrpgrquest-3.4.5-fabric-1.21.1
MC 1.21, Client, Fabric, Forge, 1.21.1, NeoForge, Server, Quilt
Release 2026-10-13 Get
mebahelrpgrquest-3.4.5-fabric-1.20.1
MC Client, Fabric, 1.20.1, Forge, 1.20, NeoForge, Server, Quilt
Release 2026-10-13 Get
mebahelrpgrquest-3.4.4-fabric-1.21.1
MC 1.21, Client, Fabric, Forge, 1.21.1, NeoForge, Server, Quilt
Release 2026-10-09 Get
mebahelrpgrquest-3.4.4-fabric-1.20.1
MC Client, Fabric, 1.20.1, Forge, 1.20, NeoForge, Server, Quilt
Release 2026-10-09 Get
mebahelrpgrquest-3.4.3-fabric-1.21.1
MC 1.21, Client, Fabric, Forge, 1.21.1, NeoForge, Server, Quilt
Release 2026-10-08 Get
mebahelrpgrquest-3.4.3-fabric-1.20.1
MC Client, Fabric, 1.20.1, Forge, 1.20, NeoForge, Server, Quilt
Release 2026-10-07 Get
mebahelrpgrquest-3.4.2-fabric-1.21.1
MC 1.21, Client, Fabric, Forge, 1.21.1, NeoForge, Server, Quilt
Release 2026-10-06 Get
mebahelrpgrquest-3.4.2-fabric-1.20.1
MC Client, Fabric, 1.20.1, Forge, 1.20, NeoForge, Server, Quilt
Release 2026-10-06 Get
mebahelrpgrquest-3.4.1-fabric-1.20.1
MC Client, Fabric, 1.20.1, Forge, 1.20, NeoForge, Server, Quilt
Release 2026-10-05 Get
mebahelrpgrquest-3.4.1-fabric-1.21.1
MC 1.21, Client, Fabric, Forge, 1.21.1, NeoForge, Server, Quilt
Release 2026-10-05 Get
mebahelrpgrquest-3.4.0-fabric-1.21.1
MC 1.21, Client, Fabric, Forge, 1.21.1, NeoForge, Server, Quilt
Release 2026-10-04 Get
mebahelrpgrquest-3.4.0-fabric-1.20.1
MC Client, Fabric, 1.20.1, Forge, 1.20, NeoForge, Server, Quilt
Release 2026-10-04 Get
mebahelrpgrquest-3.3.0-fabric-1.20.1
MC Client, Fabric, 1.20.1, Forge, 1.20, NeoForge, Server, Quilt
Release 2026-10-02 Get
mebahelrpgrquest-3.3.0-fabric-1.21.1
MC 1.21, Client, Fabric, Forge, 1.21.1, NeoForge, Server, Quilt
Release 2026-10-02 Get
mebahelrpgrquest-3.2.3-fabric-1.21.1
MC 1.21, Client, Fabric, Forge, 1.21.1, NeoForge, Server, Quilt
Release 2026-10-01 Get
mebahelrpgrquest-3.2.3-fabric-1.20.1
MC Client, Fabric, 1.20.1, Forge, 1.20, NeoForge, Server, Quilt
Release 2026-10-01 Get
mebahelrpgrquest-3.2.2-fabric-1.21.1
MC 1.21, Client, Fabric, Forge, 1.21.1, NeoForge, Server, Quilt
Release 2026-09-30 Get
mebahelrpgrquest-3.2.2-fabric-1.20.1
MC Client, Fabric, 1.20.1, Forge, 1.20, NeoForge, Server, Quilt
Release 2026-09-30 Get
mebahelrpgrquest-3.2.1-fabric-1.21.1
MC 1.21, Client, Fabric, Forge, 1.21.1, NeoForge, Server, Quilt
Release 2026-09-28 Get
mebahelrpgrquest-3.2.1-fabric-1.20.1
MC Client, Fabric, 1.20.1, Forge, 1.20, NeoForge, Server, Quilt
Release 2026-09-28 Get
mebahelrpgrquest-3.2.0-fabric-1.20.1
MC Client, Fabric, 1.20.1, Forge, 1.20, NeoForge, Server, Quilt
Release 2026-09-27 Get
mebahelrpgrquest-3.2.0-fabric-1.21.1
MC 1.21, Client, Fabric, Forge, 1.21.1, NeoForge, Server, Quilt
Release 2026-09-27 Get
mebahelrpgrquest-3.1.0-fabric-1.20.1
MC Client, Fabric, 1.20.1, Forge, 1.20, NeoForge, Server, Quilt
Release 2026-09-26 Get
mebahelrpgrquest-3.1.0-fabric-1.21.1
MC 1.21, Client, Fabric, Forge, 1.21.1, NeoForge, Server, Quilt
Release 2026-09-26 Get
mebahelrpgrquest-3.0.1-fabric-1.21.1
MC 1.21, Client, Fabric, Forge, 1.21.1, NeoForge, Server, Quilt
Release 2026-09-25 Get
mebahelrpgrquest-3.0.1-fabric-1.20.1
MC Client, Fabric, 1.20.1, Forge, 1.20, NeoForge, Server, Quilt
Release 2026-09-25 Get
mebahelrpgrquest-3.0.0-fabric-1.20.1
MC Client, Fabric, 1.20.1, Forge, 1.20, NeoForge, Server, Quilt
Release 2026-09-22 Get
mebahelrpgrquest-2.1.0-fabric-1.21.1
MC 1.21, Client, Fabric, Forge, 1.21.1, NeoForge, Server, Quilt
Release 2026-09-08 Get
mebahelrpgrquest-2.1.0-fabric-1.20.1
MC Client, Fabric, 1.20.1, Forge, 1.20, NeoForge, Server, Quilt
Release 2026-09-08 Get
mebahelrpgrquest-2.0.8-fabric-1.20.1
MC Client, Fabric, 1.20.1, Forge, 1.20, NeoForge, Server, Quilt
Release 2026-09-07 Get
mebahelrpgrquest-2.0.8-fabric-1.21.1
MC 1.21, Client, Fabric, Forge, 1.21.1, NeoForge, Server, Quilt
Release 2026-09-07 Get
mebahelrpgrquest-2.0.7-fabric-1.21.1
MC 1.21, Client, Fabric, Forge, 1.21.1, NeoForge, Server, Quilt
Release 2026-09-06 Get
mebahelrpgrquest-2.0.6-fabric-1.21.1
MC 1.21, Client, Fabric, Forge, 1.21.1, NeoForge, Server, Quilt
Release 2026-08-25 Get
mebahelrpgrquest-2.0.5-fabric-1.21.1
MC 1.21, Client, Fabric, Forge, 1.21.1, NeoForge, Server, Quilt
Release 2026-08-24 Get
mebahelrpgrquest-2.0.5-fabric-1.20.1
MC Client, Fabric, 1.20.1, Forge, 1.20, NeoForge, Server, Quilt
Release 2026-08-24 Get
mebahelrpgrquest-2.0.4-fabric-1.21.1
MC 1.21, Client, Fabric, Forge, 1.21.1, NeoForge, Server, Quilt
Release 2026-08-20 Get
mebahelrpgrquest-2.0.4-fabric-1.20.1
MC Client, Fabric, 1.20.1, Forge, 1.20, NeoForge, Server, Quilt
Release 2026-08-20 Get
mebahelrpgrquest-2.0.2-fabric-1.21.1
MC 1.21, Client, Fabric, Forge, 1.21.1, NeoForge, Server, Quilt
Release 2026-08-15 Get
mebahelrpgrquest-2.0.2-fabric-1.20.1
MC Client, Fabric, 1.20.1, Forge, 1.20, NeoForge, Server, Quilt
Release 2026-08-15 Get
mebahelrpgrquest-2.0.0-fabric-1.20.1
MC Client, Fabric, 1.20.1, Forge, 1.20, NeoForge, Server, Quilt
Release 2026-07-28 Get
mebahelrpgrquest-2.0.0-fabric-1.21.1
MC 1.21, Client, Fabric, Forge, 1.21.1, NeoForge, Server, Quilt
Release 2026-07-28 Get
mebahelrpgrquest-1.1.2-fabric-1.21.1
MC 1.21, Client, Fabric, Forge, 1.21.1, NeoForge, Server, Quilt
Release 2026-07-21 Get
mebahelrpgrquest-1.1.2-fabric-1.20.1
MC Client, Fabric, 1.20.1, Forge, 1.20, NeoForge, Server, Quilt
Release 2026-07-21 Get
mebahelrpgrquest-1.1.3-fabric-1.21.1
MC 1.21, Client, Fabric, Forge, 1.21.1, NeoForge, Server, Quilt
Release 2026-07-21 Get
mebahelrpgrquest-1.1.3-fabric-1.20.1
MC Client, Fabric, 1.20.1, Forge, 1.20, NeoForge, Server, Quilt
Release 2026-07-21 Get
mebahelrpgrquest-1.1.1-fabric-1.20.1
MC Client, Fabric, 1.20.1, Forge, 1.20, NeoForge, Server, Quilt
Release 2026-07-20 Get

More from Mebahel

Advertisement Remove ads with Premium →

You Might Also Like