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 from the dashboard, scoped to the server type so every server running this game shares one config, 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. See Config for how the dashboard groups and publishes this.
Next
- Match games - use
ctx.config()in the lifecycle. - Ports & portability - what
arena.worldand markers resolve to.