Files
BuildBattle-OG/README.md
T

22 KiB

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 the MyWorlds or the My_Worlds fork — 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:

  1. Fetch the maps from the true-og repository (maps/) and put Plaza and BB1_Hub under <server root>/maps/, the same directory Splegg-OG and TheHerobrine-OG use (MyWorlds.Map-Base in config.yml). See Bundled maps.
  2. Drop the jar in plugins/ and start the server. On every boot the plugin copies each arena world from maps/ to the server root under its world name (BB1-map from Plaza via the arena's mapname, BB1-hub from BB1_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.
  3. /bb join BB1 (/bb join alone 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:

  1. Make sure the arena exists (/bba setup create <arena>, see Quick Setup above).
  2. Place a sign in a persistent world such as the server hub — not in the BB<n>-map/BB<n>-hub worlds, which are recreated between games.
  3. Write [buildbattle] on the first line and the arena id (e.g. BB1) on the second line. Requires the buildbattle.admin.sign.create permission.
  4. 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.yml template changed from bb_lobby / bb_game_1 to BB1-hub / BB1-map, and its arena id from default to BB1. 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 and world: in arenas.yml along with your MyWorlds worlds.yml and inventories.yml entries. 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.