wearable standards

everything you need to know to rig and export an avatar or cosmetic for the portals shop. the same standard applies to both — there's one canonical rig and every wearable binds to it.

the canonical rig

every avatar and wearable in portals uses a single 90-bone mixamo skeleton: joints are prefixed mixamorig:, structured hierarchically from hips through head, and named identically across all rigs. the engine validates uploads against this exact set of bones at create time — if anything's missing the upload is rejected with a list of which bones to add.

canonical rig template

download the bare-skeleton glb to import into your DCC tool, then bind your mesh to it.

download new-rig.glb

bone reference

90 bones total, grouped by region

torso / spine · 8

Hips through Neck/Head. Every wearable must include these — they're the structural backbone every garment hangs off.

  • mixamorig:Hips
  • mixamorig:Spine
  • mixamorig:Spine1
  • mixamorig:Spine2
  • mixamorig:Neck
  • mixamorig:Head
  • mixamorig:HeadTop_End
  • mixamorig:LoweLipCenter
left arm · 3
  • mixamorig:Shoulder.L
  • mixamorig:Arm.L
  • mixamorig:ForeArm.L
right arm · 3
  • mixamorig:Shoulder.R
  • mixamorig:Arm.R
  • mixamorig:ForeArm.R
left hand (fingers) · 21

Four bones per finger (palm → tip) plus four for the thumb. Gloves and rings need these to deform naturally.

  • mixamorig:Hand.L
  • mixamorig:HandThumb1.L
  • mixamorig:HandThumb2.L
  • mixamorig:HandThumb3.L
  • mixamorig:HandThumb4.L
  • mixamorig:HandIndex1.L
  • mixamorig:HandIndex2.L
  • mixamorig:HandIndex3.L
  • mixamorig:HandIndex4.L
  • mixamorig:HandMiddle1.L
  • mixamorig:HandMiddle2.L
  • mixamorig:HandMiddle3.L
  • mixamorig:HandMiddle4.L
  • mixamorig:HandRing1.L
  • mixamorig:HandRing2.L
  • mixamorig:HandRing3.L
  • mixamorig:HandRing4.L
  • mixamorig:HandPinky1.L
  • mixamorig:HandPinky2.L
  • mixamorig:HandPinky3.L
  • mixamorig:HandPinky4.L
right hand (fingers) · 21
  • mixamorig:Hand.R
  • mixamorig:HandThumb1.R
  • mixamorig:HandThumb2.R
  • mixamorig:HandThumb3.R
  • mixamorig:HandThumb4.R
  • mixamorig:HandIndex1.R
  • mixamorig:HandIndex2.R
  • mixamorig:HandIndex3.R
  • mixamorig:HandIndex4.R
  • mixamorig:HandMiddle1.R
  • mixamorig:HandMiddle2.R
  • mixamorig:HandMiddle3.R
  • mixamorig:HandMiddle4.R
  • mixamorig:HandRing1.R
  • mixamorig:HandRing2.R
  • mixamorig:HandRing3.R
  • mixamorig:HandRing4.R
  • mixamorig:HandPinky1.R
  • mixamorig:HandPinky2.R
  • mixamorig:HandPinky3.R
  • mixamorig:HandPinky4.R
left leg · 5
  • mixamorig:UpLeg.L
  • mixamorig:Leg.L
  • mixamorig:Foot.L
  • mixamorig:ToeBase.L
  • mixamorig:Toe_End.L
right leg · 5
  • mixamorig:UpLeg.R
  • mixamorig:Leg.R
  • mixamorig:Foot.R
  • mixamorig:ToeBase.R
  • mixamorig:Toe_End.R
face · 24

Eyes, eyelids, eyebrows, jaw, lips, nose. Required even for non-face wearables so the avatar can animate facial expressions while wearing the item. The auto-migrator adds these bones if your DCC export missed them.

  • mixamorig:Eye.L
  • mixamorig:Eyelid01.L
  • mixamorig:Eyelid02.L
  • mixamorig:Eye.R
  • mixamorig:Eyelid01.R
  • mixamorig:Eyelid02.R
  • mixamorig:EyebrowMain.L
  • mixamorig:Eyebrow01.L
  • mixamorig:Eyebrow02.L
  • mixamorig:Eyebrow03.L
  • mixamorig:EyebrowMain.R
  • mixamorig:Eyebrow01.R
  • mixamorig:Eyebrow02.R
  • mixamorig:Eyebrow03.R
  • mixamorig:Jaw
  • mixamorig:LowerLip.L
  • mixamorig:LowerLip.R
  • mixamorig:UpperJaw
  • mixamorig:UpperLip.L
  • mixamorig:UpperLip.R
  • mixamorig:UpperLipCenter
  • mixamorig:MouthCorner.L
  • mixamorig:MouthCorner.R
  • mixamorig:NoseBone

