|
2 | 2 |
|
3 | 3 | ## Overview |
4 | 4 |
|
5 | | -Classic Mode support is implemented as an isolated feature for JADE games. The |
6 | | -regular game-mode flow and its existing plug-ins remain unchanged. Classic-only |
7 | | -state, persistence, resource resolution, and client plug-ins are kept separate |
8 | | -so that a Classic selection cannot leak into a regular match. |
| 5 | +Classic Mode support is isolated to JADE sessions. Its catalog, projected |
| 6 | +selection, history, random preference, chroma state, package lookup, and client |
| 7 | +controls do not replace the regular-mode implementations. The regular chroma, |
| 8 | +forms, history, and random plug-ins only add a lifecycle guard that removes |
| 9 | +their controls while JADE is active and restores their normal behavior after |
| 10 | +the session. |
| 11 | + |
| 12 | +## Mode and ID Boundary |
| 13 | + |
| 14 | +Rose derives Classic Mode from live LCU session data. `gameMode == JADE` is the |
| 15 | +primary signal, with queue `3260` and map `453` retained as compatibility |
| 16 | +fallbacks. |
| 17 | + |
| 18 | +Inside Rose, champion and skin IDs match the external `classic/` resource tree, |
| 19 | +for example champion `55` and skin `55301`. JADE's `600` prefix belongs only to |
| 20 | +the LCU transport boundary: `60055` and `60055301` are normalized when read and |
| 21 | +restored only when Rose must write a mode-native value back to LCU. Catalog, |
| 22 | +history, randomization, package lookup, naming, and injection use resource IDs. |
| 23 | + |
| 24 | +The active carrier is resolved from the live Classic catalog rather than from a |
| 25 | +per-champion fallback table. Before an LCU write, Rose verifies that the carrier |
| 26 | +belongs to the active champion and is present in the current pickable-skin |
| 27 | +catalog. |
| 28 | + |
| 29 | +## Native Carousel and Selection |
| 30 | + |
| 31 | +`ROSE-ClassicWheel` adapts Riot's native JADE skin carousel. Riot's cards remain |
| 32 | +responsible for layout, focus, animation, arrow interaction, and full champion- |
| 33 | +select splash transitions. ClassicWheel supplies the Classic catalog, enforces |
| 34 | +its finite boundaries, projects history or random targets through native |
| 35 | +navigation, and publishes one normalized selection contract to the other |
| 36 | +Classic controls. |
| 37 | + |
| 38 | +Owned Classic skins continue through the official LCU selection path. For an |
| 39 | +unowned target, Rose keeps a valid owned carrier as the server-visible LCU |
| 40 | +selection and stores the requested visual target separately. Automatic |
| 41 | +navigation may pass through owned cards to obtain the native splash transition, |
| 42 | +but those intermediate cards are not accepted as user selections. The target |
| 43 | +splash remains protected until real user navigation, a context exit, or an |
| 44 | +explicit replacement target releases it. |
| 45 | + |
| 46 | +Selection generations prevent delayed carousel or WebSocket events from |
| 47 | +replacing a newer target during the final lock transition. Injection consumes |
| 48 | +the accepted projected selection rather than inferring it again from transient |
| 49 | +card state. |
9 | 50 |
|
10 | | -## Mode Detection |
11 | | - |
12 | | -Rose normalizes the active mode from live LCU session data. `gameMode == JADE` |
13 | | -is the strongest signal, with queue `3260` and map `453` used as compatibility |
14 | | -fallbacks. The normalized mode is stored centrally and is cleared when the |
15 | | -champ-select session ends or contradicting session data is received. |
16 | | - |
17 | | -## ID and Carrier Model |
18 | | - |
19 | | -Classic Mode exposes several IDs for the same visual choice: |
20 | | - |
21 | | -- The prime champion ID identifies the regular champion. |
22 | | -- The mode champion ID identifies the Classic entity. |
23 | | -- The raw LCU skin ID identifies the mode-native skin selection. |
24 | | -- The resource skin ID identifies the package in the Classic resource library. |
25 | | -- The visual skin ID identifies the regular skin being projected locally. |
26 | | - |
27 | | -These ID domains are converted through `utils/core/classic_mode_ids.py` rather |
28 | | -than inferred at individual call sites. |
29 | | - |
30 | | -Classic champions use different native carriers. Rose resolves a carrier from |
31 | | -the current LCU catalog when possible and falls back to the versioned matrix: |
32 | | - |
33 | | -- Skin0 for champions without a Classic Skin301/302 carrier. |
34 | | -- Skin301 for the supported Skin301 champions. |
35 | | -- Skin302 for Kayle. |
36 | | - |
37 | | -The carrier belongs to the current mode champion and remains the server-visible |
38 | | -selection throughout local projection. |
| 51 | +## Classic Plug-ins |
39 | 52 |
|
40 | | -## Selection and Ownership |
| 53 | +Classic controls are separate plug-ins: |
41 | 54 |
|
42 | | -Owned Classic skins continue through the official LCU selection path and are not |
43 | | -locally injected. For an unowned visual selection, Rose keeps the owned |
44 | | -mode-native carrier in LCU and stores the requested visual skin separately. The |
45 | | -unowned projected ID is never written to LCU. |
| 55 | +- `ROSE-ClassicWheel` provides the finite native carousel adapter and shared |
| 56 | + selection contract. |
| 57 | +- `ROSE-ClassicChroma` renders variants from the Classic catalog and publishes |
| 58 | + Classic chroma selections. |
| 59 | +- `ROSE-ClassicHistoric` restores and presents mode-scoped history. |
| 60 | +- `ROSE-ClassicRandom` stores per-champion random state and presents its dice |
| 61 | + control and selected-card marker. |
46 | 62 |
|
47 | | -Selection generations reject stale events during the final lock transition. |
48 | | -This prevents delayed UI events from replacing a newer selection or updating a |
49 | | -different champion. |
| 63 | +Classic randomization follows the regular-mode probability model: it selects a |
| 64 | +parent skin first, then chooses between that parent and its eligible chromas. |
| 65 | +The visual target is projected during the stable final-countdown window instead |
| 66 | +of moving the carousel as soon as random mode is enabled. |
50 | 67 |
|
51 | | -## Classic Plug-ins |
| 68 | +Classic-specific Forms are not included because the current resource catalog |
| 69 | +does not contain a confirmed target that requires the regular FormsWheel |
| 70 | +behavior. |
52 | 71 |
|
53 | | -Classic controls are provided by separate plug-ins: |
| 72 | +## Resource and Injection Flow |
54 | 73 |
|
55 | | -- `ROSE-ClassicWheel` provides the finite Classic skin carousel. |
56 | | -- `ROSE-ClassicChroma` provides Classic chroma selection and persistence. |
57 | | -- `ROSE-ClassicHistoric` provides isolated Classic history state and display. |
58 | | -- `ROSE-ClassicRandom` provides per-champion Classic randomization. |
| 74 | +Classic packages resolve only from the isolated `classic/` resource directory; |
| 75 | +Rose does not fall back to regular `skins/` packages for a Classic selection. |
| 76 | +Parent skins and nested chroma packages use the same normalized resource IDs |
| 77 | +published by ClassicWheel. |
59 | 78 |
|
60 | | -The regular plug-ins are not modified to contain Classic conditionals. Classic |
61 | | -controls clean themselves up when champ select ends and do not leave overlays or |
62 | | -state behind for the next match. |
| 79 | +Before launching an unowned target, Rose restores the validated mode-native |
| 80 | +carrier and reuses the existing overlay and injection pipeline. The projected |
| 81 | +target, carrier, chroma, history state, selection generation, and final |
| 82 | +injection ID are retained as separate values through this boundary. |
63 | 83 |
|
64 | | -`ROSE-ClassicWheel` ports Catcat's validated JADE adapter for Riot's native |
65 | | -skin-card carousel. It is unrelated to `ROSE-CustomWheel`, which manages |
66 | | -third-party mods. The chroma, history, and random plug-ins port Catcat's |
67 | | -isolated JADE controls as Classic counterparts to Rose's regular features. |
68 | | -They preserve the corresponding behavior and bridge contracts, but they are |
69 | | -not source-level forks of the regular Rose plug-ins. |
| 84 | +Classic peer selections in Party Mode are normalized into the Classic resource |
| 85 | +namespace before package lookup. This path has passed compilation checks but |
| 86 | +has not received formal live-machine validation. |
70 | 87 |
|
71 | | -## Resource and Injection Flow |
| 88 | +Rose uses [Alban1911/LeagueSkins](https://github.com/Alban1911/LeagueSkins) as |
| 89 | +its default resource repository. Classic packages are read from that |
| 90 | +repository's isolated `classic/` directory. |
72 | 91 |
|
73 | | -Classic packages are resolved only from the `classic/` resource directory. Rose |
74 | | -does not fall back to the regular `skins/` directory for a Classic selection. |
75 | | -The downloader and cleanup logic treat `skins/`, `classic/`, and `resources/` |
76 | | -as separate resource sets. |
| 92 | +## Diagnostics |
77 | 93 |
|
78 | | -Classic packages may use a mode-native carrier while targeting a different |
79 | | -visual skin. The converted package therefore retains the required dependency |
80 | | -closure and redirects model, weapon, animation, VFX, and related asset links to |
81 | | -the correct carrier. Package preparation restores the native carrier before |
82 | | -launch and reuses Rose's existing overlay and injection path. |
| 94 | +Classic browser messages use searchable `[CLASSIC:<AREA>]` tags and are routed |
| 95 | +through the plug-in log bridge. Backend checkpoints cover catalog acceptance, |
| 96 | +selection and chroma changes, history and random state, LCU carrier state, game |
| 97 | +start identity, package resolution, and the final injection target. Regular-mode |
| 98 | +messages retain their existing prefixes. |
83 | 99 |
|
84 | | -Rose uses [Alban1911/LeagueSkins](https://github.com/Alban1911/LeagueSkins) |
85 | | -as its default resource repository. Classic packages are read from that |
86 | | -repository's isolated `classic/` directory. |
| 100 | +## Deferred Work |
87 | 101 |
|
88 | | -## Current Limitations |
| 102 | +Full third-party Mod loading in Classic Mode is still experimental and is not |
| 103 | +part of this stable commit series. The excluded work includes Classic-specific |
| 104 | +skin Mod controls, mode-scoped Mod history, and compatibility handling for map, |
| 105 | +font, announcer, UI, voiceover, loading-screen, VFX, SFX, and other Mod |
| 106 | +categories. Those paths require formal validation before they are proposed. |
89 | 107 |
|
90 | | -Classic Mode support is working end to end, but some edge cases may still need |
91 | | -follow-up validation across client versions and less common skin dependency |
92 | | -graphs. The resource changes are currently maintained separately from Rose and |
93 | | -can be proposed to the upstream resource repository in a later PR. |
| 108 | +`ROSE-SettingsPanel` integration for Classic skin Mods is also deferred. The |
| 109 | +regular `ROSE-CustomWheel`, `ROSE-CustomSkinSelector`, and SettingsPanel code |
| 110 | +remain available for regular game modes. |
0 commit comments