A roster pack is a JSON file called roster-pack.json. Here's one cut down to a team and two
players. The example repository has complete ones.
{
"format": "bladeybiscuit.rosters",
"formatVersion": 1,
"league": "POND",
"season": "2026-27",
"snapshot": "2026-10-05",
"teams": [
{
"id": "PIN", "name": "Pinecrest Porcupines", "city": "Pinecrest",
"colors": { "primary": "#1E4D2B", "secondary": "#F2E3C6" },
"lines": {
"forwards": [[102, 101, 103], [105, 104, 106], [208, 107, 108]],
"defense": [[113, 114], [115, 116], [117, 118]],
"goalies": [119, 120]
}
}
],
"players": [
{
"id": 101, "firstName": "Owen", "lastName": "Thistlewood", "team": "PIN", "number": 19,
"position": "C", "handedness": "L", "heightCm": 185, "weightKg": 86,
"ratings": { "overall": 82, "speed": 79, "passing": 91, "stickhandling": 96, "hockeySense": 88 }
},
{
"id": 119, "firstName": "Ansel", "lastName": "Fjordby", "team": "PIN", "number": 31,
"position": "G", "handedness": "L", "heightCm": 193, "weightKg": 91,
"ratings": { "overall": 75, "reflexes": 78, "positioning": 74, "reboundControl": 70 }
}
]
}
Leave a field out and the game uses its default. You can add fields of your own, like notes to yourself or birthdays. The game ignores anything it doesn't know.
The league
The fields at the top describe the whole pack.
| Field | What it does | |
|---|---|---|
format |
Required | Always "bladeybiscuit.rosters". It's how the game knows it's a roster pack. |
formatVersion |
1. If a newer version of the game ever changes the format, it'll use a bigger number. This version refuses a pack numbered higher than it knows, and asks for an update. |
|
league |
A few capital letters for the league. Team select shows them over each team (default "League"). |
|
season |
The season, like "2026-27". It appears next to the date in the Rosters menu. |
|
snapshot |
The day the rosters are as of, yyyy-MM-dd. Just for your records: the date people see comes from roster-set.json. |
|
teams |
Required | The teams. A league needs at least two. |
players |
Required | Every player on every team, in one list. Each one says which team they're on. |
files |
Every picture the pack uses (its logos), with their checksums: see Logos and art. |
Teams
| Field | What it does | |
|---|---|---|
id |
Required | The team's short name, like "PIN": 2 to 4 capital letters. It's what the scoreboard shows, and players join a team by it. A longer one is cut to 4 letters. |
name |
The full name, as team select shows it (default "Team"). |
|
city |
Where they're from. | |
colors |
primary and secondary, as "#rrggbb" colour codes. |
|
logo |
A picture of the team's logo, beside the pack: see Logos and art. | |
lines |
The depth chart: lines, pairs and goalies. | |
nickname, conference, division |
Kept with the team, not shown yet. |
Colours
primary is the jersey colour and secondary is the trim. The game makes the rest from those
two:
- Home jerseys are the primary colour, with the trim, names and numbers in the secondary. If the primary is light (a yellow, say), the two swap: the jersey takes the dark colour and the light one trims it.
- Away jerseys are white, trimmed in the team's colour.
- Pants are a dark shade of the primary. Helmets are dark with the home jersey and light with the away one.
- The design (stripes, yokes, sleeve bands) is picked from the team's name. Rename a team and its design changes with it.
Write each colour as # and six hex digits: #1E4D2B is a dark green. Any colour picker gives you
these, including the ones in Google search and in most paint programs. A team without colours plays
in navy (#334066) and white.
Lines
The game dresses three forward lines, three defence pairs and a goalie, and rolls them through
the game itself, line changes and all. lines says who plays where. Each player is listed by their
id.
"lines": {
"forwards": [[102, 101, 103], [105, 104, 106], [208, 107, 108], [111, 110, 112]],
"defense": [[113, 114], [115, 116], [117, 118]],
"goalies": [119, 120]
}
| Field | What it holds |
|---|---|
forwards |
Forward lines, best first. Each is [left wing, center, right wing]. |
defense |
Defence pairs, best first. Each is [left D, right D]. |
goalies |
Goalies, the starter first. |
- The spot decides the position. A player plays wherever their line puts them, whatever their
own
positionsays. That's how you move a center to the wing. - Only the first three lines and pairs dress. Players on a fourth line, a fourth pair or not on any line are the team's spares. The game uses them to fill holes.
- The first goalie found plays. The rest are backups.
- A hole is fine:
nullin a spot ([102, null, 103]) leaves it empty for the game to fill. - One spot per player. If someone's listed twice, the second spot is treated as a hole.
powerPlayandpenaltyKilllists are allowed, but the game picks its own special teams.
When a lineup's short
The game never refuses a team for being short. It fills each empty spot with the best spare by
overall, keeping forwards to forward spots and defencemen to defence spots if it can, then any
skater. If nobody's left, it calls up an average player called “Call-up”. A team with no goalie in
goalies gets the first player listed with "position": "G", or a call-up.
The game fills spots in order (first line, first pair, second line…), and a spare can be someone listed further down. Their own spot is then a hole too, so one gap can shuffle a whole line. The checker shows each lineup as the game will dress it. After installing a pack, the game says how many teams it had to fill out.
No lines at all
You can leave lines out completely. The game dresses each team itself: forwards fill center,
left wing, right wing on each line in turn, and defencemen fill each pair, left then right. The
highest overall goes first, so with no ratings at all it's the order they're listed in. The
smallest pack works this way.
Players
| Field | What it does | |
|---|---|---|
id |
Required | A whole number that's this player's alone in the pack, and stays theirs in every update. Lines refer to players by it. Any numbers you like: 1, 2, 3 is fine. See Keep each player's id. |
team |
Required | The id of their team, exactly ("PIN", not "pin"). |
firstName, lastName |
Their name. The back of the jersey shows the last name in capitals. | |
number |
Their jersey number, 0 to 99. |
|
position |
"C", "LW", "RW", "D" or "G". G marks a goalie. Otherwise, only forward or defenceman matters, when the game fills holes. |
|
handedness |
"L" or "R": which way they shoot. For a goalie, the hand that catches. Default "L". |
|
heightCm |
Height in centimetres (default 185). | |
weightKg |
Weight in kilograms (default 90). | |
ratings |
Their abilities, 0 to 99: see Ratings. |
Keep each player's id
A player's id is who they are from one update to the next, so keep it the same in every update
you publish, whatever else changes: their team after a trade, their number, their ratings, even
their name.
- A new player gets a new
id, one nobody in your set has had before. - Never hand a player's
idto someone else, even after they've left or retired.
The game matches players across updates by it: a season in progress takes your update's trades
and rating changes for the players it already has (with season mode, coming). A player whose id
changed looks like someone new, and one who took an old id looks like the player who had it.
Names
The game joins firstName and lastName with a space. On the jersey's back it uses the last name,
in capitals. Particles stay with it, so "van der Berg" prints VAN DER BERG. A nickname in quotes,
like "firstName": "Hal \"Tank\"", shows in menus but stays off the jersey. Accents are fine:
"Mäkelä", "Lindström".
Size
Height and weight do more than set how big a player looks:
- Bigger bodies take up more room, hit harder and are harder to knock off the puck.
- Taller players reach a little further with the stick.
- Taller goalies cover more of the net.
The effect on play levels off at about 170–203 cm and 70–117 kg. A height under 100 is ignored, so
write 185, not 1.85.
Writing JSON by hand
JSON is strict, and the game reads it strictly:
- Double quotes around every name and text:
"name": "Pinecrest", never'Pinecrest'. - No comma after the last item in a list or object.
- No comments. To leave yourself a note, add a field:
"note": "fix the third line". - Numbers without quotes.
"number": 19is a number."number": "19"is text, and the game ignores it. - Save as UTF-8, which every modern editor does by default.
A misspelt field name doesn't stop anything. The game just doesn't see it, so "shotPowr": 90
leaves that player's shot power at 50. The checker points out names it doesn't
know.