Claude Code skill· three.js · native HTML· byte-identical across runs· zero assets

One file. One function f(t). Frame-exact.

Ask for a film and it writes an animated three.js scene as native HTML — one file, opens in any browser. Not a video: no player, no build step, and the geometry is drawn live on every frame.

There is no input format — whatever your agent can already read is enough: a repo, a spec, a paper, a screenshot, a stack trace. mitate (見立て) is to see one thing as another: a codebase as a machine, a document as a scene.

GEARBOX.scene 16.50s · 5 beats · seamless loop · backend WebGPU→WebGL2
00000 / 00495
t0.000s
fps30.00
beat1 / 5
styleworkshop
determinismpass
t = 0.000sthe film's five beats, as written · a pure function of t — drag it16.500s
1 · title2 · input3 · mesh4 · output5 · ratio
01 · deterministic

A film is a pure function of t — and t is a position, not a clock.

An address you evaluate, not a cursor you advance: nothing ever asks what time it is, only what the scene looks like at this address. No simulation state, no wall clock, no random() at runtime. seekTo(8) after seekTo(2) equals seekTo(8) cold. One scene file is both the live HTML and the source of a frame-exact render — and the recorder can shoot frames out of order, because there is no order to be in. Why determinism comes first, and what it is first for, is one page.

02 · agent-directed

Primitives, not a script.

An agent is handed the building blocks — geometry, materials, a cinematography solver, a character scaffold — and composes them. Nothing about a character or a shot is hardcoded; each is a point in a parameter space.

03 · any register

Any context in, any output out.

Give it whatever you have, ask for whatever you want — it can probably make it, and when it can't yet, you build on top until it can. The tooling tries to abstract this cleanly, and clean abstraction is hard-won here — the engine, its primitives, and the seams between them are the durable part. Models get better at wielding them, not past them; personalize freely on top.

what you gain

A scene is text, so an agent can edit it.

Because the output is code rather than pixels, an agent can reshoot one shot without re-rendering the rest, and swap the entire look by changing one line. The film's own code diffs and versions like source — the shared kit inside each file is stamped from one canonical store, so a diff is the film changing, not boilerplate. It renders at any resolution from the same file, because there is nothing baked in. And determinism means a regression is byte-detectable — the same t either matches the last run or it does not.

what it can't do

No footage, no faces, no sound.

This is three.js with no image textures — flat color, node math, GPU noise — so it is stylized by construction: it cannot be photoreal, and no frame of footage ever appears in a film. What that look carries is direction, not rendering: the same kit already does silent-comedy timing and invented creatures, and bake-time simulation is on the roadmap. It will not edit an existing video, a screen recording or a slide deck. The films are silent. Faces are not built yet. The character films spend 4 to 5 seconds compiling shaders on a first visit on capable hardware — slower devices, longer — and captions stop being legible below about 700px of frame width.

where it is

There's a balance in building in AI between "unfinished" and "over-engineered" — this currently sits on the side of unfinished (I think).

A tinkering idea, in the open because it is fun to see what it can do. The films on this page run 12 to 37 seconds, and that is a choice about this page, not a limit: each 3D one embeds its own copy of three.js, so a project site that shipped long films would be a giant cache of code for no reason. Nothing caps duration. A frame at t=18000 costs what a frame at t=1 costs, and the file is the same size either way, because the duration is a number in a table rather than anything accumulated. Longer films have been built; they just do not belong here. Characters are one skeleton family.

02The filmssix works · one pipeline

Lit on the stage. Each one a single file that plays from disk.

Every title below is one self-contained HTML page — zero fetched assets, and three.js embedded in the ones that are 3D. These run 12 to 37 seconds — a film lasts exactly as long as the beats written for it, and the 3D ones are short so the page stays light, since every one of those carries its own three.js. Length costs nothing at runtime. The thumbnails are poster frames rendered from the scenes; open a film and the scene itself runs. Each is tagged with the primitives an agent composed it from. This is what composes easily today — the roadmap is the rest of it, abstracted one primitive at a time.

SCENE 01 — INT. WORKSHOP · EXPLAINER

Gearbox

A five-beat mechanism, judged frame-for-frame against the frozen predecessor. Switch one line — workshop to neon — and the same beats become a dark stage where the light is the subject.

bible
run 16.5sbeats 5loop seamless

Open Gearbox full size

buildWorlds()TSL node materialsshot solverstyle biblesRenderPipeline post
SCENE 02 — EXT. MEADOW · COMEDY SHORT

Bear & Bees

Silent-comedy timing: a 2.6s hush — one scout bee at the bear's eyeline, a double blink to camera — against 1.1s of everything at once. The gag reads with zero captions. Every contact is probe-measured.

run 21.3scamera lockedhush 2.6s

Open Bear & Bees full size

buildCharacter()fur packgait from distanceBox3 contact probespause-then-fast beats
SCENE 03 — INT. STAGE · CHARACTER DEMO

Menagerie

A furred bear, a fabric-shirted human, and a text-invented three-eyed strider — three proportion vectors through one buildCharacter. Three gaits (quadruped, biped, long-stride), all squint-distinct, all planted.

walk-in loopskeletons 1characters 3

Open Menagerie full size

proportion vectorstwo-bone IKchainCurl / chainWavefur + fabric packs
SCENE 04 — INT. STUDIO · PACK SHOWCASE

Materials

Three surfaces in three beats — TSL-native cel banding, subsurface scattering through thin ears, and transmissive glass with dispersion over an emissive core: the overlapping-transparency ordering case, solved.

beats 4surfaces 3loop held

Open Materials full size

MeshToonNodeMaterialMeshSSSNodeMaterialMeshPhysicalNodeMaterialtransparency ordering
SCENE 05 — CHART TIER · PRIMITIVE ISOLATION

Noise Chart

Eight shader primitives, one per cell — the MaterialX baseline row, a hash-lattice row, and a sin-hash drift control. New primitives are proven here, in isolation, before any film is allowed to use them.

cells 8control 1smoke 20/20

Open Noise Chart full size

mx_fractal_noisemx_worley_noisemx_aastephash latticedrift control
SCENE 06 — TERMINAL TIER · MARKET EXPLAINER

Market Crash

Ten beats with nobody in them: a candlestick tape prints, an order book thins, and the margin-call feedback loop is drawn as literal geometry — call-lines from candle to margin marker, sell-streaks into a stepped ask stack, and the cascade's bolts feeding back into the tape. The only film here with no three.js in it at all.

run 37.0sbeats 10loop bg-to-bg

Open Market Crash full size

2D canvas kernelbeat-relative easingcamera railpath draw-onseeded price series
SCENE 08 — GAME CUTSCENE · INVENTED CREATURE

Hauler

A creature invented from one sentence of description: built to carry something, and the thing it carried is gone. Low, broad, four-legged, with an empty cradle strapped to its back — it walks its route past a lit marker, stops, looks for what it used to carry, and walks on. The same skeleton that makes a tall thin strider, taken to the opposite corner of its proportion space.

run 20.8sbeats 7loop dark-to-dark

Open Hauler full size

quadruped gaitinvented proportionsrack focusmatch cutlow-key rig
SCENE 07 — GAME CUTSCENE · BOSS INTRO

Strider

A creature walks out of the dark to a shard that is the only light in the world, stops short of it, and turns three eyes on you. Then the film cuts from those eyes to the shard at identical framing — a match cut the compiler guarantees rather than the eye judges. Lit the way the register demands: one warm practical inside the set, a rim to find the silhouette, and a fill kept deliberately under the key.

run 20.4sbeats 7loop dark-to-dark

Open Strider full size

character scaffoldrack focusmatch cutlow-key rigemissive practical

Read the primitive chips on each film. Nothing there is bespoke: gait is one function that plants feet from distance travelled — biped and quadruped differ only by phase offset. A character is a point in proportion space plus a material choice, never a shipped mascot. A look is one object switched by one line. That is the whole bet — build primitives that generalize, and any register becomes cheap to shoot and re-shoot.

03How it's directedprimitives → pipeline

