Skip to content

Migration

This guide explains how to migrate from BetonQuest 1.12.X or any BetonQuest 2.0.0 dev build to BetonQuest 2.0.0.

The majority of changes will be migrated automatically. However, some things must be migrated manually.

The migration will first find any 1.12 packages in the BetonQuest plugin folder and migrate them to the 2.0 package format. It will then place them inside the newly introduced QuestPackages folder. Then it updates everything inside the QuestPackages folder to the new 2.0 syntax. This way the migration works for both 1.12 and 2.0.0-DEV packages.

Warning

Before you start migrating, you should backup your server!

Changes🔗

Steps marked with ⚙ are migrated automatically. Steps marked with ❗ must be done manually.

2.0.0-DEV-87 - Rename to ride ⚙🔗

Automated Migration

The migration is automated. You shouldn't have to do anything.


To unify the naming for riding a vehicle, we renamed the condition (riding) and the objective (vehicle) to ride.

Old Syntax (conditions.yml)
rideHorse: riding Horse
New Syntax (conditions.yml)
rideHorse: ride Horse
Old Syntax (objectives.yml)
rideHorse: vehicle Horse events:teleport
New Syntax (objectives.yml)
rideHorse: ride Horse events:teleport

2.0.0-DEV-98 - RPGMenu Merge ⚙🔗

Automated Migration

The migration is automated. You shouldn't have to do anything.


All existing RPGMenu users must update their RPGMenu config file. Simply rename it from rpgmenu.config.yml to menuConfig.yml.

2.0.0-DEV-238 - Package Structure Rework ⚙🔗

Automated Migration

The migration is automated. You shouldn't have to do anything.


  • Ensure your server is running on Java 17
  • Move your current Quests to the folder "BetonQuest/QuestPackages"`, as quests are now loaded from there
  • Rename all "main.yml" files to "package.yml"
  • Quest packages can now contain nested quest packages in sub folders. You can also have any file and folder structure with any file and folder names you want. Only the "package.yml" is reserved as indicator for a quest package.
  • Therefore, the "events.yml`, "objectives.yml", "conditions.yml", "journal.yml" and "items.yml" files must be updated to the following format: Every type that was previously a separate file with a special name is now identified by a "parent-section". It's the names of the type / the name the file previously had. Let's take a look at an example for events and conditions:

    Example

    events.yml
    myEvent: "teleport 1;2;3;world"
    myOtherEvent: "point level 1"
    
    conditions.yml
    myCondition: "location 300;200;300;world"
    

    events.yml
    events:
      myEvent: "teleport 1;2;3;world"
      myOtherEvent: "point level 1"
    
    conditions.yml
    conditions:
      myCondition: "location 300;200;300;world"
    
    This allows you to freely name the files. Also, it is no longer necessary that events, conditions etc. are in separate files. You could also put everything in a single file or use any other file structure:
    anyFileName.yml
    events:
      myEvent: "teleport 1;2;3;world"
      myOtherEvent: "point level 1"
    conditions:
      myCondition: "location 300;200;300;world"
    

    Warning

    You must do this change for all types, not just events and conditions!

  • Alongside the previous change, conversations and menus must also be updated to the following format: Add an extra prefix matching their type and the file name:

    Example

    lisa.yml
    quester: Lisa
    first: option1, option2
    NPC_options:
      option1:
      # ...
    
    anyFileName.yml
    conversations:
      lisa: #(1)!
        quester: Lisa
        first: option1, option2
        NPC_options:
          option1:
          # ...
    
    1. This key is now the conversation name that you must refer to when linking NPCs to conversations.

    Or alternatively:

    conversations.lisa:
      quester: Lisa
      first: option1, option2
      NPC_options:
        option1:
        # ...
    

2.0.0-DEV-337 - Event Scheduling Rework ⚙🔗

Automated Migration

The migration is automated. You shouldn't have to do anything.


  • All your static events need to be converted to the new scheduling system. The realtime-daily schedule makes this easy:

    Example

    Old Syntax
    static:
      '09:00': beton
      '11:23': some_command,command_announcement
    
    New Syntax
    schedules:
      betonAt09: #(1)!
        type: realtime-daily #(2)!
        time: '09:00' #(3)!
        events: beton #(4)!
      cmdAt1123:
        type: realtime-daily
        time: '11:23'
        events: some_command,command_announcement
    

    1. A name for the new schedule.
      Can be anything you want for organizing your schedules.

    2. The type schedule realtime-daily was created for easy updating.
      It behaves just like the old static events.

    3. The former key is now the time value.
      You still have to put it in 'quotes'.

    4. The former value is now the events value.