animated wearables

back capes / wings / particle props

cosmetics in the back category with the animated flag play the first animation embedded in their GLB, on loop, for as long as they're worn — on the avatar page, in the lobby and in games on Portals avatar SDK 0.47 or later. the flag is also written into the stored URL as a query parameter, so every client that loads the GLB gets it:

<your-glb-url>?animatedWearable=true

you don't need to do anything manual — flip the animated toggle on a back-category item and the create / update endpoints append (or strip) the parameter automatically. if you change the item's category later, the parameter is rewritten to match.

keep the animated part self-contained: rig it to its own small skeleton (a fish on a bone called Bone is fine) and attach it rigidly under a portals rig bone, as described below. the animation only moves nodes inside the wearable, never the avatar. only the first clip in the file plays.

emotes

dances, waves and flourishes on the same rig

an emote is motion on this rig, played over whatever the avatar is doing and faded back to it — in the lobby, on the avatar page and in every game. export the armature on its own, no mesh, with a clip named Emote and, optionally, Emote_Enter and Emote_Exit. one file plays on both bodies; the upload form writes its mode and expression into the file for you.

  • file up to 5 MB · a loop up to 30 s, a one-shot up to 60 s · entry and exit up to 5 s each
  • only the hips may move, and only up and down — within 1.5 m of rest
  • up to 200,000 keyframes across every clip

reference emotes

a one-shot with a held smile, and a loop with an entry, an exit and a hips bob. both pass every upload rule.

every emote says where its motion comes from before review — made by me, my own motion capture, licensed — with the licensor and licence for licensed motion, and you agree to:

I own this emote's motion, and any prop and sound it carries, or hold a licence that lets me sell them on Portals as a standalone item. None of it is copied from a game, film, performance, recording, song or asset pack whose terms forbid that, and I'll provide the licence if Portals asks.

motion from game rips, films, other people's performances or asset packs that forbid reselling animations on their own can't be sold. read the full emote standard.

common upload errors

and how to fix them

not-a-glb · file isn't a valid GLB

exported a .gltf instead of .glb, or the file is corrupted in transit. re-export from your DCC with format GLB (binary) selected. don't rename .gltf → .glb; the binary header is different.

no-skin · no skin binding or rigid attachment

the GLB is attached to the portals rig in neither of the two accepted ways. every wearable ships the full rig template, and then either:

  • skinned — the mesh is weight-painted to the rig's bones and deforms with the avatar. use this for clothing.
  • rigid — no skin weights; every rendered mesh is parented under a rig bone (a hat under the head, a backpack under the spine) and follows it as a solid object. use this for props and accessories. a mesh with skin weights can't be attached rigidly.

import the rig template, attach your mesh one of those two ways, and re-export.

missing-bones · rig isn't the portals rig

some required bones are missing from the GLB's skeleton. the create endpoint returns the exact list of names you're missing — add them by binding to the canonical template rather than a custom skeleton.

the auto-migrator catches one specific case: an old-rig (65-bone) export that's missing only the 25 face bones. uploads matching that fingerprint are silently upgraded server-side. anything else is rejected so creators don't ship broken wearables.

too-large · GLB is over 50 MB

GLB uploads are capped at 50 MB, and the server rejects anything larger even if it reached storage. most of that size is usually textures — downscale or compress the largest ones and re-export.

parse-failed · couldn't read the GLB metadata

the JSON chunk of the GLB couldn't be decoded. usually a sign of a partial upload or a non-spec exporter. re-export from a recent version of blender (3.0+) or your tool of choice and try again.

blender quickstart

recommended export settings

  1. import new-rig.glb as the parent armature.
  2. model your wearable in rest pose. weight-paint to the bones you actually want to influence — you don't need to weight to every bone, only the ones that should deform your mesh.
  3. file → export → glTF 2.0 (.glb). under Include: enable selected objects + the armature. under Transform: leave +Y up. under Geometry: keep apply modifiers off so blend shapes / shape keys survive.
  4. upload the resulting .glb in the sell-in-shop flow. the server validates rig + auto- upgrades old-rig exports + writes back the canonical file at the same URL.