Quests & categories
Quests are plain JSON in your datapack. This page documents every field Scripta 1.0.0 reads, the five objective types, and how ids and files relate to each other.
Where files live
Scripta scans two folders inside any datapack — yours
(data/<namespace>/) or a mod's. Both searches are
recursive and only pick up .json files.
| Content | Path |
|---|---|
| Quests | data/<namespace>/quests/quests/**/*.json |
| Categories | data/<namespace>/quests/categories/**/*.json |
A typical world-side datapack for Scripta looks like this:
data/ is any namespace you like —
mypack, server, whatever. Scripta does not
require scripta as the namespace.
Ids and file names
The id inside the JSON wins. The file name is
irrelevant to identity, so you can reorganise freely:
- Renaming a file does not change a quest's id.
- Two files declaring the same id — the last one loaded wins.
- Ids must be in
namespace:pathform.
myquests:chop_oak from a prerequisite list,
that id must match the quest's id field exactly.
Category fields
| Field | Type | Required | Notes |
|---|---|---|---|
id |
string | Yes | Unique category id, e.g. mypack:getting_started. |
display_name |
string | Yes | Shown as the category tab label. |
icon |
icon | Yes | Item/block or texture. See Icons. |
sort_order |
int | No | Default 0. Lower sorts first. |
number |
int | No | Default 0 (unnumbered). Drives the 1.1 id scheme. |
{
"id": "mypack:getting_started",
"display_name": "Getting Started",
"icon": {
"id": "minecraft:crafting_table",
"count": 1
},
"sort_order": 0
}Quest fields
| Field | Type | Required | Notes |
|---|---|---|---|
id |
string | Yes | Unique quest id. |
category |
string | Yes | Id of the category this quest belongs to. |
title |
string | Yes | Shown in the quest list and detail header. |
description |
string | Yes | May be "" if you have nothing to say. |
icon |
icon | Yes | See Icons. |
objectives |
array | Yes | May be []. All objectives must be met to complete. |
rewards |
array | No | Default []. See Rewards. |
auto_claim |
bool | No | Default true. See auto_claim. |
prerequisites |
array | No | Default []. Quest ids that must be completed first. |
Complete example
{
"id": "mypack:getting_started/chop_oak",
"category": "mypack:getting_started",
"title": "Chop Some Oak",
"description": "Break 10 oak logs.",
"icon": { "id": "minecraft:oak_log", "count": 1 },
"objectives": [
{ "type": "break_block", "target": "minecraft:oak_log", "required_count": 10 }
],
"rewards": [
{ "type": "item", "item": "minecraft:bread", "amount": 5 },
{ "type": "xp", "amount": 25 }
],
"auto_claim": true,
"prerequisites": []
}With an interactive choice
{
"id": "mypack:getting_started/choose_your_boon",
"category": "mypack:getting_started",
"title": "Choose Your Boon",
"description": "Pick one reward.",
"icon": { "id": "minecraft:enchanted_book", "count": 1 },
"objectives": [
{ "type": "collect_item", "target": "minecraft:oak_log", "required_count": 5 }
],
"rewards": [
{ "type": "xp", "amount": 10 },
{
"type": "choice",
"count": 1,
"options": [
{ "type": "item", "item": "minecraft:golden_apple", "amount": 1 },
{ "type": "item", "item": "minecraft:diamond", "amount": 2 }
]
}
],
"auto_claim": true
}Objective types
Each objective is { "type", "target", "required_count" } —
all three fields are required. target means different things
per type, so the table below matters.
| Type | target is… | How it counts |
|---|---|---|
break_block |
a block id, e.g. minecraft:oak_log |
Event-driven. Increments when you break a matching block. |
kill_entity |
an entity type, e.g. minecraft:zombie |
Event-driven. Increments when you kill a matching mob. |
collect_item |
an item id, e.g. minecraft:diamond |
Polled once per second. Stores your current held count, not a running total. |
reach_stat |
a custom stat, e.g. minecraft:jump |
Polled once per second. Stores the stat's current value.
Custom stats only — not vanilla ones like
minecraft:walk_one_cm.
|
grant_advancement |
an advancement id | Polled once per second. Completes when the advancement is done. |
collect_item, reach_stat and
grant_advancement read the player's present value.
If a collect_item quest wants 10 diamonds and you drop your
stack, the count falls back below the requirement. Use
break_block or kill_entity for goals that should
stay completed.
break_block and kill_entity behave differently:
they stop incrementing once the required count is reached, so those
objectives stay satisfied permanently.
Icons
An icon is one of two shapes. Scripta tries the item form first.
Item or block icon
"icon": { "id": "minecraft:oak_log", "count": 1 }
id is required; count defaults to 1
and controls the stack size drawn.
Texture icon
"icon": "scripta:web_icons/dragon.png"
A bare namespace:path pointing at a texture. Use one from a
resource pack, or upload a PNG through the
web editor — uploaded icons are
stored as scripta:web_icons/<name>.png and synced to
every connected client automatically.
Prerequisites
A quest is locked until every quest id in prerequisites is
completed. Locked quests appear greyed out and cannot be opened.
"prerequisites": [
"mypack:getting_started/chop_oak",
"mypack:getting_started/slay_zombie"
]auto_claim
| Value | Behaviour |
|---|---|
true default |
Non-interactive rewards are granted the instant the quest completes. Choice rewards still need the player to pick. |
false |
Nothing is granted automatically. The quest detail shows Claim, Choose and Claim All buttons instead. |
Claim state is stored per player and synced, so a player cannot claim the same reward twice.
Numbered categories
Give a category a non-zero number and the editors will
generate hierarchical quest ids for it:
{
"id": "mypack:story",
"display_name": "Story",
"icon": { "id": "minecraft:book", "count": 1 },
"sort_order": 0,
"number": 1
}
Quests in that category become mypack:1.1, mypack:1.2,
and so on — the editor's Auto button fills these in for you.
number (or 0) keeps classic
free-form ids, so all existing content stays valid.
Reloading & syncing
/reloadre-reads both folders and logs the result, e.g.[scripta] Loaded 12 quest(s) from datapacks.- A malformed file logs a parse error and is skipped — it never aborts the whole load.
- Definitions are broadcast to every player within a second of changing, and on join.
- Deleting a quest file prunes it from every player's completed list.
/reload is only for
hand-edited datapack files.