Skip to content

fix(core): a multi-worker render replays overlapping tweens behind the timeline stand-in - #7231

Merged
miguel-heygen merged 2 commits into
mainfrom
cloudperf/7223-overlap-replay
Nov 5, 2026
Merged

miguel-heygen merged 2 commits into
mainfrom
cloudperf/7223-overlap-replay

Conversation

@miguel-heygen

Copy link
Copy Markdown
Collaborator

What

A multi-worker or chunked render now replays overlapping tweens when the composition's timeline came through the producer's GSAP stub, so -w 8 matches -w 1 frame for frame on the repro in #7223.

Why

The replay from #6707 decides which frames to re-render by finding tweens that write the same property at the same time. It finds them by walking each tween's parents up to the timeline being seeked. In a render, that timeline is the stand-in the producer's early GSAP stub hands the composition (__hfReal holds the real one), so the walk never meets it. It walks past the real timeline instead, which is paused, gives up, and finds no overlaps. No frame was replayed, and the output matched 0.8.214. The unit tests seek a real timeline, which is why they passed. Preview never goes through the stub, so playback was unaffected.

Related work

Fixes #7223. Follows #6707.

How

  • gsapTimelineOf (stand-in to real timeline) moves from init.ts into the GSAP adapter, its one owner, and init.ts imports it.
  • The overlap walk compares each tween's parents with gsapTimelineOf(timeline). Seeks still go through the stand-in, which flushes queued tweens first.
  • The landing-mark walk (startOnOwner) had the same comparison: behind a stand-in, every step lost its time, so two steps at one time were not re-applied in authored order after the playhead came back onto them. It now compares with gsapTimelineOf(owner) too.
  • Checked, not changed: timeline.ts walks tween parents up to the registered root to build the clip list; I found no render output that depends on it, so it is left for a separate change if one turns up.
  • The stand-in fixture lives in gsapStandIn.test-helpers.ts, shared by both test files.

