Models
This page says what a 3D model must be to draw correctly in a game, and where to get one. The rules are the same whichever tool made the model, so your agent can check a model before it adds it.
Every model passes through the bake. Before dev and build, and whenever the dev server sees a model file appear or change, the bake measures each GLB file in the game’s public/assets/ folder. When a model is too large or too small to be in metres, draws more triangles than the budget, or is flat, the bake prints a warning that names the file, what the bake measured, and the rule. The studio MCP’s start_playtest bakes too, and lists each warning in its reply. A warning never stops the game from building. A warning looks like this:
public/assets/red-panda.glb is 467.7 m on its longest side, so it is probably in centimetres. A model is in metres: scale this one by 0.01.The bake checks only those rules, so you and your agent check the rest. spawnite model check <files...> reads model files, in a game or not, and prints each one’s triangles, its size in metres, its clips with their lengths, its bones and the bake’s warnings. It then renders one sheet of them in the headless Chromium the playtests use, each one unit tall: the front, three-quarter, right and back views by default, so your agent can see which way each model faces and how the models compare. --angle names each view instead, and --clip walk --at 0.5 adds a row with each rigged model half a second into its walk. The studio’s check_model tool does the same in one call and returns the sheet as an image:
$ spawnite model check public/assets/visor-bot.glbpublic/assets/visor-bot.glb: 2,460 triangles, 0.79 x 1.12 x 0.47 m.Clips: idle 2.33 s, jump 1.54 s, run 0.67 s, walk 1.04 s.Bones: Hips, LeftUpLeg, LeftLeg, LeftFoot, LeftToeBase, RightUpLeg, RightLeg, RightFoot, RightToeBase, Spine02, Spine01, Spine, LeftShoulder, LeftArm, LeftForeArm, LeftHand, neck, Head, head_end, headfront, RightShoulder, RightArm, RightForeArm, RightHand.It breaks none of the rules the check reads: metres, height and the triangle budget.Sheet of front, three-quarter, right, back by 1 row, in shaded, one unit tall: /tmp/spawnite/check-model-RDR6pl/visor-bot.pngThe bake stops with an error on a file it cannot measure, and dev and build stop with it. It stops on any of the following:
- A file that is not a readable GLB.
- A file with no scene.
- Two files with the same name, in any folders.
What a model must be
Section titled “What a model must be”A model meets the following rules:
- One GLB file. Put one model in each
.glbfile, with its textures inside it. - Height, for a model that stands. The engine fits a walker’s capsule to a model’s height. A flat model, such as a rug or a decal plane, has none, so the bake warns about it and gives it the least capsule, 2 cm tall with a 1 cm radius, as Roblox clamps a flat part to a least size.
- Metres. One unit in the file is one metre in the game. The bake warns about a model whose longest side measures 100 m or more, because that model is probably in centimetres: scale it by 0.01 before you export it. It warns about one whose longest side measures under 2 cm too, because that model is probably 100 times too small: scale it by 100. A rigged model measures where its bones draw it, as glTF says, whatever scale its mesh’s node holds.
- Up is +Y, and the front faces +Z. This is glTF’s own convention. Blender’s glTF exporter writes +Y up by default, and a model that faces −Y in Blender, toward its Front view, faces +Z in the file. A VRM 0.x avatar faces the other way, and the engine turns it for you.
- The origin sits in the middle of the footprint, at any height. The engine stands a model on its lowest point, so the height of the origin does not matter. Across the ground, the origin is where the model stands and the point it turns about.
- Each animation clip is named for what it does. Name clips such as
walk,idleorattack, because a game plays a clip by its name. - A budget of 100,000 triangles. This budget keeps a model drawing well on a phone. The bake counts every triangle the file draws, so a mesh that two nodes draw, or one node draws as instances, counts each time it draws. A detailed character fits: the platform’s two avatars draw 74,241 and 80,633 triangles. A prop that a game places many times should draw far fewer: the asset library’s rocks and trees draw 500 to 4,000. The build warns past the budget and builds the game anyway.
Compress a heavy model’s geometry with Draco, such as a generated or scanned model. The engine decodes Draco in every model, as Entity says, and a game with any Draco model fetches three’s decoder once: 75 KB, gzipped as a player downloads it. Draco pays once the geometry it saves outweighs the decoder. It shrinks a rigged imp of 3,512 triangles from 53 KB to 23 KB gzipped, so a game saves bytes once its Draco models draw about 9,000 triangles between them.
Get a model
Section titled “Get a model”Each of the following places gives you a GLB file for the game’s public/assets/ folder:
- The asset library.
spawnite add asset <id>copies a model from the platform’s library into the game and registers it, and Assets lists what the library holds. The library’s duck and red panda are in centimetres today, and the bake warns about each one. - Blender, driven by Claude. Claude writes a script that builds the model in Blender and exports the GLB. Blender says how to install it and what Claude does with it.
- Any other tool. Meshy, Tripo and Sketchfab are three. Check each model’s license before you put it in a game: the license has to let you publish the model in your game. Then check the file with
spawnite model check, and add it.
Check a model against its concept
Section titled “Check a model against its concept”A model your agent builds starts from a concept: a picture of what it should look like. spawnite model check lays the concept over the model and prints how far apart they are, so your agent fixes the model from numbers and looks at the sheet only to confirm.
The concept needs the following, because the check lays it over an orthographic view:
- A view the sheet renders. A front view, or a turnaround: front, side and back standing side by side. A three-quarter drawing in perspective does not lay over any view.
- A plain or transparent background. The check takes the figure as everything a fill from the image’s edge does not reach, so a light figure on a light background still cuts whole.
- The model’s pose. A concept in a T-pose against a model in an A-pose compares two poses, and the check says so.
Name each view the concept shows, left to right:
spawnite model check public/assets/visor-bot.glb --reference front=models/visor-bot-concept.png --style silhouette,outlinespawnite model check public/assets/explorer.glb --reference front,right,back=models/explorer-concept.pngWithout --angle, the sheet renders the concept’s views. The concept’s figure is scaled to the model’s height, with its feet on the model’s feet, and drawn in red over the rest pose’s tile. For each view, the check prints the following:
- The overlap: the two silhouettes’ intersection over their union, 1 where they match.
- The widths at ten heights: each silhouette’s runs across, left to right, so the body and the arms beside it read apart.
- The landmarks: the heights of the crotch, the shoulders and the neck on each silhouette, and how far apart they stand, in centimetres of the model.
- The three heights where the body sits furthest from the concept, in centimetres of the model.
The visor bot, against its front-view concept in a T-pose, scores an overlap of 0.59 and prints these lines:
visor-bot.glb from front, at rest, against robot-concept.png: overlap 0.59, the intersection over the union of the two silhouettes, with the concept scaled to the model's height, its feet on the model's and centred. Landmarks, from the feet: crotch 0.32h, concept 0.34h (3 cm lower); shoulders 0.61h, concept 0.61h; neck 0.62h, concept 0.65h (3 cm lower). The body sits furthest from the concept at 0.85h (11 cm wider), 0.65h (9 cm wider), 0.75h (9 cm wider). The arms stand apart from the body at other heights than the concept's, so the outer widths compare two poses, not two builds: read the body column, or draw the concept in the model's rest pose.A concept whose height an antenna, a hat or a raised weapon sets scales its figure too small, so every width reads wrong. --fit also fits the figure by the scale and the offset that overlap the model best. The check prints the fit, then reads the widths, the landmarks and the red outline from the fitted figure.
--style draws a band of the sheet for each question:
silhouettefor proportions.outlinefor the outer edge and the creases, with the hidden lines removed.wireframefor the topology.verticesfor the points that no face in front hides.shaded, the default, for the look.
With --clip jump, the check also steps through the whole clip, 30 times a second, and names each forearm, hand, shin or foot that passes more than 1 cm into the head or the torso, with the seconds and the depth. --at 1.47 adds a row of the sheet at that moment, so your agent sees it.
Your agent works in a loop: edit the model, run one check, and fix the height or the limb the numbers name. When the game keeps the concept beside the model’s script as models/<name>-concept.png, spawnite model make and the studio’s make_model name that check after each build. The check reads .glb files: to check a scene saved in Blender, export it first with File › Export › glTF 2.0.
Turn a Meshy character into an avatar
Section titled “Turn a Meshy character into an avatar”A character rigged by Meshy plays only the clips Meshy made for it. To make it a <CharacterSpawn> avatar that plays every VRMA clip, such as the characters’ run and jump, convert it:
$ spawnite model avatar .work/rigged.glb --output packages/assets/avatars/village-guard.vrmWrote packages/assets/avatars/village-guard.vrm: a VRM 1.0 avatar in a T-pose with 22 humanoid bones, 1424 KB. The forearms turned 96° on the left and 98° on the right to rest the palms down. Compress it and check it as the Models page says.The command maps Meshy’s bone names onto the VRM humanoid, stands the skeleton in a T-pose facing +Z and binds the mesh in it, and bakes Meshy’s centimetre armature into metres. It leaves Meshy’s clips out. A rig with bone names other than Meshy’s, such as Mixamo’s, is refused with the names it lacks.
To play one of Meshy’s clips on every avatar, write it as a VRMA:
$ spawnite model clip packages/assets/models/depthfield/soldier.glb --clip shoot --folder packages/assets/animationsWrote packages/assets/animations/soldier-shoot.vrma: shoot, 3.30 s.Without --clip, it writes every clip, each as <model>-<clip>.vrma. spawnite model check on a .vrma prints the clip’s motion in numbers: its length, where the arms peak, the hips’ drop and travel, and each humanoid bone’s largest turn and when it peaks, so an agent picks a clip from the table and starts its release mark from the arms’ peak, which spawnite play timeline settles frame by frame. Both commands take the skeleton through the same T-pose, so a clip bought on one character plays on another as it plays on its own. Unity’s Humanoid import takes the same step with Enforce T-Pose, and Godot maps bones to its humanoid profile at import. The T-pose swings each limb to point along its axis, and turns each forearm and hand about the arm until the palm faces down, as VRM’s T-pose holds it; the forearm takes half the turn and the hand the rest. Meshy’s rig has no finger bones, so the command finds the palm from the hand’s mesh: the thumb side is where the hand’s half nearer the wrist leans. Every other bone keeps its twist as rigged, and the feet keep their aim. When a hand turns out palm-up, the degrees the command prints say how far it turned.
Compress the avatar with packages/assets/scripts/compress.mjs, which keeps the VRM’s extensions, and check it with spawnite model check. Animations walks a clip from the file to a confirmed mark on your character.