Our own · ReelsRunning (our own)As of 3 Oct 2026
The reel engine.
A script and one voice take go in; a finished pixel-art reel of octyn, our mascot, comes out. Every part of it is code: the character, his skeleton, the sets and props, every pose and step, the renders, the pixel art, the screens, the sound and the edit are Python and Blender scripts. Nothing is drawn or keyframed by hand.

A cartoon that kept breaking.
We wanted octyn in short reels: often, on script, and without hand-drawing each one. The first build was a flat 2D cutout rig. On 2 Oct its proofs came back with eleven marked frames, about one mistake every three seconds: an arm growing out of the torso, a glove like a fork, a hand hidden behind the phone, tube arms going straight into a laptop lid.
Those weren't pose bugs. They came from the foundation: tubes on hinges, gloves stacked from capsules, grips drawn behind the thing held, a body that only ever faced front, joint angles tweened with no arcs. Patching that would never end, so octyn was rebuilt in Blender from the ground up, on a real skeleton, and drawn back into pixel art at the very end. The marked frames became a written test that every clip has to pass.
2D, 2 Oct
Blender, drawn as pixels
- L1an arm reads as two tubes with a hard kink
- L2an arm starts anywhere but the shoulder
- L3a forearm lies across the chest like a sling
- L4an arm is a stick into an object, no hand seen
- H1a glove reads as a fork, claw, stump or blob
- H2parts of a glove look detached
- H3a hand holding something goes behind it
- H4hands hidden where the action is
- H5fingers don't touch what they act on
- B1the body stays square while he reaches
- B2the torso is a rigid box
- B3a gesture pastes the hand flat on his chest
- P1a prop's parts misbehave
- P2a prop moves with no hand on it
- M1tweened joint angles make paths no person makes
- M2no arcs, no lead
- M3dead-still holds, or everything moves at once
The system, script to reel.
-
01Script
script.json · reels/USED.mdA reel starts as a few short lines with one picture under them. "Muscle memory" talks about learning guitar until the last lines, where it turns out to be about a company. Every topic, joke and gag goes into a ledger and is never used again.
When you start guitar, you think about every finger.
By the time the chord's ready, the song's gone.
Most businesses run like that. -
02Voice
timing.jsonOne continuous take per script, made on another machine and never chopped up or re-spaced. It comes back with a start and an end for every word, and an envelope of the voice. The picture is cut to those times, never the other way round.
The first two lines of "muscle memory", from its timing.json.
-
03Lip sync
lips.jsonRhubarb reads the take and writes mouth cues. Its nine mouth shapes fold into four mouth levels for the face on his screen, so the mouth opens on the voice, not on a guess.
- X 0
- A 1
- B 1
- F 1
- G 1
- C 2
- E 2
- H 2
- D 3
-
04Shot list
make_reel.py → reel.jsonEach shot is a line of Python whose start and end are words.
W(2, 7)is the eighth word of the third line, so this shot starts on "Bad" in "Bad idea." Cuts land on what's said.void(W(2, 7), b[3], 'stand', 'sideeye', 'cool', kind='flat', note='bad idea', camera=FACE) -
05Character, sets, props
model.py · rig.py · cube.py · phone.py · laptop.py · cat.py · 13 set filesoctyn is built from primitives on a real armature: skinned tube limbs that bend instead of kinking, gloves with jointed fingers, a CRT that floats just above the shoulders. Props work. The cube is 27 cubies, and its top layer sits on its own pivot, so a twist really turns it.

bed 
factory 
the cube -
06Pose, motion, contact
poses.py · motion.py · anim.py · contact.pyPoses are written the way an animator says them: where the wrist goes, which way the elbow points. Between two poses the head goes first, the chest follows, and the hand that matters lands last on a small arc with a little overshoot. Feet step with the ground covered, so nothing slides. Contact runs last, on every hand.
-
07Render passes
Cycles · 180 x 320 · 1 sampleEvery drawing renders at 180 x 320 with one sample, no denoising and every pixel sampled at the same spot, so edges come out clean. pixel.py barely uses the colour. It reads the data per pixel: normals, depth, object index, material index.

