A procedural short film

SilverGrass

For a swordsman, a whole life goes to meet a single instant.

Duel in the Silver Grass: a 160-second animated samurai duel in which every frame, cut and note is generated by code.

160 sof film
30shots
~150cuts
109poses
250kblades of grass
0hand-made assets

The film

Watch the full film

160 s24 fps2.35:11080poriginal score
Best with sound on · Download (1080p)

The story

Sunset. A sea of silver grass.

A masterless shinobi, Saku, faces the old sword master Tenkosai. The duel escalates over three acts and ends in a single instant.

Act I

Blade

A quick-draw stand-off, the first clash, and a perfect deflect that cuts the master's hat in two.

Act II

Fire

The spear strikes the earth and a ring of fire encloses the arena.

Act III

Thunder

In the downpour the master cuts a falling bolt, and one flash decides everything.

The repository contains no hand-made assets. Everything is generated by code. One command regenerates the whole film, and changing a number gives you a different one.

Picture

Characters, rigs, animation, cameras and VFX are Python running inside Blender.

Sound

The score and every sound effect are synthesized with numpy and scipy.

Titles

The calligraphic title cards are drawn with Pillow.

Master

ffmpeg assembles and masters the film.

Highlights

Directed in words, made in code

🤖

Made by a coding agent

The film was directed in plain language and built by a coding agent. It planned the shots, wrote every line of code, choreographed the fight, composed the score and checked the result.

🎬

A complete film with no hand-made assets

160 s, 30 shots and about 150 cuts, obeying the 180° rule, with slow-motion windows and a photosensitivity-safe flash budget. Characters, rigs, about 250k blades of grass, four sky states and every VFX are generated by code.

🥋

Choreography as code

A library of 109 poses and move macros (slash, deflect, jump, spear_thrust, …). clash() makes two blades meet at a chosen point in the world. Sparks, fire, lightning and rain are bake-free particle pools driven by a single film clock.

🎼

Motion is sound

An original score in the Japanese in scale is synthesized from scratch: taiko, shakuhachi, koto, shamisen, choir, temple bell. Every move emits a timed event, and those events place the sound effects and the musical accents on the exact frame.

♻️

Reproducible and hackable

One command regenerates the whole film. Per-shot fingerprints re-render only what changed, and every number, from story beats to render quality, can be edited.

Quick start

Make the film yourself

bash
git clone https://github.com/ZJUCQR/SilverGrass.git && cd SilverGrass
python3 -m venv .venv && source .venv/bin/activate     # Windows: .venv\Scripts\activate
pip install .

python src/run.py check     # finds Blender 5.2+, ffmpeg and the title fonts, and reports anything missing
python src/run.py all       # build → render → audio → titles → assemble

The finished film is written to assets/film/. The full render is the slow step, and you can stop it at any time: running the command again picks up where it left off. To look at one act in a few minutes, run python src/run.py preview act2.

CommandWhat it does
checkCheck the toolchain, the Python packages and the fonts
build [--lanes all] [--quality final|preview|layout]Build the scene and its event list
preview <lane>Build and render one act at low resolution. Lanes: prologue, act1a, act1b, act2, act3, finale
render [--shots S15-S20] [--slots N]Final render. Resumable, and re-renders only shots whose content changed
audioSynthesize the score, SFX and ambience from the event list, then mix and master
titlesRender the calligraphic title cards
assemble [--preview] [--range A B]Mux frames, titles and audio into the film, then run the film QC
allRun the whole pipeline end to end

Customize

Change anything

The film is data plus code, so every part of it can be changed. The timeline, story and style live in src/common/config.py. Machine and quality settings live in pyproject.toml under [tool.silvergrass]. The full guide is docs/CUSTOMIZING.md.

To change…Edit
Titles, epigraph, name and act cardsTITLES in config
Shot lengths, acts, tempo, slow motion, music cuesSHOTS, ACTS, TEMPO_MAP, TIME_WARP, MUSIC_CUES in config
Character colours and proportionsPALETTE, SHINOBI_HEIGHT, SAINT_HEIGHT in config; character modules for the designs
Choreography and cameras of one actThat act's lane module; the frame-by-frame breakdowns are in docs/shots/
Sky, light, wind, grass, VFXenvironment.* and vfx.* calls from a lane
Melodies, scales, instrumentsLEITMOTIFS, SCALE_IN, SCALE_YO in config; score and instrument modules
Resolution, samples, motion blur, encoding, loudness[tool.silvergrass] settings

You can create your own configuration or override any setting:

silvergrass.local.toml
[render]
samples_final = 32        # cleaner, slower
slots = 1

[fonts]
calligraphy = "~/fonts/ZhiMangXing-Regular.ttf"
bash
SILVERGRASS_VIDEO_CRF=18 BLENDER_BIN=/path/to/blender python src/run.py all

Project layout

Where things live

SilverGrass/
SilverGrass/
├── src/
│   ├── run.py              # command-line entry point
│   ├── common/             # film data (config), settings loader, cross-platform helpers
│   ├── blender/            # runs inside Blender: characters, moves, environment, VFX, cameras, build, render
│   │   └── acts/           # the six choreography lanes
│   ├── audio/              # DSP, instruments, SFX, ambience, score, mixing and mastering
│   ├── post/               # calligraphic titles, assembly, film QC
│   ├── tools/              # contact sheets, single-act previews, flash QC
│   └── render_supervisor.py
├── docs/                   # customizing guide, film plan, staging rules, frame-by-frame shot breakdowns
├── assets/                 # README images
└── pyproject.toml          # dependencies and every tunable setting

How it works

From data to film

SilverGrass pipeline: specification, scene synthesis in Blender, rendering, sound synthesis and post-production

Figure 1. The SilverGrass pipeline. (a) The film is specified as data: shots, handoff states, beat grid, cues and motifs in config.py, plus six choreography lanes. (b) Inside Blender, each lane keys characters, cameras and VFX within its own frame span. The build isolates the lanes in NLA strips and checks the states at every handoff. One film clock, fx_time, keeps procedural effects in step with slow motion. (c) A supervisor renders per-shot chunks and re-renders a shot only when its content fingerprint changes. (d) Every move emits a timed event, and the events place the SFX and the score's accents on the exact frame. (e) Title cards, frames and the mastered mix are assembled sample-accurately and checked for flash safety, A/V sync and loudness.

The design documents are the film plan, the staging rules and the shot breakdowns.

One instant.

For a swordsman, a whole life goes to meet a single instant.