Skip to content

freeze_at is reapplied by hand in all five render paths: the next path added will ignore it again #164

Description

@LeadcodeDev

Found while re-scoring the Remotion differential. This is a weakness in a chantier fix, not a pre-existing defect.

The finding

PR #152 fixed a real bug — scene.freeze_at was read by no code path in the world view. But it fixed it by adding a fifth copy of the same logic rather than unifying. The comment it left says so itself:

// crates/rustmotion/src/engine/render/scene.rs:958
// Apply freeze_at (parity with the other four render paths — …)

The five sites, all in crates/rustmotion/src/engine/render/scene.rs:

Line Form
138 if let Some(freeze_at) = scene.freeze_at { if time > freeze_at { time = freeze_at } }
670 same
966 anim_time = anim_time.min(freeze_at)
1119 same as line 138
1180 same as line 138

Why it matters

The bug PR #152 fixed will recur. Its root cause was not "we forgot freeze_at in the world view"; it was "there is no single place where freeze_at applies, so every new render path has to remember to redo it". That cause is intact. A sixth render path — and the chantier added one, render_scene_frame_scaled_with_prev_bg — will start out with the same omission, and nothing will flag it.

One of the five copies has already drifted in form. Line 966 uses .min() where the other four use an if. The result is equivalent today, but that is exactly the signature of a duplication starting to diverge — and no test asserts that the five paths treat freeze_at identically.

Direction

Apply freeze_at once, where scene time is computed, before it reaches the render paths — rather than inside each one. The exact shape depends on how each path derives its time; if no common point exists yet, creating one is precisely the work.

This is also the first brick of the Remotion gap "generic time container on any node": freeze_at (scene), time_scale and time_offset (today restricted to card and flex) are three facets of the same local time remap, each wired separately. Unifying them closes this debt and opens that gap at once.

Suggested verification

A test parameterized over the five render paths, asserting that at time > freeze_at each produces the frame at freeze_at. None exists today: PR #152 tested only the world path, the one it was repairing.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions