Character workshop tuning
The character workshop lists every clip the loaded character publishes, plus the bind
pose, and lets you tune how each held item sits in the hand and how each clip is posed.
The panels are src/review/character-motion-panel.ts and
src/review/character-tuning-panel.ts; the tuning schema and its validation are in
src/animation/character-tuning.ts.
Choose a motion and an item
Section titled “Choose a motion and an item”The Motion section has:
- Equipped weapon: every held item the character’s manifest fits to the hand. For the Grey that is the iron sword, steel blade, war axe, hunter’s bow, iron spear, walking cane, iron dagger, and a torch for either hand.
- A search box and a category filter (all clips, equipped weapon, movement, standing idles, emotes, sitting and sleeping, air and water, weapons, punches and kicks, reactions). Choosing a weapon switches the filter to that weapon’s actions.
- Previous and Next, a timeline scrubber, Repeat clip, a pause button and a playback speed slider. The info line shows the clip count, the clip’s duration and, for Meshy clips, the Meshy action id.
Tune in the Animation & grip tuning panel
Section titled “Tune in the Animation & grip tuning panel”Pick what to edit with Edit:
- Weapon default · all animations: grip-local position X/Y/Z in centimetres (-100 to 100), rotation in degrees (-180 to 180) and per-axis scale (0.2 to 3). It applies to every clip for that item.
- Weapon + current animation: a second grip adjustment for this item and this clip only, applied after the weapon default. Other items and clips keep theirs.
- Current animation pose: for clips with a recorded source, a playback rate (0.25 to 2), an animation Y offset in centimetres, per-foot footprint contact offsets and toe angle, and a constant local rotation (-90 to 90 degrees per axis) for the pelvis, torso, neck, head, and each side’s upper arm, forearm, wrist, thigh, knee and foot. These are whole-clip offsets, not a keyframe editor.
Also in the panel:
- Model ground offset (cm) raises or lowers the whole model for every clip, with its own reset.
- Show grip axes draws red X, green Y and blue Z at the final grip transform.
- Reset this adjustment restores the published default for the selected scope.
- Export JSON, Import JSON and Copyable settings round-trip the
CharacterTuningprofile (planets-character-tuning.json). A rejected import leaves the current tuning in place.
Every edit is saved at once as a browser tuning draft, keyed by rig family, body and revision, and separate from the player’s appearance save. The draft is restored over the published defaults on the next workshop load. Export before clearing browser data.
The profile records the body binding and the source checksum of every weapon and clip it adjusts; a profile that names a stale source or holds an out-of-range transform is rejected. The workshop, the character creator and the game player all apply published tuning through the same runtime. Grips are placed relative to the morphed hand’s grip pivot, so a tuned weapon follows body proportion changes.
Publish tuning
Section titled “Publish tuning”The tracked default tuning for the Grey is assets/character/grey-character-tuning.json
(weapon-wide grip defaults for all nine held items, one per-clip grip adjustment for
the hunter’s bow in bow-shot, and no pose overrides).
Prepared source grip placement is in assets/character/grey-held-items.json.
To publish a tuning export without touching any approved mesh, texture or animation:
node scripts/publish-character-tuning.mjs --tuning=path/to/planets-character-tuning.jsonThe script accepts either a CharacterTuning file or a full workshop export (it takes
settings.tuning from the latter). It validates the profile against the current
publication in .gear-work/meshy-grey (override with --source=), samples every body
preset with every held item through idle, walk and that item’s actions, and writes a
private candidate to .gear-work/character-tuning-candidate (override with --out=).
After reviewing the candidate, run the command again with
--source=.gear-work/character-tuning-candidate --out=.gear-work/meshy-grey to advance
the live publication. Earlier publications are kept, and saved characters stay pinned
to the publication they were created with; test tuning changes with a new character or
a fresh browser profile.
Then pack and publish the runtime files for production:
npm run assets:character-runtimenpm run assets:character-publishRelated commands:
npm run assets:character-actions(scripts/import-character-actions.mjs) turns cached Meshy action downloads into an animation-only candidate. It makes no provider call; acquisition is the separate, budgetedmeshy:recipecommand.npm run assets:character-weapons(scripts/build-character-weapons.mjs) fits the held items to the body and validates a private candidate in.gear-work/character-weapons-candidate. It takes--tuning=,--source=and--out=.npm run assets:characterruns the full production chain and replaces the publication only after every stage passes.
Every animated clip that ships must have a recorded source. npm run build runs
scripts/check-animation-provenance.mjs, which fails on any Mixamo animation data and
on any runtime clip that does not resolve to a recorded Meshy source, a retarget of
one, or an entry in assets/character/character-clip-provenance.json.
Verification
Section titled “Verification”npm run test:character-weaponsnpm run test:character-walk-clearancenpm run test:character-animationnode scripts/verify-character-workshop-tuning.mjsnode scripts/verify-character-weapon-tuning-gpu.mjsThe first three are CPU checks. The two browser scripts expect a dev server on
127.0.0.1:5187. verify-character-weapon-tuning-gpu.mjs checks the production WebGPU
path against .gear-work/character-weapons-candidate by default; pass --published
and --manifest=/.gear-work/character-tuning-candidate/manifest.json to test real
published tuning instead of synthetic transforms. Reports go to
.gear-work/character-validation/weapons/.
Written by release:site-sync from docs/character-workshop-tuning.md at v2026.10.04. Edit the engine document, not this page.