Files
animation/.humans/marvelous-designer.html
T
jeremy d1030def4e docs+tools: working-file policy, lane pruner, and a human MD explainer
Two pieces of work.

1. Keep milestones, not steps. Staged NN_*.py lanes were saving a full
   ~80 MB .blend per attempt, so Lena's lane reached 3.0 GB of which 2.2 GB
   was 30 .blend files -- five snapshots to land one crotch fix, five more
   for the bra. The .py recipes are the real history; the blends are cache.

   - .agents/rules/working-files.md: four-tier policy (KEEP / MASTER /
     SCRATCH / UNKNOWN) + how to work a lane.
   - tools/prune_lane.py: classifies a lane and prunes the scratch tier.
     Dry-run by default. Reads a per-lane .lanekeep manifest, flags
     binaries byte-identical to a registered original (canonical name
     always survives a duplicate pair), and never auto-deletes a .blend
     with no step script beside it -- those cannot be rebuilt.
   - .gitignore: scratch patterns can never be committed.

   Dry run on characters/female/lena_nude reports 2.3 GB reclaimable.
   Not applied -- that lane had a live Blender session at the time.

2. .humans/marvelous-designer.html: how we author garments in Marvelous
   Designer, written for people rather than agents -- the six-step process,
   what has been made, the traps that cost hours, and what is still
   unsolved. Matches the .humans/ HTML convention in ariki-game.

Also committing the docs the AGENTS.md knowledge map and the new page
reference, so they are not dangling: the clothing-lane architecture page,
the marvelous-designer skill, and the two screenshots the page embeds.

characters/ is deliberately untracked and stays that way -- it holds GBs of
blends and GLBs, and .gitattributes does not LFS-track .blend.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 12:05:46 -07:00

