Skip to content
View original post on X: m4lka
Published
42/100

Opus 5.5 motion design guide: direct, render, and check frame by frame

AIThe X article "Motion Design with Opus 5.5" by a motion design author describes making an 18-second, 60 fps 3D animation of two voxel mascots, Claude and Grok, using code written by Claude Opus 5.5. The author says the first render looked finished but had wrong post text, peach instead of orange, blue instead of black cards, and a generic room, and that frame-by-frame review exposed these defects.
m4lkaVerified on X
@m4lkxx
View on X

Opus 5.5 can make a beautiful first render.

Fixing one frame is the real skill.

Full motion design guide ↓ https://x.com/i/article/2112529635778965505

Motion Design with Opus 5.5: Direct It Like a Studio, Check It Like an Engineer

An 18-second 3D animation, nine rounds of review stills, two full versions, and every defect I can prove.

Two voxel mascots climb out of their own launch posts on an X feed, fight across the cards, collide head-on, give up, and trade hearts. Claude vs Grok. 18 seconds at 60 fps, one take, no cuts, every frame and every sound drawn by code that Claude Opus 5.5 wrote.

The first full render looked finished. It wasn't.

The post text was grey placeholder bars. The brief asked for real text. The orange mascot came out peach. The cards glowed blue when they should have been black. A generic desk room stood in for the reference room I had attached. None of that shows up in a single good-looking frame. All of it shows up in a contact sheet.

This article is about the gap between "the code renders" and "the clip is right": how to write a brief Opus can't misread, how to build a renderer you can interrogate, and how to review frames so every fix rests on evidence instead of vibes.

It borrows from two pieces worth reading in full: @flxrnc's Opus 5.5 Motion Lab, which publishes every prompt and follow-up behind its loops, and Reverse Engineering with Opus 5.5 by @0xwhrrari on evidence discipline in agent-driven reverse engineering. That second one isn't about animation, and its central idea turned out to be the most useful thing I applied here.

The five layers

Ask Opus for "a premium launch animation" and it fills every gap with its defaults: glow, particles, floating type, a spinning product. You don't fix that with a longer adjective list. You fix it by giving each decision to someone, and making every layer leave something you can inspect before the next one starts.

Here's what each layer looked like on Claude vs Grok.

1. Director: one sentence, then the facts

The story fits in a line: two rival launches, equal in every way, fight, give up, and like each other's post. Every other choice hangs off it. The ACTING line of the brief says it outright: equal size, weight and skill, no hero, no villain, and CHECKS turns that into something testable: no frame shows a winner.

Then comes product truth: the things Opus must not invent. For a parody of an X feed that meant the exact post copy, the real Grok logo, the real action-row icons, the signed-in account, and the room's style. Each one was a file in "ref/", named in the first line of the prompt:

Two of the v2 fixes were product-truth failures that no amount of lighting would have caught: the handle read @ m4lka instead of @m4lkxx, and the avatar pointed at a stand-in image instead of the real file. Both are one-line patches. Both are invisible unless someone compares the frame to the source.

If an asset is missing, say so before production. A convincing fake interface is still a fake interface.

2. Reference: turn "like this" into rules

"Make it look like the reference" leaves Opus to decide what like means. It copies the most visible surface and misses the structure underneath.

So the brief converts each reference into numbers and roles:

And it says what may not carry over. I attached two other people's published Opus prompts as references for character construction, timing, camera, render pipeline and frame checks, with one hard limit: do not reuse their stories. A reference should teach a method, not hand over a plot.

The room is the clearest example of why rules beat vibes. Round 5 shows what Opus built from the line "lofi voxel room at night" before it had a real reference image: a brown desk, a synthwave sunset poster, a "HELLO, WORLD" pixel heart. Fine, but generic. Once the periwinkle-and-lavender reference was attached and described in terms of palette and objects (cream trims, a lavender desk, a jointed lamp, a monitor with a purple bias light), v2 came back as a different room entirely.

3. Timeline: states first, effects second

"Zoom, morph, add particles" gives the renderer activity without a reason. Write the states first, with timestamps, and let transitions carry the viewer from one known state to the next:

Notice how often the brief says on the same frame. For a story about equals, synchronization is the message: the collision, the sit-up, and the heart swap are symmetrical by construction, and the like counters land on the same number.