normal 
depth 
object 
material -
08Pixel pass
pixel.py · face.pyEach material gets three shades, chosen by its normal against a light from the upper left. A 1px warm line goes only where one part sits in front of another. The face is drawn onto the glass in whole pixels. Then x6, nearest neighbour, to 1080 x 1920.

bands 
outline 
pixels -
09Screens and effects
screens.py · fx.pyPhone, laptop, sign and whiteboard UIs are drawn as pixel art and mapped onto the glass. Effects (bursts, speed lines, a sweat drop, sound arcs off the strings) go into the same low-res frame, each pinned to a point the scene reports: a hand, the head, the strings.

screen 
burst -
10Edit and sound
reel.py · sfx.pyShots go down on the voice's clock. Captions come from the word times, one to three words at a time, the key phrase bigger and in amber. Whips and wipes between shots, a warm grade. The sound is synthesized from the render's own events, the music ducks under the voice, and the mix is normalized to -14 LUFS.
while he talks: music 14 dB down, effects 6
-
outreel.mp4
1080 x 1920 · 24 fps · h264One file, ready to post. The last frame of "muscle memory" is its end card.

end card
Everything is cut to the voice.
The voice comes first and nothing makes it wait. Below are the first 4.6 seconds of "muscle memory", drawn from its real timing.json, lips.json and reel.json. The face is octyn's own, from face.py, moving on the real mouth cues. There is no sound on this page.
t 0.00 scue X → mouth 0shot 00
One frame, start to finish.
Frame 287 of "muscle memory", over the words "about every". Every image here is from that one render. The four passes are read straight out of its EXR the way pixel.py reads them; the bands and the outline are pixel.py's own steps, stopped halfway.
01 / 10
NormalsCycles pass
Which way every surface faces, stored as colour. The light bands come from this.
Which side a limb curves.
The review after the rebuild named one problem: deciding which side an arm, a finger or a limb curves. Each pose had been a guess at directions in space, and some guesses bent a wrist backwards or folded a hand onto itself.
So rig.py measures the hand against the forearm in one frame of reference: up to 75 degrees toward the palm, 60 toward the back, 35 sideways. A pose that asks for more is pulled back into range, and a hand asked for within range comes out exactly as asked. The elbow is picked from 36 places around the shoulder-to-wrist line, scored on how the arm reads from the camera, how far the wrist has to bend, and where the elbow was last frame, so it never flips. Anatomy outranks the camera: an elbow never folds in across his chest just to keep a forearm from pointing at the lens.
Hands touch things. They don't go into them.
Another note was short: the hands were going inside the objects. contact.py now treats every solid prop near a hand as a surface, found by name, with a BVH tree for its inside test. On every drawing it runs three steps, and the last one is the guarantee.
- Settle. If any part of the glove is inside something, the hand is pushed back out along the surface, by the smallest move that frees it, until it just touches.
- Close. Each finger curls only until it meets the surface, so a grip wraps round what it holds instead of sinking in.
- Resolve. Run last for every hand: a sunken finger opens to its least-sinking bend, the thumb moves, and if anything is still inside, the whole hand moves out. A fingertip may miss its mark. Nothing goes through a surface.
print(f'QA FAIL {t:.2f} {s} glove inside a solid by {deep_:.1f}')
One of the checks anim.py prints while tracing a clip. Others catch a head turning more than 10° in one drawing, a hand jumping, a forearm seen end-on.
He walks, sits and pours.
motion.py moves him through a set. A walk's step follows the ground covered, so a planted foot never slides; he turns to face where he is going, and sits down and gets up on an eased bend instead of snapping. Five gaits (walk, run, sneak, shuffle, strut) and 18 gestures, from a wave and a clap to a jump and a foot tap, ride on top of any pose.
Props are picked up by a grip site. The hand lands on the kettle's handle, the kettle rides in the palm while he pours, and it stays wherever he sets it down. A pour or a sip is written as where the cup should be and how far it tips; the hand is worked out from that, so the cup stays in his grip and the handle stays in his fingers.






