3D & Generative · Oct 11, 2026
This video has 0% video generation or screenshots. Everything is 100% written as Javascript by Claude…
This video has 0% video generation or screenshots. Everything is 100% written as Javascript by Claude… by Musthaq. Watch the 3d & generative video, explore…
Musthaq@haxzie_
View on XThis video has 0% video generation or screenshots. Everything is 100% written as Javascript by Claude Opus 5 on GenMotion! Here is the detailed prompt 👇 <role> You are a motion designer and graphics engineer. You make short narrative films entirely in code: Three.js scenes in plain TypeScript, rendered frame by frame, deterministically. You think like a thriller editor and build like a careful engineer. </role> <task> Make "Typing…", an 86-second (2579 frames at 30 fps) square short film, 1080×1080, about online dating. It plays as a screen recording shot like a thriller. The main character, Sam, is never seen: only a cursor, a folder called dating_pics_FINAL_2, and a profile prompt edited 9 times. Six scenes in three acts plus a coda. Sound on: a synthesised score and frame-locked sound effects. </task> <creative_direction> <proposition>We keep waiting on the dots, and somebody is waiting on ours.</proposition> <idea> Online dating filmed as a thriller: one sharp thing…
The prompt behind it.
Original prompt
The way to win me over is…".
Typed "honestly? just be kind", deleted word by word, retyped (1.08× slower) as
"honestly? just be kind." The caret is purple #5b2a86 and blinks on a 9-frame cycle
when idle. "Edited 8 times" flips to "Edited 9 times" with a small pop. The I-beam
waits by the field, then the arrow travels to Done and clicks. Slow push from 1.0 to
1.08 over 150 frames.</beat>
</scene>
<scene id="02" file="scenes/02-swipe.ts" name="The swiping" frames="487" act="I">
<beat>Hinge-style feed: the cursor clicks the heart on a prompt (heart pops 0.3→1.25→1).</beat>
<beat>Opener 1: a chat with Ava, "hey :)" typed fast (pace 0.62, typed without looking)
and sent. The bubble rises 30 px and scales 0.6→1.04→1.</beat>
<beat>Bumble-style yellow card: the check button is clicked. Opener 2 (Mia).</beat>
<beat>Tinder-style deck: a card is grabbed, dragged 260 px, released and flicked with
motion smear. Opener 3 (Lena). A second, faster flick. Opener 4 (Zoe).</beat>
<beat>The blur: 27 different people, one card per cut. Cut lengths
10, 9, 8, 8, 7, 7, 6, 6, 5, 5, 5, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 frames.
Each card holds for half its cut, then is flicked (88% right, 12% left so it reads as
a choice); the next card is already underneath.</beat>
<beat>The counter "MATCHES n" in the bottom letterbox bar: muted eyebrow 28 px, tracking
0.16; ink value 40 px. It counts 1–4 with the four matches, then rises geometrically to
312 (c = 4·(312/4)^((i+1)/27)) and pops 1.06× on every change.</beat>
<beat>The match list: every row reads "You: hey :)", "Delivered". About 48 frames in,
Jordan's row slides in from the left over 10 frames. The camera eases to it and the
counter fades out. Everything dims out over the last 8 frames.</beat>
</scene>
<scene id="03" file="scenes/03-the-one.ts" name="The one" frames="372" act="II">
<beat>The film slows down. One Hinge thread, built as the camera travels down it, keyed
between items. Messages land as an exchange: Sam first, Jordan 12–18 frames later.</beat>
<thread>
Tuesday 9:14 PM · them: "ok your third photo is unfair." · me: "the one with the dog?" ·
them: "the dog is doing a lot of work" · me: "he's my agent. he takes 15%" ·
11:40 PM · them: "ok but the pigeon thing" · me: "the pigeon is real. he waits for me" ·
them: "pigeon update tomorrow or i riot" · voice note 0:38 (played twice) ·
1:07 AM · me: "i listened to that twice" · them: "the pigeon deserved it" ·
me: "drinks thursday?" · them: "yes!!"
</thread>
</scene>
<scene id="04" file="scenes/04-thursday.ts" name="Thursday" frames="750" act="II">
<beat frames="18">Sam sends: "here, table by the window." under "Thursday 7:52 PM".</beat>
<beat frames="120, 210">Hard cuts to the clock: 8:10, then 8:25. Each holds longer than
is comfortable. The clock rides the letterbox HUD.</beat>
<beat frames="318–470">The typing indicator appears (318). The camera leans in
(322–378) until the dots fill the frame. They go (392), come back (410), go (432).
Pull back to the reply box (436–470).</beat>
<beat frames="478–~650">The cursor clicks into the reply box. "no worries if" is typed
hesitantly (pace 1.12) and word-deleted. "everything ok?" is typed (1.1) and
word-deleted. The caret sits there, blinking.</beat>
<beat frames="~650–750">The dots return, locked dead centre at lockZoom, flat, on the
beat. Handoff: they sit at the world origin at exactly the size Act III opens with.</beat>
</scene>
<scene id="05" file="scenes/05-repetition.ts" name="The repetition" frames="375" act="III">
<beat>The dots never move again. One indicator stays at the world origin while the
conversation behind it changes on every pulse. 24 cuts, one per pulse, speeding up:
21, 21, 20, 19, 18, 17, 16, 14, 13, 12, 11, 10, 9, 8, 7, 6, 6, 5, 5, 4, 4, 3, 3, 3 frames.
Every page is anchored so its own dots land on the origin.</beat>
<chats note="each caught at its most promising moment, then the dots">
Riley (iMessage) "wait we should actually do this" · Noor (WhatsApp) "saturday works" ·
theo.k (Instagram) "you're kind of great" · Maya (iMessage dark) "ok that's actually so
funny" · Eli (Bumble) "i know a place. you'd love it" · Priya (Tinder) "is it weird i
already like you" · Dev (WhatsApp dark) "tell me everything tomorrow" ·
Sasha (Hinge) "same time next week?"
</chats>
<beat>The pull-back, 110 frames. The camera stops cutting and pulls back on a log-space
zoom from lockZoom to 0.03, rolling −0.9 rad, while the rig tilts (0.32, −0.12). The
one chat turns out to be a single tile in a 15×15 wall of identical typing chats,
spaced 1580×1360 page px, with z jitter of ±1.2. Tiles share the source pages' geometry
and material, so the wall is cheap.</beat>
<beat>The twist, frames E+36 to E+48 (E = end of the cuts): the live tile's left
neighbour is "Robin" in iMessage ("so… are we still on?"), with Sam's dots on the right
in blue. Readable for about 12 frames.</beat>
<beat>Black over 10 frames, then silence.</beat>
</scene>
<scene id="06" file="scenes/06-loop.ts" name="The loop" frames="139" act="coda">
<beat frames="0–16">Black. Nothing.</beat>
<beat frames="18–52">An iPhone lock screen (860×1240, corner radius 120; "Thursday,
October 16", "11:48") lights up. A Tinder notification with the real flame drops in:
"It's a match!". A fingertip tap ring at 52.</beat>
<beat frames="56–~125">An empty chat. The cursor clicks the box (70) and types "hey"
(pace 1.15). It hovers a breath too long over send (about 22 frames), then sends. The
counter reads 313. Cut 6 frames later.</beat>
</scene>
</scenes>
<sound name="scripts/score.py — synthesised locally, locked to timeline.ts">
- Python + numpy/scipy at 48 kHz. The script reads timeline.ts through node, so
re-running it after a retime re-syncs everything.
- Output: assets/score-music.wav (the bed, track 0) plus one WAV per effect in
assets/sfx/<nn>-<name>.wav, each its own timeline clip on tracks 1–3, packed so no two
overlap. The script rewrites project.json's audio list (72 clips).
- Each clip starts exactly on a frame boundary. When a sound's sync point isn't its first
sample (a reverse swell into a hit), the file is padded so the sync point still lands on
its frame. One linked limiter levels the mix to −14 LUFS with true peak under −1 dBTP,
so every clip plays at volume 1.
- Bed: drones, risers, a "sent" chime, a wake bell, a drag tone, a dark swell, a tinnitus
tone, and the dots' lub-dub pulse as the score.
- Effects: picker clicks, keystrokes and Option-Backspace taken from the typing model's key
times (Tactile keys, Soft clicks), swipe whooshes, send swoops, message pops (different
for me and them), a muffled voice note played twice, single clock ticks at 8:10 and
8:25, the Thursday dots pulse (429 frames), heartbeat cuts (305 frames), the wall-reveal
hit, a thud on the cut to black, the match notification, the tap, and one last send.
- Silence is a beat: hold true silence for the black between the two halves.
</sound>
<file_structure>
components/core.ts stage (PX, FOV 30, fitCamera), framing(), easings (outCubic,
inOutCubic, inOutSine, inOutQuint, outExpo), prog(), keyed(),
rng(), hash(), withFonts()
components/film.ts grain + vignette/letterbox/fade/flash layers, hud group, hudLabel()
components/hud.ts letterbox counter/clock: eyebrow + value with pop and rise
components/page.ts Kit painter, makePage() with the lens shader, placeOn(), mixRect(),
cursor, mousePath(), pressShade()
components/apps.ts photoPicker, profileEditor, hingeFeed, bumbleCard, tinderDeck,
tinderTop, chatPage, threadPage, matchList, newRow, jordanThursday,
convoPage, twistPage, iphoneLock, iosNotification, STYLES, CONVOS
components/chat.ts typer, bubble, smallText, typingIndicator, selectionBadge,
heartMesh, lockZoom, GRADE
components/photos.ts fictional photo set + withPhotos(): Sam ×10 (no faces), matches
×4, swipe cards ×27
components/timeline.ts every event: typing model, PROFILE, SWIPE, ONE, THU, REPEAT,
LOOP, SCENES
scenes/01–06 one act each
scripts/score.py the score and every sound effect
</file_structure>
<quality_bar>
- Capture frames at every beat. The one thing that matters must be the only sharp,
bright thing in the frame; nothing else may compete.
- Typed text matches the keystroke sounds to the frame.
- The dots are exactly the same size, grey and position across the Act II→III cut and
across all 24 cuts.
- The blue tile is legible for about 12 frames during the pull-back.
- Nothing is ever fully still: handheld drift, lens breath and grain run on every frame.
- The final cut lands on "313".
</quality_bar>Video and prompt by Musthaq. Original post ↗



