Creating Custom Modes
Overview
This page covers creating a custom arena mode with some more advanced features. It largely picks up from the Arena Configuration page, so before continuing on with this section, it's recommended to familiarize yourself with the arena configurations. This is primarily a walk-through example.
In this example, we will be creating a 2v2 PvP game with up to 5 players on each team called Red vs Blue. Each player will have 3 lives, and the last remaining team alive wins. This will be a 10 minute game.
Standard Options
The first step will be configuring the standard options for the arena.
name: RedvsBlue
aliases: [rvb]
mode: Arena
type: Match
This sets the arena name to RedvsBlue, the aliases for the command to /rvb, the mode to Arena, and the type to Match.
Team Options
team-options:
named-teams: true
team-size: 2-5
team-amount: 2
team-selection: random
This will set the team options to use named teams, with a team size of between 2 - 5 players from earlier. This means the game will begin starting when there are at least 2 players on each team, but max out at 5 players on each.
Modules
For this mode, we will be enabling two additional modules: Classes and Team Heads.
In order to enable these, the following options have been added:
modules:
- classes
- team-heads
Lives
The lives configuration has been updated to be enabled, and give each player three lives.
lives:
enabled: true
amount: 3
Victory Conditions
The following victory conditions have been enabled: teams-alive and time-limit. We want the game to end when there is one team alive, but if after 10 minutes there is no victor, the game should end in a draw.
victory-conditions:
teams-alive:
amount: 1
time-limit:
time-limit: 10m
Events & Actions
For this mode, we will be using very similar events from the arena.yml, however some changes have been made since players will have multiple lives in this mode.
In the on-death event, the teleport and delay actions have been removed, leaving it as the following:
events:
on-death:
- clear-inventory
- repsawn
Since the player has multiple lives, we don't want them being teleported back to the waitroom on death. However, if the player has exhausted all their lives, we also don't want them being teleported into the game. The following events below are used:
events:
on-life-deplete:
- delay{ticks=2}
- give-effects{effects=[speed 300 1]}
- teleport{location=team_spawn}
- equip-class{class=warrior}
- team-heads
on-lives-exhaust:
- delay{ticks=2}
- teleport{location=waitroom}
As seen here, on-life-deplete is used when the lives are depleted. This is called upon death, but only when the player has lives remaining. We want to use this event here as it allows players to be teleported back to the game, only when they have lives to spare.
The delay option used above allows you to delay how long until the next action runs. In this case, we delay immediately since we want to ensure the player is fully respawned, and their death & lives tally have updated internally.
However, when the player runs out of lives, on-lives-exhaust is called. In this case, we want to teleport the player back to the waitroom.
More details about these events and others can be found on the Event Reference page.
Options
For the options, we will be using the same options as arena.yml, with one addition:
options:
- class-equip-only-selects{enabled=true}
This is an option from the Classes module which means that when a player runs /rvb equip <class> in a waiting lobby, rather than being equipped with the class at that point, it simply "selects" the class. Then, when the equip-class action is ran (as is above in the on-life-deplete event), it will use the player's selection. The "warrior" option above acts as a default in this case, if a player did not choose a class.
More information on the classes module can be seen at the previously linked page, which covers these options (and more) in more detail.
Phases
The phases for this game are the same as what is from arena.yml, with some minor additions.
The first one is to the options section in the waiting and countdown phases:
options:
- class-equipping{enabled=true}
This option allows players to run the /rvb equip <class> command while they are waiting for the game to start. This option is absent from the ingame and victory phases, as players are not allowed to change classes once the game starts.
The next option is to the countdown phase, increasing the countdown-time from 5 seconds to 1 minute. Since the maximum players for this game is 10, but the minimum is 4, we want to give players not in the game a longer opportunity to join before starting the game. Additionally, the allow-join option has been set to true, since we want to allow joins during the countdown phase.
And finally, in the ingame phase, the following is added to the events section:
events:
on-start:
- equip-class{class=warrior}
- team-heads
This will equip the player's selected class (or warrior if not selected) once the game starts. Additionally, it will set the player's helmet to their team color, using the team-heads action.
Conclusion
And with this done, we now have a Red vs Blue arena! Run /ba reload or restart the server, and the arena will now exist on the server. A map for this arena can be created by following the Map Creation instructions, and joined with /rvb join.
A full YAML file for the Red vs Blue arena can be found below:
name: RedvsBlue
aliases: [rvb]
mode: Arena
type: Match
team-options:
named-teams: true
team-size: 2-5
team-amount: 2
team-selection: random
modules:
- classes
- team-heads
lives:
enabled: true
amount: 3
victory-conditions:
teams-alive:
amount: 1
time-limit:
time-limit: 10m
events:
on-join:
- store{types=all}
- change-gamemode{gamemode=adventure}
- flight{enabled=false}
- teleport{location=waitroom}
on-spectate:
- store{types=all}
- change-gamemode{gamemode=spectator}
- flight{enabled=true}
- teleport{location=waitroom}
on-leave:
- clear-effects
- restore{types=all}
on-death:
- respawn
- clear-inventory
on-life-deplete:
- delay{ticks=2}
- give-effects{effects=[speed 300 1]}
- teleport{location=team_spawn;random=false}
- equip-class{class=warrior}
- team-heads
on-lives-exhaust:
- delay{ticks=2}
- teleport{location=waitroom}
options:
- block-break{enabled=false}
- block-place{enabled=false}
- block-interact{enabled=false}
- damage-entities{option=never}
- class-equip-only-selects{enabled=true}
- keep-inventory{enabled=true}
- keep-experience{enabled=true}
initial-phase: waiting
phases:
waiting:
allow-join: true
next-phase: countdown
options:
- damage-players{option=never}
- class-equipping{enabled=true}
countdown:
allow-join: true
allow-spectate: true
revert-phase: true
next-phase: ingame
countdown-time: 1m
options:
- damage-players{option=never}
- class-equipping{enabled=true}
events:
on-complete:
- teleport{location=team_spawn}
- give-effects{effects=[speed 300 1]}
- play-sound{sound=block.note_block.pling;pitch=2;volume=1}
ingame:
allow-join: false
allow-spectate: true
next-phase: victory
options:
- damage-players{option=other_team}
events:
on-start:
- equip-class{class=warrior}
- team-heads
victory:
allow-join: false
allow-spectate: false
next-phase: waiting
duration: 5s
events:
on-complete:
- clear-effects
- leave
on-victory:
- send-message{message=<green>Congrats, you won!</green>}
- play-sound{sound=entity.player.levelup;pitch=1;volume=1}
on-lose:
- send-message{message=<red>Sorry, you lost!</red>}
- play-sound{sound=block.anvil.place;pitch=0;volume=1}
on-draw:
- send-message{message=<yellow>It's a draw!</yellow>}
- play-sound{sound=block.beacon.deactivate;pitch=0;volume=1}