BuildBattle-OG
TrueOG Network's fork of Plugily-Projects/BuildBattle — a
building competition minigame for Purpur 1.19.4, using MyWorlds for arena world management.
Current version: 5.1.12 (changelog).
Two game modes ship in the box. In classic mode players build on their own plot against a theme, then vote on each other's builds. In Guess The Build one player builds while everyone else races to guess the theme in chat for points.
OG fork notes
This fork makes no outside service calls. Upstream's update checker, remote translation fetching, error
reporting and metrics are all stubbed out, so the bundled Default locale is always used and nothing phones
home. It also adds /hub, /bbjoin, /bbforcestart and reconnect handling so players reliably get back to
the main world from an arena, and integrates with the rest of the TrueOG plugin set (see
Integrations).
Return locations are recorded whenever a player enters an arena world by any route — /bbjoin, /bb join, a
portal, or /mw tp — and are kept on disk, so /hub, a relog, a respawn or a server restart all put the
player back where they started rather than at main world spawn.
/v and /vote are claimed inside BuildBattle worlds before any other plugin sees them, so VotingPlugin
cannot take the /vote label away from theme voting. BuildBattle has no map pool to vote on, so the command
drives the theme poll the vote menu already owns rather than adding a second one.
/hub, /lobby and /spawn are claimed the same way inside BuildBattle worlds. Splegg-OG and
TheHerobrine-OG register /hub too, and Bukkit gives the bare label to whichever plugin loads first, so
without the claim an arena player's /hub could run another minigame's command and teleport them out while
the arena still counted them; Spawn-OG's /spawn did the same. All three now leave the arena properly and
return the player to where they came from.
Every arena is its own lobby with its own hub world (BB1-hub, BB2-hub, ...). /bb join and /bbjoin
with no lobby list them all with a clickable join line, like /hbjoin; /bb join BB2 or /bb join 2 joins
one directly.
Requirements
- Purpur
1.19.4 MyWorlds(either theMyWorldsor theMy_Worldsfork — both plugin names are accepted)BKCommonLib(MyWorlds' own dependency)
Optional, integrated when present: Utilities-OG, Chat-OG, Scoreboard-OG, GameModeInventories-OG,
Spawn-OG, Citizens, PlaceholderAPI, ViaVersion.
Quick Setup
The bundled arenas.yml ships arena BB1 fully configured for the open source TrueOG maps, and the
bundled config.yml already protects world, world_nether and world_the_end. What is left is
putting the two worlds in place:
- Fetch the maps from the true-og repository (
maps/) and putPlazaandBB1_Hubunder<server root>/maps/, the same directory Splegg-OG and TheHerobrine-OG use (MyWorlds.Map-Baseinconfig.yml). See Bundled maps. - Drop the jar in
plugins/and start the server. On every boot the plugin copies each arena world frommaps/to the server root under its world name (BB1-mapfromPlazavia the arena'smapname,BB1-hubfromBB1_Hub), pins its void generator and loads it through MyWorlds; nothing has to be registered by hand. Worlds live at the server root only as disposable copies. /bb join BB1(/bb joinalone lists the lobbies).
A world with no map under maps/ is loaded from the server root as before, but never generated: an arena
whose world is missing from both places is skipped with an error in the console instead of being handed
a freshly generated vanilla world.
Only if your main worlds are not named world, world_nether and world_the_end: list them under
MyWorlds.Protected-Worlds in config.yml so arenas can never be created there.
To build your own arena instead, or to add a second concurrent lobby with its own BB2-hub and BB2-map
worlds: /bba setup create <arena> opens the setup inventory for the lobby, start and end locations,
/bba addplot <arena> marks each build plot with the location wand, /bba settheme <theme> overrides the
bundled themes.yml list, and /bba setup edit <arena> reopens the inventory later. Optionally place join
signs in the hub so players can join without commands (see Join Signs).
Bundled maps
Both maps are maintained in the true-og repository under maps/,
which is also where the server keeps them (MyWorlds.Map-Base), and are the canonical worlds for the
shipped BB1 arena:
| Map | Server world | License | Notes |
|---|---|---|---|
Plaza |
BB1-map |
Unlicense (public domain) | Twelve 31x31 plots (y 64 to 96) in a ring around a 41x41 plaza, floating in the void. Generated by Plaza/tools/gen_plaza.py, so it can be regenerated or resized. |
BB1_Hub |
BB1-hub |
CC BY-SA 3.0, Green Leave Lobby by Libers97 | Same lobby build as SP1_Hub and HB1_Hub; spawn at -3, 64, 1. |
The shipped arenas.yml lists the twelve plot cuboids, the plaza centre (0.5, 65, 0.5) as start and
spectator location, and the hub spawn as lobby and end location, with maximumplayers: 12 (one plot per
player). Plot floors are regenerated from the cuboid's lowest layer with Floor.Material on every reset;
Plaza's oak floors match the default log, and its frames and pedestals sit outside the cuboids so they
survive resets. Keep both worlds out of GameModeInventories-OG's restrict_adventure_worlds and Spawn-OG's
login-safety.worlds.
The server-root copies are rebuilt from maps/ on every start, so in-game edits to an arena world do not
survive a restart; to change a map, replace the files under maps/<Name>/. Chunks outside the saved
region generate as void through the bundled BuildBattle-OG:void generator, which the plugin pins onto
each arena world in MyWorlds' worlds.yml unless one is already set (MyWorlds.Void-Generator).
Join Signs
Admins can place physical signs that players right-click to join an arena. Signs render the four lines from
Signs.Lines in language.yml (title, arena name, game state, player counts) and update automatically. With
Sign-Block-States: true in config.yml, the block behind the sign also changes color with the game state
(white waiting, yellow starting, orange in game, gray ending, black restarting).
To set one up:
- Make sure the arena exists (
/bba setup create <arena>, see Quick Setup above). - Place a sign in a persistent world such as the server hub — not in the
BB<n>-map/BB<n>-hubworlds, which are recreated between games. - Write
[buildbattle]on the first line and the arena id (e.g.BB1) on the second line. Requires thebuildbattle.admin.sign.createpermission. - The sign reformats immediately; right-clicking it joins that arena.
Sign locations are saved under the arena's signs: list in arenas.yml. Breaking a registered sign requires
buildbattle.admin.sign.break and removes it from the arena.
World naming
Arena worlds must be named BB<n>-<map> and their lobby worlds BB<n>-hub, for example BB1-map and
BB1-hub. Chat-OG resolves a world to a multi-world game by that <letters><digits>- prefix and keys its
per-game Discord channel off it, so the BB prefix must also exist under discord.games in Chat-OG's
config.yml. Worlds named any other way simply stay in global chat — everything else still works.
Arena ids follow the same convention, so the arena that owns BB1-hub and BB1-map is named BB1. /bbjoin
accepts the id case-insensitively and also accepts the bare number, so /bbjoin BB1, /bbjoin bb1 and
/bbjoin 1 are the same command. A bare number that matches more than one arena is refused rather than
guessed.
Upgrading from 5.1.4 or earlier: the bundled
arenas.ymltemplate changed frombb_lobby/bb_game_1toBB1-hub/BB1-map, and its arena id fromdefaulttoBB1. Existing arenas keep whatever names they already have; changing the template does not migrate them. To adopt the convention: stop the server, rename the world folders, then update the arena id, the three location lines andworld:inarenas.ymlalong with your MyWorldsworlds.ymlandinventories.ymlentries. Until the worlds are renamed,/bbjoin <number>cannot resolve the arena and no chat formatter is registered.
Configuration
config.yml holds the fork-specific MyWorlds block:
MyWorlds:
# Applied to MyWorlds at runtime on startup; MyWorlds' own config.yml is never rewritten.
Enable-World-Inventories: true
Enable-World-Chat: true
# BuildBattle arenas, plots and lobby locations are blocked from these worlds.
Protected-Worlds:
- world
- world_nether
- world_the_end
# Days to keep a player's pre-arena return location on disk (0 = keep forever).
PreJoin-Location-Expiry-Days: 30
# Cold-storage map directory, relative to the server root (absolute paths accepted, empty disables).
# Each arena world is copied from <Map-Base>/<Name>/ to the server root and loaded on every boot.
Map-Base: 'maps'
# Pin the bundled void generator onto every arena world so unsaved chunks stay void.
Void-Generator: true
Classic and Teams matches run in rounds, set per mode under Time-Manager in config.yml:
Time-Manager:
Classic:
# Build rounds per match; each round gets its own theme and plot vote, points add up.
Rounds: 3
# Pick each round's theme at random from themes.yml instead of holding a vote.
Random-Theme: true
Voting:
# Total time of voting for themes before starting
Theme: 25
# Total time of voting per player plot
Plot: 15
# Build time per round
In-Game: 150
Each round announces its theme (drawn at random from the mode's list in themes.yml, or voted on for
Voting.Theme seconds when Random-Theme is off; a theme is never repeated within a match), runs the build
clock, then walks every plot for a vote. Plots are wiped between rounds, votes add up across them, and the
highest total after the last round wins. Rounds: 1 is the single-build upstream flow.
While building, each player is held to their plot plus a grace margin (Plot.Border in config.yml):
Plot:
# Wall around the plot a player is building in, shown only to them; the world is never changed.
Border:
# Draw the wall. Off, the limit below still holds and a builder past it is pulled back.
Enabled: true
# Blocks a builder may step outside the plot before the wall.
Grace: 3
# Wall blocks within this many blocks of the builder are drawn.
Distance: 8
# RAINBOW_GLASS, RAINBOW_WOOL, RAINBOW_TERRACOTTA, RAINBOW_CONCRETE or any block name.
Block: RAINBOW_GLASS
The wall is the one-block shell just outside that margin, sent to the builder as client-side block
changes (Player#sendMultiBlockChange) and restored as they move away, so nothing in the world changes
and nobody else sees it. It is drawn during build time only, on all six faces, and skips real solid blocks.
A move that would still end beyond the wall is cancelled, and anyone found past it by any other route
(a teleport, a vehicle) is pulled to the nearest legal spot at their own height, or to the plot spawn
when that spot is blocked. Plot.Move-Outside: true turns the whole thing off.
Arenas live in arenas.yml:
instances:
BB1:
lobbylocation: BB1-hub,-1.0,80.0,7.0,0.0,0.0
startlocation: BB1-map,-1.0,80.0,7.0,0.0,0.0
endlocation: BB1-hub,-1.0,80.0,7.0,0.0,0.0
minimumplayers: 2
maximumplayers: 10
plotmembersize: 1
mapname: mapname
world: BB1-map
# classic (deprecated: solo), guess_the_build
gametype: classic
isdone: false
signs: {}
plots: {}
Themes are in themes.yml, messages in language.yml, and per-player statistics use mysql.yml when
Database.Enabled is on.
The boss bar is a timer for the current phase: its title names the phase with a mm:ss clock and
true-og.net, its colour follows the phase, and it drains as the phase runs out. Bossbar.Display in
config.yml turns it off; the Bossbar lists in language.yml are not read.
Placeholders
Registered through Utilities-OG as MiniPlaceholders, resolved for the viewing player, and updated the moment a game's points are awarded:
| Placeholder | Value |
|---|---|
<bb_score> |
The player's POINTS_TOTAL |
<bb_rank> |
Colored rank name for that score: Apprentice (0), Builder (100), Bricklayer (300), Carpenter (750), Mason (1,500), Craftsman (3,000), Architect (6,000), Engineer (10,000), Sculptor (15,000), Master Builder (25,000), Forger (40,000), Dreamer (60,000), Extractor (100,000), Dom (150,000); Dreamweaver for the top player once they also reach Dom |
Integrations
| Plugin | Effect when installed |
|---|---|
MyWorlds / My_Worlds |
Required. Arena world management, per-world inventories and chat. |
Utilities-OG |
Registers the <bb_score> and <bb_rank> placeholders. language.yml values containing a MiniMessage tag or the &* rainbow code render through TrueOG's colorizer, enabling <#rrggbb> hex, <gradient:...>, named colours and decorations. Plain &-coded values are passed through byte-for-byte, so nothing shipped changes appearance. Without the plugin, all values keep their default formatting. |
Chat-OG |
Arena chat is scoped per world, styled by BuildBattle-OG's own formatter, and mirrored to the game's Discord channel, provided worlds follow the naming convention and discord.games.BB exists in Chat-OG's config. The formatter shows the player count in the lobby, VOTE and JUDGING during the voting phases, and the theme while building — never in Guess The Build, where the theme is the answer. |
Scoreboard-OG |
With 1.2.0 or newer, the arena sidebar is drawn through Scoreboard-OG's sidebar API instead of MiniGamesBox's packet board. The network board returns on its own when the player leaves the arena, and /togglescoreboard is honoured. Older builds, or no Scoreboard-OG at all, keep the MiniGamesBox board. Both draw the same code-built card in the TrueOG style (♥ BuildBattle-OG ♥ title, blank-separated blocks, true-og.net footer) with every line within 16 legacy characters for 1.8 clients; only Scoreboard.Title and Scoreboard.Theme-Unknown in language.yml are still read. |
GameModeInventories-OG |
Its inventory swap is suspended for everyone inside arena worlds, by any route in, and for one tick after leaving, so the survival inventory is never filed under an arena gamemode. Builders additionally get a creative exemption scoped to arena worlds at runtime. Do not grant regular players gamemodeinventories.toggle or gamemodeinventories.anywhere, and keep arena worlds out of restrict_adventure_worlds — guessers are put in adventure mode. |
Spawn-OG |
Keep arena worlds out of its login-safety.worlds list so reconnect handling stays with BuildBattle-OG. |
VotingPlugin |
Keeps /vote and /v everywhere outside BuildBattle worlds; BuildBattle-OG never declares either label in plugin.yml. |
Citizens |
Enables /bba addnpc for plot NPCs. |
PlaceholderAPI |
Exposes arena placeholders to other plugins. |
Commands
/bb (aliases buildbattle, buildb) and /bba (aliases buildbattleadmin, buildbadmin) each print
their own help listing. The tables below cover the arguments this fork defines plus the most-used ones
inherited from MiniGamesBox.
Player Commands
| Command | Permission | Description |
|---|---|---|
/bb join [lobby] |
— | Join a lobby by id (BB1, or just 1); no argument lists the lobbies with clickable join lines |
/bbjoin [lobby] |
— | The same as /bb join |
/hub, /lobby, /spawn |
— | Leave the arena and return to where you came from, or to main spawn |
/bb randomjoin |
— | Join any arena with room |
/vote [#] or /v [#] |
— | List the themes up for voting and cast a vote |
/bb leave |
— | Leave the current arena |
/bb arenas |
buildbattle.arenas |
Open the arena selector |
/bb menu |
— | Open the plot options menu |
/bb guess <word> |
— | Submit a Guess The Build guess |
/bb selectplot |
buildbattle.command.selectplot |
Select the plot you are standing in |
/bb stats |
— | Show your statistics |
/bb top [statistic] |
— | Show the leaderboard |
/hub |
— | Leave the arena or lobby and return to the main world |
Admin Commands
| Command | Permission | Description |
|---|---|---|
/bba setup create <arena> |
buildbattle.admin.setup |
Create a new arena |
/bba setup edit <arena> |
buildbattle.admin.setup |
Open the arena setup inventory |
/bba delete <arena> |
buildbattle.admin.delete |
Delete an arena |
/bba list |
buildbattle.admin.list |
List arenas and their states |
/bba reload |
buildbattle.admin.reload |
Reload configuration |
/bba stop |
buildbattle.admin.stop |
Stop the running game |
/bbforcestart [time] |
buildbattle.admin.forcestart |
Start the game ignoring minimumplayers |
/bba forcestart |
buildbattle.admin.forcestart |
Force the game to start |
/bba forceplay <arena> <theme> |
buildbattle.admin.forceplay |
Force an arena to play a theme |
/bba settheme <theme> |
buildbattle.admin.settheme |
Set the current arena's theme |
/bba theme [add/remove] [gameType] [theme] |
buildbattle.admin.theme |
Manage the theme list |
/bba addplot <arena> |
buildbattle.admin.addplot |
Add a build plot using the location wand |
/bba removeplot <arena> <plot ID> |
buildbattle.admin.removeplot |
Remove a build plot |
/bba addnpc |
buildbattle.admin.addnpc |
Place a plot NPC (requires Citizens) |
/bba locwand |
buildbattle.admin.locwand |
Get the plot selection wand |
/bba tp <arena/worldName> [location type] |
buildbattle.admin.teleport |
Teleport to an arena location |
/bba spychat |
buildbattle.admin.spychat |
Toggle arena chat spying |
/bba statistic <adjust/set> <statistic> <amount> [player] |
buildbattle.admin.statistic |
Adjust a player's statistic (buildbattle.admin.statistic.others for [player]) |
Permissions
Administration
buildbattle.admin.* (default OP) grants every node in the Admin Commands table above, plus:
| Permission | Default | Description |
|---|---|---|
buildbattle.admin |
OP | Base administrative access |
buildbattle.admin.sign.create |
OP | Create BuildBattle join signs |
buildbattle.admin.sign.break |
OP | Break BuildBattle join signs |
buildbattle.admin.statistic.others |
OP | Adjust another player's statistics |
buildbattle.admin.locale / .locales |
OP | Inspect and switch locales |
buildbattle.admin.kitfile |
OP | Manage kit files |
buildbattle.admin.placeholders |
OP | Check placeholder resolution |
buildbattle.admin.leaderboard.manage |
OP | Manage leaderboard holograms |
buildbattle.command.override |
OP | Bypass in-game command blocking (Block.In-Game.Commands) |
buildbattle.updatenotify |
OP | Update notifications (inert in this fork) |
Gameplay
| Permission | Default | Description |
|---|---|---|
buildbattle.command.selectplot |
OP | Select the plot you are standing in |
buildbattle.particles |
OP | Use the particle menu |
buildbattle.heads |
OP | Use the player-heads menu (set per entry in heads/mainmenu.yml) |
buildbattle.arenas |
OP | Open the arena selector |
buildbattle.fullgames |
OP | Join arenas that are already full |
buildbattle.join.<arena> |
OP | Join a specific arena, when per-arena join permissions are enabled |
Point, voting and experience multipliers are configured by permission node in permissions.yml. Biome menu
entries use biomes.VIP by default, configurable in biomes.yml.
Building
git clone --recursive https://git.trueog.net/trueog/BuildBattle-OG
cd BuildBattle-OG
./gradlew build
If you cloned without --recursive, run ./bootstrap.sh first. The shaded plugin jar lands in
build/libs/BuildBattle-OG-<version>.jar.
Credits
BuildBattle-OG is a fork of Plugily-Projects/BuildBattle by Tigerpanzer_02, Plajer, TomTheDeveloper and contributors, distributed under the GPLv3.
Open Source Libraries
| Library | Author | License |
|---|---|---|
| InventoryFramework | stefvanschie | Unlicense |
| ScoreboardLib | TigerHix | LGPLv3 |
| HikariCP | brettwooldridge | Apache License 2.0 |
| Commons Box | Plajer | GPLv3 |
The plot wall (PlotBorderManager) is derived from the border module of
EternalCombat by the EternalCode Team, by way of the
TrueOG Duels-OG adaptation. Both are licensed under the
Apache License 2.0; the file keeps
that notice and lists the changes made.
Attributions
Thanks to Code Whale for the Open Source POEditor license behind upstream's locales, and to Minecraft Heads for the head names and textures used in the heads menu.