Migration 2.X to 3.X
This guide explains how to migrate from the latest BetonQuest 2.X version to BetonQuest 3.X.
The majority of changes will be migrated automatically. However, some things must be migrated manually.
Warning
Before you start migrating, you should back up your server!
Info
You need to set legacy as version in your package.yml (for both QuestPackages and -Templates)
to automatically migrate from "not versioned".
package:
version: legacy
Changes🔗
Note
Fully automated migration – These steps are reliably migrated without issues in most cases. You usually don’t need to take any action. However, certain rarely used or non-standard formats (e.g., run events or math variables) may not migrate correctly if they deviate from the common structure.
Automated migration with known limitations – These steps are generally migrated automatically, especially for straightforward cases. However, there are known edge cases that cannot be detected or handled automatically. You should review these steps and be prepared to make manual adjustments where needed.
Manual migration required – These steps are not migrated at all. Either the structure is too complex to detect automatically, or the new format requires additional information. You will need to fully rewrite or convert these steps yourself.
- 3.0.0-DEV-58 - Delete messages.yml
- 3.0.0-DEV-65 - Delete menuConfig.yml
- 3.0.0-DEV-71 - Renamed Translation Keys
- 3.0.0-DEV-114 - Npc Rework
- 3.0.0-DEV-135 - Citizens Adaption to NpcID
- 3.0.0-DEV-142 - Conversation Sounds
- 3.0.0-DEV-217 - Item Type
- 3.0.0-DEV-232 - Singular to Plural
- 3.0.0-DEV-233 -
pickrandomevent - 3.0.0-DEV-244 - Menu Item move
- 3.0.0-DEV-267 - MoonPhases rename
- 3.0.0-DEV-274 - String List remove
- 3.0.0-DEV-277 - Rename Constants
- 3.0.0-DEV-284 - Change Head Owner
- 3.0.0-DEV-299 - NPC events rename
- 3.0.0-DEV-306 - MMOItems Item Type
- 3.0.0-DEV-313 - Folder Time Unit
- 3.0.0-DEV-316 - Chest Conversation IO
- 3.0.0-DEV-329 - Delete
menu_conv_iosettings - 3.0.0-DEV-337 - Menu Conversation IO line wrapping
- 3.0.0-DEV-365 - Menu Conversation IO line wrapping rework
- 3.0.0-DEV-394 - Cross packages are now referenced with
>instead of. - 3.0.0-DEV-408 - Journal entry separator
- 3.0.0-DEV-416 - Simple Item TextParser
- 3.0.0-DEV-444 - Simple Item QuestItem
3.0.0-DEV-58 - Delete messages.yml
🔗
The messages.yml file has been removed.
All messages are now stored in the lang folder, you can also customize them there and add new languages.
If you still have the old messages.yml file, you get a warning in the console.
If you don't have any custom messages,
you can delete the file safely otherwise you should move the messages to the new location.
3.0.0-DEV-65 - Delete menuConfig.yml
🔗
The "menuConfig.yml" file has been removed.
If you had the option default_close configured, you can now find this option in the "config.yml" file.
All translations in the config where also moved to the lang folder,
so also here you need to move your custom translations.
3.0.0-DEV-71 - Renamed Translation Keys
🔗
Automated Migration
The migration is automated. You shouldn't have to do anything.
All translations where moved from the messages.yml file to individual files in the lang folder.
Also all keys for the langusges have been renamed to match the new lang-region format, where lang and region are always two letters.
So the mapping of the old to the new keys is as follows:
| Old Key | New Key | Old Key | New Key | Old Key | New Key | Old Key | New Key |
|---|---|---|---|---|---|---|---|
| en | en-US | de | de-DE | es | es-ES | fr | fr-FR |
| hu | hu-HU | it | it-IT | nl | nl-NL | pl | pl-PL |
| pt-br | pt-BR | pt-pt | pt-PT | ru | ru-RU | vi | vi-VN |
| cn | zh-CN |
If you have custom translations, you need to move them to the new lang folder.
Because the keys have been renamed, you need to rename the keys in some parts of config files and scripts.
language: en-US
events:
notify: notify {en} English text {de} Deutscher text
events:
notify: notify {en-US} English text {de-DE} Deutscher text
And the most complicated change is everywhere you used multiple languages in sections, here is only one example:
conversations:
unkown:
quester:
en: Jane Doe
de: Erika Mustermann
conversations:
unkown:
quester:
en-US: Jane Doe
de-DE: Erika Mustermann
The same applies to all other sections where you used multiple languages, this should be a complete list:
conversations.*.questerconversations.*.NPC_options.*.textconversations.*.player_options.*.textcompass.*.namecancel.*.namejournal.*journal_main_page.*.textmenus.*.items.*.text
3.0.0-DEV-114 - Npc Rework
🔗
To support more Npc plugins than just Citizens the system got a rework.
Npcs are now addressed with IDs and defined in the npcs section.
Starting conversations with Npc interaction is moved inside the npc_conversations section.
Also, the teleportnpc event got renamed to npcteleport. That change is automated, when updating to version
3.0.0-DEV-299 or newer.
In addition, the npc variable to get the quester name of the current conversation got changed to quester.
That change is automated.
You can keep most of the syntax when you use the Citizens Npc id as their BetonQuest identifier, but changing the "name" makes the difference more clear.
Also, the citizens_npcs_by_name configuration option was removed in favor of the
byName argument.
npcs:
'0': "HansConv" #(1)!
'1': "HansConv"
events:
teleportNpc: teleportnpc 0 100;200;300;world #(2)!
conditions:
nearNpc: npcdistance 0 10 #(2)!
nearNpcTwo: npcdistance 1 10
conversations:
HansConv: #(3)!
quester: Hans
first: Hello
NPC_options:
Hello:
text: Hello Adventurer!
- The conversation the interaction with the Npc will start.
- The
0is here the citizens npc id. - The conversation name as used in the
npcssection.
npcs:
0: "citizens 0" #(1)!
HansTwo: "citizens 1" #(2)!
npc_conversations:
0: HansConv #(3)!
HansTwo: HansConv #(4)!
events:
teleportNpc: npcteleport 0 100;200;300;world #(3)!
conditions:
nearNpc: npcdistance 0 10 #(3)!
nearNpcTwo: npcdistance HansTwo 15 #(4)!
conversations:
HansConv:
quester: Hans
first: Hello
NPC_options:
Hello:
text: Hello Adventurer!
- The
0before the ':' is now the BetonQuest ID, where thecitizens 0defines the Npc with id "0" from the Citizens integration. - Here we use a name for the id to make the difference more clear.
- The
0is here the BetonQuest NpcID but stays the same. - An example of a "renamed" reference.
- The Npcs that start this conversation.
3.0.0-DEV-135 - Citizens Adaption to NpcID
🔗
To streamline usage of Npcs the Citizens specific events and objective now also use the NpcID introduced in 3.0.0-DEV-114.
Also, the movenpc and stopnpc events are renamed into npcmove and npcstop. These renames are automated, when
updating to version 3.0.0-DEV-299 or newer.
As in the migration above stated you can either use a descriptive name as the id or use the numeric Citizens id of the Npc.
events:
move: movenpc 0 100;200;300;world #(1)!
stop: stopnpc 0
objectives:
kill: npckill 1 amount:5 events:reward
- The
0is here the citizens npc id.
npcs:
0: "citizens 0" #(1)!
thief: "citizens thief byName"
events:
move: npcmove 0 100;200;300;world
stop: npcstop 0 #(2)!
objectives:
kill: npckill thief amount:5 events:reward
- The
0before the ':' is now the BetonQuest ID, where thecitizens 0defines the Npc with id "0" from the Citizens integration. - The
0is here the BetonQuest NpcID but stays the same.
3.0.0-DEV-142 - Conversation Sounds
🔗
The start and stop sound in the configuration for conversations were removed in favor of the notification system,
that now also has the two new build in categories conversation_start and conversation_end.
Also the messages it self are now printed in every conversation and can now be configured with the notification system.
To get the previous sounds back, you need to configure it now like the following in any quest package:
sounds:
start: ENTITY_VILLAGER_AMBIENT
end: ENTITY_VILLAGER_YES
notifications:
conversation_start:
sound: ENTITY_VILLAGER_AMBIENT
conversation_end:
sound: ENTITY_VILLAGER_YES
If you want to disable the the start and end message, now you can configure the following:
notifications:
conversation_start:
io: suppress
conversation_end:
io: suppress
and if you only want sounds and no message, you use sound instead of suppress as io.
3.0.0-DEV-217 - Item Type
🔗
Automated Migration
The migration is automated. You shouldn't have to do anything.
To allow usage of 3rd-party items in QuestItems the standard definition is now prefixed with simple.
items:
blizz: "DIAMOND_SWORD name:The_Blizz lore:Made_of_Ice"
items:
blizz: "simple DIAMOND_SWORD name:The_Blizz lore:Made_of_Ice"
3.0.0-DEV-232 - Singular to Plural
🔗
Automated Migration
The migration is automated. You shouldn't have to do anything.
BetonQuest allows a lot of lists (comma separated values) to reference for example events and conditions.
In the past the key of those lists was always event or condition.
Then someone introduced the first plural events and conditions, and so the project supported both.
As this leads into a lot of bad code and confusion, we decided to remove the singular version.
Therefore the follorwing changes were made:
- objectives -
eventandconditionare noweventsandconditions - events -
conditionis nowconditions - menus -
conditionis nowconditions - conversations - options
condition,event,pointerandextendare nowconditions,events,pointersandextends
objectives:
action: action LEFT ANY global persistent event:notify condition:sneak
objectives:
action: action LEFT ANY global persistent events:notify conditions:sneak
3.0.0-DEV-233 - pickrandom event
🔗
Automated Migration
The migration is automated. You shouldn't have to do anything.
To allow a list of events also containing variables in any form, it is not possible anymore to use the percentage,
instead the tilde ~ is used to separate the chance from the event.
events:
pickRandom: pickrandom 1%pickRandom1,2%pickRandom2,3%pickRandom3
events:
pickRandom: pickrandom 1~pickRandom1,2~pickRandom2,3~pickRandom3
3.0.0-DEV-244 - Menu Item move
🔗
Automated Migration
The migration is automated. You shouldn't have to do anything.
To use a Menu Item in multiple Menus they are now defined in their own menu_items section.
menus:
questMenu:
height: 4
title: "&6&lQuests"
bind: "openMenuItem"
command: "/quests"
slots:
4: "reputation"
5-8: "filler,filler,filler,filler"
items:
reputation:
item: "xpBottle"
amount: 1
text:
- "&2Quest Level: &6&l%point.quest_reputation.amount%"
close: true
filler:
text: "&a "
item: "filler"
menus:
questMenu:
height: 4
title: "&6&lQuests"
bind: "openMenuItem"
command: "/quests"
slots:
4: "reputation"
5-8: "filler,filler,filler,filler"
menu_items:
reputation:
item: "xpBottle"
amount: 1
text:
- "&2Quest Level: &6&l%point.quest_reputation.amount%"
close: true
filler:
text: "&a "
item: "filler"
3.0.0-DEV-267 - MoonPhase rename
🔗
Automated Migration
The migration is automated. You shouldn't have to do anything.
The mooncycle condition was renamed to moonphase and instead of numbers, which stood for the mood phases,
the names of the moon phases are now used directly.
conditions:
mooncycle: mooncycle 1
otherMooncycle: mooncycle 2 world:world
conditions:
moonphase: moonphase NEW_MOON
otherMoonphase: moonphase FULL_MOON world:world
3.0.0-DEV-274 - String List remove
🔗
Automated Migration
The migration is automated. You shouldn't have to do anything.
All string lists (lists that are new lines with dashes) at unusual places are now replaced with a comma separated list. This includes:
npcsin thenpc_hologramssectionnpcs,conditionsandlocationsin theeffectlibsection
effectlib:
effect1:
class: VortexEffect
npcs:
- NPC1
- NPC2
- NPC3
effectlib:
effect1:
class: VortexEffect
npcs: NPC1,NPC2,NPC3
3.0.0-DEV-277 - Rename Constants
🔗
Automated Migration
The migration is automated. You shouldn't have to do anything.
"Global Variables" have been replaced by "Constants" to better reflect their purpose and also to integrate them into the existing variable system.
variables:
MyVariable: Hello
MyCustomVariable: $MyVariable$ World
events:
sendNotify: notify $MyCustomVariable$
constants:
MyVariable: Hello
MyCustomVariable: %constant.MyVariable% World
events:
sendNotify: notify %constant.MyCustomVariable%
3.0.0-DEV-284 - Change Head Owner
🔗
Automated Migration
The migration is automated. You shouldn't have to do anything.
To allow pre-parsing of constant variables in simple Quest Items the owner:%player% has been replaced with owner:.
items:
head: simple PLAYER_HEAD owner:%player%
items:
head: 'simple PLAYER_HEAD owner:'
3.0.0-DEV-299 - NPC events rename
🔗
Automated Migration
The migration is automated. You shouldn't have to do anything.
Some NPC events were renamed in the versions 3.0.0-DEV-114 - Npc Rework and 3.0. 0-DEV-135 - Citizens Adaption to NpcID. These renames are automated now.
3.0.0-DEV-306 - MMOItems Item Type
🔗
MMOItems is now integrated into the item system.
Instead of using mmo specific pickup objectives or item conditions and events it now uses the standard implementations. The following obsolete implementations were removed:
mmoitemconditionmmohandconditionmmoitemgiveeventmmoitemtakeeventmmoitemcraftobjective
conditions:
hand: mmohand ARMOR SKELETON_CROWN
inventory: mmoitem ARMOR SKELETON_CROWN
events:
give: mmoitemgive ARMOR SKELETON_CROWN
take: mmoitemtake ARMOR SKELETON_CROWN
objectives:
craft: mmoitemcraft ARMOR SKELETON_CROWN
items:
crown: mmoitem ARMOR SKELETON_CROWN
conditions:
hand: hand crown
inventory: item crown
events:
give: give crown
take: take crown
objectives:
craft: craft crown
The mmoitemupgrade and mmoitemapplygem objectives exist unchanged.
3.0.0-DEV-313 - Folder Time Unit
🔗
Automated Migration
The migration is automated. You shouldn't have to do anything.
To allow variables for the time unit in the folder event, the time unit now needs a key unit.
events:
setBlocks: folder block1,block2,block3 period:10 ticks
events:
setBlocks: folder block1,block2,block3 period:10 unit:ticks
3.0.0-DEV-316 - Chest Conversation IO
🔗
To make future changes possible and to improve the possibility to add new features,
the display item is now defined in a new section called properties.
conversations:
#...
player_options:
exampleOption:
text: "{diamond}This is an example option"
conversations:
#...
player_options:
exampleOption:
text: "This is an example option"
properties:
item: "diamond"
items:
diamond: "DIAMOND"
3.0.0-DEV-329 - Delete menu_conv_io settings
🔗
All options configured in the menu_conv_io section in quest packages,
are now defined in the 'config.yml' under the path conversations.io.menu.
3.0.0-DEV-337 - Menu Conversation IO components
🔗
The new used components don't need the settings conversation.io.menu.option_selected_reset,
conversation.io.menu.option_text_reset and conversation.io.menu.npc_text_reset anymore and also the menu
conversation IO text wrapping was reworked.
As a result the line_length unit is now in pixels instead of characters.
This means that the old value is multiplied by 6.
As a result, the default value is now 320 pixels instead of 50 characters what is more precise and allows more text.
The default value is migrated automatically, but if you have a custom value, you need to change it manually.
The same applies to all the actual printed texts, all default values are automatically migrated,
but if you have custom configurations, you need to change them manually to the new message parser format.
conversation:
io:
menu:
line_length: 50
npc_text_reset: '&f'
option_text_reset: '&b'
option_selected_reset: '&f'
# More settings...
npc_text: '&l &r&f{npc_text}'
# More settings...
conversation:
io:
menu:
line_length: 320
# More settings...
npc_text: '@[minimessage] <white>{npc_text}'
# More settings...
3.0.0-DEV-365 - Menu Conversation IO line wrapping rework
🔗
Automated Migration
The migration is automated. You shouldn't have to do anything.
The Menu Conversation IO get a rework to improve and fix some line wrapping behaviors. As a result, the following settings were renamed and some new settings were added.
conversation:
io:
menu:
selection_cooldown: 10
start_new_lines: 10
npc_name_newline_separator: true
npc_text_fill_new_lines: true
npc_wrap: '@[minimessage] '
option_wrap: '@[minimessage] '
option_selected: '@[minimessage] <gray>» <dark_gray>[ <white><underlined>{option_text}</underlined></white> ]'
option_selected_wrap: '@[minimessage] <white><underlined>'
npc_name_format: '@[minimessage]<yellow>{npc_name}'
conversation:
io:
menu:
rate_limit: 10
line_fill_before: 10
npc_name_seperator: true
options_seperator: true
npc_text_wrap: '@[minimessage] '
option_text_wrap: '@[minimessage] '
option_selected_text: '@[minimessage] <gray>» <dark_gray>[ <white><underlined>{option_text}</underlined></white> ]'
option_selected_text_wrap: '@[minimessage] <white><underlined>'
npc_name: '@[minimessage]<yellow>{npc_name}'
line_count: 10
3.0.0-DEV-394 - Cross packages are now referenced with > instead of .
🔗
To fix some issues where it was not clear if a variable or a package is referenced as both use a dot . as separator,
the cross package reference now uses a greater than > symbol.
This migration is actually automated, but there are so many edge cases that it is likely that some things are not
migrated correctly. Most cases should bring up a warning or error in the console, you can fix them manually.
But there are also some edge cases that are not detected, you may need to check all cross package references manually.
objectives:
myObjective: login
conditions:OtherPackage.myCondition
events:OtherPackage.myEvent
events:
myEvent: notify Test
conditions:OtherPackage.myCondition
objectives:
myObjective: login
conditions:OtherPackage>myCondition
events:OtherPackage>myEvent
events:
myEvent: notify Test
conditions:OtherPackage>myCondition
That's how to do this in general, but there are a lot of edge cases, so please check all cross package references. Some well known edge cases are:
- The
runevents is not migrated, as it is too complex - Variables are not migrated:
- They used
.as separator what means that they previously conflicted with cross package references so it can not be detected reliably. - A special case for variables are some
phvariables and themath.calcvariable. They can contain a>as cross package reference or for some other reason. It is necessary to escape the>with a backslash\>inside those variables.
- They used
- Constants are not migrated, as we don't know in which context they are used.
- Commands executed in other scripts are not migrated, as we don't have access to this content.
3.0.0-DEV-408 - Journal entry separator
🔗
Automated Migration
The migration is automated. You shouldn't have to do anything.
The journal now does not have a show_separator option anymore. Instead only the separator setting is used.
If show_separator was previously false the separator needs to contain a newline.
journal:
separator: "---------------"
show_separator: false
journal:
separator: "@[minimessage]<newline>"
If the option was true, a newline needs to be added before the previous separator.
journal:
separator: "---------------"
show_separator: true
journal:
separator: "@[minimessage]<newline>---------------"
3.0.0-DEV-416 - Simple Item TextParser
🔗
The simple items now use the text parser for the name and lore as well as for books the title, author and text.
With that underscores won't be replaced anymore, instead you have to use quoting.
items:
holySword: simple DIAMOND_SWORD
name:&4Sword_made_of_Holy_Concrete
lore:&cOnly_this_sword_can_kill_the_Lord_Ruler
book: simple WRITTEN_BOOK
title:Malleus_Maleficarum author:&eGallus_Anonymus
text:Lorem_ipsum_dolor_sit_amet,\nconsectetur_adipiscing_elit.|Pellentesque_ligula_urna(...)
items:
holySword: simple DIAMOND_SWORD
"name:&4Sword made of Holy Concrete"
"lore:<red>Only this sword can kill the Lord Ruler"
book: simple WRITTEN_BOOK
"title:Malleus Maleficarum" "author:&eGallus Anonymus"
"text:Lorem ipsum dolor sit amet, <newline>consectetur adipiscing elit. |Pellentesque ligula urna(...)"
3.0.0-DEV-444 - Simple Item QuestItem
🔗
The way to identify "QuestItems" which can be stored in the backpack has been changed.
For the simple Item that means the quest-item tag is used instead of the lore.
That option also adds the lore line in the player's language if you enable item.quest.lore in the 'config.yml'.
All QuestItems in the backpack are migrated automatically and Items in player's inventories will also be migrated
with item.quest.update_legacy_on_join enabled in the 'config.yml'.
items:
sword: simple DIAMOND_SWORD "lore:&2Quest Item"
items:
sword: simple DIAMOND_SWORD quest-item