# VR Beat Saber Handoff ## Project Status - Unity: `6000.3.12f1` - Branch: `master` - Remote: `origin = https://whdwo798.synology.me/whdwo798/BeatSaber.git` - Latest pushed commit before this document update: `fb59fc3 feat: polish result screen UI` - Current focus: raise overall UI quality, starting from the result screen, then HUD, then song select. ## Collaboration Rule - Code changes should go through a Codex and Claude Code mutual review gate. - A proposal should score at least 80/100 before implementation. - Review criteria: - Correctness - Scope control - Unity scene/runtime risk - Maintainability - Verification plan See `COLLABORATION_RULES.md`. ## Unity / MCP Bridge - `Assets/Editor/UnityCodexBridgeServer.cs` - Bridge now falls back across ports `19744-19748` when the default port is busy. - `tools/unity-mcp-server/index.mjs` - MCP server probes the same fallback port range when `UNITY_BRIDGE_URL` is not explicitly set. - This was added because Unity reported that the bridge socket address was already in use. ## Game Scene HUD ### ScoreCanvas Placement `Assets/Scenes/Game.unity` - `ScoreCanvas` was moved closer to the player: - Z: `17.8 -> 5` - Scale: `0.005 -> 0.006` - `applyHudPlacement`: `true -> false` - This prevents HUD elements from collapsing visually near the center of the tunnel. ### Runtime HUD `Assets/VRBeatsKit/Scripts/UI/ScoreManager.cs` - Left HUD: - Combo - Score - Accuracy - Current rank - Right HUD: - Multiplier value - Multiplier ring and faint ring background - Song progress bar - Current time / total time - Dynamic legacy `Text` labels lazily load `LegacyRuntime.ttf` to avoid missing-font rendering issues. - The progress bar fills from `0 -> 1` as the song progresses. ## Timing / Completion `Assets/VRBeatsKit/Scripts/Core/AudioManager.cs` - Song time now uses scheduled DSP time instead of reading `AudioSource.time`. - This avoids the Unity warning about requesting `time` from an audio source whose resource is not a clip. `Assets/Script/SongController.cs` - Song duration falls back to metadata or last note time when `clip.length` is zero. - Completion waits until the last note / known duration instead of ending early because of a bad clip length. - Note layer Y positions were raised so low notes are easier to slice: ```text lineLayer 0: -0.12 lineLayer 1: +0.22 lineLayer 2: +0.56 ``` ## Scoring / Rank Rules `Assets/VRBeatsKit/Scripts/UI/ScoreManager.cs` ### Score Formula ```text CurrentScore = 800000 * accuracyRatio + 200000 * comboRatio ``` - Max score: `1,000,000` - Accuracy contribution: `800,000` - Max combo contribution: `200,000` ### Judgement Points ```text Perfect = 1000 Great = 900 Good = 700 Miss = 0 ``` ### Timing Windows ```text Perfect <= 0.11s Great <= 0.20s Good <= 0.32s ``` ### Combo Multiplier The multiplier is intentionally beginner-friendly: ```text 0-4 combo x1.0 5-14 combo x1.1 15-29 combo x1.2 30-49 combo x1.35 50+ combo x1.5 ``` ### Rank Thresholds - `M`: final score `>= 1,000,000` - Other ranks use `AccuracyPercent`: ```text S+ >= 98% S >= 95% A >= 90% B >= 80% C >= 70% D >= 60% F < 60% ``` ### Rank Colors ```text M #E8B7FF prism / jewel tone S+ #41F2FF cyan neon S #FFD95C gold A #B9FF72 B #FFE06A C #FFB15C D #FF7C7C F #A9B7C0 ``` ## Result Screen `Assets/VRBeatsKit/Scripts/UI/FinalScoreLabel.cs` The result screen is now the first major UI-quality target. Current result layout is generated at runtime: ```text ResultLayoutRoot RankShadowText RankDepthText RankMainText ResultScoreText ResultAccuracyText ResultComboText ``` Implemented: - Existing `Title` is hidden while result content is shown. - Existing serialized `scoreText` is hidden and used as a font/material source. - Rank uses layered TMP text for a more dimensional badge. - Result info now shows: - `SCORE` - final score - `ACCURACY` - max combo - Result popup and restart/back buttons were tinted toward a darker translucent cyan UI style. Known follow-up: - `tmp.lineSpacing = -8.0f` is aggressive and may need visual tuning if the `SCORE` label overlaps the score value. - Button styling is improved by color, but does not yet have a dedicated neon border/glow treatment. - The scene appears to contain both result and game-over popup/button sets; verify that shared color changes are intentional. ## Visual Effects Blue visibility improvements were made in: - `Assets/VRBeatsKit/Settings/Settings.asset` - `Assets/VRBeatsKit/Scripts/Core/SaberTrailEffect.cs` - `Assets/VRBeatsKit/Scripts/Core/SliceTrailEffect.cs` - `Assets/VRBeatsKit/Scripts/Other/Spark.cs` Goal: - Keep red strong. - Make blue saber/trail/spark readable against the bright cyan tunnel. ## UI Quality Direction Current agreed direction: 1. Finish result screen polish first. 2. Then polish in-game HUD. 3. Then consider HUD migration from legacy `UI.Text` to TMP for sharper VR rendering. 4. Then redesign song select cards/details. Design principles: - Thin readable text. - Dark translucent panels, not heavy opaque boxes. - White/cyan baseline UI with rank color accents. - Large values, small labels. - Avoid clutter in the note highway. - Add micro animations only after the static layout is readable. ## Verification Notes - `git diff --check` passed for the latest result UI changes. - `dotnet build beatSaber.slnx --no-incremental` is not reliable for this Unity project in the current environment because regular .NET build cannot resolve many Unity/TMP/UI/XR assemblies. - Prefer Unity Editor compile and Play Mode for final verification. ## Recommended Next Checks 1. Play the Game scene and finish a song. 2. Check result screen layout for `M`, `S+`, `S`, and `F`. 3. Verify score, accuracy, and max combo do not overlap. 4. Confirm Restart and Back buttons remain clickable. 5. Check whether result popup and game-over popup color changes should both stay. 6. If result screen is stable, move to HUD polish and TMP migration discussion.