Guide
Trophy models
A televised event's trophy stands on a pedestal at stage right during the match. Each trophy is one glTF binary file (.glb) named by a trophies record. The game's own are the core pack's: the records in core/data/trophies.json, the models in core/assets/trophies/. A worked example of a mod is example-trophy (a turned cup written by tools/mods/make_example_trophy.py, named on an event by a patch).
Status. Built: the trophies records with the loader's checks of the model file, the stage building the trophy an event names from its record (units, scale, turn), the checks made when it is built, and the fallback with a line on the Mods screen. The parts not built are listed under Not built yet. This page has the same shape as Dart part models) and Stage models).
The trophy frame#
- Metres. A trophy 45 cm tall is 0.45 high in the file. (The stage works in millimetres; the game scales the trophy by 1000.) The record can say
"units": "mm"or give a"scale"instead. - glTF's own frame: right-handed, y up.
- The origin is the centre of the trophy's foot: the model stands on the plane
y = 0, centred on the y axis. The game puts the origin on the middle of the pedestal's top. - The front faces +z: the engraved plate, the side the cameras see.
- In Blender (z up, with the exporter's "+Y up" on, the default) the trophy stands on the grid's origin with its plate towards -Y.
The pedestal is the game's own (a plain plinth). Do not model one; a base that is part of the trophy is fine.
The core trophies for size: 0.36 m wide, 0.40 m tall (the invitational's crystal) and 0.23 m wide, 0.47 m tall (the world championship's globe).
Materials are drawn as authored#
A trophy has no roles to fill. Every material is drawn from its own glTF values:
| glTF | Used |
|---|---|
baseColorFactor, baseColorTexture | yes |
metallicFactor, roughnessFactor, metallicRoughnessTexture | yes (glTF's packing: roughness in green, metallic in blue) |
doubleSided | yes |
alphaMode: "BLEND" | drawn as glass: see-through over the rest, at the base colour's alpha, without refraction |
emissiveFactor | read, not drawn on a trophy yet |
normal, occlusion and emissive textures, alphaMode: "MASK", vertex colours | ignored |
Textures are embedded in the glb as PNG or JPEG. Model the detail that matters (an engraving, a rim) as geometry or paint it into the base colour: there are no normal maps.
Materials with the same name in one file share one material in the game, so give different looks different names.
Naming a trophy on an event#
An event names its trophy in its record (Calendar):
{ "id": "acme.event.harbour-masters", "trophy": "acme.trophy.harbour-cup" }The field takes a trophy's id, or the last part of one ("world-championship" finds core.trophy.world-championship: the core pack's events, and careers begun before trophies were records, name theirs that way). Without the field (or when it names no trophy the game has) the game looks for a trophy whose id is in the event's name, written in lower case with hyphens for everything that is not a letter or a digit (world-championship is in "The Kingsgate World Championship"); the longest id wins. An event with no trophy has no pedestal. The id's last part is what is looked for in the name, so acme.trophy.harbour-cup is also found by an event called "The Harbour Cup".
Grip points for the winner's hands#
When the human wins a final on a televised stage, the winner lifts the trophy. The game needs to know where the hands close on it: two empty nodes in the glb, grip.left and grip.right, each the centre of a round bar the hand wraps round:
- the node's position is the bar's centre, in the trophy's frame (metres, like the meshes);
- the node's +z axis (after export; Blender's +z, the exporter turns it) runs along the bar;
- extras (custom properties)
radiusandlength, in metres: the bar's radius (15 to 40 mm reads as a hand's grip) and how much of it a hand may use.
The left hand comes to its bar from the trophy's left (its −x side), the right hand from the right, palms toward the trophy, knuckles to the front (+z); the bars should be reachable that way: on the sides of the body of the trophy (the Ring's grips are its sides, the obelisk concept's are two heights of the shaft). Empties are not drawn. A trophy without grip points gets a bar through its middle, 20 mm thick: the hands then hover rather than hold. tools/blender/trophy_lib.py's grip() writes them.
The base (since 2026-10-09). The lift itself holds the trophy by its base, both hands flat on the base's sides with the fingers hooked over its top edge, the way a real trophy is raised; only the photographs' hold uses a grip bar (the right hand) with the left hand open under the base. The game reads the base from the meshes named base and top (their top and their half width in x); a trophy without them is taken to have a base in its lowest sixth, as wide as the model. Name the plinth's mesh base (and a plate on it top) and keep it at least about 0.15 m wide, so two hands fit on its sides.
The trophy record#
A trophy is a content record like any other: a pack lists its trophies in data/trophies.json (or files under data/trophies/), and the model is an asset of the pack.
[
{
"id": "acme.trophy.harbour-cup",
"name": "The Harbour Cup",
"model": "assets/trophies/harbour-cup.glb"
}
]- **
id**: unique and namespaced. A record with an id that exists already replaces it (a mod can replacecore.trophy.world-championship); a patch ("target": "trophy:<id>") changes one field. - **
name**: shown on the Mods screen and in the Mod Studio's pickers. - **
model**: the glb, relative to the mod, like every other asset path. - **
units** ("m"by default, or"mm"), **scale(a number, applied after the units),turn** (degrees about the upright axis, for a model whose front is not +z): optional.
Every mesh node of the file is drawn, with its own transform and its parents'. Cameras, lights, skins and animations in the file are ignored.
File rules#
- glTF 2.0 binary (
.glb), one file, everything embedded. - Triangles only, with normals and one uv set. Indexed or not.
- No Draco or meshopt compression, no sparse accessors, no KTX2 or WebP textures (PNG or JPEG only).
- Size limits (a file over one is refused, see below): 20 MB, 100,000 triangles, textures up to 2048 px a side, and the trophy must fit a box 0.6 m wide and deep and 0.8 m tall after
unitsandscale. The core trophies are 7 and 11 MB, 12,000 and 68,000 triangles. The limits are the proposal for, to be settled when the loader is built.
A bad file never breaks a match#
Checked when mods load (the Mods screen shows the result against the mod):
| Problem | Result |
|---|---|
The file does not parse, or a record has no id or model | error on the mod; the record is left out |
The model file is missing, is not a .glb, or is over 20 MB | a problem on the mod naming the file and the reason; the record has no usable model |
| The glb uses a feature under File rules, or is over the triangle, texture or size-of-trophy limits | found when the trophy is first built for a match: reported then, as below |
| An event names a trophy nobody has | warning on the mod; the event falls back as below |
A trophy that was left out, or that still fails when the match builds its stage (a broken buffer, an image that does not decode), falls back: the game's own trophy for that event's name if there is one, else the pedestal is not drawn. The failure is logged once ([stage] the trophy ... did not load: reason) and added to the mod's issues on the Mods screen, so it is seen without reading the log. The match goes on.
Not built yet#
- The trophy anywhere but the stage (the season review, the trophy cabinet, an event's page).