Then put time in frames. At 60 fps, 1.6 s is frame 96. At 24 fps, a 400 ms move is about 10 frames. The music here runs at 138 BPM, so one beat is 60/138 ≈ 0.435 s, about 26.1 frames. That fraction matters: compute each beat from time and round it once; never add a rounded frame count over and over, or you drift off the music within a few bars.

A starting table for weight:

One hero move per shot. Secondary motion lags it. Ambient motion stays quiet enough that the eye knows where to go.

4. Renderer: every frame on demand

This is the property everything else depends on.

Frame 240 must render correctly without playing frames 0 to 239. If it can't, you can't jump to a frame to inspect it, you can't re-render one section, and two renders of the same frame won't match.

The brief puts the contract in one line: renderAt(t) pure, seeded, ?t= freezes. Here's how the project honors it:

- Seeded randomness only. Every random value comes from mulberry32(seed). Filler posts, spark bursts, city windows, and sound all come out identical on every run. There is no Math.random() in the file.

- Closed-form motion. Sparks aren't simulated step by step. Each particle's position is p + v·a − 30·a², where a is the time since its burst. Card dents are recomputed from a list of impacts for every t. Nothing accumulates between frames.

- Motion blur without history. Each output frame averages several sub-samples spread within the frame (t + jitter) on a deterministic Halton sequence. No feedback buffer, no TAA.

- One clock for picture and sound. The soundtrack is synthesized from the same timeline with its own seed, so a hit can't drift from its frame.

- Ready means ready. Capture waits on document.fonts.ready, then sets window.__ready.

- The live preview is just a player. performance. now() appears in exactly one place: the preview loop that turns wall-clock time into t and calls renderAt. In capture mode it never starts.

The renderer is a small Node script driving headless Chrome on the real GPU: stills for review frames plus a contact sheet, video piping raw frames into ffmpeg at 60 fps, audio and mux for the soundtrack. Frames 0 to 1079: eighteen seconds, and never frame 1080.

No Date. now() in the choreography. No timers that must run from the start. No unseeded randomness. Wait for fonts. For a loop of N frames, render 0 to N−1.

5. Critic: evidence, not impressions

Here the motion workflow borrows from reverse engineering, and it's the part I'd keep if I could keep only one.

An agent produces confident explanations faster than it produces certainty. The fix is to label every claim:

- Observed: visible in a specific rendered frame, or measured from its pixels.

- Inferred: several observations point to a cause, but no frame proves it yet.

- Unknown: not checked, or the evidence conflicts.

And one rule above the labels: the model doesn't get to grade its own work. If Opus writes the rule and decides the render follows it, it can agree with itself perfectly while the frame disagrees. The judge is always the render, the reference, or a measurement.

Cheap evidence first

A full MP4 is an expensive way to learn that a title clips on frame 148. Render a handful of stills, put them on one contact sheet, and inspect while changes are still cheap.

The project's review folders show the shape of that loop:

Round counts drop as the questions narrow. That's the point: each round asks a smaller question than the last.

What the contact sheets actually caught

These are the real defects between the first render and v2, reconstructed from the review stills, the v1 backup, and the patch scripts. Each is tagged with its evidence.

1. Placeholder text where the brief demanded real text. Observed in every feed frame of r1 and r2: post bodies and sidebars are grey bars. The brief said real post text in E7E9EA. By r3 the posts read "Introducing Claude Opus 5.5…" and "Grok 5 is live…", and the sidebars carry the real nav, trends, and who-to-follow. A single hero frame can hide this. A 24-frame sheet can't.

2. Claude came out peach, not Claude orange. Observed and measured. tools/probe.py finds the lit body of each mascot in a still and reports its median color:

In r1 the cool screen light washed the orange toward skin tone. "Make it more orange" is a mood. #E2A276 → #D97757 is a target, and you can tell when you've hit it. The brief asked for exactly this: CLAUDE probed at D97757 and GROK at EDEDED on the lit body. What the probe can't tell you is whether #E07958 is close enough. It's slightly brighter than spec, and I accepted it by eye. That's a judgment, and I'm labeling it as one.

3. The cards glowed blue. Observed in r1: the screen-light glow tinted every card mid-blue, while the brief specified black 000000 post cards. From r2 on, the cards stay dark and only the accents light. In v2 one more leak showed up: grey edges around the feed, where the empty plane was picking up environment reflections. Inferred from the material and confirmed by the fix: a plain unlit black material, and the edges vanished.