An agent doesn't write a movie. It composes primitives.

The skill ships the building blocks and the discipline. Any harness — Claude or otherwise — reads them and directs a film: it writes a beats table, scaffolds a scene, reviews it on three axes, passes an automated gate, and delivers. Expect iteration — a few look-and-edit rounds are the method, not a failure of it — and a film that needs a primitive that doesn't exist yet is how the library grows. Here is what it's handed.

BEATS[]

The beats table

A film is written as a short list of named moments — beats — each with a duration and an optional caption. The only place a timestamp exists: retiming one beat is one edit, and every caption and camera keyframe derives from it.

buildWorlds()

Procedural geometry

Every shape authored in code, zero fetched assets. Even physics is closed-form — a drop is y₀ − k·(t−t₀)², evaluated from t, never integrated.

TSL + MaterialX

Node materials

Cel, subsurface, physical glass, driven through node slots. GPU-computed MaterialX noise gives surfaces detail with no image files.

SHOTS[]

The shot solver

A cinematographer's vocabulary — subject, size ladder, angle, lens, cut — compiled onto the camera per frame. Raw keyframes are gone on purpose.

buildCharacter()

The character scaffold

One parametric skeleton family. A proportion vector plus a material choice returns a posable rig — two-bone IK, planted gait, neck and tail chains.

BIBLES / STYLE

Style bibles

The whole look — palette, exposure, post, lens, cut pace, camera energy — is one object, switched by one line. A hex literal left in a material is a look hiding from the switch.

RenderPipeline

The post chain

Always on, pass-through by default. Bloom and depth-of-field are STYLE flags; rack focus is two shots differing only in focus, joined by a blend.

sheet · motion · smoke

The instruments

Contact sheets, squint strips, motion profiles, and an automated gate. The lint can reject a scene; it can never approve one. Looking is the method.

The pipelinespec → delivery
01 · SPEC

Beats first

Write the beats as text. Check meaning while it's still words — a beat you can't follow is a slideshow.

02 · SCAFFOLD

One file

Geometry, materials, characters, shots assembled into a self-contained HTML scene on the window contract.

03 · REVIEW

Three axes

Composition (inside a frame), continuity (between frames), semantics (captions covered). Looking, not filenames.

04 · GATE

Smoke

Determinism, a shipped-frame check, aspect containment. The automated floor before any full shoot.

05 · DELIVER

Four formats

HTML, MP4, WebP, AVIF — chosen at spec time. Whatever ships, every format renders from the one scene file.

the whole bet

Generalize the primitive. Never hardcode the character.

The lesson from every film is the same: don't copy a walk cycle per creature — parameterize the gait. One function plants feet from distance travelled; two legs and four legs are the same function with different phase offsets. The character scaffold ships anatomy; the scene ships character. That is what makes a new register cheap to generate, and cheap to re-shoot.

04How it's constrainedwhy it stays deterministic

Two constraints everything else derives from.

The scene is a pure function of t. Tooling talks only to a fixed window contract, never to scene internals. Hold those two, and one file is at once the live artifact, the render source — and, later, an interactive experience for free.

kernel
Pure functions — pose(state), materials(state), camera(state). No clock, no input, no side effects. State is a plain value.
driver
Produces the state stream. The timeline driver is state = g(t) from the beats — that is the film. An input driver (state = g(events)) reuses the same kernel later — that is the interactive spike.
contract
seekTo · DURATION · stopPlayback · sceneReady hard, BEATS · FRAME · … behind fallbacks — unchanged, implemented by the timeline driver. The one seam tooling is allowed to touch, and it is tiered: a scene missing a soft name is degraded, not broken.
tooling
Build, shoot, smoke, instruments — talk only to the contract. Which is why the recorder and the live page can never disagree about when.
what it looks like

A handful of window properties. That is the whole surface.

Every scene ends by exporting the same few names — this is the driver block from gearbox.html, abridged to its shape. Everything the recorder, the gate, and this page's own hero can do, they do through these. The names are permanent — every tool depends on them — but the list grows: FLASHES and SHOTS joined the day a check needed them. When a tool is tempted to parse a scene's internals, the contract is missing an export. And this page is itself a consumer: the hero at the top is driving gearbox through seekTo right now — view source and watch it.