2.0.0-DEV-450 - Package Section ⚙🔗

Automated Migration

The migration is automated. You shouldn't have to do anything.


  • There is now a new section package for organizing package related settings. As a result of this the enabled boolean was moved to this section. If you use the enabled boolean you need to move it to the package section.

    Example

    Old Syntax
    enabled: false
    
    New Syntax
    package:
      enabled: false
    

2.0.0-DEV-485 - Experience changes ❗🔗

Due to a misuse of the Spigot API, all code regarding player experience (experience event, condition and objective) had to be changed. It is not possible to obtain the amount of experience points a player has, only their level can be obtained.

If you used any of these elements you might have to adjust the configured values because the behaviour changed as follows:

  • The experience objective and condition do not allow raw experience anymore. Only levels are supported from now on.
  • The experience objective, condition and event now supports decimal numbers.
    For example, you can use experience 1.5 to check for one and a half level.
    You can convert raw experience points to levels, using such decimal numbers.

2.0.0-DEV-538 - Smelt Objective ❗🔗

The smelt objective now requires a quest item instead of a BlockSelector. Therefore, you now need to define the item you want to smelt in the items section. It is recommended to use the /q item packageName.ItemName command to save the target item from in-game. This will save the item you currently hold in your hand to the given package with the given name. After you did this, you need to replace the BlockSelector in the smelt objective with the item's name.

2.0.0-DEV-539 - NPC and Non-NPC Holograms ❗🔗

Potentially Faulty Automatic Migration

In some cases this migration will not be run although the configuration is in the 1.12 format. This is the case because it is not possible to reliably detect if the configuration must be migrated - it simply has not changed enough.
If the (NPC-)hologram section does NOT contain one of the following keys the migration will NOT be run:

  • follow
  • check_interval

If this is the case you need to update the configration manually. See the steps below.

Both NPC and Non-NPC Holograms were reworked. Mainly three things have to be changed:

  • The vector is now above the head of the NPC by default. This was previously achieved with 0;3;0. Therefore, every hologram that has defined a vector is now three blocks higher than before. If it is set to 0;3;0 delete the vector argument. Otherwise, subtract 3 from the y-axis.
  • The follow boolean can now be set for each NPC Hologram, so you have to add it to each NPC Hologram. It's off by default. Don't add it to still-standing NPCs. This will save you a lot of performance.
  • The check_interval can now be set for each NPC Hologram as well. This allows for finer control over how much server resources are used.
Old Syntax
npc_holograms:
  check_interval: 200
  follow: true
  default:
    lines:
      - "Some text!"
    conditions: "has_some_quest"
    vector: 0;3;0
    npcs:
      - 0
      - 22
New Syntax
npc_holograms:
  default:
    lines:
      - "Some text!"
    conditions: "has_some_quest"
    vector: 0;0;0 #(1)!
    check_interval: 200 #(2)!
    follow: true #(3)!
    npcs:
      - 0
      - 22
  1. You can delete this if you had 0;3;0 previously as the origin was changed. Subtract 3 from the y-axis for any other value.
  2. You can delete this if you had the default value of 200 (or whatever you set in "config.yml").
  3. You can delete this if you had the default value of false.

2.0.0-DEV-644 - Database migration for profiles ⚙🔗

Automated Migration

The migration is automated. You shouldn't have to do anything.


The database migrated to a new format for profiles and every profile will have a name. You can set a initial creation name in your config.yml, so every new generated profile (through migration or joining of a new player) will get this name. If you don't set a initial name, the initial name will be "default".

Example

config.yml
profiles:
  initial_name: player # (1)!
  1. Only set this if you want to change the initial name. If you don't set this, the initial name will be "default".

2.0.0-DEV-647 - EffectLib ⚙🔗

Automated Migration

The migration is automated. You shouldn't have to do anything.


The EffectLib integration was rewritten. With this rewrite, the following things are now possible:

  • NPC effects will now move with the NPC
  • Effects can be assigned to locations

The following changes need to be done:

  • Rename npc_effects to effectlib.
  • Add pitch: -90 to preserve the old rotation to NPC effects.
  • Remove check_interval from the npc_effects section
  • Remove disabled from the npc_effects section
Old Syntax
npc_effects:
   check_interval: 50
   disabled: false
   farmer:
      class: VortexEffect
      iterations: 20
      particle: crit_magic
      helixes: 3
      circles: 1
      grow: 0.1
      radius: 0.5
      interval: 30
      npcs:
         - 1
      conditions:
         - '!con_tag_started'
         - '!con_tag_finished'
New Syntax
effectlib: 
   farmer: 
      class: VortexEffect 
      iterations: 20 
      particle: crit_magic 
      helixes: 3
      circles: 1
      grow: 0.1
      radius: 0.5
      pitch: -60 #(4)!
      yaw: 90
      interval: 30 #(1)!
      checkinterval: 80 #(2)!
      npcs: #(3)!
         - 1 
      locations:
         - 171;72;-127;world
      conditions: 
         - '!con_tag_started'
         - '!con_tag_finished'
  1. This field is optional. You can delete this if you had the default value of 100.
  2. This field is new and optional. It replaces the old check_interval field. You can delete this if you had the default value of 100.
  3. In case you never had the npcs field and the effect were played on every npc in the package, you now need to add the npcs section with every npc the effect should be played at.
  4. In case you never had the pitch field, you need to use the default value of -90.

2.0.0-DEV-674 - MMO Updates ⚙🔗

Automated Migration

The migration is automated. You shouldn't have to do anything.


A change related to the integration of the MMO suite by Phoenix Development was made. The objectives mmocorecastskill and mmoitemcastability were merged into the mmoskill objective. The mmoskill objective works exactly like its predecessors, but also supports defining one or more trigger types.

See the objective's documentation for more information.

Old Syntax
castMMOCoreSkill: "mmocorecastskill DEEP_WOUND"
castMMOItemSkill: "mmoitemcastability DEEP_WOUND"
New Syntax
castMMOCoreSkill: "mmoskill DEEP_WOUND trigger:CAST"
castMMOItemSkill: "mmoskill DEEP_WOUND trigger:RIGHT_CLICK"

2.0.0-DEV-749 - Static Event Rework ⚙🔗

Automated Migration

The migration is automated. You shouldn't have to do anything.


Until now if you used non-static events in a schedule, they were executed for every player that was online at the time.
If you run such a schedule now you will get a warning message in the console similar to this:

Example

[15:27:10 WARN]: [BetonQuest] Cannot fire non-static event 'announcements.ringBell' without a player!

To fix this wrap the event in a runForAll event:

Old Syntax
events:
  # Events that require a player (non-static events).
  bell_sound: 'notify io:sound sound:block.bell.use'
  bell_ring: 'folder bell_sound,bell_sound,bell_sound,bell_sound period:0.5'
  # Player independent events (static events).
  notify_goodNight: 'notifyall &6Good night, sleep well!'


schedules:
  sayGoodNight:
    type: realtime-daily
    time: '22:00'
    events: bell_ring,notify_goodNight
New Syntax
events:
  # Events that require a player (non-static events).
  bell_sound: 'notify io:sound sound:block.bell.use'
  bell_ring: 'folder bell_sound,bell_sound,bell_sound,bell_sound period:0.5'
  # Player independent events (static events).
  notify_goodNight: 'notifyall &6Good night, sleep well!'
  bell_ring_all: 'runForAll events:bell_ring' #(1)!

schedules:
  sayGoodNight:
    type: realtime-daily
    time: '22:00'
    events: bell_ring_all,notify_goodNight #(2)!
  1. Runs bell_ring for all online players.
  2. notify_goodNight is a static event, so no need to wrap it in runForAll.

While this seems like more work for the same functionality it gives you more control over how events are run.
With this change we finally allow using conditions in schedules!
Just keep in mind you can only add player dependent conditions if the event is run player dependent (wrapped inside runForAll).

Tip

To check if your event still works inside a schedule or if it must be wrapped, use the following command to run the event without a player:

/q event - <package>.<event>
The - is important, it means run independent 😉.

2.0.0-DEV-769 - RemoveEntity-Event ⚙🔗

Automated Migration

The migration is automated. You shouldn't have to do anything.


As you probably noticed, the ClearEntity event and the KillMob event did almost the same thing. Both got merged into the RemoveEntity event, while keeping the syntax more or less the same.

Old Syntax
events:
  clearArea: 'clear ZOMBIE,CREEPER 100;200;300;world 10 name:Monster'
  killBolec: 'killmob ZOMBIE 100;200;300;world 40 name:Bolec'
New Syntax
events:
  clearArea: 'removeentity ZOMBIE,CREEPER 100;200;300;world 10 name:Monster'
  killBolec: 'removeentity ZOMBIE 100;200;300;world 40 name:Bolec kill'