I will be assuming you have some prior knowledge of:
Basic JSON formatting
Basic command and datapack stuff (ex. what is JSON text formatting, command formatting for /playsound, /execute if, /tag, ...)
To generate functions, you'll need to download the generator. It comes packaged inside the datapack. First unzip it into a folder inside of your datapacks folder. Then click through to the folder npc. There should be generator.py, the software, and 2 other files accompanying it. config.txt is the config file and dialog.json is where you'll be inputting your dialogue. The generator comes pre-loaded with an example. You can try to open generator.py. This should make some new files. If Windows tells you to search an app to open these kinds of files, you should probably install Python.
This paragraph covers all the things that have to fill in in config.txt
NAME: the name this NPC is called in all of the files. This should never contain upper case letters, spaces or special characters!
NAME_COMPONENT: This is the prefix that will be added to every message. This should be a JSON text component. This is required but it can also be a blank string ("") if you want.
For the basic syntax I'll be using this tree as an example:
{
"root1": {"text": ["This is A","Where to go next?"],"refer": {"Go to B": "b" , "Go to C": "c"}},
"b": {"text": ["This is B"]},
"c": {"text": ["This is C"]}
}
This tree can be visualised with a simple graph. Every tree has nodes. These are the elements of the outermost dict. Each node also has characteristics of its own.
The dialogue tree always starts at the root1 node (A on the image). Every node has two parameters:
text: these are the dialogue (and other stuff) the NPC will do or say. Every element of this list is played sequentially. The player needs to sneak to go to the next item of the list. In the example: This is A. then you sneak. Where to go next?
refer (not required): this is for when you want to fork your conversation. The keys (stuff before colon) are the options the player gets to see. The values (stuff after colon) are where they take the player. If refer is left empty, this is the end of the line.
Notes:
Node names should never contain upper case letters, spaces or special characters!
Do not make a circular dialogue. (A➔B and B➔A) It won't work. When the code tries to find what root this structure is connected to. It won't find any and keep looking forever!
As an example I've chosen a dialogue with a fork, because it works better for the explanation, but dialogue doesn't need to fork. You can also just make a simple tree that's just linear.
E.g. {"root1": {"text": ["To be, or not to be, that is the question","Whether 'tis nobler in the mind to suffer the slings and arrows of outrageous fortune,","Or to take arms against a sea of troubles"]}}
TIP: Use a program to control your JSON syntax. I personally use notepad++ with the plugin JsonTools.
By making more nodes labeled as root, you can add multiple conversations. If you reach the end of a branch of root1, the conversation you will move on to root2 the next time you talk to the NPC
{
"root1": {"text": ["If you talk to me again I will say more words!"]},
"root2": {"text": ["More words","@REVERT root2"]}
}
@CMD: Designates a command that will be run.
{"root1": {"text": ["I, the greatest magician of all time, will now make this man disappear!","@CMD effect give @s minecraft:invisibility"]}
@SOUND: Basically like CMD, but only for sounds.
{"root1":{"text":["Listen to this weird noise I can make!","@SOUND minecraft:entity.enderman.death§@RESET"]}}
@JSON: Signifies a JSON text component. This can be used to make custom looking text.
TIPS: Use a /tellraw generator to make the JSON text component. Use a program like notepad++ and use find and replace (ctrl+h in notepad++) to replace " with \" (escape characters) to stop errors from happening.
{"root1": {"text": ["@JSON {\"obfuscated\":true,\"text\":\"corrupt\"}"]}}
@ADV: grants the player an advancement
{"root1":{"text":["I bestow upon thee this great honour!§@ADV minecraft:adventure/bullseye","@RESET"]}}
@RESET: Starts the NPC back from zero, like you never talked to them. Good for background npc's that just need to say the same thing over and over again! Also ends the conversation.
{"root1": {"text": ["I have short term memory loss","@RESET"]}}
@REVERT: goes back to a certain point in the conversation. Also ends the conversation.
{
"root1": {"text": ["If you talk to me again I will say more words!"]},
"root2": {"text": ["More words","@REVERT root2"]}
}
@CHECK: Move a conversation to another node if a condition is met. If it isn't met, you just continue in the node where you are. Type your condition first (like in /execute), then type ' -> ' and then your destination. Before the arrow = condition, after the arrow = destination
{
"root1": {"text": ["I'm so hungry","Could someone bring me an apple!"]},
"root2": {"text": ["@CHECK if items entity @s weapon.mainhand apple -> apple§I'm still hungry!","@REVERT root2"]},
"apple": {"text": ["Thank you, kind stranger!§@CMD clear @s apple 1"]}
}
@CHECKADV: It's like @CHECK, but for advancements. Formatting options: example:example_advancement=true/false, example:example_advancement={subcriterium=true/false}
{
"root1": {"text": ["@CHECKADV minecraft:husbandry/tadpole_in_a_bucket=true -> tadpole§You're too lame for me!","Come back when you've caught a tadpole tadpole in a bucket!","@RESET"]},
"tadpole": {"text": ["You are very cool!","@REVERT tadpole"]}
}
The §-symbol can be used to do two or more things on the same dialogue step. Like saying a dialogue line and running a command or playing a sound! All of the parts are played in order from left to right on the same tick.
{"root1": {"text": ["Herh§@SOUND minecraft:entity.villager.ambient"]}}
A lot more examples can be found throughout the docs.
Now that you've configured everything and built your tree. Let's get it in-game. You should now run the generator. You can just click on the file and everything should be fine, but I would recommend running it with another program, like IDLE, which comes pre-installed with python. If you right click the file you can select edit with IDLE. You can then run the module in IDLE, so you get notified if there's any errors.
Here's an overview of some errors I think you'll be encountering quite a few times. These are mostly simple typos.
json.decoder.JSONDecodeError: Expecting ',' delimiter: Your JSON formatting is wrong and you missed a comma somewhere!
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: Your JSON formatting is wrong. You have a comma somewhere there shouldn't be one!
KeyError: You are referring to a node that doesn't exist!
To fix some of the JSON errors, I would recommend using some software to control your syntax, like the JsonTools plugin for Notepad++.
You'll need to manually add a command to 2 functions, or else it won't work. Go to npc/function/dev and make the following edits (NAME=the npc name you filled in in the config):
continue_dialog.mcfunction
Add line: execute if entity @s[tag=npc.NAME.talk] run function npc:npc/NAME/redirect
end_dialog.mcfunction
Add line: tag @s remove npc.NAME.talk
To test the dialogue you can manually trigger /function npc:npc/NAME/interact. If it doesn't work the way you want it to, either you have done something wrong or I have done something wrong. If you can't figure out what's wrong, DM me on discord.
Now, to make the NPC itself, you need an interaction entity. You can make this manually or with the help of the auto_hitbox utility command. Then, add the tag npc.NAME to this interaction. Right click it and the hitbox should trigger the dialogue.
The pack also has some utility functions that make your life easier. Here's the rundown:
npc_from_head: run this command while holding a player head to summon a mannequin with that skin.
edit_skin_from_head: when holding a player head, this command will change the skin of the nearest mannequin to the skin of the head.
name_from_item: when holding a named item, the name of this item will be given to the nearest mannequin.
toggle_gravity: It turns gravity on or off for the nearest mannequin. This toggle has no effect if immovable is on
toggle_immovable: It turns the ability for the player to push the mannequin around on or off for the nearest mannequin.
toggle_look: It toggles constantly looking at the player for the nearest mannequin. If your npc isn't a mannequin, you can do this manually by giving them the tag npc.look. Is not compatible with sitting NPC's!
toggle_name: It toggles whether the name of the nearest mannequin should always be visible.
auto_hitbox: automatically makes a 2x1 hitbox around the nearest mannequin
crouch/fall_fly/lay/stand/swim: Changes the nearest mannequin's pose to the one specified. Not compatible with sitting (obviously)
sit/unsit: sits or unsits the nearest NPC. If you want to change an NPC's pose or make them look at the player, unsit them first, or else an invisible display entity will be left behind. Not compatible with look or poses
If you need help, want to give some feedback or just want to say hi, send me a DM on discord!