Velocity: 0.00 px/ms
Curvature: 0.00
Draw inside the box. Faster = Thicker line. Sharper curves = Redder line.
This a personal blog of movie- and book-related musings of David Joyner. See also https://sites.google.com/site/wdjoyner/
The basic idea is to hide carefully crafted syntax that AI video generators (such as flow or kling) can use for generating accurate animations. The [[ KEY: value ]] notes are embedded in the fountain file so they can be read by the converter (fountain2pam, which uses new python functions as well as the parsing of screenplain) to filter out prop, motion cues, and other blocking information. These fountain+ additions are valid fountain notes (hidden by standard renderers such as highland or screenplain or afterwriting), so they do not interfere with the standard screenplay format.
In other words, fountain+ exists to enrich and extend a standard .fountain screenplay so that fountain2pam.py can generate both better PAM JSON blocking and higher-quality
AI video prompts (https://github.com/wdjoyner/pam). The idea is simple: put richer production metadata into the screenplay file itself so the same source file can drive
PAM animation, prompt generation, and later video assembly.
The guide below was written with the help of sonnet 4.6 (anthropic) and chatGPT (openai).
[[ KEY: value ]]
Notes may span multiple lines:
[[ KEY: first line continuation line ]]
Keys are case-insensitive and terminate at the first colon.
| Key | Scope | Effect |
|---|---|---|
MOOD |
Scene | Visual tone appended to every subscene prompt |
SCENE POPULATION |
Scene / mid-scene | Character presence note for AI prompt generation |
NEGATIVE |
Scene / mid-scene | Negative prompt text |
CAMERA |
Scene / mid-scene | Camera direction override |
KIND |
File | Species/type template for character descriptions |
Use MOOD immediately after a scene heading to specify visual tone,
lighting, palette, and general emotional register for all subscenes in
that scene.
INT. VENUS CITY OBSERVATORY - NIGHT [[ MOOD: cool blue-green, holographic, bureaucratic-noir ]]
Use 3–5 strong descriptive terms rather than vague labels.
Use SCENE POPULATION to tell the converter which characters are
present at a given point in the scene. This is especially useful for AI
video generation, because it helps prevent missing or hallucinated
characters in a shot.
[[ SCENE POPULATION: Governor, Sidel. No other characters. ]]
Update it whenever characters enter or exit:
[[ SCENE POPULATION: Governor, Sidel, then Nona enters. ]]
[[ SCENE POPULATION: Sidel, Nona only. Governor exits here. ]]
In practice, this works best when paired with an updated NEGATIVE
note so the active prompt and the “do not render” guidance stay aligned.
Use NEGATIVE to supply explicit negative-prompt text for image or
video generators.
[[ NEGATIVE: No additional human figures. No crowd. No extras. No faces on the dodecahedron. ]]
Update it after entrances or exits:
[[ NEGATIVE: No dodecahedron. No geometric objects. No additional human figures. ]]
Use CAMERA when you want to override the converter’s default shot
choice.
[[ CAMERA: Wide establishing shot. ]]
[[ CAMERA: slow push in toward the Governor during this exchange ]]
[[ CAMERA: over-the-shoulder from Sidel's perspective ]]
When CAMERA is present, it takes priority over automatic camera
heuristics.
KIND defines a reusable species/type template for character
appearance. Place these notes anywhere in the file; they are file-level,
not tied to a single scene.
[[ KIND: Venusian | short, green-skinned humanoid, wide-waisted, large dark eyes, minimal body hair ]]
[[ KIND: talking dog | four-legged, golden retriever coloring, expressive face, wears a small bow tie ]]
Tag a character with a kind on the intro line:
NONA SONNOF [Venusian] — short, early 50s, formidable... RAMIS [Dog], a compact robot dog with silver-grey joints, trots in.
The converter uses the kind template as a species/type baseline and combines it with the character’s own description.
Characters tagged as non-humanoid or special prop-characters can be
routed to non-HumanGraph representations when appropriate.
RAMIS [Dog], a compact robot dog with silver-grey joints, trots in.
This allows dialogue to route to prop_say and movement to the proper
non-humanoid action such as trot_to.
INT. VENUS CITY OBSERVATORY - NIGHT [[ MOOD: cool blue-green, holographic, bureaucratic-noir ]] [[ SCENE POPULATION: Governor, Sidel. No other characters until Nona enters at her cue. ]] [[ NEGATIVE: No additional human figures. No crowd. No extras. No faces on the dodecahedron. ]] The room is a domed observatory. Cool blue-green light from slowly orbiting holographic planets. Foreground: a long conference table with a computer terminal. Background: two robot sentinels at sealed blast doors, status lights blinking amber.
MOOD under the scene headingUse 3–5 words covering palette, lighting style, and emotional register.
INT. HOSPITAL CORRIDOR - DAY [[ MOOD: cold white fluorescent, clinical, quietly tense ]]
Go near → far, mention the light source early, and end on the overall mood impression.
The room is a domed observatory. Cool blue-green light from slowly orbiting holographic planets. Foreground: a long conference table with a computer terminal. Midground: star maps covering the curved walls. Background: two robot sentinels at sealed blast doors, status lights blinking amber. The air feels bureaucratic and slightly ominous.
SERGEANT SIDEL [Venusian] — compact, mid-40s, the kind of face that has followed orders for twenty years and found it agreeable. Classic Venusian military dress uniform: deep cobalt blue, high collar, gold piping at the shoulders and cuffs, regulation boots. Stands at attention: chin up, arms at sides, eyes forward.
The GOVERNOR OF VENUS — a slowly rotating dodecahedron roughly the size of a basketball, hovering at eye level above the conference table. Translucent gold, glowing from within. Each face catches light differently as it turns. It pulses brighter when speaking. It goes amber-orange in low-power mode. It goes dark when it exits. It has no face and needs none.
NONA SONNOF [Venusian] — short, early 50s, formidable in the way that small objects under high pressure are formidable. Futuristic Venusian business suit: structured but fluid, deep charcoal with subtle iridescent trim that shifts color in the light. She sweeps in through the blast doors with the energy of someone who owns every room she enters.
NONA (not looking at Sidel — eyes on the Governor) Every time one fails, the hospital fills up.
A beat. The holographic Earth diagram pulses quietly behind them. Nobody moves. The room hums.
Anything PAM cannot map directly into blocking may still enrich the AI prompt output.
The dodecahedron's glow dims from gold to a flat amber-orange. Its rotation slows. A power-conservation mode — the AI equivalent of someone putting a hand up and saying "one moment."
The dodecahedron's surface turns a corporate amber. Then, in clean sans-serif: > PLEASE WAIT... > THE GOVERNOR OF VENUS > WILL BE RIGHT WITH YOU.
Describe what still moves and what emotional scale remains.
Nona stares at the empty air where the Governor was. The holographic planets continue their silent orbits above her. She looks very small in the room.
| What you're writing | Rule of thumb |
|---|---|
| Scene heading | Put [[ MOOD: ... ]] immediately below |
| Species / type | Use [[ KIND: name | description ]] anywhere in file |
| Character intro | [Kind] tag, then build/age, wardrobe, posture |
| Prop-character intro | size, surface, glow behavior, color states |
| Entrance | silhouette, wardrobe, entrance energy, first gesture |
| Parenthetical | eye contact or body orientation, not just tone |
| Unanimatable action | write what the camera sees |
| Prop color change | color, motion change, dramatic meaning |
| On-screen text | add a context lead-in line |
| Final image | say what remains moving and what the emotional scale is |
| Population change | update SCENE POPULATION and NEGATIVE together |
| Camera override | add [[ CAMERA: ... ]] before the relevant beat |
| Small accessories | remove if they cause generator inconsistency |
The --prompts output contains per-subscene video prompts in a
four-paragraph cinematic format:
[SHOT / CAMERA] — framing and camera movement [SETTING / ATMOSPHERE] — environment, lighting, mood [CHARACTERS & ACTION] — who does what, in what order [DRAMA / CUT] — what the scene is building toward
Clip modes:
| Mode | Boundary rule | Best for |
|---|---|---|
per-speaker (default) |
New clip per speaker change | Kling and similar |
timed |
Drama-aware 5–10 second windows | Strong-consistency generators |
The code from a specific type of json file called a PAM screenplay is fed into a python module (pam_player.py) directing the animation. The output is below (click on the lower corner to enlarge).
I have recently been developing a Python-based toolset designed to translate chess game data (PGN) into structured video via the Manim animation engine. The project, chess-animator, provides a programmatic framework for visualizing moves alongside underlying evaluation metrics produced by engine analysis.
The package integrates python-chess for logic and
Stockfish for centipawn evaluation, generating a multi-panel
animation that includes a real-time evaluation bar and comparative metrics for
various positional factors.
The source code and documentation are available on GitHub: https://github.com/wdjoyner/chess-animator
A primary objective of this visualization is to map engine heuristics to an intuitive geometric scale. The evaluation bar and the positional metrics strip follow these specific definitions:
By utilizing Manim’s ability to render mathematical objects, these metrics are updated move-by-move in synchronization with the piece animations. This provides a granular view of how the character of a position evolves through the interaction of these heuristics.
Here is an example of the game below
[Event "Candidates Tournament"] [Site "Toronto CAN"] [Date "2024.04.04"] [Round "5"] [White "Caruana, Fabiano"] [Black "Nepomniachtchi, Ian"] [Result "1-0"] [WhiteElo "2803"] [BlackElo "2758"] [ECO "C54"] [Opening "Italian Game"] 1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. c3 Nf6 5. d3 d6 6. O-O O-O 7. Re1 a6 8. Bb3 Ba7 9. h3 Re8 10. Nbd2 Be6 11. Bc2 d5 12. exd5 Bxd5 13. Nf1 h6 14. Ng3 Qd7 15. Be3 Bxe3 16. Rxe3 Rad8 17. Qe2 Qc8 18. Rae1 b5 19. Qd2 Ne7 20. d4 exd4 21. cxd4 Ng6 22. Bb3 Bxb3 23. axb3 Rxe3 24. Rxe3 Nf4 25. Qc3 Rd5 26. Ne5 N6h5 27. Nxh5 Nxh5 28. Re1 Nf6 29. Nc6 Qd7 30. Ne5 Qc8 31. Nc6 Qd7 32. Ne5 1-0
Analysis generated by Stockfish 17.1 | Event Date: 2018.11.10
The second round of the 2018 World Chess Championship in London [cite: 17, 18] was a masterclass in technical accuracy. Playing White, Magnus Carlsen faced Fabiano Caruana in a game that engine analysis now classifies as "balanced and one-sided," with White maintaining a slight but consistent comfort level throughout.
| Metric | Magnus Carlsen (White) | Fabiano Caruana (Black) |
|---|---|---|
| Total Moves | 49 | 48 |
| Accuracy | 97.7% | 98.6% |
| Avg. Centipawn Loss | 4.6 | 2.9 |
| Blunders/Mistakes | 0 | 0 |
While the game ended in a draw, the underlying positional metrics show a fascinating tug-of-war between different strategic advantages:
With a total evaluation spread of only 0.63, this encounter is the definition of "Balanced" play. Neither side allowed a single inaccuracy or mistake, resulting in a technical 1/2-1/2 draw.
The latex report can be found here: Download Full PDF Report.