Dialogue files
Every field a dialogue can hold: pages, choices, portrait, theme, sounds, and what runs when the player is finished.
data/<yourpack>/dialogues/<name>.json. Everything is optional except having something to say.
The fields
| Field | Meaning |
|---|---|
pages | One page per click, typed out in turn. Give this or variants. |
variants | Several tellings, one picked per opening. |
speaker | The name at the head of the panel. Left out, whoever was clicked supplies theirs. |
portrait | Who stands in the window. See Portraits. |
sounds | { "move": <sound> }, with optional volume and pitch. The panel under the player's hands, not the speaker. |
reveal_speed | Characters per tick, 1–64. Default 2. 64 means "already written", no reveal at all. |
dismissible | Whether escape closes it early. Default true. false makes them read it through. |
theme | Six colours. See Themes. |
choices | What the player can say at the end. None means the last page simply closes. May include a slot for another pack to fill. |
with | Facts the world has to supply before a line can be said. See Values. |
on_close | Actions that run when the player is finished, whatever they chose and even if nothing. |
once | Whether on_close runs only the first time each player finishes it. |
once is for a welcome that hands out a keepsake. It gates on_close only; choices are never gated this way.
Choices
A choice is a label, an optional requires, and an optional actions.
"choices": [
{
"label": { "translate": "mypack.smith.repair" },
"requires": [ { "condition": "has_items", "item": "minecraft:iron_ingot", "count": 3 } ],
"actions": [
{ "type": "take_item", "item": "minecraft:iron_ingot", "count": 3 },
{ "type": "run_command", "command": "..." }
]
},
{ "label": { "translate": "rpg_dialogue.choice.leave" } }
]A choice whose requires do not hold is never sent to the client at all, so writing conditions is how you hide an answer rather than grey it out.
A file that only branches still needs a way out
A conversation offering no valid choices is given a farewell line automatically. Write your own anyway: yours will be in the speaker's voice.
Portraits
Leave portrait out and the window shows whoever the player walked up to, exactly as they look, framed on their face. How close to stand is measured off them, so a baby and an iron golem both fill the window. That gets you a villager's profession, outfit and badge, or any mob's armour and trim, without the dialogue describing any of it.
| Field | Default | Meaning |
|---|---|---|
entity | whoever was clicked | Builds a copy of that entity type to draw instead. See the warning below. |
framing | face | face for head and shoulders, full to stand them in the window whole. |
scale | measured | Pixels per block of speaker. Naming one overrules the measurement for every speaker who ever reads this dialogue. |
body_yaw | -32.0 | Three-quarter turn, so the speaker is angled rather than facing dead-on. |
head_yaw | 15.0 | Head turned back off that angle, so they still address the player. |
tilt | -11.0 | Slight downward view tilt, for the isometric feel. |
offset_x | per framing | Centring nudge in blocks, applied after the scale. |
offset_y | per framing | The same, vertically. Positive lowers the speaker in the window. |
framing owns the rest of the defaults along with it, so asking for full does not mean restating the scale and centring to get a sensible result back.
A portrait with an `entity` does not move
Naming a type builds a copy purely to be drawn, and a copy is never added to a level and never ticked, so an animation pack driving a model off the entity's own counters holds it on one frame. Anything chosen per entity rather than per type goes the same way: a face picked off a UUID is picked off a brand new one, so the window shows a different villager from the one the player walked up to.
Name a type for a speaker who is genuinely absent: a voice out of a book, somebody being quoted, a dialogue nobody walked up to.
"portrait": { "entity": "minecraft:evoker", "framing": "full" }For anyone standing in front of the player, leave portrait out, or give it framing and scale without an entity, and open the dialogue with them as the target. They are then drawn as they are, moving as they move.
Themes
Six colours, written as #RRGGBB or #AARRGGBB. The defaults suit vanilla's inventory texture.
| Field | Default | What it colours |
|---|---|---|
speaker | #4A2410 | The name at the head of the panel, a warm brown so it reads as a heading. |
body | #1F1F1B | The spoken text. Near-black on purpose. |
hint | #3D3D36 | A choice at rest. |
hint_hover | #D9901A | A choice under the pointer or lit by the keyboard. |
separator | #5D6159 | The rule under the speaker's name, drawn as a bevel shadow. |
backdrop | #73000000 | The tint laid over the world behind the panel. |
"theme": {
"speaker": "#B03A2E",
"hint_hover": "#E8C547",
"backdrop": "#A0000000"
}Anything you leave out keeps its default.
Sounds
"sounds": { "move": "minecraft:ui.button.click", "volume": 0.55, "pitch": 1.0 }This is the sound of the panel, made as the player moves between answers, not the sound of somebody talking. For that, see what a speaker sounds like.
Reveal speed
Characters per tick, from 1 to 64. The default of 2 reads at about the pace of somebody speaking.
Set 64 for a conversation that should simply be on screen: a sign, a note, an interface pretending to be a conversation.
Text is a text component, everywhere
Every field that takes text takes a full Minecraft text component, so all of this is available:
{ "text": "Careful with that.", "color": "red", "italic": true }
{ "translate": "mypack.smith.warning" }
{ "translate": "mypack.golem.count", "fallback": "I keep %s of them." }Use translate for anything you intend to ship. A fallback keeps the line readable for anyone who has not installed your language file, which is what the bundled example does.