Ones for strums, twos for the rest.
Hand-drawn animation often holds each drawing for two frames. anim.py does the same by default: 24 frames a second, a new drawing every second frame. A shot where he plays is drawn on ones, a new drawing every frame. The strum sound is a Karplus-Strong pluck per string, 12 ms apart, landing on the frame the picture does.


Thirteen places to stand.
Each set is one Python file that builds a .blend. The props he uses are their own objects on their own pivots, and every sign, menu board, TV or mirror is a screen that takes a word. The shop's sign says DENTIST here; the same set can say BAKERY or PLUMBING, so one front desk covers whatever business a reel is about. A void set, octyn alone on a colour, makes thirteen.













The screen shows what the line says.
When the line is about the sheet only one person understands, the shot is that sheet, on a laptop, in his world. screens.py draws the UI as pixel art at the size the glass has in that frame and maps it onto the glass, so it tilts with the phone and a finger can tap it. An earlier round pasted chat screens over the picture. That was rejected, and it doesn't happen now.
Where a screen is too small for the 3x5 pixel font, lines of text become grey bars, the way pixel art shows small text.



- chat
- notif
- call
- home
- word
- sign
- terminal
- sheet
- formula
- flow
- calendar
- draft
- approve
- booking
- morning
Metaphor first. Nothing reused.
Before writing a line, we took apart 60 reels by 10 creators, rem.archivess and jaidenanimations among them: words a second, the gaps between words, cut rhythm, how long a pose holds, caption timing, effect levels. In all ten, the median gap between words was zero. The voice never stops, and the picture rides on it.
So a script opens on a picture, not a pitch. No numbers that didn't happen. Every topic and gag is logged and retired after one use, and whole themes get retired too.
- 01When you start guitar, you think about every finger.
- 02Where it goes, how hard to press, which string.
- 03By the time the chord's ready, the song's gone.
- 04Most businesses run like that.
- …five more lines
- 10We build the muscle memory.
| reel | date | topic |
|---|---|---|
| muscle2 | 2 Oct | muscle memory (learning guitar) |
| jaiden | 3 Oct | the follow-up system that follows up with everyone |
| Retired themes: follow-up systems, inbox and email systems, drafting replies, approve-before-send. | ||


On the record.
- Made by hand
- Nothing. The character, the rig, the sets and props, every pose and step, the renders, the pixel art, the screens, the effects, the sound and the edit are Python and Blender scripts. A script and a voice take go in; a finished reel comes out.octyn-px, one repository
- Character
- Built from primitives on an armature. 13 grips, 13 face expressions, a 32 x 30 face of his own.model.py · rig.py · face.py
- Motion
- 5 gaits (walk, run, sneak, shuffle, strut) and 18 gestures that ride on any pose. The cat lives on her own clock: breathing, a tail that waves and flicks, slow blinks.motion.py · anim.py
- Sets and props
- 13 sets. A working 3x3 cube, a phone, a laptop, an acoustic guitar with anchors on its strings, a kettle, mugs and cups held by their handles, a counter bell, and the cat with a full rig.room.py · bed.py · void.py · kitchen.py … stage.py
- Screens and effects
- 16 kinds of in-world screen and 13 kinds of effect, each effect pinned to a point the scene reports.screens.py · fx.py
- Checks
- FAULTS.md as the eval for every clip, a grip sheet and a pose check before animating, and QA lines on every traced drawing.handsheet.py · posecheck.py · anim.py
- Reels made
- "Muscle memory", 33.6 s in 33 shots. "The follow-up system", 26.7 s in 19 shots.reels/muscle2 · reels/jaiden
- Output
- 1080 x 1920 at 24 fps, h264, loudness normalized to -14 LUFS.reel.py
Something like this, for your company?
The first conversation is with the people who would build it. If there is a fit, the Consult comes next.