Pose to Shrine

How one character image became an interactive saint in a painted shrine, in eight steps.

Written by Claude (Opus 5.5). Project directed by Jonas Heinke. November 2026. Enter the shrine · Project page

The system underneath is called Dalang, after the puppeteer of wayang kulit. A character is treated as a function: pose numbers go in and a vector drawing comes out. Everything else here either writes those numbers or reacts to them.

1. Parts sheetto rig2. Pose vectorand hand keys3. One paintingto a 3D stage4. Physicsand event hooks5. Voiceto score, mouth, wall6. Waterand ribbon7. Soundfollows the stage8. Static siteon the homepageEach step reads the one before it. Click a box to jump there.

Where it started

A tweet by Araminta described a chain from character image to rigged puppet, keyframes, AI in-betweens and a retrace. The chain was tried on this character first.

Tracing the AI frames made the lower body jitter more than three times as much as the plain puppet (a score of 3.09 against 0.82). The video models were dropped. The rig became the system, and hand keying became the motion.

The first comparison: puppet tween, raw AI and retraces. Kept as history; none of this is in the final build.

Parts sheet to rig

A parts sheet is generated with every piece separated, complete and on pure white. Each piece is cut out once, traced to Bezier curves and given skin weights.

The result is 0.62 MB of data: 45 parts, 43 controls and 3 views. No pixels are involved at runtime. Each point is moved by deformers, then by linear-blend skinning.

Parts sheet: head, face features, hair, crown, earrings, torso, arms, trousers and feet, separated on white
The generated parts sheet.
The rig's sliders, moved one at a time. Hair, earrings and skirt are springs, reacting on their own.
pose, tick 42yaw0.19head-0.30uarmR8.49farmR-33.92handR-39.78spine-3.30+37 moreDeformershead dome, offsets,mouth bowSkinninglinear blend throughbones, per pointVector drawingBezier paths for thispose, every tickcanvas, SVG, or a texturethe sink never changes the poseKeys, springs, IK, video solvers, a webcam or an LLM can only write those numbers. Nothing else can touch the drawing.
The limitCutout puppets suit front-facing, acting-led work. A side-scrolling test looked wrong, so the first use became a dialogue-led shrine.

Pose vectors and hand keys

Motion is keyed by hand, pose to pose, as tick, value and ease. She never walks, because front-view cutouts can't. She hops in 9-tick arcs, and her feet move only in the air, so they can't slide on the stones.

Layers are mixed in a fixed order, from body clip to face to a reach on one arm, and springs run after them.

Ringing the bell. Consecutive ticks of the shipped page, at 24 frames a second.
Twenty-four consecutive ticks of her hopping to and pulling the bell cord
A frame sheet, one tick apart. This is how motion is judged.
What went wrongEarly animation passed 55 tests and looked dead. Tests can prove contact and replay, and they can't show whether a figure looks alive. Motion now counts as done only after consecutive frames have been inspected.

One painting to a 3D stage

One painting sets the look. A depth map (Depth Anything V2) and object masks (SAM 2.1) guide a simple proxy: a wall, a floor and a card for each object, standing at its depth and showing exactly its own pixels. From the locked camera, the stage looks identical to the painting.

Clean plates sit behind the objects so they can move. She is drawn each tick into a texture on her own card, so one light gives her, the bell and the bowl shadows that agree.

The camera swung away from the locked view and back. The black areas show where one painting has no evidence, which is why the public camera stays locked.
02468101214depth from the camera, metresbasinstreamspoutsackfrogstoolboardribbonricebowlwallshe standscamera, 1.6 m high, focal 1400Side view of the proxy, from calibration.json. A card standing on the floor gets depth = focal × height ÷ (foot y − horizon y).
First shrine: frontal, flat, clean
Round one was rejected as lifeless: frontal, centred and pristine.
Painted shrine with blotchy leaf shadows, one on her face
A later version faked its shadows in 2D. One landed on her face.
What went wrongThe fake shadows are why the real proxy was built. The art was repainted with obliques, overlap and wear, using principles from Studio Ghibli's free-use stills; no frame was traced. Generated edits also drifted in colour across the whole image, so they are masked back onto the master, and pixels outside the mask stay exact.

Physics and event hooks

Every click is recorded. Each tick, the stage produces an ordered list of what happened (bell, drop, land, catch) with real positions and speeds. Speech, ribbon and sound all read that list and can't change the scene, so any run replays exactly.

A grip counts only if the palm measurably reached its target. If it misses, no bell rings.

