A quest is a file. Who offers it, what it asks, how it is told, what it pays and what it changes are all data - and ZARP uses every piece of it, in readable JSON, if you would rather learn from a working example.
Where files go
Drop a chapter and a quest into config/chronicler/chapters/ and
config/chronicler/quests/ as YAML, or into any datapack at
data/<pack>/chronicler/{chapter,quest}/<name>.json.
# config/chronicler/quests/things_in_the_dark.yml
name: Things in the Dark
description: They come out at night. Make it fewer of them.
chapter: prologue
requires: [first_steps]
objectives:
- { type: kill, target: minecraft:zombie, count: 5 }
rewards:
- { type: item, item: minecraft:iron_sword }
- { type: money, amount: 25 }
Restart the server to apply content. Chapters and quests are
a frozen registry, the same as vanilla's data-driven content, so /reload will
not pick them up. /chronicler reload reloads messages only, and says so.
Givers
A right-click makes the offer, with Accept and Info buttons; a second click accepts. A hidden quest
with a giver is found by walking up to it. An admin can make any block, or any Cast NPC, a
giver by looking at it: /quest giver set <quest>.
giver: { type: position, at: [120, 64, -40], label: "the vault door" }
giver: { type: place, biome: "#minecraft:is_jungle" }
giver: { type: npc, name: "Dr Okafor", skin: Sablednah, near_spawn: [6, 0],
greeting: "You look like you can hold a torch.",
equipment: { head: minecraft:iron_helmet } } | Type | Options | What it is |
|---|---|---|
| position |
at · label near_spawn · block · decor |
A block. near_spawn places it relative to spawn on any seed, and block plus decor build it there once - a campfire with a camp around it. |
| place | biome · structure · dimension · lot | A kind of place, offered the moment a player is in one - no coordinate written down. lot is a CityWorld lot. |
| npc |
name · skin · entity · greeting at · near_spawn · of equipment · defy_gravity |
A person, through Cast: a human with that account's skin, or entity for a creature. of lets one person give several quests. |
Stages, choices and deadlines
A quest can be told in stages: ordered beats, each with its own
narrated text, objectives, and
on_enter / on_complete effects. A quest with plain
objectives is one stage.
stages:
- text: Get a light. The dark is not empty.
objectives: [ { type: collect, item: minecraft:torch, consume: false } ]
- text: They found you. Hold until it is quiet.
on_enter:
- { type: title, title: "&cThey are here", subtitle: "&7Hold the line" }
- { type: spawn, entity: minecraft:zombie, count: 2, radius: 6 }
objectives: [ { type: kill, target: minecraft:zombie, count: 2 } ]
- text: A stranger asks for your torch.
choices:
- { label: Give it, effects: [ { type: karma, delta: 5 } ], end: true }
- { label: Keep it, effects: [ { type: karma, delta: -5 } ], end: true }
A stage with choices and no objectives is a decision. The
options arrive as clickable buttons in chat and in the journal, each with its own
text and effects, and either next: <stage>,
end: true, or nothing to carry on to the following stage.
A stage with a deadline (seconds) counts down on the action
bar, and when it runs out fires on_fail and falls back to a
fail stage, or drops the quest.
Endings. ending: cure on a stage or a
choice records an ending for the chapter. A chapter with replayable: true can
be started over with /quest replay - endings stay, so players can go back for
the others.
Refusals are story first. locked on a
quest is the in-character line for a refusal, spoken by its NPC if there is one; what it really
means follows in grey brackets, generated from the requirements - "finish The Camp; be Immune".
Objectives
| Type | Options | What it measures |
|---|---|---|
| kill |
target · count · tag drop · own_kill |
An entity id, a #tag, any, or a ZombieMod genus - or a list, so a file names the genus first and a vanilla stand-in second. tag counts anything a spawn effect tagged; drop makes counted kills drop a quest item. A quest-spawned mob that dies to something else still counts, unless own_kill: true. |
| collect |
item · tag · quest_item count · consume |
Items in your pack. consume: false only requires carrying them. |
| deliver | quest_item · count · to · radius | The hand-over: complete by clicking the giver of quest to while holding the items, or standing within radius. The items go then. |
| visit |
x · z · y · radius dimension · label |
Reach a spot. label is how the text names it. |
| place |
biome · structure dimension · lot · any |
Be in a kind of place. any takes alternatives, so a CityWorld lot can have a vanilla fallback. |
| ritual | block · pattern · item · consume | A multiblock: right-click block while every pattern entry (offset and block) is in place, holding item. A wrong pattern says which block is missing where. |
| wait | seconds | Let time pass from entering the beat - "come back later". |
| flag | name · value | Wait for a world flag. |
| reputation | standing · at_least | Wait on a Standards standing. |
Rewards and effects
Rewards pay out on completion; effects run on entering or completing a stage, or on a choice. Effects use the whole reward vocabulary too. Anything that needs a companion mod says so plainly when it is not there.
| Type | Through | What it does |
|---|---|---|
| item | vanilla | An item, or a quest_item. |
| xp | vanilla | Experience. |
| command | vanilla | Run a command with gamemaster permission. Substitutes {player}, {uuid}, {quest}, {x}, {y} and {z}. |
| money | Standards | Through its economy. |
| reputation | Standards | Move a standing by a delta. |
| karma · class_xp · levels · skill_points | LegendQuest | Through its own API. |
| flag | Chronicler | Set a world flag, or the player's own with player: true. |
| title · message | effect | A title card, or a line in chat - action_bar: true for the bar. |
| spawn | effect | An entity or a ZombieMod genus, with name, tag, health and equipment. Give both a genus and an entity and the entity stands in when ZombieMod is absent - one file, two servers. |
| npc_say · npc_remove | effect | Make a quest's NPC speak, or leave. |
| ending | effect | Record an ending for the chapter. |
Availability and consequences
Beyond requires, a quest can carry availability
conditions - so a Mechanic and a Paramedic are offered different work, and unmet lines are told to the
player rather than the quest silently not appearing.
availability:
karma_min: 20 # LegendQuest karma (also karma_max, level_min, level_max)
race: [immune] # LegendQuest ids, any of the list
class: [doc, combat_medic]
flags: { bridge_repaired: true } # world flags a questline set
player_flags: { chose_mercy: true } # this player's own choices
reputation: { survivors: 10 } # a Standards standing World flags are named facts a quest sets and anything can read. ZombieMod genus files can gate spawning on one, so finishing a questline changes what spawns:
{ "type": "chronicler:flag", "flag": "hospital_cleared", "value": false }
Party quests. scope: party on a chapter,
or overridden on a quest, pools progress across the party, scales targets to its size, and pays
everyone. Membership comes through Standards' groups seam.
Bounties. A repeatable quest with a
cooldown in seconds can be done again and again, but not at once.
Progress. /quests and the journal show a
percentage, moved only by quests that count - counts: true|false, and unsaid
means "main chapter and not repeatable", so bounties and side lines never hold anyone short of 100%.
Quest items
Quest items live in their own registry and are marked invisibly in the item's data, so renaming an
ordinary item in an anvil does not make one. They are not eaten or drunk unless the entry says
usable: true.
# data/<pack>/chronicler/item/origin_sample.json, or config/chronicler/items/
{ item: minecraft:nether_star, name: "&5The Origin Sample", lore: [...], glint: true, max_stack: 1 }
# reward one, or drop one from a loot table
{ type: item, quest_item: zarp:origin_sample }
{ "function": "chronicler:quest_item", "id": "zarp:ember_heart" }