Repository navigation
Guide Fit Lab Workflow
Goal: take one equipment slot from "the part floats or pokes through" to "every item of the slot sits right in every animation and facing, and the Blender render agrees". You finish with saved adjustments that every later build uses.
Reference for each control: Fit Lab. The same lab drives the Blender render guide.

The facing ring and the 1 view / 2×2 switch in these screenshots come from PR #19 (pending merge). Everything else applies to
maintoday.
-
Installation done: the Python environment,
SPRITEMOTION_UO_SOURCE, UO_Model3D v13 installed withpipeline.py setup, and Blender reachable (SPRITEMOTION_BLENDERif it isn't found by itself). - A pack export for the lab. The bundled CC0 starter needs nothing else. A private pack needs its mapping and an export (see Asset Packs).
launchers\editor\workbench.bat cc0-starterThat starts Content Studio (8772) and Fit Lab (8774) and prepares the starter export the first time (Blender runs once). For a private pack:
python <sidecar>/tools/<pack>/lab_items.py --per-slot 4 # the pack's item list, in your sidecar
python tools/fit-lab/run.py export --pack <pack> # Blender: body.glb, items/*.glb, manifest.json
launchers\editor\fit-lab.bat <pack> # or: python tools/fit-lab/run.py serve --pack <pack>Open http://127.0.0.1:8774. Exports are reused; add --force to export after the pack mapping changes.
Choose the slot on the left. All items of the slot are listed; tick the ones to show and click one to select it. The selected item is the one This item only and the Render tab act on; Slot fit applies to all of them.
Switch the 3D pane to 2×2: the orbit view plus fixed Front, Side and Back views that turn with the character. Press Play, then step the facing ring: each number sits where the character faces on screen (0 faces you, then 45° clockwise per step), and the arrow keys turn one step.

On the Fit tab:
| Problem | Control |
|---|---|
| Part floats off or sinks into the body | Offset X/Y/Z (cm) |
| Part tilted | Rotate X/Y/Z (degrees) |
| Too big or small everywhere | Scale |
| Torso shell too thick front to back, but the width is right | Front/back depth (not Scale) |
| Metal stretches with the bones | Binding: rigid (follows one bone) |
| One item of the slot is off, the others are fine | This item only X/Y/Z |
| Gloves or boots: one side is off | Left / Right X/Y/Z (the character's left and right) |
A slider drag is one undo step. Saves happen 800 ms after you stop (Saved to disk, green dot).
In Hide body under this slot, keep it on for garments. Outward and Inward set how close a body face must be to the item to be hidden. Turn on Hidden faces to see them in red, from all four sides in 2×2.

Hiding too much shows gaps where the body should be visible (wrists, neck); hiding too little lets the body poke through and cut holes in the item sprite.
On the Measure tab, tick the animations to check and click Measure slot. It counts body pixels that show through each item over every frame in 5 directions. The first run is the baseline; later runs show the change (green is better). Turn on Poke pixels under the slot previews to see them in magenta.

Compare counts between runs; don't read them as absolutes (the renderer's holdout margin and push-out aren't modelled, so they run high).
When one animation or facing is off and the rest are fine, don't move the slot fit. Use the Corrections tab: Apply to this item, the slot, a named group or the pack; When all poses, this animation, this direction, or both. Corrections add to the slot fit (offsets and angles add, scales multiply). Directions 5–7 share corrections with 3–1.

In the Blender render pane click Render animation. Blender renders the current animation in the background while you keep working; the pane then follows the main frame and facing. Sprite sheet shows every frame of the 5 stored directions; click one to jump the lab to that pose.
![]()
The status reads Matches the saved fit or Fit changed since this render. Turn on Auto re-render to re-render once the fit has been still for 3 seconds.
-
lab-adjustments.jsonfor the pack (in your sidecar for private packs), validated byschemas/fit-adjustments.schema.json, with the previous three saves inlab-adjustments-backups/. - A lab render per animation you checked, shown as Matches the saved fit.
- Lower poke counts than the baseline on the Measure tab.
Next: render the whole item with the Blender render guide.
- Fixing one pose with the slot fit. It moves every pose. Use a correction scoped to that animation or facing.
- Raising Scale to cover a thick torso. It widens the shoulders too. Use Front/back depth.
- Trusting the live preview over the render. Previews are approximate; the Blender render is the final word.
- Reading left/right as screen sides. Left/right offsets are the character's sides, and mirrored facings (5–7) mirror the result.
- Two tabs or tools editing the same pack. Saving pauses and asks Use disk version or Keep my recovered edits; pick deliberately, the other version is backed up first.
-
Expecting a mapping change to show up. After changing a pack mapping, export again with
--force.
SpriteMotion is MIT licensed · Repository · License · Third-party notices
Not affiliated with or endorsed by Electronic Arts or Broadsword. Ultima Online is a trademark of its owners. No game data is distributed with this project.
Start
Guides
- Fit a slot in Fit Lab
- Render an item end to end
- Clean up with masking
- Troubleshoot a failing step
- Take content into GUO
Tools
Reference
Project