CineCode
Tutorials

Your first video

Build a first CineCode scene one small render at a time.

Now that the engine works, let's make something of your own. This lesson is not one big copy-paste. You'll build the scene in small render checkpoints:

  1. Start with a title.
  2. Give the title a stronger visual style.
  3. Add real source code.
  4. Make the code type, spotlight, and move under the camera.
  5. Change the source and render again.

That loop is the whole CineCode habit: change one thing, render, watch what it did.

Step 1 โ€” Scaffold a project

The new command creates a ready-to-render project:

./target/release/cinecode new my-video

That gives you exactly three files โ€” and those three files are the whole idea behind CineCode:

my-video/
โ”œโ”€โ”€ codescene.toml      # โ‘  the manifest โ€” settings & which scenes to play
โ”œโ”€โ”€ scenes/
โ”‚   โ””โ”€โ”€ intro.ccs       # โ‘ก the director's script โ€” how to film the code
โ””โ”€โ”€ src/
    โ””โ”€โ”€ main.rs         # โ‘ข your code โ€” the thing being filmed

Think of it like a film set: src/main.rs is the actor (your real code), intro.ccs is the director (telling the camera what to do), and the rendered .mp4 is the finished film. The script never contains your code โ€” it read(...)s it.

Step 2 โ€” Meet the three files

Open the project and look at each file. The most important thing to notice: the script doesn't hold the code, it reads src/main.rs and then says how to animate it.

This is ordinary Rust โ€” the thing you actually want to show. CineCode never edits it; it only films it. Change this file and the video changes on the next render.

src/main.rs
fn main() {
    let greeting = "Hello, CineCode!";
    println!("{greeting}");
}

Step 3 โ€” Start with a title

Open scenes/intro.ccs and temporarily reduce it to only a title:

scenes/intro.ccs
let s = scene("Intro", sec(4));

s.text("Hello, CineCode", 96, 80)
    .font_size(56)
  .fade_in(0, ms(600));

Render it:

./target/release/cinecode render my-video -o title.mp4
Checkpoint 1: a single title fading in. Expand the source bundle to see the tiny scene that made it.
Files that made this video

The first checkpoint in the beginner tutorial: a manifest plus a title-only scene script.

codescene.toml
Renders only the title checkpoint scene.
Open full file
scenes = ["scenes/intro.ccs"]
theme = "dark_documentary"

[episode]
title = "my-video"

[output]
fps = 30
width = 1280
height = 720

What you just learned:

  • scene("Intro", sec(4)) creates a 4-second scene.
  • s.text(...) places text at (x, y) pixels from the top-left.
  • .font_size(56) makes it large enough to read.
  • .fade_in(0, ms(600)) fades it in over the first 600 ms.

This is the first useful CineCode unit: create a node, then chain animation methods onto it.

Step 4 โ€” Style the title

Now make the title feel more intentional. Replace the title block with this:

scenes/intro.ccs
let s = scene("Intro", sec(4));

s.text("Hello, CineCode", 96, 80)
    .font("Georgia")
    .font_size(64)
    .glow(0.5)
  .slide_in("up", 50, 0, ms(800));

Render again:

./target/release/cinecode render my-video -o title-styled.mp4
Checkpoint 2: the same title with font, glow, size, and motion added.
Files that made this video

The second beginner checkpoint: the same title with a font, glow, and slide-in animation.

codescene.toml
Renders only the styled-title checkpoint scene.
Open full file
scenes = ["scenes/intro.ccs"]
theme = "dark_documentary"

[episode]
title = "my-video"

[output]
fps = 30
width = 1280
height = 720

What changed:

  • .font("Georgia") asks for a system font by name.
  • .glow(0.5) adds a soft documentary-style glow.
  • .slide_in("up", 50, 0, ms(800)) starts the title 50 pixels lower and slides it upward over 800 ms.

Later, when you want to compare more fonts, the example project includes a full font gallery:

A larger font gallery built from the same .font(...) idea.
Files that made this video

A text-node font gallery using system fonts.

codescene.toml
Project manifest: output size, theme, scene order, transitions, and shader names.
Open full file
scenes = ["scenes/intro.ccs", "scenes/terrain.ccs", "scenes/pathfind.ccs", "scenes/particles.ccs", "scenes/graph.ccs", "scenes/life.ccs", "scenes/boids.ccs", "scenes/tweens.ccs", "scenes/inserts.ccs", "scenes/edit.ccs", "scenes/edit_source.ccs", "scenes/editor_theme.ccs", "scenes/font_set.ccs", "scenes/remove_styles.ccs", "scenes/morph.ccs", "scenes/shapes.ccs", "scenes/effects.ccs"]
theme = "dark_documentary"

[episode]
title = "How Rivers Form"

[output]
fps = 30
width = 1280
height = 720

[shaders]
aurora = "shaders/aurora.wgsl"
glitch = "shaders/glitch.wgsl"
scanlines = "shaders/scanlines.wgsl"

