3D
The Factory v2: sound and phone size
The diagram film, reframed for phones and given sound.
Paste it into Claude or ChatGPT, answer its questions, and it makes the video. It works best in an app that can run code.
Make me a short film for my product the same way zippr made one particular film: "The Factory v2: sound and phone size" (zippr.to). In it, a small chat window asks "Make me a presentation." and a huge factory draws itself in above it, piece by piece, with a clank for every piece and a machine hum that grows as it fills. Seven orange crates, each labelled with one small job, ride the line, and a tiny stack of slides lands. The chat window closes: the hum cuts dead, the factory quietly comes apart, and there are two seconds of silence. A new window asks again, and the identical factory builds itself again, with the identical sound. Hard cut to silence: one small module lights up with "ACTION: CREATE PRESENTATION" on a single soft, bright tone. It looks like an isometric 3D diagram, pale grey boxes with thin dark outlines on warm paper and one orange accent, made for a phone screen. Below is the exact recipe zippr used: the tools, the steps, the settings and the timings. Follow it as closely as you can. Only the parts about my product change.
WHAT IT COSTS
- The code tools in this recipe are free; all but GSAP are open source, and GSAP is free under its own no-charge licence. - zippr made it with Claude (Opus 5.5) on a paid Claude plan. Any AI app that can run code can follow it. - There was no paid step beyond the AI app's plan: every piece is drawn in code and every sound is synthesised in code. There are no recordings and no generated pictures.
STEP 1: ASK ME FIRST
Before you make anything, ask me these questions. Use your question tool if you have one. Otherwise ask them one at a time in the chat. If I skip one, suggest an answer and tell me what you picked. 1. What is your product or business, in a sentence or two? 2. What is the one thing a viewer should take away? (zippr's: "Your AI shouldn't rebuild the factory every time you ask it to do the same work.") 3. Who is going to watch it, and where: reels, a website, a talk? 4. Length and shape. zippr's film is 39.2 seconds, portrait 1080x1920 for phones, with a landscape 1920x1080 cut from the same page. Keep that? 5. Your brand colours (hex codes if you have them), and your product's name as it should appear at the cut. 6. The words on screen. zippr's: the three asks ("Make me a presentation.", "Make another version with the same structure.", "Make another version."), the seven crate labels, "ACTION: CREATE PRESENTATION", the name, and the end line. Nothing else is written anywhere. Give me yours, or say which to keep. 7. Your story in zippr's shape: - the ask (zippr's: "Make me a presentation."); - the absurd machine the AI builds for it (zippr's: a whole factory, far too big, and loud); - the small jobs it carries in, one per crate (zippr's seven: "Find files", "Read instructions", "Find the template", "Find the logo", "Figure out the format", "Ask what slide 7 should say", "Figure out where the source data lives"); - the small result (zippr's: a stack of five slides); - the moment it is thrown away (zippr's: the chat window closes, the sound cuts, the factory comes apart); - the repeat ask, and the identical rebuild, heard as well as seen; - your version: one small thing that is already there and just runs, in near silence (zippr's: a module that lights up with "ACTION: CREATE PRESENTATION" on one tone). 8. The pictures and sounds. Everything is drawn in code from simple 3D shapes, and every sound is made in code: nothing to find, record or generate. Do you want any sound of your own brand (a notification tone, say) as the one tone at the payoff? It must be yours to use. 9. The colours. zippr's: warm paper #E9E5DC, pale grey shapes, a dark graphite ink for every outline and word, and one orange #D98B2B for the crates and the lit module. Which of your colours goes on the accent's role, or keep zippr's?
STEP 2: THE RECIPE (exactly how zippr made this film)
Where the method came from This is the second pass of zippr's diagram film. The first was built silent, landscape, from a one-page direction: close the chat, and it comes apart; no caption, no announcement. Ask again, and it draws itself again from nothing, the same pieces in the same order; the viewer should notice the repeat before any word points at it. The picture was kept and frozen, and this pass added only two things, the sound and a portrait version for phones, from a one-page brief to one Claude (Opus 5.5) agent. The sound's idea is contrast, not narration: the old way is dense and a little too much; the close is silence, and the silence is the point; the rebuild is the SAME sound, sample for sample, so the repeat is heard; the product is near-silence and one soft, bright tone.
The tools - Claude (Opus 5.5): added the portrait layout and the sound, rendered both shapes, read the frames and measured the mix. - A web page with three.js 0.182.0 (the free 3D library, MIT): every piece of the factory is one of its stock shapes (box, cylinder, cone, torus) with thin outlines, seen through an isometric camera. - GSAP 3.13.0 (the animation library, under GSAP's standard no-charge licence): one paused timeline sets every piece's progress at an exact second. - Playwright for Python driving headless Chromium: opens the page from a local server, calls seek(t) for each frame and screenshots it. It also reads the page's own timeline out into a cue file for the sound. - Python with numpy: every sound, from sines, decays and shaped noise, at a fixed seed. There are no recordings. - ffmpeg with libx264 and AAC: joins the frames and the sound, and measures the loudness (its ebur128 filter). - The font: Helvetica Neue, the Mac's own system font (any clean sans works; the page loads no web font). - Both libraries were copied into the page's folder, so nothing is fetched while rendering.
The steps, in order 1. One page, one config block at the top: every colour, the camera, every beat's second, every word. Motion never reads a colour. 2. The shape is read from the page's address (?fmt=portrait, else landscape) before anything is built; a portrait block in the config changes the frame, the camera's view and the placement of the window, the name and the labels. Timing, motion and colour never change between shapes. 3. seek(t) draws any frame from numbers only: no Math.random, no clock, no requestAnimationFrame. The build is ONE function called twice, which is why the rebuild cannot drift. 4. The cue sheet: the page lists every tween on its timeline (what it moves, what kind of part, where, when, how long). The render step writes that list to a file, and the sound step reads every time from it. Sound and picture share one clock and cannot drift apart. 5. The sound (below), then render each shape frame by frame, then mux. 6. Read the frames by eye at 1.0, 8.6, 15.0, 19.8, 26.6, 31.6 and 36.0 s in portrait, and measure the loudness of every section. 7. Check the finished file (below), then export.
The look (every value is zippr's; the landscape picture is the same film, and portrait changes only the frame) - The 3D is drawn by three.js at a pixel ratio of 2; the chat window, the labels, the plate, the name and the end line are plain HTML on top. - The camera: orthographic (no perspective), from 420 units along the direction (1, 0.86, 1). Landscape looks at (3.0, 6.2, -1.0) with a view 57 units tall. Portrait looks at (5.74, -5.55, 6.36), which is the same target moved in the screen plane only, with a view 110 units tall, so the factory is about 940 px wide with about 70 px each side, its middle near y 660, and the chat window under it. The camera never moves. - The light: a white ambient light at 2.05 and one white key light at 1.15 from (-40, 70, 30). Flat and even. - Every piece: a flat-shaded shape plus its edges drawn as thin lines in the ink colour at 62%. The factory: 9 foundation slabs in a row and 8 smaller ones; a conveyor bed 62 units long on 18 legs with 20 rollers; 4 gantries (two 15-unit columns, a beam and three cross bars each); two overhead rails 58 units long; 3 silos with cones and ducts; 2 machine blocks with caps; 5 jointed arms (base, upright, joint, angled forearm); and a small output tray, small on purpose. - How a piece arrives: it starts at a seeded offset (2 to 7 units back, 11 to 20 up, up to 7 across), small (0.86 scale) and invisible, and slides into place over 1.05 s, growing and fading in. The seeds come from one fixed-seed generator (seed 1315). - Portrait sizes: the chat window 640 px wide at (220, 1140), 16 px corners, a 46 px bar with three 14 px dots, its words 34 px; the whole ask is laid out from the first keystroke (the untyped rest is transparent), so it wraps inside the window and no word jumps a line mid-typing. Labels 24 px, always kept 28 px inside the frame (their leader line stays on the crate). The name 42 px at (84, 150). The plate 28 px. The end line 60 px, 920 px wide, centred in the space above the bottom 340 px. Nothing ever sits in the bottom 340 px, which a phone's buttons cover. Landscape keeps its own sizes: window 392 px at (148, 742) with 21 px words, labels 17 px, name 26 px, plate 19 px, end line 52 px. - The colours are ROLES. My brand colours go onto the roles; zippr's value stays for any role my colours don't fill. - PAPER, the background and the ground (one colour, so no edge ever shows): #E9E5DC. Mine: my lightest warm neutral. - THE MACHINE, every shape: light faces #FBFAF8, heavier parts #E1DDD3. Mine: two near-whites a step apart. The machine stays quiet: it is a drawing, not the hero. - INK, every outline and every word: graphite #2B2F36. Mine: my darkest colour. - THE ACCENT, the only colour in the film: orange #D98B2B, on the seven crates, on the module's lit face and on the action plate. Mine: my brand colour. It must stand clearly apart from the paper and the machine. - THE CHAT WINDOW: white #FFFFFF, a 1 px ink border at 22%, a soft shadow. Deliberately generic, so it reads as "a chat", not as anyone's product. - The labels: white boxes at 94% with a 1 px ink border at 20%, on a 1 px ink leader line down to their crate; alternate labels sit high and low, so neighbours don't collide.
zippr's story, beat by beat (39.2 s; 30 frames a second; frame = seconds x 30) - 0.20 s: the chat window fades in over 0.5 s. From 0.75 s, "Make me a presentation." types one letter at a time over 1.85 s. In portrait the window sits alone, below the middle, where the factory will stand above it. - 3.20 to 8.6 s: the factory draws itself in, foundations first, then the conveyor, gantries, rails, silos and blocks, arms, and the tray. Every piece has its own start inside the 5.4 s build (0 to 3.74 s after 3.20) and slides in over 1.05 s. - 8.60 s: the five arms fit their own tools (a cone, a cylinder, a ring, a cube, a five-sided cone), one every 0.22 s, each springing into place over 0.55 s. - 10.80 to 17.4 s: seven orange crates ride the conveyor end to end in 4.3 s each, one every 0.5 s, each with its label on its leader line; a label appears only once its crate is moving. - 17.20 s: five thin slides stack onto the small tray, one every 0.16 s. - 19.20 s: the chat window closes: it shrinks by a tenth and fades over 0.22 s. An ordinary close. - 19.35 to 21.8 s: the factory un-draws, starting on the close: the last piece built is the first to go, each leaving 0.4 x (4.3 s minus its build start) after 19.35 s and falling away over 0.70 s. - 21.80 to 24.00 s: nothing. Empty paper, and silence. - 24.00 s: a new window; from 24.45 s "Make another version with the same structure." types over 1.75 s. - 26.20 to 31.6 s: the identical rebuild: the same function as the first build, so the same pieces land in the same places in the same order. In portrait, everything above the window at 31.6 s matches the 8.6 s frame pixel for pixel. - 31.80 s: hard cut. No factory. Already there: the name at the top left, one small module with a tray, and the window reading "Make another version." in full. At 32.65 s the module's front face lights up orange and the plate "ACTION: CREATE PRESENTATION" appears above it on a leader line. From 33.0 s five slides drop onto the tray. Nothing is built. - 35.45 s: everything fades out over 0.55 s. - 36.15 s: the end line, "Your AI shouldn't rebuild the factory every time you ask it to do the same work.", fades in over 0.7 s (three lines in portrait) and holds to 39.2 s. - Faults still in zippr's cut; avoid them in mine: the plate's leader line starts at the plate's centre and runs through its text (start it at the plate's bottom edge); the plate sits left of the module's visual centre; one leader line crosses the "Ask what slide 7 should say" label; there is an empty frame from 36.0 to 36.15 s between the module fading and the end line; in portrait the zippr beat is top-heavy (name and module high, window low).
The sound (no music; the machine's own sounds are the story) - Made in numpy at 48 kHz, stereo, 16-bit, from sines, decays and shaped noise, with a fixed random seed (1341). Every time is read from the cue file, so each sound sits on the tween it belongs to. There is no music and no voice. - In zippr's cut, the sound didn't land on the picture's beats. So in mine: every hit sound goes with something the eye sees happen, and starts 2 frames BEFORE that frame (the ear hears that as exactly on time); swells and fades END on their frame instead. Everything below is zippr's design; that rule is the one change. - The ask: one soft key tick per character, at the moment that character shows (18 ms of band noise, 1 to 4.5 kHz, with a small 260 Hz body; a space is lower, 0.5 to 3 kHz and 190 Hz), panned a little left. - The build (both runs): one rendered track. - A mechanical bed that grows with how much of the factory has landed: a 55 Hz hum weighted to its upper harmonics so a phone speaker plays it (strengths 0.45, 0.8, 0.55, 0.35, 0.15 for harmonics 1, 2, 3, 4 and 6), pumped by a press rhythm at 4.4 Hz, over a rumble (band noise 30 to 190 Hz), a faint motor whine near 443 Hz and a sparse metal clatter (900 Hz to 4.2 kHz). - One struck-metal clank for every placement, 117 of them in about 4.8 s, each panned by where its part sits on screen: a few inharmonic sine partials with their own decays plus a short noise hit. Its pitch and ring follow the part: deep and long for slabs, rails, silos and machine blocks (fundamentals 44 to 140 Hz, rails ringing up to 1.6 s), bright 50 ms ticks for the 20 rollers (1.75 kHz), a ratchet of five clicks in a tenth of a second for each joint, and a servo whirr (a buzzy tone rising from 240 to 600 Hz over 0.2 s) into a clank for each arm. - The whole build track is high-passed at 60 Hz (sub-bass under the heavy hits adds peak, not loudness, and a phone drops it anyway). Dense, and a little too much: that is the point. - zippr put each clank 0.36 s into its part's 1.05 s slide, where the part turns fully solid and is about three quarters of the way down. Put mine on the frame where the part is seen to land. - The tools: for each arm, a ratchet-wrench zip (8 clicks 26 ms apart, from 1850 Hz) then a snap (640, 1480 and 2600 Hz). - The crates: a wooden thunk as each crate lands on the line (96, 190 and 330 Hz, over low noise), panned left, and a conveyor rattle (10.5 small clicks a second near 1300 Hz) for as long as any crate rides, louder with more crates riding. - The deck: a paper slap as each slide lands (noise 700 Hz to 5 kHz over a 230 Hz body), panned right. - The close: the bed is cut in 40 ms at the moment the window is half gone (19.37 s). The un-draw carries only a faint airy dissolve (band noise 1.2 to 6 kHz, tilted darker, rising and falling with how fast pieces are leaving). From 21.80 s: digital silence until the next ask's first key. - The rebuild: the build track placed a second time, sample-identical, and cut in 6 ms at the hard cut (31.80 s). - The product: 0.85 s of digital silence, then ONE soft, bright tone as the label lights (32.65 s): E6 (1318.5 Hz, with a twin at 1319.9 Hz for a slow shimmer), its octave (2637 Hz) and two glassy upper partials (3955.5 and 5274 Hz) that fade faster (0.40 s) than the body (0.75 s), a 12 ms attack, and a tail that runs through the end card. Nothing else: the slides land silently. - The balance, before mastering (linear, relative): bed 0.40, clanks 0.55, conveyor rattle 0.30, key ticks 1.6 (on a very quiet tick), airy dissolve 0.032, the tone 0.46. - The hits and their frames (at 30 fps): typing from 23 (one tick per letter over 1.85 s) and from 734; the build from 96 (the first clanks near 107); tools from 258; crate thunks from 331; slides from 522; the bed cut 581; silence from 654; the rebuild from 786; the hard cut 954; the tone 980. - Master: ONE linear gain to -16 LUFS integrated, then a memoryless soft knee (untouched below -4 dBFS, eased so it never passes -1.6 dBFS). No compressor and no look-ahead limiter, because either would make the rebuild differ from the first build. zippr's muxed file measured -16.0 LUFS, true peak -1.9 dBTP. The sections, measured: the build about -16 LUFS; the close about -38; the rebuild about -14; the product beat about -25; the end near silence. - Make the WAV 0.5 s longer than the picture and let ffmpeg stop at the shorter one, so the film ends on its last frame.
The finish - 1080x1920 (and 1920x1080), 30 fps, 39.2 s, 1,176 frames. Render with Chromium flags --use-angle=swiftshader, --enable-unsafe-swiftshader, --force-color-profile=srgb, --hide-scrollbars, --font-render-hinting=none and --disable-lcd-text, at device scale 1, the page served from 127.0.0.1. Encode: ffmpeg -framerate 30, libx264, preset slow, crf 19, yuv420p, with AAC 192 kbit/s at 48 kHz stereo and -shortest. zippr's portrait file came out at about 3.8 MB.
STEP 3: SWAP IN MY PRODUCT
Keep the camera, the shapes, the build-and-unbuild motion, the close-then-silence, the identical rebuild (seen and heard), the one tone, the beats and their seconds, and the mastering exactly. Change only these: - The three asks become my customer's ask, its repeat, and the short ask to my product. - The seven crate labels become the small jobs my customer's AI redoes every time. - The slides become the small result, and the plate becomes my one-step payoff. - The name and the end line become mine. - The orange becomes my brand colour on the accent's role. - The tone can become my own brand sound, if it is mine to use; keep it soft, bright and alone.
STEP 4: SHOW ME THE PLAN, THEN WAIT
Write my story in two sentences, then my beat table with times in zippr's format, then my colours on their roles, then my sound list with each hit's frame. If you can run code, show me 4 portrait stills in the finished look (for example at 2.8 s, 15.0 s, 23.0 s and 33.5 s). Wait for my yes before you build the whole film.
STEP 5: MAKE IT
If you are an AI app that can run code and save files, follow the recipe and give me the MP4 with sound. Ask me before installing anything: three.js and GSAP are downloads unless they are already on this machine. If GSAP can't be had, drive every piece's progress from plain functions of time inside seek(t), write the cue list from those functions, and tell me. If WebGL won't run headless, keep the swiftshader flags; if it still won't, tell me before you change the method. If you can't run code, build it as one self-contained web page that plays in the chat: the same scene in three.js if it can load, or the same isometric boxes drawn on a canvas if not, on the same timeline, with the sounds made live in the browser from the same recipes. Add a big Play button (browsers only play sound after a tap), a Replay button, and a "Save as video" button if the browser allows. Tell me how to screen-record it with sound on a phone and on a computer.
STEP 6: CHECK IT BEFORE YOU GIVE IT TO ME
- Put one frame from every second on a contact sheet and look at it at phone size. Could someone who never saw this message say what the film means from the frames alone, and say "it rebuilt the whole thing because the chat closed"? Fix what doesn't read. - On the file: it plays start to end; nothing sits in the bottom 340 px of the portrait film; the rebuild's sound matches the first build's sound sample for sample (compare the two stretches of the WAV); each hit sound starts 2 frames before the frame it belongs to and is clearly audible; the silence after the close is real silence; the loudness is -16 LUFS and the peaks are below -1 dB. - Then give me the file, one still, and one honest line on anything you couldn't do. Never use copyrighted music.