gameplay: fix crossover cue fade timing and crossfade behavior#597
Draft
adstep wants to merge 3 commits into
Draft
gameplay: fix crossover cue fade timing and crossfade behavior#597adstep wants to merge 3 commits into
adstep wants to merge 3 commits into
Conversation
The cue builder overlaps consecutive crossover cues by CROSSOVER_CUE_FADE_SECONDS (0.075s), but the renderer faded each cue in and out over COLUMN_CUE_FADE_TIME = 0.15s — twice the overlap. With the fade longer than the overlap, the outgoing cue's fade-out never lined up with the incoming cue's fade-in, so back-to-back cues looked like they barely overlapped. Set COLUMN_CUE_FADE_TIME to 0.075s to match the original Simply Love 8ms theme's fadeTime (and the builder's overlap), so a cue's fade-out fully crossfades with the next cue's fade-in. Updates the column_cue_alpha tests for the new timing; notefield tests pass.
…crossfade The crossover render path used active_column_cue, which returns only the single most-recently-started cue. The instant the next cue started (at prev_end - fade) the previous cue stopped rendering, dropping its entire fade-out and defeating the crossfade the builder sets up. Add active_column_cues, returning every cue whose [start, start+duration] window contains the current time, and loop over them in the crossover render path so the outgoing fade-out and incoming fade-in draw simultaneously — matching the 8ms theme, where each cue animates on its own independent column actor. At most two cues overlap by construction. Adds a unit test; cue tests pass and the workspace builds clean.
deadsync's crossover cue rendering is time-based, so it can show a cue's true state at any playhead position — something the 8ms theme's fire-and-forget tweens could not, which is why that theme simply suppresses a cue whose start you seek past. Instead of suppressing, anchor each cue's fade-in to the point it first becomes visible: its own start during normal play, or the seek-landing time when the playhead jumps into the middle of it. The cue then ramps up from 0 instead of popping in at full alpha, while still fading out at its real end. Normal play is unchanged (anchor == start), and anchors clear when the playhead rewinds before a cue's start so replays fade in naturally. Adds column_cue_alpha_anchored (column_cue_alpha now delegates to it) and stores per-cue entry times in the cue runtime, advanced once per player per frame in update_song_position_from_time. New tests cover the anchor tracking and the no-pop fade-in; workspace builds clean.
69a0f48 to
8e345f1
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Crossover cues were recently ported from the custom Simply Love 8ms theme, and a user reported that the fade-out of one cue and the fade-in of the next did not overlap enough. Digging in showed the port split a single fade constant into two mismatched ones and changed the rendering model in ways that quietly broke the intended crossfade.
What changed
Three focused fixes to how crossover cues display (in
deadsync-gameplayanddeadsync-notefield):Match the 8ms fade time. The cue builder overlaps consecutive cues by
CROSSOVER_CUE_FADE_SECONDS(0.075s), but the renderer faded each cue in/out over 0.15s, twice the overlap. Set the render fade to 0.075s so a cue's fade-out fully crossfades with the next cue's fade-in.Render every active cue. The render path used
active_column_cue, which returns only the single most-recently-started cue, so the moment the next cue began the previous cue's fade-out was dropped. It now draws every cue whose[start, start+duration]window contains the playhead (at most two by construction), producing a true crossfade that matches the 8ms theme's independent per-column actors.Fade seeked-into cues from the landing point. Instead of popping a cue in at full alpha when you seek into its middle in practice mode, each cue's fade-in is anchored to the point it first becomes visible: its own start during normal play, or the seek-landing time when you jump into it. Normal play is byte-for-byte unchanged.