Test plan

  • Unit tests added/updated: gsap.order.test.ts adds "gives every frame the same value when the producer hands out a stand-in for the timeline", 8 interleaved workers seeking a stand-in shaped like the stub's. Fails without the fix: expected [ 56, 1.040171 ] to deeply equal [ 56, 1.449293 ].
  • gsap.steps.test.ts: "shows two steps on one later time in authored order after the playhead comes back onto %s" now runs for a timeline and for the producer's stand-in. Fails without the fix: expected 'hidden' to be 'visible'.
  • Both files pass three runs in a row. All core runtime tests pass (118 files, 2,799 tests); tsc --noEmit, oxlint and oxfmt are clean.
  • Manual testing performed: the Multi-worker render still differs from -w 1 on 0.9.15 with a set and a tween inside a running tween (#6707 pattern) #7223 composition with GSAP 3.15.0 on Linux x64, box width measured on row 960:
    • 0.9.15, -w 1 vs -w 8: 59 of 90 frames differ (17 to 75).
    • This branch, -w 1 vs -w 8: 0 of 90 differ (t = 0.8 s: 1.420 in both).
    • This branch -w 1 vs 0.9.15 -w 1: 0 differ.
  • Documentation updated (if applicable)
  • Comments follow CONTRIBUTING.md "Comments"

…e timeline stand-in

The overlap and landing-mark walks compared tween parents with the stand-in the producer's GSAP stub hands out, never met it, and lost the overlaps and step times. Both now compare with the real timeline behind the stand-in.

@heygengenesis heygengenesis Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: REQUEST CHANGES · 1 blocker · 0 important · 0 nits · head ba5ce982

The fix is right. Both parent walks that compare against the seeked timeline (writeOf, startOnOwner) now resolve the stand-in, and the producer stub's __hfReal matches the test stand-in. The two tests on Fails without the fix: lines prove it.

  • blocker: the Comments check fails at this head. Moving gsapTimelineOf carried its comment into gsap.ts, which raises that file's comment share (3/583 vs 2/576). The ratchet checks each file, so the line removed from init.ts doesn't offset it. Drop the doc comment on gsapTimelineOf (the name and the __hfReal read carry it), or fold it into the name.
Scope

I read all 5 files, every parent-identity walk in adapters/gsap.ts and init.ts, and the stub's stand-in in producer/stubs/hf-early-stub.ts. structure.owner reaches startOnOwner unchanged, so the resolution there covers every landing-mark caller. CI, regression and the player jobs were still running when I reviewed. Only Comments had failed.

— Genesis lane B

@github-actions

github-actions Bot commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

Edit accuracy: accurate 267 (base branch 267), smooth 91 of those

The gate passes.
Smoothness is reported in the artifact, not gated. A case fails only if it fails 2 of 3 runs.

Quarantined, measured but not gated (8)

Unstable (1)

  • seqplainkeys-none-pct-r0-nested-z100: tracking 0.05, pressJump 0, drop 0, reload 0, render 0.02, renderKey -, undo false, teleport true / tracking 0.05, pressJump 0, drop 0, reload 0, render 0.02, renderKey -, undo true, teleport true / tracking 0.05, pressJump 0, drop 0, reload 0, render 0.02, renderKey -, undo true, teleport true

@heygengenesis heygengenesis Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: APPROVE — 1 resolved, 0 open, 0 new · ba5ce982 → d3cb83a9

✅ The only change since ba5ce982 is the removed doc comment, and Comments passes. CI is red, but not from this change. Test (studio) and SDK: unit + contract + smoke failed on 504s while downloading setup files (ffmpeg-static, setup-test-workspace). Studio: timeline viewport gate missed its p95 timing budget. Test (runtime), Producer unit and integration, Typecheck and Lint pass. Re-run the failed jobs before merge.

— Genesis lane B

@miguel-heygen
miguel-heygen added this pull request to the merge queue Nov 5, 2026
Merged via the queue into main with commit b96d3c8 Nov 5, 2026
147 of 151 checks passed
@miguel-heygen
miguel-heygen deleted the cloudperf/7223-overlap-replay branch November 5, 2026 09:54
miguel-heygen added a commit that referenced this pull request Nov 5, 2026
@heygengenesis heygengenesis Bot mentioned this pull request Nov 5, 2026
miguel-heygen added a commit that referenced this pull request Nov 5, 2026
mitanshu450 pushed a commit to mitanshu450/hyperframes-video-generation that referenced this pull request Nov 5, 2026
* chore: release v0.9.16

* chore: format v0.9.16 release notes

* chore: add heygen-com#7228 and heygen-com#7231 to v0.9.16 notes

* chore: add heygen-com#7217 heygen-com#7224 heygen-com#7225 heygen-com#7226 heygen-com#7229 heygen-com#7233 to v0.9.16 notes
SanHsien added a commit to SanHsien/hyperframes that referenced this pull request Nov 6, 2026
…eview

Adopts or partially adopts 11 groups: multi-worker tween replay behind
the timeline stand-in (heygen-com#7231), template entries in the shared compile
stage (heygen-com#7217), HYPERFRAMES_CACHE_DIR and HYPERFRAMES_CONFIG_DIR for
every per-user cache and settings file (heygen-com#7224, heygen-com#7229; HeyGen
credentials stay under HEYGEN_CONFIG_DIR), WebKit audio clock (heygen-com#7225),
packet-based video length (heygen-com#7233), HLG tone mapping (heygen-com#7234), fetch
network cause (heygen-com#7236), .hyperframesignore in lint (heygen-com#7239), info
--media (heygen-com#7235), lint priority (heygen-com#7244), check --budget (heygen-com#7245) and the
unknown-command answer (heygen-com#7247). bun.lock gains only the lint `ignore`
edge from heygen-com#7239, already resolved. Watermark advances to 0a6746e.

Co-authored-by: Jerrai <jerrai@heygen.com>
Co-authored-by: Miguel Ángel <miguel.sierra@heygen.com>
Co-authored-by: WaterrrForever <miao.yang@heygen.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@miguel-heygen
miguel-heygen restored the cloudperf/7223-overlap-replay branch November 9, 2026 19:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Multi-worker render still differs from -w 1 on 0.9.15 with a set and a tween inside a running tween (#6707 pattern)

1 participant