Skip to content

Keep vocal modifier uniformity from overwriting saved selections#1517

Open
XaiaX wants to merge 1 commit into
YARC-Official:devfrom
XaiaX:bug/modifier-clobber
Open

Keep vocal modifier uniformity from overwriting saved selections#1517
XaiaX wants to merge 1 commit into
YARC-Official:devfrom
XaiaX:bug/modifier-clobber

Conversation

@XaiaX

@XaiaX XaiaX commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

NOTE: This depends on this PR.

Summary

Two changes: the launch-time loop that gives all vocal players the selecting player's modifiers now calls ApplySessionModifiers instead of CopyModifiers, so the uniformity is session-scoped instead of being written into the other players' persisted profiles; and when difficulty select opens, every player's effective modifiers are re-seeded from their saved selection (RestoreSavedModifiers), so a prior song's imposed modifiers don't linger on the long-lived in-memory profile and reappear on the next visit.

Steps to reproduce

  1. Create 2+ vocal profiles. Give the second one a vocal modifier (No Vocal Percussion or Unpitched Only) — e.g. sit the first profile out in difficulty select so the second becomes the modifier selector, set the modifier, play or back out.
  2. Now play a song with both profiles in (nobody sitting out). The first profile readies first, becoming the modifier selector with "None".
  3. After the song, check the second profile's modifiers (sit the first profile out again to see its modifier menu).
  4. Bug: the second profile's modifiers read "None" — its saved selection was permanently overwritten, including in the profile JSON on disk.

Root cause

DifficultySelectMenu.ChangePlayer enforces uniform vocal modifiers at launch (only the selector may edit them — the menu item is hidden for everyone else — and the selector's set is copied to all non-sitting-out vocal players). The enforcement is correct; the implementation (CopyModifiers) writes the persisted CurrentModifiers field, making a session rule permanent. The affected players can't even see it happen: the modifier menu is hidden for them in exactly the sessions where the overwrite occurs.

A second, subtler defect surfaced on first in-game test of the ApplySessionModifiers swap: with the persisted value no longer overwritten, the effective value still lingered. Profiles are long-lived objects, so the modifiers a player received from the selector stayed in effect after the song, and the menu (which reads the effective value via IsModifierActive) showed them on the next visit, looking identical to the original bug even though the saved value on disk was correct and an app restart would show it correctly.

Fix

  1. Swap the launch-time copy to the session-scoped YargProfile.ApplySessionModifiers (see Core PR). Gameplay engines, score screen, and replay recording still see the uniform effective modifiers; each profile's saved selection is no longer overwritten.
  2. When difficulty select opens, call RestoreSavedModifiers on every player so the effective value is re-seeded from the saved selection, discarding any modifiers a previous song imposed, so the menu shows (and edits) each player's own saved selection.

Changes

File Change
Assets/Script/Menu/DifficultySelect/DifficultySelectMenu.cs CopyModifiersApplySessionModifiers in the launch-time uniformity loop; RestoreSavedModifiers on all players when the menu opens

Testing done

  • In-game (2026-06-12), both branches in the runtime: ran the repro with 3 vocal profiles, modifiers set on lower profiles and on the selector, across repeated song→menu→song cycles. Each profile's saved modifier shows correctly on every difficulty-select visit (not just after a restart), and the song plays with the selector's modifiers for everyone. Earlier build (swap only, before RestoreSavedModifiers) reproduced the lingering-effective defect; corrected build is clean.
  • Core-side behavior covered by YargProfileModifierTests (session-apply not persisted; restore discards session modifiers; explicit edits persisted; legacy profile JSON loads).

The difficulty select menu enforces uniform vocal modifiers by giving every
vocal player the selecting player's modifiers at song launch. That copy
(CopyModifiers) wrote the persisted modifier field, permanently erasing the
other players' saved modifier selections - and they could not see it happen,
since the modifier menu is hidden for non-selecting vocal players.

Use the new session-scoped YargProfile.ApplySessionModifiers for the launch
copy so gameplay and replay recording still see uniform modifiers while each
profile's saved selection is left intact. Additionally, re-seed every player's
effective modifiers from their saved selection when difficulty select opens
(RestoreSavedModifiers), so modifiers imposed by a previous song do not linger
on the long-lived in-memory profile and reappear in the menu.

Requires the corresponding YARG.Core change.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants