Skip to main content

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}