💬 Conversations
General Information🔗
Each conversation must define name of the NPC (some conversations can be not bound to any NPC, so it’s important to specify it even though an NPC will have a name) and his initial options.
quester: Name
first: option1, option2
stop: 'true'
final_events: event1, event2
interceptor: simple
NPC_options:
option1:
text: Some text in default language
events: event3, event4
conditions: condition1, !condition2
pointers: reply1, reply2
option2:
text: '&3This ends the conversation'
player_options:
reply1:
text:
en: Text in English
pl: Tekst po polsku
event: event5
condition: '!condition3'
pointer: option2
reply2:
text: 'Text containing '' character'
Note
Configuration files use YAML syntax. Google it if you don't know anything about it. Main rule is that you must use two spaces instead of tabs when going deeper into the hierarchy tree. If you want to write '
character, you must double it and surround the whole text with another '
characters. When writing true
or false
it also needs to be surrounded with '
. If you want to start the line with &
character, the whole line needs to be surrounded with '
. You can check if the file is correct using this tool.
quester
is name of NPC. It should be the same as name of NPC this conversation is assigned to for greater immersion, but it's your call.first
are pointers to options the NPC will use at the beginning of the conversation. He will choose the first one that meets all conditions. You define these options innpc_options
branch.final_events
are events that will fire on conversation end, no matter how it ends (so you can create e.g. guards attacking the player if he tries to run). You can leave this option out if you don't need any final events.stop
determines if player can move away from an NPC while in this conversation (false) or if he's stopped every time he tries to (true). If enabled, it will also suspend the conversation when the player quits, and resume it after he joins back in. This way he will have to finish his conversation no matter what. It needs to be in''
! You can modify the distance at which the conversation is ended / player is moved back withmax_npc_distance
option in the config.yml.interceptor
optionally set a chat interceptor for this conversation. Multiple interceptors can be provided in a comma-separated list with the first valid one used.NPC_options
is a branch with texts said by the NPC.player_options
is a branch with options the player can choose.text
defines what will display on screen. If you don't want to set any events/conditions/pointers to the option, just skip them. Onlytext
is always required.conditions
are names of conditions which must be met for this option to display, separated by commas.events
is a list of events that will fire when an option is chosen (either by NPC or a player), defined similarly to conditions.pointer
is list of pointers to the opposite branch (from NPC branch it will point to options player can choose from when answering, and from player branch it will point to different NPC reactions).
When an NPC wants to say something he will check conditions for the first option (in this case option1
). If they are met, he will choose it. Otherwise, he will skip to next option (note: conversation ends when there are no options left to choose). After choosing an option NPC will execute any events defined in it, say it, and then the player will see options defined in player_options
branch to which pointers
setting points, in this case reply1
and reply2
. If the conditions for the player option are not met, the option is simply not displayed, similar to texts from NPC. Player will choose option he wants, and it will point back to other NPC text, which points to next player options and so on.
If there are no possible options for player or NPC (either from not meeting any conditions or being not defined) the conversations ends. If the conversation ends unexpectedly, check the console - it could be an error in the configuration.
This can and will be a little confusing, so you should name your options, conditions and events in a way which you will understand in the future. Don't worry though, if you make some mistake in configuration, the plugin will tell you this in console when testing a conversation. Also, study the default conversation included with the plugin to fully understand how powerful this system can be.
Cross-conversation pointers🔗
If you want to create a conversation with multiple NPCs at once or split a huge conversation into smaller, more focused files, you can point to NPC options in other conversations. Just type the pointer as conversation.npc_option
.
Keep in mind that you can only cross-point to NPC options. It means that you can use those pointers only in first
starting options and in all player options. Using them in NPC options will throw errors.
Warning
This does not work across packages yet.
Conversation variables🔗
You can use variables in the conversations. They will be resolved and displayed to the player when he starts a conversation. A variable generally looks like that: %type.optional.arguments%
. Type is a mandatory argument, it defines what kind of variable it is. Optional arguments depend on the type of the variable, i.e. %npc%
does not have any additional arguments, but %player%
can also have display
(it will look like that: %player.display%
). You can find a list of all available variable types in the "Variables List" chapter.
Note
If you use a variable incorrectly (for example trying to get a property of an objective which isn't active for the player, or using %npc% in message
event), the variable will be replaced with empty string ("").
Translations🔗
As you can see in default conversation, there are additional messages in other languages. That's because you can translate your conversations into multiple languages. The players will be albe to choose their preferred one with /questlang command. You can translate every NPC/player option and quester's name. You do this like this:
quester:
en: Innkeeper
pl: Karczmarz
de: Gastwirt
As said before, the same rule applies to all options and quester's name. The player can choose only from languages present in messages.yml, and if there will be no translation to this language in the conversation, the plugin will fall back to the default language, as defined in config.yml. If that one is not defined, there will be an error.
You can also translate journal entries, quest cancelers and message
events, more about that later.
Conversation displaying🔗
BetonQuest provides different conversation styles, so called "conversationIO's". They all look different but the biggest difference is the way the user interacts with them.
A modern conversation style that works with some of Minecraft's native controls.
All options can be found in the compatibility section.
This is a video of it in action:
A chat output. The user has to write a number into their chat to select an option.
Also a chat output. The user can click on the options instead of typing them.
The same as tellraw
but the NPC's text is printed line by line, delayed by 0.5 seconds.
A chest GUI with clickable buttons where the NPC's text and options will be shown as item lore.
You can change the option's item to something else than ender pearls by adding a prefix to that option's text.
The prefix is a name of the material (like in items.yml) inside curly braces, with an optional damage value after a colon.
Example of such option text: {diamond_sword}I want to start a quest!
.
You can control the colors of conversation elements in the config.yml file, in conversation_colors
section. Here you must use names of the colors.
BetonQuest uses the menu
conversationIO by default. If ProtocolLib is not installed, the chest
IO will be used.
You can however change the utilized conversationIO by setting the default_conversation_IO
option in the config.yml file.
In case you want to use a different type of conversation display for just one specific conversation you can add a conversationIO:
<type>
setting to the conversation file at the top of the YAML hierarchy (which is the same level as quester
or first
options).
Chat Interceptors🔗
While engaged in a conversation, it can be distracting when messages from other players or system messages interfere with the dialogue. A chat interceptor provides a method of intercepting those messages and then sending them after the conversation has ended.
You can specify the default chat interceptor by setting default_interceptor
inside the config.yml
.
Additionally, you can overwrite the default for each conversation by setting the interceptor
key inside your conversation file.
The default configuration of BetonQuest sets the default_interceptor
option to packet,simple
.
This means that it first tries to use the packet
interceptor. If that fails it falls back to using the simple
interceptor.
BetonQuest adds following interceptors: simple
, packet
and none
:
The simple
interceptor works with every Spigot server but only supports very basic functionality and may not work with plugins like Herochat.
The packet
interceptor requires the ProtocolLib plugin to be installed. It will work well in any kind of situation.
The none
interceptor is an interceptor that won't intercept messages. That sounds useless until you have a conversation
that you want to be excluded from interception. In this case you can just set interceptor: none
inside your conversation file.
Advanced: Extends🔗
Conversation also supports the concept of inheritance. Any option can include the key extends
with a comma delimited list of other options of the same time. The first option that does not have any false conditions will have it's text, pointers and events merged with the extending option. The extended option may itself extend other options. Infinite loops are detected.
NPC_options:
## Normal Conversation Start
start:
text: 'What can I do for you'
extends: tonight, today
## Useless addition as example
tonight:
# Always false
condition: random 0-1
text: ' tonight?'
extends: main_menu
today:
text: ' today?'
extends: main_menu
## Main main_menu
main_menu:
pointers: i_have_questions, bye