# Minigame Definition Reference Minigame definitions live in `src/main/resources/Server/Minigames/.json`. JSON keys use PascalCase. The filename should match the `Id` field. ## Identity | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| | `Id` | String | Yes | none | Unique asset ID. Use underscores instead of spaces. | | `Name` | String | Yes | none | Display name shown in commands and UI. | | `Description` | String | No | `""` | Short display description. | | `Enabled` | Boolean | No | `true` | Whether the minigame can be started. | | `Debug` | Boolean | No | `false` | Enables verbose minigame debug messages when supported by runtime logic. | | `GameType` | Enum | No | `GENERIC` | `GENERIC`, `BATTLE`, `PUZZLE`, `RACE`, `CAPTURE`, or `SURVIVAL`. | ## World Binding | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| | `WorldId` | String | No | `""` | When set, the game may only be started in this world; starts from other worlds are refused with a message. | | `RequiredGameMode` | Enum | No | `Adventure` | Game mode applied to each player when they become active. | ## Players | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| | `MinPlayers` | Integer | No | `1` | Minimum player count. | | `MaxPlayers` | Integer | No | `16` | Maximum player count. | | `DefaultPlayerLives` | Integer | No | `0` | Initial lives assigned to each player when a queued runtime starts. | | `AllowJoinMidgame` | Boolean | No | `false` | When `true`, a player who disconnects mid-game is re-activated on reconnect. When `false`, reconnecting players get their saved inventory back and are dropped from the game. | | `AllowSpectators` | Boolean | No | `true` | Whether `/minigame spectate` may join the game as a spectator. | ## Teams | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| | `TeamMode` | Enum | No | `SOLO` | `SOLO`, `TEAMS`, or `FREE_FOR_ALL`. With `TEAMS`, teams are auto-created and balanced when a queued game starts (using `TeamCount` / `PlayersPerTeam`). | | `TeamCount` | Integer | No | `0` | Explicit number of teams when using `BalanceTeams`. `0` defers to `PlayersPerTeam`. | | `PlayersPerTeam` | Integer | No | `0` | When `TeamCount` is `0`, `BalanceTeams` divides total players by this to determine team count. `0` means no automatic splitting. | ## Timing | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| | `RoundLengthSeconds` | Integer | No | `300` | Active round duration. | | `TotalRounds` | Integer | No | `1` | Number of rounds to run. Values less than or equal to `0` allow open-ended round progression. | | `CountdownSeconds` | Integer | No | `10` | Pre-game countdown duration. | | `OvertimeEnabled` | Boolean | No | `false` | When the final round ends, enters `OVERTIME` for `OvertimeSeconds` and dispatches `on_overtime_start`. When the overtime timer expires the game either enters sudden death (if enabled) or ends. | | `OvertimeSeconds` | Integer | No | `60` | Overtime duration. Must be positive when overtime is enabled. | | `SuddenDeathEnabled` | Boolean | No | `false` | After the final round (and overtime, if enabled), enters `SUDDEN_DEATH` for `SuddenDeathSeconds` and dispatches `on_sudden_death_start`. The game ends when the timer expires. | | `SuddenDeathSeconds` | Integer | No | `60` | Sudden-death duration. Must be positive when sudden death is enabled. | ## Win Condition | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| | `WinCondition` | Enum | No | `HIGHEST_SCORE` | How the winner is determined. Affects end-score display order and reward distribution. | | `MapSelectionMode` | Enum | No | `VOTE` | How a waiting session chooses a discovered map: `VOTE` or `RANDOM`. | | `FriendlyFireKillScoreMode` | Enum | No | `NO_POINTS` | How same-team player kills affect kill scoring: `OFF`, `LOSES_POINTS`, or `NO_POINTS`. | Supported values: | Value | Description | |-------|-------------| | `HIGHEST_SCORE` | Highest score at the end wins. Players ranked descending. | | `LOWEST_SCORE` | Lowest score at the end wins. Players ranked ascending. | | `FIRST_TO_SCORE` | First player or team to a target score wins. | | `LAST_ALIVE` | Last active player or team wins. | | `OBJECTIVE_COMPLETE` | Objective completion determines the winner. | | `LOWEST_TIME` | Fastest completion time wins. Use `StartPlayerTimer` on the start pad and `StopPlayerTimer` on the finish line. Players who have not finished (score = 0) are ranked last. Times display as `M:SS.cc`. | | `CUSTOM` | Trigger logic determines the winner. | ## World Rules | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| | `AllowPvp` | Boolean | No | `false` | Enforced: player-vs-player damage is cancelled for players in this game when `false` (applies when either the attacker or the victim is in a no-PvP game). | | `AllowBlockBreaking` | Boolean | No | `false` | Enforced: block breaking by players in this game is cancelled when `false`. | | `AllowBlockPlacing` | Boolean | No | `false` | Enforced: block placing by players in this game is cancelled when `false`. | ## Lifecycle | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| | `ResetOnEnd` | Boolean | No | `true` | After clearing runtime state at game end, dispatches `on_arena_reset` so trigger volumes can reset world state. | | `SavePlayerInventory` | Boolean | No | `true` | Saves and then **clears** each player's inventory the first time they become `ACTIVE`. Items are only granted by volume effects (`SetPlayerLoadout`, `SpawnItem`) — nothing is given automatically. Restored on game end if `RestorePlayerInventory` is true, and when a player leaves or disconnects. | | `RestorePlayerInventory` | Boolean | No | `true` | Restores each player's saved inventory when the game ends. | ## Items | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| | `StartItems` | `ItemStackConfig[]` | No | `[]` | Items given to each player when they become `ACTIVE`, if they have no assigned loadout. | | `StartLoadouts` | `LoadoutConfig[]` | No | `[]` | Named item loadouts. A player's assigned loadout (set via `SetPlayerLoadout`) takes priority over `StartItems`. | | `Rewards` | `RewardConfig[]` | No | `[]` | Rewards distributed at game end, before `on_game_end` fires. | ## HUD | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| | `ShowHud` | Boolean | No | `false` | Whether to show a HUD for each active player. Opt-in per game. | | `ShowScore` | Boolean | No | `true` | Whether to show the player's current score on the HUD. | | `ShowLives` | Boolean | No | `true` | Whether to show the player's remaining lives on the HUD. Only visible when `DefaultPlayerLives` is greater than `0`. | | `ShowPosition` | Boolean | No | `false` | Whether to show the player's current race position (rank among active non-eliminated players). Useful for racing games using `LOWEST_SCORE`. | | `ShowRound` | Boolean | No | `true` | Whether to show the current round out of total rounds (e.g. `2 / 3`). Only rendered when `TotalRounds` is greater than `1`. | | `ShowTime` | Boolean | No | `true` | Whether to show the time remaining in the current round (e.g. `1:45`). Only rendered when `RoundLengthSeconds` is greater than `0`. Displays `0:00` once the round timer has expired. | | `ShowScoreboard` | Boolean | No | `false` | Whether to show a ranked scoreboard panel on the HUD listing player names and scores in order. Capped at 10 rows or `MaxPlayers`, whichever is smaller. | The HUD is shown when a player becomes `ACTIVE` and removed when the game ends. It refreshes approximately once per second. Position is ranked by current score respecting `WinCondition` (`LOWEST_SCORE` ranks lower scores ahead). ## Queue UI | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| | `UIQueueable` | Boolean | No | `false` | Whether this minigame appears in the global queue UI browser. Must be `true` for the game to show in `GLOBAL` mode. `SINGLE` and `LOCAL` modes work regardless of this flag — they are controlled by the `UIQueue=True` volume tag. | When `UIQueueable=true`, the game will appear in the `OpenMinigameQueueUI` global browser alongside the queue count and a clickable join button, provided at least one `MainArena` volume has `UIQueue=True`. ## ItemStackConfig ```json { "ItemId": "event_fishing_rod", "Amount": 1 } ``` | Field | Type | Required | Description | |-------|------|----------|-------------| | `ItemId` | String | Yes | Hytale item ID. | | `Amount` | Integer | Yes | Stack amount. | ## LoadoutConfig ```json { "Id": "archer", "DisplayName": "Archer", "Items": [ { "ItemId": "hunting_bow", "Amount": 1 }, { "ItemId": "arrow", "Amount": 32 } ] } ``` | Field | Type | Required | Description | |-------|------|----------|-------------| | `Id` | String | Yes | Loadout ID referenced by `SetPlayerLoadout`. | | `DisplayName` | String | No | Player-facing name for UI display. | | `Items` | `ItemStackConfig[]` | No | Items given when this loadout is applied. | | `PlayerCustomizable` | Boolean | No | Reserved for a future loadout-selection UI. When `true`, item giving is skipped at activation. Defaults to `false`. | Loadouts are selected by a `SetPlayerLoadout` effect before the player becomes `ACTIVE`. If no loadout is assigned, `StartItems` is used as a fallback. ## RewardConfig ```json { "Target": "winner", "Items": [ { "ItemId": "gold_coin", "Amount": 25 } ] } ``` | Field | Type | Required | Description | |-------|------|----------|-------------| | `Target` | String | Yes | Who receives the reward. See target values below. | | `Items` | `ItemStackConfig[]` | Yes | Items to grant. | Reward target values: | Value | Recipients | |-------|------------| | `all` | Every player in the runtime. | | `winner` | The player ranked first (rank determined by `WinCondition`). | | `top_N` | Top N players, e.g. `top_3`. | ## Minimal Example ```json { "Id": "Quick_Brawl", "Name": "Quick Brawl", "Enabled": true, "MinPlayers": 2, "MaxPlayers": 8, "TeamMode": "SOLO", "WinCondition": "LAST_ALIVE", "RoundLengthSeconds": 120, "AllowPvp": true } ``` ## Validation Current validation is definition-focused: - `Name` must not be blank. - `MinPlayers` must be greater than or equal to 1. - `MaxPlayers` must be greater than or equal to `MinPlayers`. - `RoundLengthSeconds` must be greater than 0. - `CountdownSeconds` must be greater than or equal to 0. The old custom `MinigameAreaVolume` validation requirement no longer applies. Minigame areas are normal Hytale trigger volumes configured in the editor.