[transition]
kind = "crossfade"
frames = 18

Step 5 โ€” Add code to the frame

Put the starter scene back together, but read it from the bottom up: title first, then code.

scenes/intro.ccs
let s = scene("Intro", sec(5));

s.text("Hello, CineCode", 96, 48)
    .font_size(52)
    .glow(0.5)
  .fade_in(0, ms(600));

let code = s.code(read("src/main.rs"), "rust", 96, 150);
code.font_size(34)
    .shadow(0.5)
  .fade_in(0, ms(533))
  .typewriter(ms(200), ms(2333));

Render this checkpoint:

./target/release/cinecode render my-video -o code.mp4
Checkpoint 3: title plus real Rust source code read from src/main.rs.
Files that made this video

The third beginner checkpoint: title plus real Rust source code read from `src/main.rs`.

codescene.toml
Renders only the title-plus-code checkpoint scene.
Open full file
scenes = ["scenes/intro.ccs"]
theme = "dark_documentary"

[episode]
title = "my-video"

[output]
fps = 30
width = 1280
height = 720

Now there are two different node types in one scene:

  • s.text(...) creates normal title text.
  • s.code(read("src/main.rs"), "rust", ...) reads a real file, syntax highlights it as Rust, and places it on screen.
  • .typewriter(ms(200), ms(2333)) reveals the code like typing, starting after 200 ms.

The clip above is the first point where the scene starts to feel like a code documentary: the page title gives context, while the code block gives the thing being explained.

Step 6 โ€” Make the code explain itself

Code on screen is useful, but documentary code needs direction. Add a spotlight after the typewriter:

scenes/intro.ccs
code.spotlight(2, 0.6, sec(3), ms(600));

That means: at 3 seconds, brighten line 2 and dim the other lines by 0.6 over 600 ms.

Then add a camera move:

scenes/intro.ccs
let cam = s.camera();
cam.focus_on(code, 96, 24, 1.6, 2);
cam.zoom_to(1, ms(4333), ms(800));

Render again:

./target/release/cinecode render my-video -o spotlight.mp4

What you can do with this pattern:

  • Spotlight the line your narration is talking about.
  • Underline or point at a line when a small detail matters.
  • Push the camera into the code, then pull back for context.
  • Repeat spotlight calls to walk the viewer through an algorithm.

This example shows the next version of that idea: the spotlight walks from one line to another while the code stays readable.

A code walkthrough: type the code, spotlight line 2, then move the focus to line 3.
Files that made this video

A small tutorial project: `src/main.rs` is typed, then the script spotlights line 2 and line 3.

scenes/intro.ccs
Adds the line spotlight, underline, and camera timing.
Open full file
let s = scene("Intro", 220);

let code = s.code(read("src/main.rs"), "rust", 96, 150);
code.font_size(38).fade_in(0, 16).typewriter(6, 70);

code.spotlight(2, 0.6, 92, 18);
s.underline(code, 2, 98, 12);
code.spotlight(3, 0.6, 150, 24);
code.unfocus(200, 16);

Step 7 โ€” Render the finished starter scene

One command turns the three files into a video:

./target/release/cinecode render my-video -o my-video.mp4

Here is the actual output of the project above โ€” the real code from src/main.rs typing itself out, with the spotlight landing on line 2:

my-video.mp4 โ€” your first render. The code in src/main.rs, filmed by intro.ccs.
Files that made this video

The starter project created by `cinecode new my-video`: one manifest, one scene script, and one Rust file.

codescene.toml
Tells CineCode to render `scenes/intro.ccs` at 1280x720 and 30 fps.
Open full file
scenes = ["scenes/intro.ccs"]
theme = "dark_documentary"

[episode]
title = "my-video"

[output]
fps = 30
width = 1280
height = 720

Coordinates are in pixels from the top-left, before camera transforms. With a 1280ร—720 output, x = 96 leaves a comfortable left margin.

Step 8 โ€” Change something and re-render

Make the loop click. Open src/main.rs and change just the greeting:

src/main.rs
fn main() {
    let greeting = "Rivers carve canyons.";
    println!("{greeting}");
}

Render again โ€” you don't touch the script at all, because the script just reads the file:

./target/release/cinecode render my-video -o my-video.mp4

The new text types itself out. That's the entire workflow: edit your code (or the script), render, watch.

Before moving on, try one small change from each category:

  • Change the title text in scenes/intro.ccs.
  • Change .font_size(52) to .font_size(44).
  • Change .glow(0.5) to .glow(0.9).
  • Change code.spotlight(2, ...) to code.spotlight(3, ...).
  • Change the greeting in src/main.rs.

Render after each one. You will learn faster from five tiny renders than from one large script you do not yet understand.

You did it

You created and rendered your own project. Next, you'll make the code perform โ€” spotlighting and dimming lines like a real documentary.

On this page