Skip to content

Improve win cascade animation performance - #100

Merged
austin-smith merged 3 commits into
mainfrom
improve-win-cascade-performance
Aug 12, 2026
Merged

Improve win cascade animation performance#100
austin-smith merged 3 commits into
mainfrom
improve-win-cascade-performance

Conversation

@austin-smith

Copy link
Copy Markdown
Owner

What Changed

  • Replaced the win cascade's Task.sleep loop (fixed 1/60s step) with a tick driven by TimelineView(.animation)'s frame clock that advances the physics by real measured elapsed time, clamped by the existing step bounds.
  • Rewrote WinCascadeOverlayView to render the whole cascade as a single Canvas: each card face resolves once as a Canvas symbol and is stamped with a per-frame translate/rotate transform, replacing 52 live CardViews with per-card layout, diffing, and shadow blurs.
  • Removed the cascade-only extra drop shadow so flying cards look identical to resting cards (no shadow pop at launch); cards keep the shadow baked into their artwork.
  • Live simulation state moved behind @ObservationIgnored so per-frame mutation cannot schedule redundant SwiftUI updates; a new observable launchStates snapshot drives symbol creation. Cascade completion defers the phase flip off the render pass, guarded by a generation token.
  • Settled cards now skip the simulation loop entirely, and the canvas size feeds the physics bounds so mid-cascade window resizes track.
  • Removed the now-unneeded cancelTask() (the timeline stops itself when the view disappears).

Why

The win animation could visibly lag and slow down. Two compounding causes: the fixed-timestep loop turned every dropped frame into slow motion (real time passed faster than simulated time), and the per-card live shadow blurs were the dominant GPU cost producing those dropped frames. The rework fixes the timing model and collapses rendering to one draw pass per frame, and the animation now runs at the display's native cadence (120 Hz on ProMotion).

Validation

  • Full macOS Debug build succeeds.
  • Complete macOS test suite passes (602 executed, 0 failures, 10 pre-existing skips), re-run on the final state of the branch.
  • Manually reviewed cascade behavior parity: launch stagger, bounce/settle physics, restored-win settled pile, and Reduce Motion path are unchanged.

UI Changes

Flying cascade cards no longer gain an extra drop shadow beyond the card artwork's own — they now match resting cards exactly. Motion timing is otherwise visually identical, minus the lag.

the cascade was driven by a task.sleep loop stepping a fixed 1/60s per
tick, so any dropped frame stretched the animation into slow motion, and
each of the 52 cards rendered as a live swiftui view with its own
per-frame shadow blur — the dominant gpu cost that caused the drops in
the first place.

the physics now advances by real elapsed time off a timelineview frame
clock (native 120 hz on promotion), and the overlay renders as a single
canvas that resolves each card face once as a symbol and stamps it with
a per-frame transform. the extra cascade-only drop shadow is removed so
flying cards match resting cards exactly; settled cards skip simulation
entirely, and the canvas size feeds the physics bounds so mid-cascade
resizes track.
@austin-smith

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5f963c54af

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread ComputerSolitaire/Animation/WinCelebrationController.swift Outdated
the tick previously clamped measured frame deltas to [1/120, 1/30]s,
which discarded time beyond 33ms on slow frames and fabricated time on
displays above 120hz. advance() now splits real frame time into <=1/60s
substeps so simulated time matches wall time at any refresh rate, capped
at 133ms per frame so a long stall jumps ahead instead of
fast-forwarding.
@austin-smith

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 👍

Reviewed commit: aef86c7712

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@austin-smith
austin-smith merged commit ee5cd6f into main Aug 12, 2026
3 checks passed
@austin-smith
austin-smith deleted the improve-win-cascade-performance branch August 12, 2026 05:39
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.

1 participant