1
self-contained HTML file per film — no player, no build step, opens from disk
0
fetched assets — geometry and texture compute on the GPU
2
backends: WebGPU with a transparent WebGL2 fallback, plus Canvas2D
~2.3×
faster on hardware WebGPU-Metal vs the WebGL2 fallback path
05Roadmapbuilt · next · later

The scaffold grows by adding primitives, not characters.

The thing being built is an engine — primitives, and the abstractions that let you say what you mean instead of how to compute it. Every phase adds a declarative layer: you declare beats and never write timestamps, declare a shot and never write camera coordinates, declare a look as one object and never touch a material value. Films are how each layer gets proven, not the product. So every phase raises the ceiling for all registers at once, because it lands as a reusable primitive rather than a one-off asset. Since August a second track runs beside the phases — about the representation of the films themselves rather than a capability — and it advances without waiting on any phase gate; it sits at the end of this list because it is parallel, not next-in-line. Here is what exists and what comes next.

0 · 1

Foundation, regression & shading.

The node-stack templates, recorder, and instruments — gated green on both backends. Cel, subsurface, and glass material packs, verified under byte-determinism.

done
2

Character scaffold.

One parametric skeleton family with two-bone IK, distance-driven gait, neck and tail chains, and fur/fabric packs. A bear, a human, and an invented creature from one buildCharacter.

done
4

Physics bake.

A build-time simulation step: simulate once, bake to keyframes, play back pure. Cloth, secondary motion, and soft contact — with runtime determinism fully intact. This is the declarative layer for interaction, the way lighting is one for illumination: declare mass and solidity, and let the system work out what happens when two things meet, instead of hand-tuning sine waves that approximate a swing. Opt-in and per-object, never a global mode — clipping through a wall as a joke is a legitimate authoring choice. Moved ahead of faces by choice.

3

The human — faces & expressions.

A face morph basis, an expression library, hands, and hair. The bar: expressions carry the beat in the caption-covered pass — the words are not doing the work. Scaffolded as generalizable primitives, not per-character rigs.

planned
5 · 6

Registers & the interactive spike.

Cutscene and meme film-language extensions; then an input driver over the unchanged kernel — the same characters, materials, and camera solver, now responding to events instead of a clock.

planned
REP

The parallel track: the kit lives once.

Where does data stop and code start? That boundary is now a recorded decision — data is what a tool can check without running the scene, and every place checking ends is a named, typed hole — and its first consequence has landed: the shared kit inside every film is stamped from one canonical store instead of being held byte-identical across nine files by discipline. Edit the store, regenerate every film; a drifted copy fails loudly against the source instead of outvoting it. And the static validator now reads that same store: the checker and the renderer run the same code, with a standing control that drives both against the review's divergence corpus — a new case becomes an arm, not a memory. Where agreement is unachievable (an input the checker cannot read), the arm pins honesty instead: the checker must declare its stand-in rather than go quietly green. And the two open bags — the look and the config — now police their own keys: a declared key that nothing reads draws a warning naming the nearest real one, with the vocabulary derived from the kit's actual reads rather than kept as a list. Its first run found a dead key in a shipped template. And a subject's framed extent now derives from construction instead of being declared beside it — a hand adjustment rides as a named term, the checker warns on a bare number, and its first run caught the base template framing its own demo a quarter too small. Next on this track: making the promotion counting cheap enough that its triggers actually fire.

landed · continuing

Hand an agent the primitives. Get back f(t).

mitate installs as a Claude Code plugin. Point it at any input, in any register, and it directs — spec, scaffold, review, gate, deliver — then re-directs until the film is yours.

Where it is pointed: a 200-page terms of service, explained by a figure who keeps falling over. That one is reachable rather than shipped — expect to iterate, and to build a primitive or two on the way. The films above are what today's primitives compose without a fight.

terminalclaude code
$ /plugin marketplace add fblissjr/mitate
$ /plugin install mitate@mitate