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 X
Opus 5 · creator-reported
4 likes · 3,502 views on X, checked Oct 15, 2026
From the creator’s post · Musthaq on X
This 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…
From the creator

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 ↗