Manifest & config
hive-game.json tells the network how to size lobbies and load your game. Config is a typed Java class operators tune from the dashboard.
Two files describe a game to the network. hive-game.json is the manifest -
fixed facts the network needs to register, size and route your game. The
config class is the per-network knobs operators tune at runtime.
hive-game.json
The manifest sits at the root of your game jar. The network reads it to register the game, size the lobby, and boot a fresh instance whenever one fills.
{
"id": "skywars",
"name": "SkyWars",
"genre": "match",
"engine": "hytale",
"main": "net.example.SkyWars",
"minPlayers": 2,
"maxPlayers": 12,
"countdownSeconds": 20,
"arena": {
"world": "skywars-map-1",
"spawns": "Player_Spawnpoint"
}
} | Field | Meaning |
|---|---|
id | the serverType / world type matchmaking routes by - must be unique on your network |
name | display name shown in lobbies and the dashboard |
genre | match or party - picks the lifecycle (match / party) |
engine | hytale or minecraft - which adapter this jar targets |
main | fully-qualified class that extends MatchLifecycle / hosts the party |
minPlayers | players needed before the countdown starts |
maxPlayers | lobby capacity; also what matchmaking treats as “full” |
countdownSeconds | lobby countdown once minPlayers is reached |
arena.world | the GameWorld template to instantiate per match |
arena.spawns | the marker type the genre reads for spawn points |
minPlayers / maxPlayers / countdownSeconds are exactly the numbers
matchmaking’s start-aware routing uses to fill lobbies
top-down - declare them here and the routing follows.
Party rounds
A party game lists its micro-game pool instead of a single arena. The host
rolls from this pool each turn:
{
"id": "blockparty",
"genre": "party",
"engine": "hytale",
"main": "net.example.PartyHost",
"board": "party-board-1",
"turns": 12,
"rounds": [
"net.example.rounds.FallingFloor",
"net.example.rounds.HotPotato",
"net.example.rounds.CoinRush"
]
} Typed config
Per-network settings are a plain Java class - no annotations, no schema file. The
network loads it, validates the types, and hands it to your instance.
MatchLifecycle<SkyWarsConfig> is generic over it, so ctx.config() is fully
typed.
public final class SkyWarsConfig {
int chestRefillSeconds = 120;
boolean doubleJump = true;
int coinsPerKill = 10;
} Read it straight off the context:
public void onStart(MatchContext ctx) {
if (ctx.config().doubleJump) ctx.players().forEach(this::enableDoubleJump);
} Manifest vs. config - which goes where
A simple rule keeps the split clean:
- Manifest = facts the network needs before your code runs - how to register, size and route the game. Fixed per build.
- Config = knobs your game reads at runtime. Tunable per network without a rebuild.
The field defaults in your config class are the starting values; an operator overrides them per network from the dashboard, and the network passes the resolved object to every new instance. You never parse a file or read an environment variable - you read typed fields.
Next
- Match games - use
ctx.config()in the lifecycle. - Ports & portability - what
arena.worldand markers resolve to.