inputsclicks, pointer,recordedbeforePoseaccepted andrejected commandsactorlayers sampledinto one posephysicsattachment, flight,collision, cordafterPhysicsordered batchof consequencesOne scene tick, 1/24 s. The same inputs give the same run, frame for frame.speechwords knocked, reactionsliferibbon gustssoundreads only, never writesrendersamples state, cannot advance the scene
She takes the bowl, is poked, drops it, stamps on it and catches it.
What went wrongCorrect physics was the wrong policy for a small stage. A review acting as a stranger found the bowl thrown off canvas with her running after it, drops hidden behind the stool, and a frog levitating under fast clicks. Dropped bowls now fall in a fixed lane in front of the props, capped at 1.8 m/s.

Voice to score, mouth and wall

Lines are recorded with character timing (ElevenLabs, the Aki voice) and compiled into one score, in whole ticks. Mouth, body, lettering and audio read the same score, so nothing has to be synchronised.

Mouth shapes cut between drawings and never blend. Her words are placed on a baked map of free plaster, drawn before the shadows, so she blocks them and her shadow darkens them. Ink words hop out of her way, the bell knocks them down and the frog eats them.

One spoken line, with the same frames cropped to her face. These clips are silent; the voice is on the live page.
SomeonekeepsliftingmyarmIhaven'tdecidedwhethertoallowitwordsvoicemouthheadyawspinebob024487296120144
The compiled score for that line. Her body starts moving before the voice does, because the score knows a breath is coming.
0%2%4%6%8%10%12%14%16%armarrowbeforebowlburncorpsedeedsfroghallsmeritnothingrangsixthsmallstairsthird
Every raw take, by share of samples above 0.7. Rings mark what ships.
What went wrongAudio leveling was reported as having cured harsh takes. Listening overturned that: the overdrive is baked into the generation, and leveling only makes it quieter. Analysis then found a predictor, the share of samples above 0.7.

Water and ribbon

Generated water frames changed how the water looked more than they showed flow. Instead, the painting's own brush marks are moved down the stream through a looping strip, and a ripple runs through the basin. The loops take 12 frames and 258 KB, and nothing changes outside the masks.

The ribbon is cut from the painting and bent through three bones. Wind drives its springs, and bells, landings and clicks add gusts.

The basin. Frames are picked from the tick, so they replay exactly.
One click on the ribbon. The knot stays pinned and the paint travels with the cloth.

Sound follows the stage

Sound reads the same list of events, so each sound follows something that happened.

On stageHeard
Bowl landsA clank scaled by the computed impact speed
Bell swing turnsThe clapper strikes, darker as it weakens
Her arm jerksBangles
Anything loudInsects stop dead and creep back
She speaksNo new zither note starts
Bowl fallsStrings are damped mid-phrase until it is home

The music is launched note by note so it can stop anywhere. The bell measured C#6, so the piece is in C#, with no third. Ambient beds play overlapping random windows of random takes, so they have no repeat period.

Spectrogram of the fall-and-recover scene
A fall and recovery, rendered silently. This is all any agent has seen of the sound.
The limitAgents can't hear. Silent renders caught real faults, such as a clank that didn't get louder with impact, and they can't say whether a mix is good. That call was left to a human listener, and it was still open when this was written.

Static site

An allow-list build copies only what the page needs: 14 MB of static files that run from any subfolder. Loading waits for 6.3 MB, and room sound arrives in the background.

Phone layouts at three widths, each showing the opening, a first line and a long line
Emulated phones at 320, 360 and 390 px wide. Real devices are still untested.
What went wrongThe site's .gitignore dropped any folder named vendor/, so three.js would never have shipped, with every local test still passing. A careless edit also broke the renderer while all 132 tests stayed green, because unit tests never load it. Only a browser run on the real page caught that.

How the work was run

The project was built over two days by a coordinating Claude session and separate agents, with direction, taste and playtesting from Jonas.

Agents were briefed by letter. Each brief gave the situation, the director's actual words, what was decided and what was open.

Reviews crossed model families. Claude's work was reviewed by GPT-6 Astra and the reverse, always on a frozen commit, with instructions to break it and name where the report overclaimed.

Agents see frames and numbers. They can't hear or feel continuous play, so those calls stayed with Jonas, and they reversed several decisions.

What transfers

Credits and open work

  • Jonas Heinke created the character, directed the project, and did the listening and playtesting.
  • Claude Opus 5.5 wrote the keyed motion, speech, page and sound, coordinated the work, and wrote this page.
  • GPT-6 Astra built the stage and physics.
  • Codex image mode drew the art.
  • ElevenLabs generated the voice and effects; the instruments are VCSL and VSCO 2 CE (CC0).

Still open: the mix hasn't been reviewed by ear, Safari and real phones are untested, the new smaller hands aren't wired in, and next to the painted props she still reads somewhat as a sticker.