4. The action row wasn't X's. v1 had four chunky icons and small counters. v2 rebuilt the row as X's thin outline set, including bookmark and share, with launch-sized counts shown the way X shows them (3.8K, 22K). The Grok nav icon was redrawn to match the real logo.

5. The room was generic. Observed in r5 against the room reference. It was rebuilt for v2, including the two framed pictures from ref/ and a window onto a purple night city.

6. The seams. r4 exists for one reason: dissolves and camera transitions are where an awkward in-between frame hides between two good key poses. Three frames 1/60 s apart around each seam is the cheapest check there is.

Finally, check the file you ship, not the source. A successful encoder run proves the file exists. It doesn't prove the file is right.

Check the checker

The reverse-engineering article makes a point I'd never applied to animation: a green test is evidence about the test you ran, nothing more. If your checker is wrong, it certifies wrong work.

In motion that means: plant a defect on purpose and confirm your review catches it. Shift Claude's color by 10%, push one landing three frames late, leave a placeholder bar in one post, then run your usual contact sheet and probe. If the review doesn't flag it, your review isn't a review yet. It's a ritual.

Ask for defects, not opinions

When you hand the frames back to Opus, ask a narrow question:

Translate feelings into frames before you send them:

- "It feels slow" → shorten the hold by one beat (≈26 frames at 138 BPM) and keep the cut on the next beat.

- "It feels busy" → one hero move; delay secondary elements by 150 ms.

- "The color is off" → probe the lit body; target #D97757.

- "The transition is weird" → render 1.58, 1.60 and 1.62 s and describe what changes between them.

Sound lives on the same timeline

The silent render looks finished. Turn on the audio and the click lands late, or the cut misses the beat.

Treat sound as timed events on the picture's clock. Here every sound is synthesized in code at 138 BPM from the same t the frames use: counter ticks, landings, the collision, the heart swap. Then it's rendered to WAV and muxed with loudness normalization (loudnorm=I=-14:TP=-2). Put each hit on the frame of its visual event, never before it: light arrives before sound in real life, and a sound that leads its picture feels wrong immediately.

Two rules from the encoded file:

- Measure sync in the decoded MP4, not the source timeline. Encoders add padding and move peaks.

- Watch it on mute too. The feed autoplays silent, and the picture has to tell the story before audio adds force.

Keep the studio in files

The next animation is where this pays off. If the only record is a chat, the next run starts from memory. Everything in this project is a file:

The patch scripts deserve a word. Each v2 change is a small Python edit with an assert that its target string appears exactly once. If the code has moved, the patch fails loudly instead of quietly editing the wrong place. That's the same idea as the observed / inferred / unknown labels, applied to code: no silent assumptions.

What I'd add next time is the piece I didn't keep: the follow-up notes themselves, verbatim, in a reviews/ file next to each round. The stills and patches let me reconstruct what changed. They don't preserve the exact words I used to ask, and those words are the most reusable part of the work.

The production prompt

By now the prompt reads like a contract. It says what to decide, what to show, and when to stop.

What actually changed

The model is the same for everyone. Opus 5.5 wrote the voxel characters, the 3D feed, the room, the camera, and the soundtrack. That's the part everyone posts.

What made the clip right rather than merely impressive was the loop around it: references turned into numbers, a renderer that can show any frame on demand, contact sheets that ask smaller questions every round, a color probe that turns "too peach" into a hex code, and the discipline to call a judgment a judgment.

A first export proves the code can render. The evidence proves the animation works.

The animation is in the replies. Eighteen seconds, sound on. You now know every defect it used to have: see if you can spot where each one was.

If you read this far

Your animation breaks on frame 148. Do you know which line to change, or are you asking Opus to start over?

The real flex is a render you can repair.

✧ Watch the full Claude vs Grok animation in the replies

✧ Bookmark and repost before your next animation

✧ Send it to someone who thinks the first render is the final render

✧ Get the full prompt (PDF) in my Telegram: https://t.me/m4lka4

✧ Follow me on X: @m4lkxx

Source details

m4lka · x.comPublished · added here

Original title: Opus 5.5 can make a beautiful first render.