Описание
# Mebahel's RPG: Villager Quests & Companions
**Turn Minecraft villages into RPG adventures.**
Discover **79 included quests**, make choices that change what happens next, and recruit unexpected companions. Take on repeatable contracts and follow your adventures through a dedicated **quest journal, HUD tracker, and branching quest map**.
Ready to play, with full **English, French, Russian, and Simplified Chinese** localization.

## Quest journal & HUD tracking
Keep your story quests and board contracts together in one journal. Check objectives, progress, rewards, and destinations across **active, completed, and failed quests**. Follow your current task on a HUD that can be resized and placed in any screen corner.
Press **J** to open the journal. The key is configurable, and server owners can disable clickable journal coordinates.
[Join the Discord](https://discord.com/invite/y8uC2NepkB) to share quest ideas, discuss your adventures, and give feedback directly to Mebahel.
## Story quests, choices & consequences
A village job can lead to an investigation, a confrontation, or a story that returns later. Talk to named characters, ask questions, choose who to trust, and decide when to fight or show mercy. Some spared characters can eventually become companions.
The included adventures mix **branching stories and everyday village work**: defend a settlement, escort someone to safety, deliver supplies, help with construction, or investigate trouble in a mine. Villager rumors gradually unlock hidden quests, while discoverable books give you new stories to follow during exploration.
**Consequences can last beyond the reward.** Selected decisions affect follow-up quests and village dialogue. Some continuations arrive after time has passed, giving you a reason to return.
### See how your story branches
Press **K** to open the quest map and explore the connections between stories: choices, prerequisites, rumor discoveries, and delayed or chance-based continuations. The key is configurable, and server owners can disable the map.

### Included adventures
Explore the content overview below without revealing the endings.
Category
Included content
Gameplay focus
Major storylines
Ash Court, Armed Dead, False Hero, Mad Scientist, Most Important Cow, No Banner, Village Defense, Witch, Last Heat
Branching choices, investigations, combat, mercy paths, consequences, and multi-part progression
Village stories
Village Arrival, village construction, animal enclosure, deliveries, mine incidents, and local threats
Building, collecting, defending, escorting, and restoring village life
Quest-book stories
Nine discoverable quest books with standalone or delayed follow-ups
Exploration, reading clues, hidden encounters, unusual objectives, and long-form mysteries
Repeatable contracts
Hunts, spawned groups, deliveries, village protection, incursions, escorts, and elite targets
Board reputation, five difficulty levels, scaling danger, and randomized rewards
Discovery content
Villager rumors and hidden prerequisites
Gradual unlocking instead of presenting every adventure immediately
## Quest boards & repeatable contracts
Visit a village quest board, inspect the objectives and rewards, and choose a contract. Offers refresh over time, with **hunts, deliveries, protection jobs, incursions, escorts, and elite targets** to tackle between story quests.
Each board has its own reputation and level. Completing its contracts makes harder offers more likely and shortens the refresh time. Five difficulty levels run from **Common** to **Legendary**, scaling the danger and rewards.

Accepted contracts go straight into your journal and HUD tracker. Board offers are personal to each player by default; servers can also configure shared offers. The board's reputation and level are shared.
## Recruitable companions
Some stories give you the chance to spare someone you first met as a threat. **Selected characters can become permanent companions**, following you and fighting hostile enemies at your side.
Manage supported companions' equipment through a dedicated inventory screen. Their combat behavior avoids peaceful villagers and animals.

## Villager conversations & reactions
Walk through a village and hear conversations about crops, work, golems, books, and local gossip. Villagers can notice you and react to important events from your adventures.
The **40 ambient dialogue scenes** use text above the speaker, dialogue sounds, and speaking animations. Conversations take nearby danger and ongoing quest dialogue into account, and each player sees them in their selected supported language.

### Another look at village life
A quest board and a speaking villager in the village.
## Installation
Choose the file for your Minecraft version from the [Files tab](https://www.curseforge.com/minecraft/mc-mods/mebahels-rpg-villager-quests-and-companions/files), then install the dependencies for your setup. Use matching Minecraft versions for the mod and its dependencies.
| Setup | Required dependencies |
| --- | --- |
| **Fabric** | [Fabric API](https://www.curseforge.com/minecraft/mc-mods/fabric-api) |
| **Forge / NeoForge through Sinytra** | [Sinytra Connector](https://www.curseforge.com/minecraft/mc-mods/sinytra-connector) and [Forgified Fabric API](https://www.curseforge.com/minecraft/mc-mods/forgified-fabric-api) |
Forge and NeoForge use the Fabric mod through Connector. Check that Connector supports your chosen Minecraft and loader version.
### Your first adventure
1. **Visit a village** and interact with villagers to discover available stories and rumors. Not every villager offers a quest.
2. **Browse a quest board** for repeatable contracts, or discover quest books as you explore.
3. **Open your journal with J**, follow the objectives, and see where your decisions lead.
The included quests are ready to play. Datapacks are optional and let you add your own content.
## Compatibility
These optional integrations and compatible mods expand your adventures. Availability depends on the Minecraft and mod versions you install.
| Mod | What to expect |
| --- | --- |
| **MCA Reborn** | Dedicated interaction handling returns control to MCA after quest interactions. |
| **Ice and Fire CE** | Optional elite contracts for fire, ice, and lightning dragons, with scaled stages and dedicated rewards. |
| **Saint's Dragons** | Configurable village-attack contracts featuring Varasuchus, Volitans, Nulljaw, Atroxiia, Raevyx, and Ignivorus, plus a separate Draconian Swarm contract. Each contract type has its own enable toggle, selection weight, and star range. |
| **Guard Villagers** | Choose which quests guards may offer through a dedicated configuration. |
| **Villagers Reborn** | Compatible villager models and interaction changes. |
| **Epic Villages** | Tested with the quest system. |
| **Luki's Grand Capitals** | Tested with the quest system. |
| **Villager Retaliation** | Both systems can coexist and remain independent. |
Quest assignments support vanilla and modded locations, so village and structure overhauls are generally compatible. Specific combinations can still depend on their structure and interaction changes.
## Multiplayer and customization
**Story progress is individual by default.** Servers can enable shared quest progress, outcomes, rewards, and story traits. Personal board offers and shared board progression have their own behavior, so you can choose how your group plays.
Adjust quest and rumor assignment, ambient conversations, board generation, HUD placement, and navigation aids. Additional files let you manage ignored quests, Guard Villager assignments, and contract generation.
### Configuration reference
Main server/world configuration:
config/mebahelrpgrquest/mebahelrpgrquest_config.json
Option
Default value
Purpose
villagerQuestChance
0.15
Weight for assigning a story quest to a newly loaded villager
villagerRumorChance
0.15
Weight for assigning a rumor
disableQuestCoordinateClick
false
Disables clickable journal coordinates
disableQuestMap
false
Disables access to the quest map
shareQuestsBetweenPlayers
false
Shares progress, outcomes, rewards, and story traits server-wide
inventoryJournalButtonPosition
left
Places the inventory journal button on the left or right
hideInventoryJournalButton
false
Hides the inventory journal shortcut
questTrackerPosition
top_left
Chooses one of four tracker corners
questTrackerScale
1.0
Resizes the HUD tracker
questBoardVillageChance
1.0
Controls village quest-board generation chance
individualBoardOffers
true
Gives each player personal board offers
questBoardStructures
minecraft:village_plains
minecraft:village_desert
minecraft:village_savanna
minecraft:village_snowy
minecraft:village_taiga
Lists the structure IDs eligible for quest-board generation
questBoardPreferMeetingPoint
true
Prefers the village meeting point when placing a quest board
questBoardPlacementSearchRadius
24
Sets the search radius for a suitable quest-board placement position
questBoardDropsOnBreak
true
Controls whether a quest board drops as an item when broken
questBoardMinimumPlacementDistance
48
Sets the minimum spacing between generated quest boards
ambientDialoguesEnabled
true
Enables ambient villager conversations
ambientDialogueCheckIntervalTicks
100
Sets ambient-dialogue check frequency
ambientDialogueChance
0.08
Sets chance per eligible ambient-dialogue check
ambientDialogueActivityRadius
24.0
Sets activity radius around each player
Additional files manage ignored quest IDs, Guard Villager assignments, and contract generation.
## Help shape the next village story
**Which quest stayed with you? Which choice was hardest to make?** Share your experience or suggest a new village problem on [Discord](https://discord.com/invite/y8uC2NepkB). Feedback on dialogue, difficulty, and translations helps me improve the next update.
For bug reports, include your Minecraft version, loader, mod version, and steps to reproduce the issue. Add a log or screenshot when it helps explain what happened.
Follow the project on CurseForge for updates, and [discover more of my mods](https://www.curseforge.com/members/mebahel/projects):
- **[Draugr Invasion](https://www.curseforge.com/minecraft/mc-mods/mebahels-creatures-draugr)** brings Nordic undead, dangerous ruins, and boss encounters to your adventures.
- **[Dwarven Automatons](https://www.curseforge.com/minecraft/mc-mods/mebahels-creatures-dwarven-automatons)** adds ancient machines, Dwemer-inspired ruins, and summonable mechanical companions.
These are separate projects, not required dependencies for Villager Quests & Companions.
***
## Creator documentation
**Build your own stories with JSON datapacks.** Add dialogue, branching choices, rumors, objectives, named enemies, rewards, and repeatable contracts. Use vanilla or modded content to tailor adventures to your world or modpack.
The reference sections below include quest and contract examples. Expand the section closest to what you want to create.
### Story quests and rumors: setup
Anyone can create new quests for the mod with JSON files in a datapack or mod. You can add dialogue, objectives, rumors, named enemies, rewards, choices, ambushes, raids, deliveries, escorts, and complete branching questlines.
File Locations
Place quest and rumor files in your own namespace:
data/<namespace>/quests/<quest_file>.json
data/<namespace>/rumors/<rumor_file>.json
For example:
data/my_quests/quests/old_well.json
This creates the quest id:
my_quests:old_well
Quest subfolders are allowed, but they do not become part of the quest id. Keep every quest filename unique inside your namespace.
Quick Start
Choose the example below that is closest to the quest you want to make.
Copy its JSON into a new file under data/<namespace>/quests/ or data/<namespace>/rumors/.
Replace the example or modid namespace with your own namespace.
Change the dialogue, entities, structures, objectives, rewards, and linked quest ids.
Reload the datapack and test the quest in a development or backup world.
JSON does not allow comments or trailing commas. Always use full identifiers such as minecraft:zombie, and use full quest ids such as my_quests:old_well when one file references another.
Player-facing text can use a translation object:
{
"translate": "quest.my_quests.old_well.title",
"fallback": "The Old Well"
}
The fallback value is displayed when no matching translation is available, so a separate language file is optional.
### Named Threat with Attack or Spare Branches
Spawn a named enemy, let the player speak to it, then continue into a different quest depending on whether the target is attacked or spared.
First Quest
{
"title": "QUEST TITLE",
"summary": "Villager-facing summary shown before acceptance.",
"flow": {
"on_kill": "modid:kill_branch_2",
"on_spare": "modid:spare_branch_2"
},
"goals": [
{
"id": "talk_to_threat",
"talk": "minecraft:zombie",
"amount": 1,
"name": "NAMED THREAT"
},
{
"id": "kill_threat",
"kill": "minecraft:zombie",
"amount": 1,
"attack_only": true,
"from_threats": true
}
],
"threat": {
"entity": "minecraft:zombie",
"name": "NAMED THREAT",
"structure": "minecraft:ruined_portal",
"search_radius": 4000,
"spawn_on_accept": true,
"spawn_min_radius": 3,
"spawn_max_radius": 6,
"spare": true,
"glow": false,
"max_health": 150,
"equipment": {
"mainhand": "minecraft:diamond_sword",
"helmet": {
"item": "minecraft:iron_helmet",
"enchants": {
"minecraft:unbreaking": 3
}
}
},
"line": "Quest giver line that describes the threat.",
"target": "Initial line spoken by the threat.",
"talk": [
[
"Player question one?",
"Threat answer one."
],
[
"Player question two?",
"Threat answer two."
]
]
},
"choice": {
"attack": {
"label": "Attack choice label.",
"traits": [
"trait_from_attack"
],
"return": "Quest giver line after the target is killed."
},
"spare": {
"label": "Spare choice label.",
"line": "Immediate line after sparing the target.",
"post": "Follow-up line shown after the spare.",
"villager": "Quest giver line after spare.",
"traits": [
"trait_from_spare"
],
"rewards_from_giver": true,
"rewards": {
"xp": 160,
"items": {
"minecraft:iron_ingot": 4
}
},
"after": {
"offer_chance": 70,
"ambush_chance": 30,
"nothing_chance": 0,
"ambush": "minecraft:zombie",
"ambush_name": "Fallback Ambush Name",
"count": 5,
"ambush_max_health": 50,
"ambush_equipment": {
"helmet": "minecraft:leather_helmet"
},
"line": "Line used when the spared target offers the next quest.",
"ambush_line": "Line used if mercy triggers an ambush.",
"nothing": "Line used if no follow-up happens."
}
}
},
"dialogue": {
"return": "Quest giver line after kill.",
"reward": "Quest giver reward line.",
"done": "Quest giver already-completed line."
},
"rewards": {
"xp": 260,
"items": {
"minecraft:emerald": 10
}
}
}
For spare-enabled threat confrontations, prefer the talk plus attack_only kill pattern shown above. The first interaction opens dialogue without completing the stage; the stage completes only after the player explicitly chooses attack or spare.
Kill Branch
{
"title": "KILL BRANCH TITLE",
"summary": "Follow-up summary after the player chose attack.",
"dialogue": {
"intro": "Intro line.",
"offer": [
[
"Player question?",
"Quest giver answer."
]
],
"return": "Return line.",
"reward": "Reward line.",
"done": "Already completed line."
},
"goals": [
"kill 3 minecraft:zombified_piglin"
],
"threats": [
{
"entity": "minecraft:zombified_piglin",
"name": "Branch Threat",
"structure": "minecraft:ruined_portal",
"search_radius": 4000,
"spawn_on_accept": true,
"spare": false,
"max_health": 70,
"equipment": {
"mainhand": "minecraft:golden_sword"
}
}
],
"rewards": {
"xp": 360,
"items": {
"minecraft:emerald": 14
}
}
}
Spare Branch
{
"title": "SPARE BRANCH TITLE",
"summary": "Follow-up summary after the player chose spare.",
"flow": {
"next": "modid:spare_branch_3"
},
"dialogue": {
"intro": "Intro line from the spared target or quest giver.",
"offer": [
[
"Player question?",
"Answer."
]
],
"return": "Return line.",
"reward": "Reward line.",
"done": "Already completed line."
},
"goals": [
{
"collect": "minecraft:iron_ingot",
"amount": 4
}
],
"rewards": {
"xp": 240,
"items": {
"minecraft:emerald": 6
}
}
}
### Staged Building and Defense
Ask the player to build or gather supplies first, then begin a second stage that spawns attackers around the quest giver.
Based on questlines/village_build/village_pig_enclosure.json.
Key points:
sequential_objectives: true makes stage 0 finish before stage 1 starts.
Build objectives use place, bring, collect, or other normal objective shortcuts.
Threats can be assigned to stage: 1 and spawned around the quest giver with spawn_origin: "quest_giver".
Use from_threats: true on kill goals when the spawned named/custom threats should count.
Add one threats entry per mob to spawn. amount is not read on threat entries.
{
"title": {
"translate": "quest.example.first_pen_defense.title",
"fallback": "A Pen Worth Defending"
},
"summary": {
"translate": "quest.example.first_pen_defense.summary",
"fallback": "Build a small animal pen, bring livestock inside, then defend it from raiders."
},
"sequential_objectives": true,
"dialogue": {
"intro": {
"translate": "quest.example.first_pen_defense.dialogue.intro",
"fallback": "The villager points to a bare patch of grass near the farm."
},
"offer": [
[
{
"translate": "quest.example.first_pen_defense.dialogue.offer.0.0",
"fallback": "What do you need built?"
},
{
"translate": "quest.example.first_pen_defense.dialogue.offer.0.1",
"fallback": "A fence, a gate, two torches, and enough room for the first herd."
}
]
],
"return": {
"translate": "quest.example.first_pen_defense.dialogue.return",
"fallback": "The pen held. So did you."
},
"reward": {
"translate": "quest.example.first_pen_defense.dialogue.reward",
"fallback": "Take this. A defended farm feeds more than one house."
},
"done": {
"translate": "quest.example.first_pen_defense.dialogue.done",
"fallback": "The animals are still inside, and the raiders are gone."
}
},
"goals": [
{
"id": "place_fences",
"place": "minecraft:oak_fence",
"amount": 12,
"stage": 0,
"range": 60
},
{
"id": "place_gate",
"place": "minecraft:oak_fence_gate",
"amount": 1,
"stage": 0,
"range": 60
},
{
"id": "place_torches",
"place": "minecraft:torch",
"amount": 2,
"stage": 0,
"range": 60,
"say": {
"translate": "quest.example.first_pen_defense.goals.place_torches.say",
"fallback": "The pen is lit. Stay close."
}
},
{
"id": "bring_animals",
"bring": "minecraft:pig",
"amount": 2,
"stage": 0,
"range": 60
},
{
"id": "kill_raiders",
"kill": "minecraft:pillager",
"amount": 3,
"stage": 1,
"from_threats": true
},
{
"id": "kill_raider_captain",
"kill": "minecraft:vindicator",
"amount": 1,
"stage": 1,
"from_threats": true
}
],
"threats": [
{
"entity": "minecraft:pillager",
"name": {
"translate": "quest.example.first_pen_defense.threats.0.name",
"fallback": "Hungry Raider"
},
"stage": 1,
"spawn_origin": "quest_giver",
"spawn_min_radius": 18,
"spawn_max_radius": 30,
"spawn_on_accept": true,
"spare_enabled": false,
"glow": true
},
{
"entity": "minecraft:pillager",
"name": {
"translate": "quest.example.first_pen_defense.threats.1.name",
"fallback": "Fence-Cutting Raider"
},
"stage": 1,
"spawn_origin": "quest_giver",
"spawn_min_radius": 18,
"spawn_max_radius": 30,
"spawn_on_accept": true,
"spare_enabled": false,
"glow": true
},
{
"entity": "minecraft:pillager",
"name": {
"translate": "quest.example.first_pen_defense.threats.2.name",
"fallback": "Torch-Kicking Raider"
},
"stage": 1,
"spawn_origin": "quest_giver",
"spawn_min_radius": 18,
"spawn_max_radius": 30,
"spawn_on_accept": true,
"spare_enabled": false,
"glow": true
},
{
"entity": "minecraft:vindicator",
"name": {
"translate": "quest.example.first_pen_defense.threats.3.name",
"fallback": "Fence Breaker"
},
"stage": 1,
"spawn_origin": "quest_giver",
"spawn_min_radius": 22,
"spawn_max_radius": 34,
"spawn_on_accept": true,
"spare_enabled": false,
"glow": true,
"max_health": 40.0
}
],
"rewards": {
"xp": 180,
"items": {
"minecraft:emerald": 6,
"minecraft:wheat": 12
}
},
"traits": {
"complete": [
"farm_defender"
]
}
}
### Generated Container, Written Book, and TNT
Place quest items inside a structure container, make the player read a written clue, then complete a demolition objective and spawn enemies.
Based on questlines/sculk/sculk_mineshaft_investigation.json.
Key points:
read_book objectives must include item: "minecraft:written_book".
quest_book.title, quest_book.author, and quest_book.pages can be translation objects.
Use in_chest: true with container to spawn the objective item inside a generated container.
Generated chest/container items are placed into random empty slots by the quest item spawner.
detonate_tnt should use block for the target block near the explosion, not the TNT block itself.
force_place_block: true can prepare the target block when the structure does not reliably contain one.
{
"title": {
"translate": "quest.example.mine_demolition.title",
"fallback": "Notes Under the Mine"
},
"summary": {
"translate": "quest.example.mine_demolition.summary",
"fallback": "Find a sealed mineshaft, recover the foreman's notes, and destroy the marked spawner."
},
"sequential_objectives": true,
"goals": [
{
"id": "reach_old_mine",
"reach": "minecraft:mineshaft",
"structure": "minecraft:mineshaft",
"radius": 3200,
"range": 80,
"stage": 0,
"auto_advance": true
},
{
"id": "read_foreman_notes",
"type": "read_book",
"item": "minecraft:written_book",
"amount": 1,
"structure": "minecraft:mineshaft",
"container": "minecraft:barrel",
"stage": 1,
"radius": 3200,
"in_chest": true,
"auto_advance": true,
"tag": "example_foreman_notes",
"quest_book": {
"title": {
"translate": "quest.example.mine_demolition.book.title",
"fallback": "Foreman's Notes"
},
"author": {
"translate": "quest.example.mine_demolition.book.author",
"fallback": "Mine Foreman"
},
"pages": [
{
"translate": "quest.example.mine_demolition.book.page.0",
"fallback": "We sealed the lower drift after the spawner woke again. If anyone returns, place charges near the cage, not in the tunnel mouth."
}
]
},
"block_patch": {
"radius": 4,
"palette": [
"minecraft:sculk",
"minecraft:deepslate"
]
}
},
{
"id": "take_tnt_from_barrel",
"collect": "minecraft:tnt",
"amount": 3,
"mandatory": false,
"sequential": true,
"stage": 1,
"in_chest": true,
"structure": "minecraft:mineshaft",
"container": "minecraft:barrel"
},
{
"id": "place_demolition_charges",
"place": "minecraft:tnt",
"amount": 3,
"structure": "minecraft:mineshaft",
"stage": 2,
"range": 12
},
{
"id": "detonate_spawner",
"type": "detonate_tnt",
"block": "minecraft:spawner",
"required_mob": "minecraft:skeleton",
"structure": "minecraft:mineshaft",
"force_place_block": true,
"amount": 3,
"stage": 2,
"radius": 3200,
"range": 14,
"auto_advance": true,
"block_patch": {
"radius": 3,
"palette": [
"minecraft:sculk",
"minecraft:deepslate"
]
}
},
{
"id": "kill_what_crawls_out",
"kill": "minecraft:zombie",
"amount": 4,
"stage": 3,
"from_threats": true
}
],
"threats": [
{
"entity": "minecraft:zombie",
"name": {
"translate": "quest.example.mine_demolition.threats.0.name",
"fallback": "Sculk-Crowned Dead"
},
"stage": 3,
"spawn_origin": "player",
"spawn_min_radius": 8,
"spawn_max_radius": 16,
"spawn_on_accept": true,
"spare_enabled": false,
"glow": true,
"equipment": {
"head": "minecraft:sculk"
}
},
{
"entity": "minecraft:zombie",
"name": {
"translate": "quest.example.mine_demolition.threats.1.name",
"fallback": "Sculk-Marked Dead"
},
"stage": 3,
"spawn_origin": "player",
"spawn_min_radius": 8,
"spawn_max_radius": 16,
"spawn_on_accept": true,
"spare_enabled": false,
"glow": true,
"equipment": {
"head": "minecraft:sculk"
}
},
{
"entity": "minecraft:zombie",
"name": {
"translate": "quest.example.mine_demolition.threats.2.name",
"fallback": "Sculk-Marked Dead"
},
"stage": 3,
"spawn_origin": "player",
"spawn_min_radius": 8,
"spawn_max_radius": 16,
"spawn_on_accept": true,
"spare_enabled": false,
"glow": true,
"equipment": {
"head": "minecraft:sculk"
}
},
{
"entity": "minecraft:zombie",
"name": {
"translate": "quest.example.mine_demolition.threats.3.name",
"fallback": "Sculk-Marked Dead"
},
"stage": 3,
"spawn_origin": "player",
"spawn_min_radius": 8,
"spawn_max_radius": 16,
"spawn_on_accept": true,
"spare_enabled": false,
"glow": true,
"equipment": {
"head": "minecraft:sculk"
}
}
],
"rewards": {
"xp": 320,
"items": {
"minecraft:emerald": 10,
"minecraft:echo_shard": 1
}
}
}
### Delivery to Another Structure or Village
Collect supplies, travel to another structure or village, hand the items to a generated target, and return to the original quest giver.
Based on delivery_cobblestone_oak_log_other_village.json.
Key points:
The delivery target is configured in threat.
delivery_objectives must list the objective ids that should be handed over.
The target talk objective should usually use auto_advance: true.
Add a final return: true objective in the next stage if the player must report back.
min_structure_distance is useful when the target should not spawn in the same village.
{
"title": {
"translate": "quest.example.remote_delivery.title",
"fallback": "Stone for the Next Village"
},
"summary": {
"translate": "quest.example.remote_delivery.summary",
"fallback": "Carry supplies to a messenger waiting in another village."
},
"sequential_objectives": true,
"goals": [
{
"id": "delivery_cobblestone",
"collect": "minecraft:cobblestone",
"amount": 32,
"mandatory": true,
"stage": 0
},
{
"id": "delivery_oak_logs",
"collect": "minecraft:oak_log",
"amount": 16,
"mandatory": true,
"stage": 0
},
{
"id": "deliver_to_messenger",
"talk": "minecraft:villager",
"amount": 1,
"mandatory": true,
"stage": 0,
"auto_advance": true,
"name": {
"translate": "quest.example.remote_delivery.goals.deliver_to_messenger.name",
"fallback": "Village Messenger"
},
"say": {
"translate": "quest.example.remote_delivery.goals.deliver_to_messenger.say",
"fallback": "The messenger takes the supplies. Return to the villager who sent you."
}
},
{
"id": "return_to_sender",
"return": true,
"amount": 1,
"mandatory": true,
"stage": 1
}
],
"threat": {
"entity": "minecraft:villager",
"name": {
"translate": "quest.example.remote_delivery.threat.name",
"fallback": "Village Messenger"
},
"structure": "minecraft:villages",
"search_radius": 4200,
"spawn_radius": 10,
"spawn_on_accept": true,
"spare_enabled": false,
"glow": false,
"target_line": {
"translate": "quest.example.remote_delivery.threat.target_line",
"fallback": "If you have the stone and oak, hand them over before the wall gives way."
},
"delivery_objectives": [
"delivery_cobblestone",
"delivery_oak_logs"
],
"delivery_choice_label": {
"translate": "quest.example.remote_delivery.threat.delivery_choice_label",
"fallback": "Hand over supplies"
},
"delivered_line": {
"translate": "quest.example.remote_delivery.threat.delivered_line",
"fallback": "That will hold. Tell them the road between our villages is still worth keeping open."
},
"depart_after_delivery": false,
"min_structure_distance": 700
},
"rewards": {
"xp": 180,
"items": {
"minecraft:emerald": 7,
"minecraft:bread": 6
}
}
}
### Village Raid Defense
Start a normal Minecraft raid when the quest is accepted and complete the objective when the village survives.
Based on questlines/village_defense/village_defense_chain_3_the_bell_and_the_raid.json.
Key points:
Use type: "defend_raid".
amount: 1 is the normal value for a single raid defense objective.
This objective depends on the normal Minecraft raid flow, so it should be offered from a villager in or near the village being defended.
Use rewards with enchanted items when the raid reward should feel unique.
{
"title": {
"translate": "quest.example.bell_raid.title",
"fallback": "The Bell and the Raid"
},
"summary": {
"translate": "quest.example.bell_raid.summary",
"fallback": "Stand with the village and survive the raid."
},
"dialogue": {
"intro": {
"translate": "quest.example.bell_raid.dialogue.intro",
"fallback": "The villager stands beside the bell, one hand on the rope."
},
"offer": [
[
{
"translate": "quest.example.bell_raid.dialogue.offer.0.0",
"fallback": "You think they are coming now?"
},
{
"translate": "quest.example.bell_raid.dialogue.offer.0.1",
"fallback": "If we ring the bell, they will know we are ready to fight."
}
]
],
"return": {
"translate": "quest.example.bell_raid.dialogue.return",
"fallback": "The horn is silent. The village still stands."
},
"reward": {
"translate": "quest.example.bell_raid.dialogue.reward",
"fallback": "This was taken from the raid leader. By right of battle, it is yours."
},
"done": {
"translate": "quest.example.bell_raid.dialogue.done",
"fallback": "The bell rings for warning again, not fear."
}
},
"goals": [
{
"id": "defend_the_village",
"type": "defend_raid",
"amount": 1
}
],
"rewards": {
"xp": 650,
"items": {
"minecraft:emerald": 20,
"minecraft:crossbow": {
"count": 1,
"enchantments": [
{
"id": "minecraft:power",
"level": 3
},
{
"id": "minecraft:unbreaking",
"level": 2
},
{
"id": "minecraft:piercing",
"level": 1
}
]
}
}
},
"traits": {
"complete": [
"village_defender"
]
}
}
### Rumor That Unlocks a Hidden Quest
Keep a quest unavailable until the player hears the correct rumor from a villager.
Based on rumors/mine_smoke_below.json and blaze_mineshaft_threat.json.
Key points:
The rumor file lives under data/<namespace>/rumors/<rumor_id>.json.
unlock_quest should be the full quest id.
When the rumor is discovered, the player receives the trait quest_discovered:<full quest id>.
The hidden quest should require that trait.
Use conditions.not_completed_quests so the rumor stops being useful after the quest is complete.
Rumor line and discovered_line are currently plain strings.
Rumor file
{
"id": "example_smoke_below",
"weight": 15,
"line": "Miners swear smoke is rising from shafts sealed for years.",
"unlock_quest": "example:hidden_mineshaft_fire",
"conditions": {
"not_completed_quests": [
"example:hidden_mineshaft_fire"
]
},
"discovered_line": "Rumor discovered: something hot and hostile is moving in an old mineshaft."
}
Hidden quest file
{
"title": {
"translate": "quest.example.hidden_mineshaft_fire.title",
"fallback": "Flame in the Mineshaft"
},
"summary": {
"translate": "quest.example.hidden_mineshaft_fire.summary",
"fallback": "A villager reports a blaze burning through an abandoned mineshaft."
},
"requires": {
"traits": [
"quest_discovered:example:hidden_mineshaft_fire"
]
},
"goals": [
{
"id": "kill_mine_blaze",
"kill": "minecraft:blaze",
"amount": 1
}
],
"threat": {
"entity": "minecraft:blaze",
"name": {
"translate": "quest.example.hidden_mineshaft_fire.threat.name",
"fallback": "Ignivar the Mineflame"
},
"structure": "minecraft:mineshaft",
"search_radius": 4000,
"spawn_on_accept": true,
"spare_enabled": false,
"max_health": 150.0,
"offer_line": {
"translate": "quest.example.hidden_mineshaft_fire.threat.offer_line",
"fallback": "Something from the Nether is burning through an old mineshaft."
},
"target_line": {
"translate": "quest.example.hidden_mineshaft_fire.threat.target_line",
"fallback": "The blaze crackles with hostile heat. There is no sign it understands mercy."
}
},
"rewards": {
"xp": 260,
"items": {
"minecraft:emerald": 12,
"minecraft:blaze_rod": 2
}
}
}
### Escort to a Structure
Escort a quest entity to a searched structure, with configurable search distance and completion range.
Based on questlines/armed_zombie/armed_zombie_chain_spare_2_forgotten_road.json.
Key points:
Use the escort shortcut with a structure id. The parser converts it to escort_entity.
radius controls how far the structure search can go.
range controls how close the escorted entity must be to the target structure.
This works well as a follow-up after a spare/recruit branch.
{
"title": {
"translate": "quest.example.forgotten_road.title",
"fallback": "The Forgotten Road"
},
"summary": {
"translate": "quest.example.forgotten_road.summary",
"fallback": "Escort a spared enemy toward the village road it remembers."
},
"flow": {
"next": "example:remembered_name"
},
"dialogue": {
"intro": {
"translate": "quest.example.forgotten_road.dialogue.intro",
"fallback": "The spared creature keeps its weapon low and looks toward the road."
},
"offer": [
[
{
"translate": "quest.example.forgotten_road.dialogue.offer.0.0",
"fallback": "You remember a village?"
},
{
"translate": "quest.example.forgotten_road.dialogue.offer.0.1",
"fallback": "A bell. Smoke. A well with cracked stone. Take me there."
}
]
],
"return": {
"translate": "quest.example.forgotten_road.dialogue.return",
"fallback": "The bell. I know that sound."
},
"reward": {
"translate": "quest.example.forgotten_road.dialogue.reward",
"fallback": "I found this under the well stones. It was mine once."
},
"done": {
"translate": "quest.example.forgotten_road.dialogue.done",
"fallback": "The village road remembers me."
}
},
"goals": [
{
"id": "escort_to_village",
"escort": "minecraft:village_plains",
"radius": 3500,
"range": 40
}
],
"rewards": {
"xp": 220,
"items": {
"minecraft:iron_ingot": 6,
"minecraft:emerald": 4
}
},
"traits": {
"complete": [
"escort_memory"
]
}
}
### Quest-board contracts: progression and datapack setup
Quest boards can appear in configured village structures and generate repeatable contracts independently from the included story quests. Their offers refresh over time and can include hunts, deliveries, village protection, and elite targets.
Open a board to browse its current contracts, inspect each objective and reward, and accept the one you want. Accepted contracts are added directly to the normal quest journal and HUD: there is no contract item to keep in the inventory. Each board has its own shared reputation and level. Completing contracts for that board makes harder offers more likely and shortens its refresh time. In multiplayer, offers can be configured as individual per player or claimed globally.
Contracts use five difficulty levels:
Difficulty
Scaling applied
Common (1 star)
Group mobs: +0; health per group mob: +0 HP; elite count: x1.00; health per elite: +0 HP.
Dangerous (2 stars)
Group mobs: +1; health per group mob: +5 HP; elite count: x1.15; health per elite: +20 HP.
Deadly (3 stars)
Group mobs: +2; health per group mob: +10 HP; elite count: x1.35; health per elite: +50 HP.
Nightmare (4 stars)
Group mobs: +4; health per group mob: +20 HP; elite count: x1.60; health per elite: +75 HP.
Legendary (5 stars)
Group mobs: +6; health per group mob: +40 HP; elite count: x2.00; health per elite: +150 HP.
Elite counts are rounded up after applying the multiplier. A specific elite can opt out of count scaling with "scale_count_with_difficulty": false; health bonuses still apply when it has a configured max_health.
Difficulty also affects equipment, status effects, rewards, and the amount of reputation earned with the board.
Datapack Configuration
Quest-board contracts are fully data-driven. A datapack or mod can add vanilla or modded entities, items, structures, equipment, and rewards without replacing the built-in files.
Use the normal datapack layout:
<datapack>/
pack.mcmeta
data/
<your_namespace>/
quest_board_contracts/
Do not place custom files inside the mebahelrpgrquest namespace unless you deliberately want to override data with the same resource path. Contract definitions from different namespaces are discovered and merged. References such as example:raider_rewards resolve inside the referenced namespace.
Each contract family has its own definition file and optional tables:
quest_board_contracts/kill/mobs.json
quest_board_contracts/kill/reward_tables/
quest_board_contracts/spawn_groups/groups.json
quest_board_contracts/spawn_groups/equipment_tables/
quest_board_contracts/spawn_groups/reward_tables/
quest_board_contracts/deliveries/deliveries.json
quest_board_contracts/deliveries/reward_tables/
quest_board_contracts/protection/protection.json
quest_board_contracts/protection/reward_tables/
quest_board_contracts/elites/elites.json
quest_board_contracts/elites/equipment_tables/
quest_board_contracts/elites/reward_tables/
Definitions whose required modded entity, item, or structure is unavailable are ignored safely. Invalid entries produce a warning in the log without preventing other valid contracts from loading. Missing custom reward tables fall back to the built-in global table for that contract family; missing equipment tables leave the mob's normal equipment unchanged.
### Regular Hunts
kill/mobs.json contains a mobs array. These contracts count ordinary kills of the selected entity:
{
"mobs": [
{
"id": "examplemod:mutant_zombie",
"min": 2,
"max": 5,
"reward_table": "example:mutant_hunt"
}
]
}
The optional reward table above belongs at:
data/example/quest_board_contracts/kill/reward_tables/mutant_hunt.json
### Spawned Group Hunts
spawn_groups/groups.json contains a groups array. Every accepted group contract locates one of its configured structures, generates the group there, and tracks only those generated targets.
A minimal group entry follows this format:
{
"groups": [
{
"entities": [
{
"id": "minecraft:zombie",
"weight": 10
}
],
"min": 1,
"max": 2,
"structures": [
"minecraft:villages"
],
"equipment_table": "example:group_enemies",
"reward_table": "example:group_rewards",
"search_radius": 3000,
"ignore_current_structure": true,
"min_structure_distance": 128,
"spawn_min_radius": 8,
"spawn_max_radius": 32
}
]
}
entities is a weighted pool rolled separately for every group member. structures is also a pool: one destination is selected when the contract is generated. ignore_current_structure searches outside the board's village, while min_structure_distance sets the exclusion distance.
### Deliveries
deliveries/deliveries.json contains a deliveries array. When accepted, the contract locates the destination and generates a named recipient. The player must carry the items to that recipient; interacting consumes the required items and completes the contract.
{
"deliveries": [
{
"item": "examplemod:medical_supplies",
"min": 8,
"max": 20,
"structures": [
"minecraft:villages"
],
"reward_table": "example:medical_delivery",
"search_radius": 3000,
"ignore_current_structure": true,
"min_structure_distance": 128,
"spawn_min_radius": 0,
"spawn_max_radius": 24,
"recipient_name": "Village Quartermaster"
}
]
}
### Village Protection
protection/protection.json contains a contracts array. Supported built-in protection types are iron_golem and lighting.
{
"contracts": [
{
"type": "lighting",
"target": "minecraft:torch",
"min": 6,
"max": 12,
"structures": [
"minecraft:villages"
],
"search_radius": 5000,
"ignore_current_structure": false,
"completion_range": 96
}
]
}
Set ignore_current_structure to false to protect the board's village, or to true with min_structure_distance to send the player to another village.
### Elite Contracts
elites/elites.json contains a contracts array. Each contract may contain several elite entries, each with its own count, name, health, effects, and equipment table.
{
"contracts": [
{
"structures": [
"minecraft:pillager_outpost"
],
"reward_table": "example:elite_rewards",
"search_radius": 3000,
"spawn_min_radius": 0,
"spawn_max_radius": 24,
"elites": [
{
"entity": "minecraft:vindicator",
"min": 1,
"max": 1,
"name": "The Iron Captain",
"max_health": 80,
"equipment_table": "example:elite_raiders",
"effects": [
{
"id": "minecraft:strength",
"duration_seconds": 3600,
"amplifier": 1
}
]
}
]
}
]
}
### Reward Tables
Reward tables live in the reward_tables folder of their contract family:
{
"rolls": {
"min": 1,
"max": 2
},
"rewards": [
{
"type": "item",
"id": "minecraft:emerald",
"weight": 4,
"base_min": 1,
"base_max": 3,
"per_kill_min": 0.2,
"per_kill_max": 0.5
},
{
"type": "xp",
"weight": 2,
"base_min": 20,
"base_max": 40,
"per_kill_min": 8,
"per_kill_max": 12
}
]
}
rolls controls how many weighted entries are selected. Delivery tables may use per_item_min and per_item_max as aliases for per_kill_min and per_kill_max.
### Equipment Tables
Equipment tables use the same weighted slot format as group hunts. For example:
{
"slots": {
"right_hand": [
{
"id": "minecraft:iron_hoe",
"weight": 1,
"enchantments": [
{
"id": "minecraft:knockback",
"min_level": 3,
"max_level": 3
}
]
}
],
"helmet": [
{
"id": "minecraft:sculk",
"weight": 1
}
]
}
}
Supported slot names are right_hand, left_hand, mainhand, offhand, helmet, chestplate, leggings, and boots. Every configured slot is rolled independently. Use minecraft:air as a weighted entry when a slot should sometimes be explicitly empty.
### Contract generation settings
The generated server configuration file is:
```text
config/mebahelrpgrquest/quest_board_contracts.json
```
Its `contractTypeWeightsByBoardLevel` section controls how frequently each kind of contract appears at every board level.
***
Created by **Mebahel**. [Join the community](https://discord.com/invite/y8uC2NepkB) or [explore the full mod collection](https://www.curseforge.com/members/mebahel/projects).