walkthrough-film
Skill1 starsChanged 4 months agoMITView on GitHub
Build a long-form (2-6 minute) narrated product walkthrough film as a deterministic logical-clock HTML page, then render it per scene and assemble a pacing-warped mix. Use when a product demo is too long for a single-page explainer, when a film must ship in many review rounds or in several brand skins from ONE source tree, when scene durations must be derived from voiceover word timestamps, when a client keeps sending frame-by-frame feedback, or when parallel builder subagents each own part of one film. Triggers: "long product walkthrough video", "chaptered demo film", "white-label this film for another brand", "dark and light versions of the same video", "re-render just one scene", "the render judders / drops frames", "sync the chapters to the voiceover", "film spec for the builders", "version 7 of the video".
In this repository16 other files it gives its agents.
- aesthetic-presetsSkill
- audio-stemsSkill
- backgrounds-gradientsSkill
- element-motionSkill
- explainer-videoSkill
- glass-cardsSkill
- kinetic-typographySkill
- mark-driven-groundSkill
- motion-graphicsSkill
- product-motionSkill
- scene-transitionsSkill
- smooth-renderSkill
- text-motionSkill
- travelling-markSkill
- ui-data-motionSkill
- vo-syncSkill
The file
We split this skill into the rules it gives an agent
5 rules. About 0 are common, 2 are distinctive, and 3 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 31
Not for: a 30-60 s single-idea explainer (use explainer-video), a pure CSS loop, a screen recording recut.
- Distinctive: line 37
One easing curve per move: Never two writers on the same element's transform in one frame.
- Very specific: line 68
All ink/ground/glass values are tokens (--bg --txt --dim --glass-bg --grad …).
- Distinctive: line 69
Card-scoped ink: when a surface is light on a dark ground (or vice versa), re-declare the ink tokens *on the surface element itself*, so …
- Very specific: line 81
Keep a SPEC.md decision log with one dated bullet per round — it is the only record of why a frame looks the way it does, and the client …
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Walkthrough Film
A deterministic logical-clock HTML film: one page, one render(gt), N chapter scenes, rendered
frame-by-frame and assembled offline. Built for the case a single-page explainer cannot survive —
a 3+ minute walkthrough that ships in 9 versions across 2 brands, where a client reviews it frame
by frame and each round must re-render only what moved.
What makes it different from explainer-video/smooth-render: the timeline is computed from
voiceover word timestamps, not authored; each scene renders as its own MP4 by seek()+screenshot
(zero dropped frames, re-render one scene in minutes); pacing is warped at assembly, not in the page;
and the whole look is theme-token driven so a second brand is a URL parameter, not a fork.
When to use
- Chaptered product tours, platform walkthroughs, white-label demo films, launch films > 90 s.
- Anything that will go through review rounds: the per-scene render +
VERversioning is the point. - Not for: a 30-60 s single-idea explainer (use
explainer-video), a pure CSS loop, a screen recording recut.
The one hard rule
Every visual is a pure function of time. A scene draws from its scene-local lt (and the ground
from global gt) with no state carried between frames, no timers, no Date, no CSS transitions.
Corollaries, each learned the expensive way:
- One easing curve per move. Never two writers on the same element's transform in one frame.
- Verify at 1/30 s. Shoot consecutive frames
t, t+.033, t+.067 …across every move you touch and confirm the element advances monotonically by a similar delta. Pops and stalls are invisible at 0.5 s steps. - Scrubbing to any
tmust produce the exact frame the render produces. If it doesn't, the render is not reproducible.
Method
- Script and record VO first. Per-scene clips with word-level timestamps (see the
vo-syncskill). The script is the spine; nothing gets animated before the words exist. - Compute the timeline (
scripts/compute_timing.js): aCONFIGarray of{id, cues:[[key, spokenWord]]}turns word timestamps into per-scenestart,durand namedcues[]. Durations come frommax(HEAD + voLength + TAIL, lastCue + 1.0, MIN[id]), so every chapter ends ~1 s after its last spoken word. Outputstiming.json+timing.js(window.__TIMING), VO events and sentence captions.CUT=a,b node compute_timing.jsdrops scenes to make a short cut without touching the page. - Build the page.
engine.jsowns the clock, the scene registry, layers, the theme flag and the per-frame hooks; each chapter is its ownjs/ch_<id>.js+css/ch_<id>.cssexporting{layer, draw(lt,dur), enter?, exit?}. Scenes read their cue times fromwindow.__TIMING— never hard-code a beat that a cue can anchor. Seereference/PIPELINE.md. - Verify continuously.
node scripts/play.mjs 14(headless high-rate sweep) must enderrors: 0;node scripts/shots.mjs <dir> <t…>for frames, and look at every JPEG — an error-free sweep proves nothing about layout. - Render per scene (
scripts/render_scene_step.mjs): for each output frame,seek(start+(k+.5)/30), wait two rAFs, screenshot, then encode. Deterministic, no duplicated or dropped frames whatever the page's real-time speed.scripts/render_all.shruns 3 workers and skips existing files, so a re-render is "delete the stale clips, run again". - Assemble the mix (
scripts/build_mix.mjs): per-scene pacing warp, VO tempo-fit per segment, an SFX event table keyed off cues, a music bed beat-locked to one cue and sidechain-ducked under the voice, two-pass loudnorm, concat, output toVersions/<name>_${VER}_final.mp4.
Theme switching (one tree, many skins)
?theme=<name> → engine sets window.__THEME and adds theme-<name> to both <body> and
<html> → CSS custom-property token blocks do the rest. Rules:
- All ink/ground/glass values are tokens (
--bg --txt --dim --glass-bg --grad …). No hard-coded colour outside the token sheet. - Card-scoped ink: when a surface is light on a dark ground (or vice versa), re-declare the ink tokens on the surface element itself, so text inside cards stays readable whatever the ground is doing.
- A ground that changes over time writes the dynamic tokens per frame from a
GROUND3.update(gt)hook the engine calls before the scene draws. Ink should flip fast (a narrow smoothstep) while the ground crossfades slowly. - Every change is gated (
.theme-xselector orif (__THEME==='x')) so earlier versions stay pixel-identical. Prove it: run the sweep in the old themes too, and shoot one old-theme frame from your area. - Assets are chosen per theme (dark vs light wordmark) at the point of use, not at parse time. See
reference/THEMING.md.
Multi-version workflow
One VER env threads through everything: renders_${VER}/NN_id.mp4 → warped_${VER}/ →
Versions/<name>_${VER}_final.mp4. To ship round N+1: change the page, delete only the affected
NN_id.mp4 and its warped twin, re-run render_all.sh (it skips the rest), re-run the mix.
Keep a SPEC.md decision log with one dated bullet per round — it is the only record of why a frame looks
the way it does, and the client will ask.
Parallel builders
Rounds are large; split them. Write a brief (reference/SUBAGENT_BRIEF_TEMPLATE.md) that gives each owner
an exclusive file set (two agents editing one file will clobber each other), the tokens to use, the exact
frame times to check, and the standing rules. Every owner must also prove no regression: run the sweep in
the other themes and shoot one frame from each of them in their own area. Collect deviations back into the spec.
Files
reference/PIPELINE.md— timing → scenes → render → mix in detail, with the config shapes.reference/THEMING.md— token tables, card-scoped ink, the load-order trap, per-frame token lerp.reference/PITFALLS.md— 24 numbered gotchas, each of which cost a render cycle.reference/SUBAGENT_BRIEF_TEMPLATE.md— the parallel-builder brief.scripts/compute_timing.js— word timestamps + CONFIG →timing.json, cues, captions, VO events.scripts/render_scene_step.mjs— deterministic seek+screenshot render of one scene.scripts/render_all.sh— all scenes, N workers, skip-existing,VER→renders_${VER}.scripts/shots.mjs/scripts/play.mjs— frame shots and the error sweep (both honourTHEME).scripts/build_mix.mjs— warp / SFX / music / duck / loudnorm / concat → final MP4.
Companions: vo-sync (word timestamps), smooth-render (real-time capture when frame-step is overkill),
audio-stems (music + SFX generation), motion-graphics (the move vocabulary).
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