422 lines
19 KiB
HTML

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Ariki — How We Make Clothes in Marvelous Designer</title>
<style>
:root {
color-scheme: dark;
--ink: #f4efe6;
--muted: #a9a396;
--gold: #d9a66c;
--aqua: #72d5cb;
--rose: #e08585;
--line: rgba(255,255,255,.12);
--panel: rgba(18, 24, 27, .92);
}
* { box-sizing: border-box; }
body {
margin: 0;
padding: 2rem clamp(1rem, 4vw, 3rem) 5rem;
color: var(--ink);
background:
radial-gradient(circle at 90% 0%, rgba(67,139,132,.22), transparent 28rem),
#0b1113;
font-family: Inter, ui-sans-serif, system-ui, -apple-system, sans-serif;
line-height: 1.6;
}
.eyebrow {
color: var(--gold);
font: 700 .75rem/1 ui-monospace, Menlo, monospace;
letter-spacing: .14em;
text-transform: uppercase;
}
h1 {
margin: .4rem 0 1.2rem;
font-size: clamp(2rem, 5vw, 3.6rem);
letter-spacing: -.04em;
line-height: 1.05;
max-width: 20ch;
}
h2 {
margin: 3rem 0 .8rem;
font-size: 1.25rem;
color: var(--aqua);
letter-spacing: -.01em;
}
h3 { margin: 1.8rem 0 .5rem; font-size: 1rem; color: var(--gold); }
p { max-width: 60rem; margin: 0 0 1rem; }
p.lede { color: var(--muted); font-size: 1.1rem; max-width: 56rem; margin: 0 0 1.5rem; }
ul, ol { max-width: 60rem; padding-left: 1.2rem; }
li { margin: .35rem 0; }
a { color: var(--aqua); }
code {
font: .88em/1.4 ui-monospace, Menlo, monospace;
background: rgba(255,255,255,.07);
padding: .12em .4em;
border-radius: .3rem;
}
strong { color: #fff; }
.wrap {
overflow-x: auto;
border: 1px solid var(--line);
border-radius: 1rem;
background: var(--panel);
margin: 1rem 0 1.5rem;
}
table { width: 100%; border-collapse: collapse; min-width: 640px; font-size: .92rem; }
th, td { padding: .8rem 1rem; text-align: left; vertical-align: top; border-bottom: 1px solid var(--line); }
th {
color: var(--gold);
font: 700 .7rem/1.2 ui-monospace, Menlo, monospace;
letter-spacing: .08em;
text-transform: uppercase;
background: rgba(0,0,0,.25);
}
tr:last-child td { border-bottom: 0; }
.num { font: .9rem ui-monospace, Menlo, monospace; color: var(--aqua); white-space: nowrap; }
figure { margin: 1.5rem 0; }
figure img {
max-width: 100%;
height: auto;
border: 1px solid var(--line);
border-radius: 1rem;
display: block;
background: #111;
}
figcaption { color: var(--muted); font-size: .88rem; margin-top: .6rem; max-width: 52rem; }
.shots { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr)); gap: 1.5rem; }
.shots figure { margin: 0; }
.flow {
border: 1px solid var(--line);
border-radius: 1rem;
background: var(--panel);
padding: 1.2rem 1.4rem;
overflow-x: auto;
margin: 1rem 0 1.5rem;
}
.flow pre {
margin: 0;
font: .82rem/1.7 ui-monospace, Menlo, monospace;
color: var(--ink);
white-space: pre;
}
.callout {
border-left: 3px solid var(--gold);
background: rgba(217,166,108,.08);
padding: .9rem 1.2rem;
border-radius: 0 .6rem .6rem 0;
margin: 1.2rem 0;
max-width: 60rem;
}
.callout.warn { border-left-color: var(--rose); background: rgba(224,133,133,.09); }
.callout p:last-child { margin-bottom: 0; }
.meta { color: var(--muted); font-size: .85rem; border-top: 1px solid var(--line); margin-top: 3.5rem; padding-top: 1.2rem; }
hr { border: 0; border-top: 1px solid var(--line); margin: 3rem 0 0; }
</style>
</head>
<body>
<p class="eyebrow">Ariki · Clothing lane · For humans</p>
<h1>How we make clothes in Marvelous Designer</h1>
<p class="lede">
We build Ariki's garments as <strong>real sewn cloth</strong> — flat pattern pieces, stitched
along seams, dropped onto Lena's actual game body and simulated until they hang. Nothing is
sculpted by hand. This page explains what we've made, how the process runs, and the things
that took us a long time to learn.
</p>
<figure>
<img src="../tools/tailor/screenshots/lena_kapahaka_outfit_v3.png"
alt="Lena in a red, black and white tāniko bodice with a flax-coloured piupiu skirt, arms out in T-pose.">
<figcaption>
The kapa haka outfit, v3 — a tāniko-patterned pari (bodice) over a piupiu (flax skirt), draped
on the game body inside Marvelous Designer. Both the tāniko diamonds and the flax strand
banding are textures we generated from reference photos, not painted by hand.
</figcaption>
</figure>
<h2>The short version</h2>
<p>
Clothing runs on a two-stage lane. Marvelous Designer is the <strong>upstream</strong> half — it
answers "what is this garment, and what shape is it on <em>our</em> body?" A headless Blender
pipeline is the <strong>downstream</strong> half — it answers "how does the game wear it?"
They meet at a garment mesh.
</p>
<div class="flow"><pre>reference photo ──▶ [ MARVELOUS DESIGNER ] ──▶ garment mesh (FBX/OBJ)
or concept draft · drape · texture 1.2k4.7k verts, already fitted
measure · screenshot + .zprj editable source
[ clothing/garment_pipeline.py — headless Blender ]
census · prepare · fit · reduce · skin · export
ariki-game/assets/quaternius/outfits/&lt;set&gt;/
per-slot GLB on the shared 65-bone skeleton</pre></div>
<p>
The upstream half needs a human to start each session. The downstream half is fully automatic.
</p>
<figure>
<img src="../clothing/kapahaka_ingame_dance_2026-07-31.png"
alt="The same tāniko bodice and piupiu skirt on an animated character in the game's clothing test bed.">
<figcaption>
The same two garments after the downstream half, worn in-game in the Clothing Test Bed and
playing an animation. Note the piupiu clipping through the left thigh — that is the kind of
defect the downstream <code>fit</code> stage's clearance shell exists to prevent, and it is
why we review in the test bed rather than trusting the MD render.
</figcaption>
</figure>
<h2>How a garment actually gets made</h2>
<p>Six steps. Every one of them produces numbers that the next one is checked against.</p>
<h3>1 · Take the reference apart</h3>
<p>
Before drafting anything, the reference image is deconstructed into a worksheet: which body slot
each piece belongs to, where it's anchored, where its edges should sit in metres, and how much
ease (slack) it needs. Every downstream number traces back to a row of that worksheet. Skipping
this step is how early garments shipped <strong>414 cm off target</strong>.
</p>
<h3>2 · Draft from Lena's measurements, not a size chart</h3>
<p>
Lena is stylized. Her card reads roughly <span class="num">108 67 109 cm</span> with
<span class="num">72 cm</span> thighs on a <span class="num">178 cm</span> frame. Real-world
size charts produce clothes that simply do not fit her. The measurements are extracted straight
off the game mesh by a script that slices it at known heights
(<code>tools/tailor/measure_body.py</code>), so they describe the body the game actually renders.
</p>
<h3>3 · Build from blocks, not freehand</h3>
<p>
We have parametric <em>blocks</em> — a fitted top, an A-line skirt, a strand/fringe skirt — that
turn worksheet numbers into a runnable pattern. You give it the band height, hem height and ease;
it emits the panel outlines, the seam pairing and the arrangement rules with the known fixes
already baked in. Hand-typing point lists is how the early mistakes happened.
</p>
<h3>4 · Drape it on the body</h3>
<p>
The flat panels get arrangement points on the avatar (shoulders, waist, skirt front/back), then
the cloth simulates onto her. The sequence matters more than the settings:
</p>
<ul>
<li><strong>Stiffen the fabric for the whole settle, relax only at the end.</strong> Soft cloth
from frame zero rolls into a bunch at the waist.</li>
<li><strong>Apply waist elastic mid-settle, never from the start.</strong> Elastic applied before
the cloth has wrapped cinches the garment off one hip.</li>
<li><strong>Bottoms stay up by tension, not elastic</strong> — cut the waist smaller than the hips
and let the fabric stretch hold it.</li>
<li><strong>One garment per scene.</strong> A second garment, even frozen, grabs and inverts the
new one. Outfits are assembled at the very end from finished pieces.</li>
</ul>
<h3>5 · Judge the fit by numbers, not by eye</h3>
<div class="callout">
<p>
This is the step that was missing at the start, and it matters most. Early drapes were accepted
because they <em>looked like clothing</em>. They were bunched around the middle.
</p>
</div>
<p>
Now every drape is measured. A script (<code>qc_placement.py</code>) reads the render, separates
background from skin from garment, calibrates pixels-to-metres off Lena's known 1.777 m height,
and reports where each garment band's top and bottom actually sit — against a target table pulled
from the reference photo. For the kapa haka outfit that table was: pari top at
<span class="num">1.31 m ±3 cm</span> (above the bust), pari hem and piupiu waist at
<span class="num">1.05 m ±3 cm</span>, piupiu hem at <span class="num">0.45 m ±4 cm</span>
(below the knee). We iterate until it's inside tolerance.
</p>
<p>
Every shipped garment also gets a screenshot committed to
<code>tools/tailor/screenshots/</code>, front <em>and</em> back. That's how the work gets reviewed
without anyone opening Marvelous Designer.
</p>
<h3>6 · Export four ways</h3>
<div class="wrap">
<table>
<thead><tr><th>File</th><th>Why we keep it</th></tr></thead>
<tbody>
<tr><td><code>.zprj</code></td><td>The editable source of truth. Opens in MD normally. Regenerating a variant from this always beats re-authoring.</td></tr>
<tr><td><code>.fbx</code></td><td>What the downstream Blender pipeline consumes.</td></tr>
<tr><td><code>.obj</code></td><td>Plain-text backup, and the only reliable way to measure the mesh (see below).</td></tr>
<tr><td><code>.zpac</code></td><td>For assembling multi-piece outfits later.</td></tr>
</tbody>
</table>
</div>
<h2>The unusual part: we drive MD with code</h2>
<p>
Marvelous Designer has an embedded Python API. We wrote a small plugin that opens a socket inside
MD (<code>TinqsMDBridge</code>), so a script on the outside can send it commands — create these
panels, sew this edge to that one, simulate 250 frames, render the viewport to a PNG.
</p>
<p>
<strong>The whole method is a vision loop</strong>: draft, drape, render, look at the image,
measure it, adjust, repeat. That's what makes it possible to iterate a garment dozens of times in
an afternoon.
</p>
<div class="callout warn">
<p>
<strong>Two things to know if you're sitting at the machine.</strong> MD's embedded Python
can't run in the background, so the bridge takes over the main thread: <strong>a human has to
click Plugin → TinqsMDBridge to start a session</strong>, and <strong>MD's window freezes for
the whole session</strong> — "Not Responding" is normal, not a crash. Ending the session with
<code>python tools/md_bridge.py --stop</code> gives the UI straight back. If you want to look at
the model yourself, we stop the session first.
</p>
</div>
<p>
None of this locks the work up. The <code>.zprj</code> files are ordinary MD projects — open them,
edit patterns, re-drape, re-export by hand any time. The bridge is just how the automation drives
the same buttons.
</p>
<h2>What we've made so far</h2>
<p>
Authored on and after 2026-07-30. Vertex counts are the exported garment mesh.
</p>
<div class="wrap">
<table>
<thead><tr><th>Garment</th><th>What it is</th><th>Versions</th><th class="num">Verts</th></tr></thead>
<tbody>
<tr><td>Tee</td><td>First test — fitted top block</td><td>v1</td><td class="num">2,335</td></tr>
<tr><td>Skirt</td><td>First test — A-line block, the most forgiving garment</td><td>v1</td><td class="num">1,988</td></tr>
<tr><td>Pari</td><td>Kapa haka bodice, tāniko pattern</td><td>v1 → v4</td><td class="num">1,406</td></tr>
<tr><td>Piupiu</td><td>Kapa haka flax skirt, strand block</td><td>v1 → v3</td><td class="num">3,022</td></tr>
<tr><td>Cape</td><td>Shoulder garment</td><td>v1, v2</td><td class="num">4,664</td></tr>
<tr><td>Kapa haka outfit</td><td>Pari + piupiu assembled together</td><td>v1 → v3</td><td class="num"></td></tr>
</tbody>
</table>
</div>
<div class="callout">
<p>
<strong>Our own garments are far cheaper than downloaded ones.</strong> These export at
<span class="num">1.2k4.7k</span> verts. The downloaded MD dress the clothing pipeline was
first piloted on was <span class="num">2.49 million</span> verts / 110 MB. So the brutal
<em>reduce</em> stage downstream is mostly unnecessary for our work — and because they were
draped on the real game body, they arrive already fitted.
</p>
</div>
<h2>Textiles do more work than tailoring</h2>
<p>
For traditional wear, garment identity lives in the <strong>pattern</strong>, not the cut. Kapa
haka, Mexica and Pacific garments are largely rectangles and simple blocks. So we model the shape
simply and spend the effort on the cloth: <code>taniko.png</code> (concentric woven diamonds) and
<code>piupiu.png</code> (flax strands with geometric banding) are both generated procedurally from
reference photos, and both are reusable.
</p>
<p>
One non-obvious control: in MD, <strong>a PNG's DPI sets its physical size on the cloth</strong>.
1024 px at 54.2 dpi is 480 mm of fabric. You tile a motif by changing the DPI, not by scaling the
image.
</p>
<h2>Things that cost us hours</h2>
<div class="wrap">
<table>
<thead><tr><th>What happens</th><th>Why</th></tr></thead>
<tbody>
<tr>
<td>The garment drapes <strong>upside-down over her head</strong> and tangles</td>
<td>In MD's 2D pattern window, <strong>y+ is UP in 3D</strong>. Panels drafted y-down come out inverted. It looks exactly like a seam bug and isn't — seven iterations were lost to this once.</td>
</tr>
<tr>
<td>A strapless top <strong>slides down to the underbust</strong></td>
<td>Cloth falls to the narrowest catch. MD doesn't simulate <em>putting a garment on</em> — it materialises the cloth where you arranged it. Add straps; it fixes placement and coverage at once.</td>
</tr>
<tr>
<td>The garment <strong>slides off the shoulders</strong> or twists partly inside out</td>
<td>Seam pairing. Panels drafted as identical copies offset sideways are <em>not</em> mirrored, and need the opposite flip setting from mirrored ones.</td>
</tr>
<tr>
<td>Everything in the scene <strong>changes colour at once</strong></td>
<td>Fabric slot 0 is the shared default. Colouring it dyes every garment. Always add a new fabric.</td>
</tr>
<tr>
<td>A defect ships because <strong>nobody saw the back</strong></td>
<td>MD's snapshot camera has no rear view at all — bottom, front, ¾, sides, top, and that's it. Four separate defects shipped through this blind spot before we started using turntable renders for the back.</td>
</tr>
<tr>
<td>A busy texture <strong>hides folds and inside-out panels</strong></td>
<td>Judge shape with the texture off: cloth renders white on its front face and grey on its back, so a grey patch seen from outside is inside out and a white streak is a fold.</td>
</tr>
</tbody>
</table>
</div>
<div class="callout">
<p>
<strong>The one diagnostic that unsticks everything:</strong> render the scene right after
arranging the panels but with <em>zero</em> simulation frames. That shows where the cloth
actually starts, before physics muddies the picture. Reach for it the moment a drape
misbehaves.
</p>
</div>
<h2>What doesn't work yet</h2>
<ul>
<li>
<strong>Trousers and shorts are unsolved.</strong> Two-panel construction with a crotch notch
twists every time — fabric can't thread between Lena's touching thighs, and every seam
configuration has been tried. The next idea is four panels arranged on the per-leg points, so
the cloth starts already wrapped around each thigh.
</li>
<li>
<strong>The placement measurement is honest but crude.</strong> It counts the body's baked-in
underwear and the floor shadow as garment. Fine for band positions; needs per-garment colour
masks when precision matters.
</li>
<li>
<strong>MD's AI Image Generator and EveryWear are GUI-only</strong> — they can't be scripted, so
they're outside this workflow entirely.
</li>
</ul>
<h2>Where everything lives</h2>
<div class="wrap">
<table>
<thead><tr><th>Path</th><th>What's there</th></tr></thead>
<tbody>
<tr><td><code>tools/tailor/</code></td><td>The garment workshop: per-garment recipes, the parametric blocks, Lena's measurement card, QC scripts, generated textures, and every shipped <code>.zprj</code>/<code>.fbx</code>/<code>.obj</code></td></tr>
<tr><td><code>tools/tailor/screenshots/</code></td><td>The review renders — start here to see what exists</td></tr>
<tr><td><code>tools/md_bridge.py</code> + <code>tools/md_bridge/</code></td><td>The socket bridge into MD, and a dump of MD's real API surface (688 functions, introspected — the published docs are thin and several signatures in them are wrong)</td></tr>
<tr><td><code>clothing/</code></td><td>The downstream half: garment mesh → game-ready skinned GLB</td></tr>
<tr><td><code>.claude/skills/marvelous-designer/</code></td><td>The full operating playbook, written for whoever (or whatever) is driving</td></tr>
<tr><td><code>.agents/wiki/architecture/clothing-lane.md</code></td><td>How the two halves fit together</td></tr>
</tbody>
</table>
</div>
<hr>
<p class="meta">
Animation repo · <code>.humans/marvelous-designer.html</code> · written 2026-08-06.<br>
Everything here was learned by doing it, and verified against Marvelous Designer 2026 Personal on
the PC. If a detail here disagrees with the playbook in
<code>.claude/skills/marvelous-designer/</code>, the playbook is the source of truth — this page
is the explanation, not the spec.
</p>
</body>
</html>