Communitygithub.com

gallowforge/forge-motion

FilmForge motion: plans each shot's life in code instead of credits (painted holds brought alive with drifting fog, ash, snow, rain, embers, glints, light sweeps, firelight flicker, heat shimmer, shake, lightning, glass cracks, transitions, golden threads, handwritten words and titles), maps every effect to the painted-film-pipeline renderer's exact parameters, applies frame-QA code fixes, exports the edit timeline and renders the preview; decides when paid video is worth its credits. Use...

What is forge-motion?

forge-motion is a Claude Code agent skill that filmForge motion: plans each shot's life in code instead of credits (painted holds brought alive with drifting fog, ash, snow, rain, embers, glints, light sweeps, firelight flicker, heat shimmer, shake, lightning, glass cracks, transitions, golden threads, handwritten words and titles), maps every effect to the painted-film-pipeline renderer's exact parameters, applies frame-QA code fixes, exports the edit timeline and renders the preview; decides when paid video is worth its credits. Use...

Works with~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/gallowforge/filmforge/tree/HEAD/skills/forge-motion

Ask in your favorite AI

Open a new chat with this agent skill pre-loaded.

Documentation

FilmForge Motion

Paintings hold like film frames; no zooms, no drift. Movement comes from inside the frame: particles, fog, flicker, shimmer, light, all rendered on the GPU for nothing. Paid video is kept for what code cannot do (real flight, a transformation that is the film's climax). This skill fills each shot's motion field, applies the QA fixes, exports the timeline for the renderer and renders the preview the director signs off.

Paths: scripts/, templates/ and config/ below are folders inside this skill (the base directory shown when it loads), put there by ./install.sh. Working from a clone of the repository, they are tools/, templates/ and config/ at its root.

The renderer is painted-film-pipeline (Python and GLSL; modules named below). All pixel values are 4K (3840x2160); the renderer scales them by K = W / 3840, so a 1080p preview uses the same numbers.

Step 1. Read the shot

For each shot: its beat, its scene's mood and colour script, its length after retime, the music under it (phrases, hits in beatmap.json), what is already in the painting (fire, sea, sky, glass). Life must belong to the world of the painting: embers rise from a fire that is painted there; snow falls where the sky is.

Step 2. Choose its life (the vocabulary)

EffectParameter (shot field)Values
Drifting fog bandfog + fogc(strength 0..1, y where it starts, y where it is full, drift speed); colour (r, g, b) 0..1
Light sweep over highlightssweep(period s, band width px, intensity, 0)
Firelight flicker around a pointflick + fireamplitude (0.07 to 0.45); (x, y, radius px)
Heat shimmer in a bandshim(y full, y zero, 0, strength)
Camera shakeshake(start s, length s, amplitude px)
Transition in / outtin, tout("fade" or "white", seconds); default is a hard cut
Reframecrop(x0, y0, x1, y1) in source pixels
Particle tintashc(r, g, b)
Particleslifea recipe or a lambda over the particle systems below
Lightningboltslist of times in the shot
Glass crackcrack(start s, length s)

Particle systems (painted.py): ash(t, n, wind=(vx, vy), size=(min, max), alpha, seed) for ash, dust and snow; flakes(...) for large soft flakes; sparkles(t, n, alpha, size) for glints and stars; streaks(t, n, speed) for rain; embers(t, n, src=(x, y), spread, rise, life) for embers rising from a source. Recipes from the real film (film_cut.py): SNOW(n, wind), EMB(n, alpha), GLINT, RAIN, STARS(n), GOLD. Full parameter meanings: references/pipeline-modules.md; tested mood recipes: references/effects-cookbook.md.

Graphics (graphics.py, overlays.py): golden thread ribbons that draw on, sway with the music and snap (T(points, t0, draw, w)); handwritten words written on left to right (W(text, t0, x, y, size)); place names that form out of the scene's own material and blow away (V(...)); the title finale.

Step 3. Let the music drive it

graphics.Drive measures the score per frame (level and pulse). Bloom, ember flare, thread glow and text breathing follow it, so a hit flares the embers without a keyframe. Put transitions and shakes on hits from beatmap.json (shake start = the hit's time minus the shot's start).

Step 4. Write the motion field

In shotlist.yaml, per shot (example: a fire-forest shot from Simorgh, and The Lantern Moth's beam):

    motion:
      life: EMB(320)
      flick: 0.09
      fire: [1920, 1300, 2600]
      shim: [2160, 300, 0, 0.8]
      ashc: [0.62, 0.55, 0.5]
    motion:
      tin: [white, 0.4]
      sweep: [3.0, 520, 0.35, 0]
      life: GOLD
      shake: [0.0, 0.4, 10]

A shot that needs nothing gets motion: none (the gate wants every shot decided).

Step 5. Apply the QA fixes

For every fix in qa.yaml: run its call (grade.py recolor or blue, a patch, a crop on the shot), write the _g file, re-measure with ledger.py palette, then set done: true. The matched grade (plate levels) and the 4K upscale are automatic in the renderer.

Step 6. Export, render, look

python3 scripts/shotlist.py export-cut shotlist.yaml --paintings art/film > code/timeline.py

prints the timeline as P_() lines for film_cut.py. Then, in the renderer:

W=1920 H=1080 python film_cut.py still out/frames 6.0 12.0 24.0     # stills at the story hits
python film_cut.py sheet out/sheet.jpg                              # one frame per shot
python film_cut.py video film/preview_1080p.mp4 audio/score.wav     # the preview with the score

Watch the preview with sound. Check the stills at every hit. Then the director signs off the motion stage.

When to pay for video

Only when the motion is the story and code cannot fake it: flight (Simorgh's launch: real clips with speed ramps), a birth or transformation at the climax. Cost it in budget.py (Kling 4.0: 16.25 credits per 5 s at 1080p, plus the keyframe painting); paint the keyframes first and pass them through QA; draft cheaply where the model offers a draft and finalise one take. Everything else is told in painted key poses that snap (poses: 2), the way anime holds a pose.

Output

  • every shot's motion field (or none)
  • code/timeline.py from export-cut
  • the applied fixes (_g files, done: true in qa.yaml)
  • film/preview_1080p.mp4, stills at the hits, a one-frame-per-shot sheet

Gate checklist

  • Every painted shot has a motion plan or motion: none
  • Every QA fix applied and re-measured
  • The preview watched with sound; stills at every hit checked
  • Signed off

Repair table

SymptomFix
It feels like a slideshowEvery hold needs one living layer tied to its world (particles, fog, flicker); vary them by scene
Effects look pasted onTint particles with ashc from the painting; emitters at painted sources; fog colour from the sky
Busy, noisy framesFewer particles (halve n), lower alpha; one effect family per scene
Shots from different generations do not cut togetherThe matched grade is off for that plate: check levels; one grade, grain and vignette for all
Effects ignore the musicHits not used: place shakes, flares and transitions on beatmap hits
Text is hard to readMove it to the painting's quiet area (text_area), size up, slow the write-on

References

  • references/pipeline-modules.md: the renderer's modules and every parameter
  • references/effects-cookbook.md: tested recipes per mood, from a finished film

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

gallowforge/forge-director

FilmForge director: runs an AI film production end to end (story, style lock, score, paintings, frame QA, motion in code, sound, delivery, archive) through stage gates, so no credit is spent before its gate passes. Keeps the production state file (production.yaml) and the credit ledger, prices the plan against the credits, and always names the one next action. Use this skill whenever the user wants to make, plan, budget, continue or check on a short film, painted film, animated story, music...

gallowforge/forge-frame-qa

FilmForge frame QA: inspects every painting at full size against the character sheets and the continuity ledger, measures colour rules, palette and exposure with tools, scores it on a nine-criterion rubric and decides: accept, fix in code (naming the module and the exact parameters), or repaint (with the root cause and the full corrected prompt). Use this skill whenever paintings, stills, keyframes, character sheets or book pages come back from an image model, when the user asks whether...

gallowforge/forge-painter

FilmForge painter: writes every shot's image prompt from the shot list, the character sheets and the style lock, on a fixed twelve-slot order with continuity anchors (handles, anchors, scale locks, props, states, forbidden-colour clauses); keeps the continuity ledger; lints every prompt before a credit is spent; paints in batches of four and hands each batch to frame QA. Use this skill whenever the user wants image prompts for a film's shots or a picture book's pages, storyboard frames,...

gallowforge/forge-style-lock

FilmForge style lock: fixes one image model and setting, one look sentence (or two when the drawing itself carries the story), the palette and colour rules, the line, brush and lens language, the character-sheet specs with scale bars, and the prompt grammar every shot must follow, so every painting in a film or book matches. Use this skill whenever the user starts the visual side of a film, music video or picture book, wants consistent characters or one consistent look across many images,...

Related Skills