Skip to content

feat(classic-random): add per-champion Classic skin randomization - #346

Draft
ccccxp wants to merge 11 commits into
Alban1911:mainfrom
ccccxp:pr/classic-random
Draft

ccccxp wants to merge 11 commits into
Alban1911:mainfrom
ccccxp:pr/classic-random

Conversation

@ccccxp

@ccccxp ccccxp commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Merge order

This PR requires ClassicWheel #344. Please merge #344 first. This branch contains only its eleven randomization commits and does not include ClassicWheel, history, or chroma commits.

What this adds

This adds a Rift Classic dice control and random marker. Random mode is saved per champion and selects only skins and chromas present in the current Classic catalog.

The result is applied during the stable finalization window rather than when the button is enabled. The native carousel then moves to the selected parent card and updates the full-screen artwork. Any manual skin or chroma choice disables the active and saved random setting for that champion. A valid random target takes priority over Classic history.

Why a separate plugin

The regular random plugin expects the ordinary selector and its Skin0 base-selection flow. Classic randomization has a fixed live catalog, 600xx IDs, different timing, optional chromas, and direct history coordination.

ROSE-ClassicRandom owns only the Classic control and state. ClassicWheel owns carousel movement. The regular random plugin remains unchanged outside Rift Classic and stays available as a fallback if the Classic plugin is unavailable.

Carrier and resource compatibility

The random pool stores resource skin and chroma IDs, not carrier IDs. With #344 alone it uses upstream's Skin0 + classic/ path. If #318 is present, the result follows Rose's automatic choice between native default + classic-native/ and Skin0 + classic/. This PR does not choose or mix carrier package families.

For standalone review, optional wheel helpers fall back to upstream Skin0 behavior instead of copying the wheel implementation.

Validation

  • 39 focused injection, Classic library, history, Pengu bridge, chroma, and countdown tests passed.
  • JavaScript syntax and changed Python module checks passed.
  • Integrated live testing covered delayed activation, per-champion restore, manual cancellation, history priority, random badges, parent-card movement, artwork synchronization, and random chroma injection.

Changed files

  • Pengu Loader/plugins/ROSE-ClassicRandom/index.js
  • Pengu Loader/plugins/ROSE-RandomSkin/index.js
  • ui/core/user_interface.py
  • ui/handlers/classic_random_integration.py
  • ui/handlers/randomization_handler.py
  • utils/core/random_preferences.py

ccccxp added 11 commits October 18, 2026 16:51
Add an isolated Classic random control that selects only skins present in the validated live carousel, includes eligible chromas, and projects the chosen result during the stable finalization window instead of changing the card immediately.

Persist the enabled state per champion and reactivate it only after a valid Classic catalog arrives. Explicit skin or chroma navigation clears the preference, while lifecycle resets leave it available for the next selection of the same champion.

Classic activation bypasses the regular Skin0 base-selection request, keeps the random result and selected chroma state aligned for injection, and disables active Classic history before taking control. Regular-mode random behavior is unchanged.

Source commits consolidated: a7e1109b, 3e3f6598, and the random portion of 485f65a8.

Verification: random selection and finalization carousel movement were previously exercised in live Classic games, including chroma results. The preference round-trip test passed locally and the plugin passed node --check.
Disable active Classic history before random mode takes control, preserve chroma identity in the selected random target, and emit dedicated Classic random diagnostics.

Validation: covered by final branch syntax and git diff checks. No separate live-client run is claimed for this commit.
Keep random preferences independent of the selected carrier and project the chosen skin or chroma through the optional Classic wheel API. Explicit manual selection clears both active and saved random state.

Validation: covered by final branch syntax and git diff checks. No separate live-client run is claimed for this commit.
Keep the dice button, enabled state, and random badge attached to the selected native card across wheel refreshes. Delay visual carousel movement until finalization while preserving the randomly selected skin or chroma for injection.

Validation: covered by final branch syntax and git diff checks. No separate live-client run is claimed for this commit.
Compare random candidates against the state-aware Classic default instead of reading only the native-carrier field. This preserves the same random pool when the wheel runs with the upstream Skin0 fallback policy.

Validation: covered by final branch syntax and git diff checks. No separate live-client run is claimed for this commit.
Rename the internal random-state reset helper so Classic-specific lifecycle integration can clear only the active result without changing the saved per-champion preference.

The actual wheel lifecycle adapter is added separately, keeping this commit limited to the reusable random-state operation.

Validation: Python compilation and git diff checks pass for the changed handler.
Mount the dice button and random marker in the wheel-owned stable host, and explicitly preserve pointer interaction through the host overlay. This prevents reused card nodes from flashing or temporarily carrying random controls on side cards.

The plugin remains independent of the carrier policy and works with both upstream Skin0 and an optional supplied native carrier.

Validation:

- JavaScript syntax and git diff checks passed.

- Focused history and random regression checks passed (9 tests).
Publish the Classic random owner only after its bridge subscriptions and assets are initialized.

The regular RandomSkin plugin now stops rendering only in JADE sessions where the matching Classic random owner is ready. Ordinary modes remain unchanged, and JADE keeps the upstream fallback when the dedicated plugin is missing or cannot initialize.

Keeping this UI switch in the random feature PR avoids a global Classic-mode switch and makes the PR independently reviewable after the Classic wheel interface is merged.

Validation: covered by final branch syntax and git diff checks. No separate live-client run is claimed for this commit.
Provide the optional lifecycle adapter consumed by ClassicWheel after its catalog is ready and when a champion context is reset. Restore the saved per-champion random target only from the validated active catalog, release stale runtime selections, and keep random mode ahead of Classic history only after a valid target is active.

The adapter is inert without ClassicWheel and contains no carousel implementation. This keeps the random PR limited to randomization while preserving normal-mode behavior.

Validation: Python compilation and git diff checks pass for the new adapter and randomization handler.
Preserve the established catalog lifecycle after moving random hooks out of ClassicWheel. A valid persisted random target still takes ownership first; when random mode is disabled or cannot restore a catalog-backed target, the saved Classic history target is allowed to activate.

This restores the behavior from the previously published combined branch without moving wheel code back into the random PR. The history lookup remains optional, so the random feature still operates with ClassicWheel alone and gains scoped history restoration when the history PR is present.

Validation: five focused random preference, manual-selection, mode-coordination, and history-fallback regressions pass against the ClassicWheel combination; the champion reset contract and git diff checks pass.
Use the carrier-aware ClassicWheel helpers when that base PR is present, while retaining the upstream Skin0 behavior when this feature branch is reviewed or merged on its own.

This keeps the random PR functionally isolated: it does not copy the wheel implementation or modify the shared Classic core module.

Validation: 39 focused injection, Classic library, history, Pengu bridge, chroma, and countdown tests passed.
@ccccxp
ccccxp force-pushed the pr/classic-random branch from 2a16246 to 7238eca Compare October 18, 2026 14:42
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