Wiki 9Minecraft Wiki 9Minecraft

NPC Dialogue and Branching Conversations

Create branching conversation trees, custom dialogue scenes, and button actions for entities.

6Sections
2Code examples
4Known errors

The NPC dialogue system lets you build branching conversation screens with clickable command buttons that run when a player interacts with an entity. Instead of forcing mapmakers to manually type dialogue into dozens of in-world NPCs, you define conversation scenes in Behaviour Pack JSON files and open them on demand using the `/dialogue` command. You reach for this system whenever you are making quest givers, shops, or story characters that need to talk to the player and trigger gameplay events.

How the Dialogue System Works

Despite the name, NPC dialogue is not limited to the vanilla `minecraft:npc` entity. Any custom entity in your add-on can host a conversation screen as long as it has the `minecraft:npc` component included in its Behaviour Pack definition. This component acts as the hook that stores the entity's display name, portrait skin index, and current dialogue state.

The actual conversation text and button commands live inside a separate `dialogue/` folder in the root of your Behaviour Pack. Each JSON file in this folder holds an array of scenes. A scene represents a single screen of text with up to six action buttons. Because scenes are referenced globally by their `scene_tag` identifier, a button in one scene can use a command to immediately open another scene, creating a branching dialogue tree without spawning multiple entities.

Preparing the Entity

Before an entity can display a dialogue scene, its Behaviour Pack file needs the `minecraft:npc` component. If you are building a custom entity from scratch, add this component to either the main `components` block or a component group. If you omit this component and try to force a dialogue screen open on the entity, the command will fail.

When a player right-clicks or taps an entity that has `minecraft:npc`, the game opens its assigned dialogue screen automatically—unless the player is in Creative mode with operator permissions, in which case right-clicking opens the vanilla NPC editor screen instead. To prevent operators from accidentally editing your entity during testing, always switch to Adventure or Survival mode when testing interactions, or trigger the conversation through commands.

BP/entities/quest_giver.json
{
  "format_version": "1.16.0",
  "minecraft:entity": {
    "description": {
      "identifier": "my_pack:quest_giver",
      "is_spawnable": true,
      "is_summonable": true
    },
    "components": {
      "minecraft:type_family": {
        "family": [ "npc", "mob" ]
      },
      "minecraft:Physics": {},
      "minecraft:collision_box": {
        "width": 0.6,
        "height": 1.8
      },
      "minecraft:npc": {
        "npc_data": {
          "portrait_offsets": {
            "translate": [ -7, 50, 0 ],
            "scale": [ 1.75, 1.75, 1.75 ]
          },
          "picker_offsets": {
            "translate": [ 0, 20, 0 ],
            "scale": [ 1.7, 1.7, 1.7 ]
          }
        }
      },
      "minecraft:damage_sensor": {
        "triggers": {
          "cause": "all",
          "deals_damage": false
        }
      }
    }
  }
}

Writing a Dialogue File

Dialogue files are placed inside the `BP/dialogue/` folder. The file name itself does not matter to the game engine; the game parses every JSON file in that directory and registers each scene by its `scene_tag`. However, grouping related conversations into named files (such as `blacksmith_quest.json`) keeps your project organized.

Inside the `minecraft:npc_dialogue` object, the `scenes` array holds your individual screens. Each scene defines the NPC's overhead name, the body text, commands that fire when the window opens or closes, and an array of buttons. Both the `npc_name`, `text`, and button `name` fields accept rawtext JSON objects, which allows you to use localization keys from your `.lang` files instead of hardcoding strings.

BP/dialogue/blacksmith_quest.json
{
  "format_version": "1.17",
  "minecraft:npc_dialogue": {
    "scenes": [
      {
        "scene_tag": "my_pack:blacksmith_greeting",
        "npc_name": {
          "rawtext": [
            { "translate": "npc.my_pack.blacksmith.name" }
          ]
        },
        "text": {
          "rawtext": [
            { "translate": "dialogue.my_pack.blacksmith.greeting" }
          ]
        },
        "on_open_commands": [
          "/playsound mob.villager.haggle @initiator"
        ],
        "buttons": [
          {
            "name": {
              "rawtext": [
                { "text": "I have the iron ingots." }
              ]
            },
            "commands": [
              "/dialogue open @s @initiator my_pack:blacksmith_trade"
            ]
          },
          {
            "name": {
              "rawtext": [
                { "text": "Maybe later." }
              ]
            },
            "commands": [
              "/tellraw @initiator {\"rawtext\":[{\"text\":\"Come back when you are ready.\"}]}"
            ]
          }
        ]
      },
      {
        "scene_tag": "my_pack:blacksmith_trade",
        "npc_name": " Master Blacksmith",
        "text": "Hand over the iron, and this sword is yours.",
        "on_close_commands": [
          "/playsound random.anvil_use @initiator"
        ],
        "buttons": [
          {
            "name": "Trade 5 Iron",
            "commands": [
              "/clear @initiator iron_ingot 0 5",
              "/give @initiator iron_sword 1 0",
              "/dialogue change @s my_pack:blacksmith_thanks @initiator"
            ]
          }
        ]
      },
      {
        "scene_tag": "my_pack:blacksmith_thanks",
        "npc_name": "Master Blacksmith",
        "text": "Good luck out there, traveler."
      }
    ]
  }
}

Scene Properties and Selectors

Commands inside an NPC dialogue file run in a specific execution context. In these commands, the `@s` selector always refers to the NPC entity hosting the conversation, while the special `@initiator` selector refers to the specific player who is viewing the dialogue screen. Always use `@initiator` instead of `@p` when giving items, playing sounds, or branching to the next scene; `@p` targets the closest player by distance, which can easily target the wrong person in multiplayer.

Every button in the `buttons` array automatically closes the dialogue screen after running its command list, unless one of those commands is `/dialogue open`, which immediately transitions the screen to the newly requested scene.

FieldWhat it doesNotes
scene_tagUnique identifier for the scene.Used by the /dialogue command to open or assign this specific screen. Namespace prefixes are recommended.
npc_nameSets the title text at the top of the window.Accepts a plain string or a rawtext object. Also updates the entity's nametag while this scene is assigned.
textThe main body copy of the dialogue box.Accepts a plain string or a rawtext object.
on_open_commandsArray of slash commands run as soon as the window opens.Runs before the player clicks anything.
on_close_commandsArray of slash commands run when the window closes.Fires whether the player clicks a button or presses Escape to back out.
buttonsArray of clickable button objects.Maximum of 6 buttons per scene. Each object takes a 'name' and a 'commands' array.

Triggering and Branching with /dialogue

Minecraft provides two sub-commands under `/dialogue` to control conversations: `open` and `change`. Understanding the difference between them is essential for building quests that remember your progress.

The `/dialogue open <npc: target> <player: target> [sceneName: string]` command immediately forces the dialogue box to pop up on the target player's screen, regardless of how far away they are from the NPC, as long as the NPC entity is in a loaded ticking area. You use `open` inside button commands to create branching pages, where clicking a button immediately switches to the next page of text.

The `/dialogue change <npc: target> <sceneName: string> [player: target]` command does not open a window. Instead, it changes which scene the NPC will show the next time a player walks up and interacts with it. By including the optional `[player: target]` argument at the end, that change is saved only for that specific player, allowing the NPC to give a completed-quest greeting to one player while still offering the initial quest to everyone else.

Portraits and Custom Entity Models

The dialogue window includes a live 3D preview box on the left side that renders the entity you are speaking to. For the vanilla NPC, you can select between built-in skins using the `minecraft:skin_id` component in the Behaviour Pack. For a completely custom entity, the preview box renders your entity's actual geometry and texture.

Because custom entities come in wildly different shapes and sizes, a giant golem or a tiny insect will rarely fit inside the portrait frame by default. You can adjust how the entity is framed in the UI by modifying the `portrait_offsets` block inside the `minecraft:npc` component, using `translate` to shift the model along the X, Y, and Z axes and `scale` to shrink or enlarge it until it fits cleanly inside the window.

Which versions this applies to

Available in stable Bedrock Edition since version 1.17.0. Does not require any experimental toggles.

When it does not work

What you seeWhyThe fix
Running '/dialogue open' returns 'Failed to execute dialogue as <Entity>' or nothing happens on screen.Either the target entity does not have the 'minecraft:npc' component in its active Behaviour Pack components, or the 'scene_tag' string you typed does not match any loaded scene in 'BP/dialogue/'.Verify that 'minecraft:npc' is applied to the entity, check the Content Log for JSON syntax errors in your dialogue files, and double-check the spelling of your 'scene_tag'.
Right-clicking the custom NPC opens the vanilla skin and command editor instead of showing the conversation.You are testing the entity while in Creative mode with operator permissions. In Creative mode, interacting with an NPC entity defaults to opening the mapmaker edit screen.Change your gamemode to Survival or Adventure ('/gamemode s' or '/gamemode a') before right-clicking the entity, or trigger the conversation using '/dialogue open'.
Clicking a button that uses '/dialogue open' to go to the next page briefly flashes the screen or fires 'on_close_commands' unexpectedly.Every button press closes the current scene before opening the next one, which means 'on_close_commands' on the first scene will always execute during a page transition.Move commands that should only run when a conversation is completely finished into a dedicated goodbye button's 'commands' array instead of using 'on_close_commands' on branching scenes.
Rawtext translations inside 'text' or 'npc_name' display the raw JSON braces on screen instead of the translated string.In older dialogue format versions or when mixing plain strings with rawtext syntax incorrectly, the parser treats the JSON structure as literal text.Ensure your dialogue file's 'format_version' is set to at least '1.17' and that the 'rawtext' array is the direct child of the 'text', 'npc_name', or button 'name' object, not wrapped in quotation marks.

Reference, straight from the game files

Read out of the game itself, so the ids match the version you are building for.