From 694fcfa064b4943e46d75ef0ea5722995c51113a Mon Sep 17 00:00:00 2001 From: xwalfie Date: Tue, 7 Jul 2026 23:34:30 +0200 Subject: [PATCH 01/18] feat: import nightly settings adds a new button that finds settings.json in nightly userfolder and maps the kv adds a new function to compute dB to percentage --- scripts/SoundManager.cs | 6 + scripts/database/settings/SettingsProfile.cs | 137 +++++++++++++++++-- scripts/ui/SettingsMenu.cs | 6 +- 3 files changed, 132 insertions(+), 17 deletions(-) diff --git a/scripts/SoundManager.cs b/scripts/SoundManager.cs index 9eb59133..e0fcea83 100644 --- a/scripts/SoundManager.cs +++ b/scripts/SoundManager.cs @@ -375,6 +375,12 @@ public static float ComputeVolumeDb(float volume, float master, float range) return (float)(-80 + range * Math.Pow(volume / 100, 0.1) * Math.Pow(master / 100, 0.1)); } + public static float ComputeVolumeFromDb(float db, float master, float range) + { + if (float.IsNegativeInfinity(db) || master <= 0) return 0; + return (float)Math.Clamp(100 * Math.Pow((db + 80) / (range * Math.Pow(master / 100, 0.1)), 10), 0, 100); + } + public static void UpdateVolume() { var settings = SettingsManager.Instance.Settings; diff --git a/scripts/database/settings/SettingsProfile.cs b/scripts/database/settings/SettingsProfile.cs index dd085036..c731b16f 100644 --- a/scripts/database/settings/SettingsProfile.cs +++ b/scripts/database/settings/SettingsProfile.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Text.Json; using Godot; public partial class SettingsProfile @@ -342,11 +343,11 @@ public partial class SettingsProfile /// public SettingsItem DisplayFPS { get; private set; } - // [Order] + [Order] /// /// Import settings from previous (nightly) version /// - // public SettingsItem RhythiaImport { get; private set; } + public SettingsItem RhythiaImport { get; private set; } [Order] /// @@ -1030,18 +1031,126 @@ public SettingsProfile() #region Other - // RhythiaImport = new(default) - // { - // Id = "RhythiaImport", - // Title = "Import Nightly Settings", - // Description = "Imports settings from the nightly client", - // Section = SettingsSection.Other, - // Buttons = - // [ - // new() { Title = "Import", Description = "", OnPressed = () => { } } - // ], - // SaveToDisk = false, - // }; + RhythiaImport = new(default) + { + Id = "RhythiaImport", + Title = "Import Nightly Settings", + Description = "Imports settings from the nightly client", + Section = SettingsSection.Other, + Buttons = + [ + new() { Title = "Import", Description = "", OnPressed = () => { + string nightlyDir = $"{Path.GetDirectoryName(Constants.USER_FOLDER)}/SoundSpacePlus"; + + if (Directory.Exists(nightlyDir)) { + string nightlySettingsPath = $"{nightlyDir}/settings.json"; + + string nightlySettings = File.Exists(nightlySettingsPath) ? File.ReadAllText(nightlySettingsPath) : null; + + if (nightlySettings == null) { + ToastNotification.Notify("Nightly settings not found, choose the settings file manually."); + }; + + using JsonDocument json = JsonDocument.Parse(nightlySettings); + JsonElement root = json.RootElement; + + T? getSetting(string key) where T : struct { + if (root.TryGetProperty(key, out JsonElement element)) { + return element.Deserialize(); + } + + return null; + } + + // needs a separate helper for strings due to the struct constraint in getSetting() + string? getStringSetting(string key) { + if (root.TryGetProperty(key, out JsonElement element)) { + return element.GetString(); + } + return null; + } + + double importVolume(string nightlyKey, double range) { + double? channelDb = getSetting(nightlyKey); + + if (channelDb == null) { + return 50; + } + + double masterDb = getSetting("master_volume") ?? 20 * Math.Log10(0.5); + double totalDb = Math.Clamp(masterDb + channelDb.Value, -80, 0); + + return SoundManager.ComputeVolumeFromDb((float)totalDb, 100, (float)range); + } + + SettingsProfile nightlyProfile = new SettingsProfile(); + + nightlyProfile.Sensitivity.Value = getSetting("sensitivity") * 2.16 * (70 / (getSetting("fov") ?? 70)) ?? nightlyProfile.Sensitivity.Value; + nightlyProfile.AbsoluteSensitivity.Value = getSetting("absolute_scale") ?? nightlyProfile.AbsoluteSensitivity.Value; + nightlyProfile.AbsoluteInput.Value = getSetting("absolute_mode") ?? nightlyProfile.AbsoluteInput.Value; + nightlyProfile.CursorDrift.Value = getSetting("enable_drift_cursor") ?? nightlyProfile.CursorDrift.Value; + nightlyProfile.ApproachRate.Value = getSetting("approach_rate") ?? nightlyProfile.ApproachRate.Value; + nightlyProfile.ApproachDistance.Value = getSetting("spawn_distance") ?? nightlyProfile.ApproachDistance.Value; + nightlyProfile.Pushback.Value = getSetting("do_note_pushback") ?? nightlyProfile.Pushback.Value; + nightlyProfile.CameraParallax.Value = getSetting("parallax") * 0.025 ?? nightlyProfile.CameraParallax.Value; + nightlyProfile.HUDParallax.Value = getSetting("ui_parallax") * 0.025 ?? nightlyProfile.HUDParallax.Value; + nightlyProfile.FoV.Value = getSetting("fov") ?? nightlyProfile.FoV.Value; + nightlyProfile.NoteColors.Value = getStringSetting("selected_colorset") ?? nightlyProfile.NoteColors.Value; + nightlyProfile.NoteMesh.Value = getStringSetting("selected_mesh") ?? nightlyProfile.NoteMesh.Value; + nightlyProfile.NoteSize.Value = getSetting("note_size") * 0.875 ?? nightlyProfile.NoteSize.Value; + nightlyProfile.NoteOpacity.Value = getSetting("note_opacity") ?? nightlyProfile.NoteOpacity.Value; + nightlyProfile.CursorScale.Value = getSetting("cursor_scale") ?? nightlyProfile.CursorScale.Value; + nightlyProfile.CursorRotation.Value = getSetting("cursor_spin") ?? nightlyProfile.CursorRotation.Value; + nightlyProfile.CursorTrail.Value = getSetting("cursor_trail") ?? nightlyProfile.CursorTrail.Value; + nightlyProfile.TrailTime.Value = getSetting("trail_time") ?? nightlyProfile.TrailTime.Value; + nightlyProfile.TrailDetail.Value = getSetting("trail_detail") ?? nightlyProfile.TrailDetail.Value; + nightlyProfile.SimpleHUD.Value = getSetting("simple_hud") ?? nightlyProfile.SimpleHUD.Value; + nightlyProfile.HitPopups.Value = getSetting("score_popup") ?? nightlyProfile.HitPopups.Value; + nightlyProfile.MissPopups.Value = getSetting("show_miss_effect") ?? nightlyProfile.MissPopups.Value; + nightlyProfile.Fullscreen.Value = getSetting("window_fullscreen") ?? nightlyProfile.Fullscreen.Value; + nightlyProfile.FPS.Value = getSetting("target_fps") ?? nightlyProfile.FPS.Value; + nightlyProfile.VolumeMaster.Value = 100; + nightlyProfile.VolumeMusic.Value = importVolume("music_volume", 70);; + nightlyProfile.VolumeHitSound.Value = importVolume("hit_volume", 80); + nightlyProfile.VolumeMissSound.Value = importVolume("miss_volume", 80); + nightlyProfile.VolumeSFX.Value = importVolume("fail_volume", 80); + nightlyProfile.EnableHitSound.Value = getSetting("play_hit_snd") ?? nightlyProfile.EnableHitSound.Value; + nightlyProfile.EnableMissSound.Value = getSetting("play_miss_snd") ?? nightlyProfile.EnableMissSound.Value; + nightlyProfile.EnableMenuMusic.Value = getSetting("play_menu_music") ?? nightlyProfile.EnableMenuMusic.Value; + nightlyProfile.AutoplayJukebox.Value = getSetting("auto_preview_song") ?? nightlyProfile.AutoplayJukebox.Value; + nightlyProfile.LocalOffset.Value = getSetting("music_offset") ?? nightlyProfile.LocalOffset.Value; + nightlyProfile.RecordReplays.Value = getSetting("record_replays") ?? nightlyProfile.RecordReplays.Value; + + // prevents overriding existing 'nightly' profile + string getProfileName(string baseName) { + string profilesDir = $"{Constants.USER_FOLDER}/profiles"; + Directory.CreateDirectory(profilesDir); + + string name = baseName; + int suffix = 0; + + while (File.Exists($"{profilesDir}/{name}.json")) { + suffix++; + name = $"{baseName}-{suffix}"; + } + + return name; + } + + string profileName = getProfileName("nightly"); + string profileJson = SettingsProfileConverter.Serialize(nightlyProfile); + File.WriteAllText($"{Constants.USER_FOLDER}/profiles/{profileName}.json", profileJson); + + SettingsManager.SetCurrentProfile(profileName); + SettingsManager.Load(); + SettingsMenu.Instance.UpdateProfileSelection(); + + ToastNotification.Notify($"Created profile '{profileName}'"); + } + } } + ], + SaveToDisk = false, + }; DisplayFPS = new(true) { diff --git a/scripts/ui/SettingsMenu.cs b/scripts/ui/SettingsMenu.cs index 1b89c2c5..af8998d5 100644 --- a/scripts/ui/SettingsMenu.cs +++ b/scripts/ui/SettingsMenu.cs @@ -53,7 +53,7 @@ public override void _Ready() SettingsManager.SetCurrentProfile(profile); SettingsManager.Reload(); - updateProfileSelection(); + UpdateProfileSelection(); }; profilesButton.ItemSelected += (index) => @@ -67,7 +67,7 @@ public override void _Ready() SettingsManager.Load(); }; - updateProfileSelection(); + UpdateProfileSelection(); Panel settingTemplate = categoryTemplate.GetNode("Container").GetNode("SettingTemplate"); CheckButton checkButtonTemplate = settingTemplate.GetNode("CheckButton"); @@ -248,7 +248,7 @@ public void SelectCategory(ScrollContainer category) sidebar.GetNode(new(selectedCategory.Name)).Color = Color.Color8(255, 255, 255, 8); } - private void updateProfileSelection() + public void UpdateProfileSelection() { // skip default for (int i = 1; i < profilesButton.ItemCount; i++) From 019bfbd6918396e2b5b3c953901dbd0cb955ca38 Mon Sep 17 00:00:00 2001 From: xwalfie Date: Wed, 8 Jul 2026 01:13:19 +0200 Subject: [PATCH 02/18] feat: added option to choose settings file manually --- scenes/main.tscn | 12 +- scripts/database/settings/SettingsProfile.cs | 239 +++++++++++-------- scripts/ui/SettingsMenu.cs | 3 + 3 files changed, 150 insertions(+), 104 deletions(-) diff --git a/scenes/main.tscn b/scenes/main.tscn index 4a9b0bfe..0796fbf3 100644 --- a/scenes/main.tscn +++ b/scenes/main.tscn @@ -130,7 +130,7 @@ handle_input_locally = false size = Vector2i(1280, 720) render_target_update_mode = 4 -[node name="Settings" type="ColorRect" parent="." unique_id=1393582030] +[node name="Settings" type="ColorRect" parent="." unique_id=1393582030 node_paths=PackedStringArray("ImportNightlyDialog")] visible = false z_index = 1 anchors_preset = 15 @@ -141,6 +141,7 @@ grow_vertical = 2 mouse_filter = 2 color = Color(0, 0, 0, 0.501961) script = ExtResource("2_o6xl0") +ImportNightlyDialog = NodePath("ImportNightlyDialog") [node name="Hide" type="Button" parent="Settings" unique_id=1153372742] self_modulate = Color(1, 1, 1, 0) @@ -333,6 +334,8 @@ layout_mode = 1 anchors_preset = -1 anchor_right = 1.0 offset_bottom = 50.0 +grow_horizontal = 2 +grow_vertical = 2 focus_mode = 0 mouse_default_cursor_shape = 2 theme = SubResource("Theme_jhjkh") @@ -429,6 +432,13 @@ grow_vertical = 2 mouse_filter = 2 theme_override_styles/panel = SubResource("StyleBoxFlat_popqt") +[node name="ImportNightlyDialog" type="FileDialog" parent="Settings" unique_id=1831752407] +title = "Open a File" +file_mode = 0 +access = 2 +filters = PackedStringArray("*.json") +use_native_dialog = true + [node name="Volume" type="Panel" parent="." unique_id=1219254705] modulate = Color(1, 1, 1, 0) z_index = 1 diff --git a/scripts/database/settings/SettingsProfile.cs b/scripts/database/settings/SettingsProfile.cs index c731b16f..cd83b2a5 100644 --- a/scripts/database/settings/SettingsProfile.cs +++ b/scripts/database/settings/SettingsProfile.cs @@ -349,6 +349,12 @@ public partial class SettingsProfile /// public SettingsItem RhythiaImport { get; private set; } + [Order] + /// + /// File dialog for the nightly import + /// + public SettingsItem ImportDialog { get; private set; } + [Order] /// /// Toggles recording for replays @@ -1043,115 +1049,27 @@ public SettingsProfile() string nightlyDir = $"{Path.GetDirectoryName(Constants.USER_FOLDER)}/SoundSpacePlus"; if (Directory.Exists(nightlyDir)) { - string nightlySettingsPath = $"{nightlyDir}/settings.json"; - - string nightlySettings = File.Exists(nightlySettingsPath) ? File.ReadAllText(nightlySettingsPath) : null; - - if (nightlySettings == null) { - ToastNotification.Notify("Nightly settings not found, choose the settings file manually."); - }; - - using JsonDocument json = JsonDocument.Parse(nightlySettings); - JsonElement root = json.RootElement; - - T? getSetting(string key) where T : struct { - if (root.TryGetProperty(key, out JsonElement element)) { - return element.Deserialize(); - } - - return null; - } - - // needs a separate helper for strings due to the struct constraint in getSetting() - string? getStringSetting(string key) { - if (root.TryGetProperty(key, out JsonElement element)) { - return element.GetString(); - } - return null; - } - - double importVolume(string nightlyKey, double range) { - double? channelDb = getSetting(nightlyKey); - - if (channelDb == null) { - return 50; - } - - double masterDb = getSetting("master_volume") ?? 20 * Math.Log10(0.5); - double totalDb = Math.Clamp(masterDb + channelDb.Value, -80, 0); - - return SoundManager.ComputeVolumeFromDb((float)totalDb, 100, (float)range); - } - - SettingsProfile nightlyProfile = new SettingsProfile(); - - nightlyProfile.Sensitivity.Value = getSetting("sensitivity") * 2.16 * (70 / (getSetting("fov") ?? 70)) ?? nightlyProfile.Sensitivity.Value; - nightlyProfile.AbsoluteSensitivity.Value = getSetting("absolute_scale") ?? nightlyProfile.AbsoluteSensitivity.Value; - nightlyProfile.AbsoluteInput.Value = getSetting("absolute_mode") ?? nightlyProfile.AbsoluteInput.Value; - nightlyProfile.CursorDrift.Value = getSetting("enable_drift_cursor") ?? nightlyProfile.CursorDrift.Value; - nightlyProfile.ApproachRate.Value = getSetting("approach_rate") ?? nightlyProfile.ApproachRate.Value; - nightlyProfile.ApproachDistance.Value = getSetting("spawn_distance") ?? nightlyProfile.ApproachDistance.Value; - nightlyProfile.Pushback.Value = getSetting("do_note_pushback") ?? nightlyProfile.Pushback.Value; - nightlyProfile.CameraParallax.Value = getSetting("parallax") * 0.025 ?? nightlyProfile.CameraParallax.Value; - nightlyProfile.HUDParallax.Value = getSetting("ui_parallax") * 0.025 ?? nightlyProfile.HUDParallax.Value; - nightlyProfile.FoV.Value = getSetting("fov") ?? nightlyProfile.FoV.Value; - nightlyProfile.NoteColors.Value = getStringSetting("selected_colorset") ?? nightlyProfile.NoteColors.Value; - nightlyProfile.NoteMesh.Value = getStringSetting("selected_mesh") ?? nightlyProfile.NoteMesh.Value; - nightlyProfile.NoteSize.Value = getSetting("note_size") * 0.875 ?? nightlyProfile.NoteSize.Value; - nightlyProfile.NoteOpacity.Value = getSetting("note_opacity") ?? nightlyProfile.NoteOpacity.Value; - nightlyProfile.CursorScale.Value = getSetting("cursor_scale") ?? nightlyProfile.CursorScale.Value; - nightlyProfile.CursorRotation.Value = getSetting("cursor_spin") ?? nightlyProfile.CursorRotation.Value; - nightlyProfile.CursorTrail.Value = getSetting("cursor_trail") ?? nightlyProfile.CursorTrail.Value; - nightlyProfile.TrailTime.Value = getSetting("trail_time") ?? nightlyProfile.TrailTime.Value; - nightlyProfile.TrailDetail.Value = getSetting("trail_detail") ?? nightlyProfile.TrailDetail.Value; - nightlyProfile.SimpleHUD.Value = getSetting("simple_hud") ?? nightlyProfile.SimpleHUD.Value; - nightlyProfile.HitPopups.Value = getSetting("score_popup") ?? nightlyProfile.HitPopups.Value; - nightlyProfile.MissPopups.Value = getSetting("show_miss_effect") ?? nightlyProfile.MissPopups.Value; - nightlyProfile.Fullscreen.Value = getSetting("window_fullscreen") ?? nightlyProfile.Fullscreen.Value; - nightlyProfile.FPS.Value = getSetting("target_fps") ?? nightlyProfile.FPS.Value; - nightlyProfile.VolumeMaster.Value = 100; - nightlyProfile.VolumeMusic.Value = importVolume("music_volume", 70);; - nightlyProfile.VolumeHitSound.Value = importVolume("hit_volume", 80); - nightlyProfile.VolumeMissSound.Value = importVolume("miss_volume", 80); - nightlyProfile.VolumeSFX.Value = importVolume("fail_volume", 80); - nightlyProfile.EnableHitSound.Value = getSetting("play_hit_snd") ?? nightlyProfile.EnableHitSound.Value; - nightlyProfile.EnableMissSound.Value = getSetting("play_miss_snd") ?? nightlyProfile.EnableMissSound.Value; - nightlyProfile.EnableMenuMusic.Value = getSetting("play_menu_music") ?? nightlyProfile.EnableMenuMusic.Value; - nightlyProfile.AutoplayJukebox.Value = getSetting("auto_preview_song") ?? nightlyProfile.AutoplayJukebox.Value; - nightlyProfile.LocalOffset.Value = getSetting("music_offset") ?? nightlyProfile.LocalOffset.Value; - nightlyProfile.RecordReplays.Value = getSetting("record_replays") ?? nightlyProfile.RecordReplays.Value; - - // prevents overriding existing 'nightly' profile - string getProfileName(string baseName) { - string profilesDir = $"{Constants.USER_FOLDER}/profiles"; - Directory.CreateDirectory(profilesDir); - - string name = baseName; - int suffix = 0; - - while (File.Exists($"{profilesDir}/{name}.json")) { - suffix++; - name = $"{baseName}-{suffix}"; - } - - return name; - } - - string profileName = getProfileName("nightly"); - string profileJson = SettingsProfileConverter.Serialize(nightlyProfile); - File.WriteAllText($"{Constants.USER_FOLDER}/profiles/{profileName}.json", profileJson); - - SettingsManager.SetCurrentProfile(profileName); - SettingsManager.Load(); - SettingsMenu.Instance.UpdateProfileSelection(); - - ToastNotification.Notify($"Created profile '{profileName}'"); + ImportFromNightlySettings($"{nightlyDir}/settings.json"); } } } ], SaveToDisk = false, }; + ImportDialog = new(default) + { + Id = "ImportDialog", + Title = "", + Description = "", + Section = SettingsSection.Other, + Buttons = + [ + new() { Title = "Choose file", Description = "", OnPressed = () => { + SettingsMenu.Instance.ImportNightlyDialog.PopupCentered(); + }} + ] + }; + DisplayFPS = new(true) { Id = "DisplayFPS", @@ -1257,4 +1175,119 @@ private static List getAvailableMeshes() return meshes; } + + public static void ImportFromNightlySettings(string settingsPath) + { + string nightlySettings = File.Exists(settingsPath) ? File.ReadAllText(settingsPath) : null; + + if (nightlySettings == null) + { + ToastNotification.Notify("Nightly settings not found, choose the settings file manually."); + return; + } + + using JsonDocument json = JsonDocument.Parse(nightlySettings); + JsonElement root = json.RootElement; + + T? getSetting(string key) where T : struct + { + if (root.TryGetProperty(key, out JsonElement element)) + { + return element.Deserialize(); + } + + return null; + } + + // needs a separate helper for strings due to the struct constraint in getSetting() + string? getStringSetting(string key) + { + if (root.TryGetProperty(key, out JsonElement element)) + { + return element.GetString(); + } + return null; + } + + double importVolume(string nightlyKey, double range) + { + double? channelDb = getSetting(nightlyKey); + + if (channelDb == null) + { + return 50; + } + + double masterDb = getSetting("master_volume") ?? 20 * Math.Log10(0.5); + double totalDb = Math.Clamp(masterDb + channelDb.Value, -80, 0); + + return SoundManager.ComputeVolumeFromDb((float)totalDb, 100, (float)range); + } + + SettingsProfile nightlyProfile = new SettingsProfile(); + + nightlyProfile.Sensitivity.Value = getSetting("sensitivity") * 2.16 * (70 / (getSetting("fov") ?? 70)) ?? nightlyProfile.Sensitivity.Value; + nightlyProfile.AbsoluteSensitivity.Value = getSetting("absolute_scale") ?? nightlyProfile.AbsoluteSensitivity.Value; + nightlyProfile.AbsoluteInput.Value = getSetting("absolute_mode") ?? nightlyProfile.AbsoluteInput.Value; + nightlyProfile.CursorDrift.Value = getSetting("enable_drift_cursor") ?? nightlyProfile.CursorDrift.Value; + nightlyProfile.ApproachRate.Value = getSetting("approach_rate") ?? nightlyProfile.ApproachRate.Value; + nightlyProfile.ApproachDistance.Value = getSetting("spawn_distance") ?? nightlyProfile.ApproachDistance.Value; + nightlyProfile.Pushback.Value = getSetting("do_note_pushback") ?? nightlyProfile.Pushback.Value; + nightlyProfile.CameraParallax.Value = getSetting("parallax") * 0.025 ?? nightlyProfile.CameraParallax.Value; + nightlyProfile.HUDParallax.Value = getSetting("ui_parallax") * 0.025 ?? nightlyProfile.HUDParallax.Value; + nightlyProfile.FoV.Value = getSetting("fov") ?? nightlyProfile.FoV.Value; + nightlyProfile.NoteColors.Value = getStringSetting("selected_colorset") ?? nightlyProfile.NoteColors.Value; + nightlyProfile.NoteMesh.Value = getStringSetting("selected_mesh") ?? nightlyProfile.NoteMesh.Value; + nightlyProfile.NoteSize.Value = getSetting("note_size") * 0.875 ?? nightlyProfile.NoteSize.Value; + nightlyProfile.NoteOpacity.Value = getSetting("note_opacity") ?? nightlyProfile.NoteOpacity.Value; + nightlyProfile.CursorScale.Value = getSetting("cursor_scale") ?? nightlyProfile.CursorScale.Value; + nightlyProfile.CursorRotation.Value = getSetting("cursor_spin") ?? nightlyProfile.CursorRotation.Value; + nightlyProfile.CursorTrail.Value = getSetting("cursor_trail") ?? nightlyProfile.CursorTrail.Value; + nightlyProfile.TrailTime.Value = getSetting("trail_time") ?? nightlyProfile.TrailTime.Value; + nightlyProfile.TrailDetail.Value = getSetting("trail_detail") ?? nightlyProfile.TrailDetail.Value; + nightlyProfile.SimpleHUD.Value = getSetting("simple_hud") ?? nightlyProfile.SimpleHUD.Value; + nightlyProfile.HitPopups.Value = getSetting("score_popup") ?? nightlyProfile.HitPopups.Value; + nightlyProfile.MissPopups.Value = getSetting("show_miss_effect") ?? nightlyProfile.MissPopups.Value; + nightlyProfile.Fullscreen.Value = getSetting("window_fullscreen") ?? nightlyProfile.Fullscreen.Value; + nightlyProfile.FPS.Value = getSetting("target_fps") ?? nightlyProfile.FPS.Value; + nightlyProfile.VolumeMaster.Value = 100; + nightlyProfile.VolumeMusic.Value = importVolume("music_volume", 70); ; + nightlyProfile.VolumeHitSound.Value = importVolume("hit_volume", 80); + nightlyProfile.VolumeMissSound.Value = importVolume("miss_volume", 80); + nightlyProfile.VolumeSFX.Value = importVolume("fail_volume", 80); + nightlyProfile.EnableHitSound.Value = getSetting("play_hit_snd") ?? nightlyProfile.EnableHitSound.Value; + nightlyProfile.EnableMissSound.Value = getSetting("play_miss_snd") ?? nightlyProfile.EnableMissSound.Value; + nightlyProfile.EnableMenuMusic.Value = getSetting("play_menu_music") ?? nightlyProfile.EnableMenuMusic.Value; + nightlyProfile.AutoplayJukebox.Value = getSetting("auto_preview_song") ?? nightlyProfile.AutoplayJukebox.Value; + nightlyProfile.LocalOffset.Value = getSetting("music_offset") ?? nightlyProfile.LocalOffset.Value; + nightlyProfile.RecordReplays.Value = getSetting("record_replays") ?? nightlyProfile.RecordReplays.Value; + + // prevents overriding existing 'nightly' profile + string getProfileName(string baseName) + { + string profilesDir = $"{Constants.USER_FOLDER}/profiles"; + Directory.CreateDirectory(profilesDir); + + string name = baseName; + int suffix = 0; + + while (File.Exists($"{profilesDir}/{name}.json")) + { + suffix++; + name = $"{baseName}-{suffix}"; + } + + return name; + } + + string profileName = getProfileName("nightly"); + string profileJson = SettingsProfileConverter.Serialize(nightlyProfile); + File.WriteAllText($"{Constants.USER_FOLDER}/profiles/{profileName}.json", profileJson); + + SettingsManager.SetCurrentProfile(profileName); + SettingsManager.Load(); + SettingsMenu.Instance.UpdateProfileSelection(); + + ToastNotification.Notify($"Created profile '{profileName}'"); + } } diff --git a/scripts/ui/SettingsMenu.cs b/scripts/ui/SettingsMenu.cs index af8998d5..bbb718e4 100644 --- a/scripts/ui/SettingsMenu.cs +++ b/scripts/ui/SettingsMenu.cs @@ -22,6 +22,8 @@ public partial class SettingsMenu : ColorRect private ScrollContainer selectedCategory; + [Export] public FileDialog ImportNightlyDialog; + public override void _Ready() { Instance = this; @@ -189,6 +191,7 @@ public override void _Ready() HideMenu(); hideButton.Pressed += HideMenu; + ImportNightlyDialog.FileSelected += SettingsProfile.ImportFromNightlySettings; } // Adding GetViewport().SetInputAsHandled() will prevent the Quit popup from appearing when clicking ESC in settings public override void _Input(InputEvent @event) From 0e0b51e8579b44aa3e764cb741cf26ca14fc6599 Mon Sep 17 00:00:00 2001 From: xwalfie Date: Wed, 8 Jul 2026 01:25:56 +0200 Subject: [PATCH 03/18] refactor: add comment and remove random thingy from scene --- scenes/main.tscn | 2 -- scripts/database/settings/SettingsProfile.cs | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/scenes/main.tscn b/scenes/main.tscn index 0796fbf3..317c889a 100644 --- a/scenes/main.tscn +++ b/scenes/main.tscn @@ -334,8 +334,6 @@ layout_mode = 1 anchors_preset = -1 anchor_right = 1.0 offset_bottom = 50.0 -grow_horizontal = 2 -grow_vertical = 2 focus_mode = 0 mouse_default_cursor_shape = 2 theme = SubResource("Theme_jhjkh") diff --git a/scripts/database/settings/SettingsProfile.cs b/scripts/database/settings/SettingsProfile.cs index cd83b2a5..98d2414d 100644 --- a/scripts/database/settings/SettingsProfile.cs +++ b/scripts/database/settings/SettingsProfile.cs @@ -1226,6 +1226,7 @@ double importVolume(string nightlyKey, double range) SettingsProfile nightlyProfile = new SettingsProfile(); + // sensitivity scales with fov but in nightly it doesnt nightlyProfile.Sensitivity.Value = getSetting("sensitivity") * 2.16 * (70 / (getSetting("fov") ?? 70)) ?? nightlyProfile.Sensitivity.Value; nightlyProfile.AbsoluteSensitivity.Value = getSetting("absolute_scale") ?? nightlyProfile.AbsoluteSensitivity.Value; nightlyProfile.AbsoluteInput.Value = getSetting("absolute_mode") ?? nightlyProfile.AbsoluteInput.Value; From f60df596d77c31aa257770ed9db32f57fd257b78 Mon Sep 17 00:00:00 2001 From: xwalfie Date: Thu, 9 Jul 2026 06:16:30 +0200 Subject: [PATCH 04/18] mmmm remove ; --- scripts/database/settings/SettingsProfile.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/database/settings/SettingsProfile.cs b/scripts/database/settings/SettingsProfile.cs index 98d2414d..758587d9 100644 --- a/scripts/database/settings/SettingsProfile.cs +++ b/scripts/database/settings/SettingsProfile.cs @@ -1252,7 +1252,7 @@ double importVolume(string nightlyKey, double range) nightlyProfile.Fullscreen.Value = getSetting("window_fullscreen") ?? nightlyProfile.Fullscreen.Value; nightlyProfile.FPS.Value = getSetting("target_fps") ?? nightlyProfile.FPS.Value; nightlyProfile.VolumeMaster.Value = 100; - nightlyProfile.VolumeMusic.Value = importVolume("music_volume", 70); ; + nightlyProfile.VolumeMusic.Value = importVolume("music_volume", 70); nightlyProfile.VolumeHitSound.Value = importVolume("hit_volume", 80); nightlyProfile.VolumeMissSound.Value = importVolume("miss_volume", 80); nightlyProfile.VolumeSFX.Value = importVolume("fail_volume", 80); From b6fbcc6677eb31dc12fbc413db39c5dcf6c501d0 Mon Sep 17 00:00:00 2001 From: xwalfie Date: Thu, 9 Jul 2026 18:13:36 +0200 Subject: [PATCH 05/18] refactor: move nightly folder variable into a constant --- scripts/Constants.cs | 2 ++ scripts/database/settings/SettingsProfile.cs | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/scripts/Constants.cs b/scripts/Constants.cs index 580934f3..7f0a19f6 100644 --- a/scripts/Constants.cs +++ b/scripts/Constants.cs @@ -10,6 +10,8 @@ public partial class Constants : Node public static readonly string USER_FOLDER = OS.GetUserDataDir(); + public static readonly string NIGHTLY_FOLDER = $"{Path.GetDirectoryName(USER_FOLDER)}/SoundSpacePlus"; + public static readonly string DEFAULT_MAP_EXT = "phxm"; public static readonly bool TEMP_MAP_MODE = false;//OS.GetCmdlineArgs().Length > 0; diff --git a/scripts/database/settings/SettingsProfile.cs b/scripts/database/settings/SettingsProfile.cs index 758587d9..58659241 100644 --- a/scripts/database/settings/SettingsProfile.cs +++ b/scripts/database/settings/SettingsProfile.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Reflection.Metadata; using System.Text.Json; using Godot; @@ -1046,10 +1047,9 @@ public SettingsProfile() Buttons = [ new() { Title = "Import", Description = "", OnPressed = () => { - string nightlyDir = $"{Path.GetDirectoryName(Constants.USER_FOLDER)}/SoundSpacePlus"; - if (Directory.Exists(nightlyDir)) { - ImportFromNightlySettings($"{nightlyDir}/settings.json"); + if (Directory.Exists(Constants.NIGHTLY_FOLDER)) { + ImportFromNightlySettings($"{Constants.NIGHTLY_FOLDER}/settings.json"); } } } ], From 8d90bd17a46c4fd9d154ba692dd1a1bc30a69cb9 Mon Sep 17 00:00:00 2001 From: xwalfiee Date: Wed, 15 Jul 2026 00:54:02 +0200 Subject: [PATCH 06/18] refactor: move nightly import to dictionary --- scripts/database/settings/SettingsProfile.cs | 86 +++++++++++--------- 1 file changed, 49 insertions(+), 37 deletions(-) diff --git a/scripts/database/settings/SettingsProfile.cs b/scripts/database/settings/SettingsProfile.cs index 58659241..d3bff747 100644 --- a/scripts/database/settings/SettingsProfile.cs +++ b/scripts/database/settings/SettingsProfile.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Reflection.Metadata; using System.Text.Json; using Godot; @@ -1226,42 +1225,55 @@ double importVolume(string nightlyKey, double range) SettingsProfile nightlyProfile = new SettingsProfile(); - // sensitivity scales with fov but in nightly it doesnt - nightlyProfile.Sensitivity.Value = getSetting("sensitivity") * 2.16 * (70 / (getSetting("fov") ?? 70)) ?? nightlyProfile.Sensitivity.Value; - nightlyProfile.AbsoluteSensitivity.Value = getSetting("absolute_scale") ?? nightlyProfile.AbsoluteSensitivity.Value; - nightlyProfile.AbsoluteInput.Value = getSetting("absolute_mode") ?? nightlyProfile.AbsoluteInput.Value; - nightlyProfile.CursorDrift.Value = getSetting("enable_drift_cursor") ?? nightlyProfile.CursorDrift.Value; - nightlyProfile.ApproachRate.Value = getSetting("approach_rate") ?? nightlyProfile.ApproachRate.Value; - nightlyProfile.ApproachDistance.Value = getSetting("spawn_distance") ?? nightlyProfile.ApproachDistance.Value; - nightlyProfile.Pushback.Value = getSetting("do_note_pushback") ?? nightlyProfile.Pushback.Value; - nightlyProfile.CameraParallax.Value = getSetting("parallax") * 0.025 ?? nightlyProfile.CameraParallax.Value; - nightlyProfile.HUDParallax.Value = getSetting("ui_parallax") * 0.025 ?? nightlyProfile.HUDParallax.Value; - nightlyProfile.FoV.Value = getSetting("fov") ?? nightlyProfile.FoV.Value; - nightlyProfile.NoteColors.Value = getStringSetting("selected_colorset") ?? nightlyProfile.NoteColors.Value; - nightlyProfile.NoteMesh.Value = getStringSetting("selected_mesh") ?? nightlyProfile.NoteMesh.Value; - nightlyProfile.NoteSize.Value = getSetting("note_size") * 0.875 ?? nightlyProfile.NoteSize.Value; - nightlyProfile.NoteOpacity.Value = getSetting("note_opacity") ?? nightlyProfile.NoteOpacity.Value; - nightlyProfile.CursorScale.Value = getSetting("cursor_scale") ?? nightlyProfile.CursorScale.Value; - nightlyProfile.CursorRotation.Value = getSetting("cursor_spin") ?? nightlyProfile.CursorRotation.Value; - nightlyProfile.CursorTrail.Value = getSetting("cursor_trail") ?? nightlyProfile.CursorTrail.Value; - nightlyProfile.TrailTime.Value = getSetting("trail_time") ?? nightlyProfile.TrailTime.Value; - nightlyProfile.TrailDetail.Value = getSetting("trail_detail") ?? nightlyProfile.TrailDetail.Value; - nightlyProfile.SimpleHUD.Value = getSetting("simple_hud") ?? nightlyProfile.SimpleHUD.Value; - nightlyProfile.HitPopups.Value = getSetting("score_popup") ?? nightlyProfile.HitPopups.Value; - nightlyProfile.MissPopups.Value = getSetting("show_miss_effect") ?? nightlyProfile.MissPopups.Value; - nightlyProfile.Fullscreen.Value = getSetting("window_fullscreen") ?? nightlyProfile.Fullscreen.Value; - nightlyProfile.FPS.Value = getSetting("target_fps") ?? nightlyProfile.FPS.Value; - nightlyProfile.VolumeMaster.Value = 100; - nightlyProfile.VolumeMusic.Value = importVolume("music_volume", 70); - nightlyProfile.VolumeHitSound.Value = importVolume("hit_volume", 80); - nightlyProfile.VolumeMissSound.Value = importVolume("miss_volume", 80); - nightlyProfile.VolumeSFX.Value = importVolume("fail_volume", 80); - nightlyProfile.EnableHitSound.Value = getSetting("play_hit_snd") ?? nightlyProfile.EnableHitSound.Value; - nightlyProfile.EnableMissSound.Value = getSetting("play_miss_snd") ?? nightlyProfile.EnableMissSound.Value; - nightlyProfile.EnableMenuMusic.Value = getSetting("play_menu_music") ?? nightlyProfile.EnableMenuMusic.Value; - nightlyProfile.AutoplayJukebox.Value = getSetting("auto_preview_song") ?? nightlyProfile.AutoplayJukebox.Value; - nightlyProfile.LocalOffset.Value = getSetting("music_offset") ?? nightlyProfile.LocalOffset.Value; - nightlyProfile.RecordReplays.Value = getSetting("record_replays") ?? nightlyProfile.RecordReplays.Value; + Dictionary> conversions = new() + { + // sensitivity scales with fov but in nightly it doesnt + ["Sensitivity"] = () => getSetting("sensitivity") * 2.16 * (70 / (getSetting("fov") ?? 70)) ?? nightlyProfile.Sensitivity.Value, + ["AbsoluteSensitivity"] = () => getSetting("absolute_scale") ?? nightlyProfile.AbsoluteSensitivity.Value, + ["AbsoluteInput"] = () => getSetting("absolute_mode") ?? nightlyProfile.AbsoluteInput.Value, + ["CursorDrift"] = () => getSetting("enable_drift_cursor") ?? nightlyProfile.CursorDrift.Value, + ["ApproachRate"] = () => getSetting("approach_rate") ?? nightlyProfile.ApproachRate.Value, + ["ApproachDistance"] = () => getSetting("spawn_distance") ?? nightlyProfile.ApproachDistance.Value, + ["Pushback"] = () => getSetting("do_note_pushback") ?? nightlyProfile.Pushback.Value, + ["CameraParallax"] = () => getSetting("parallax") * 0.025 ?? nightlyProfile.CameraParallax.Value, + ["HUDParallax"] = () => getSetting("ui_parallax") * 0.025 ?? nightlyProfile.HUDParallax.Value, + ["FoV"] = () => getSetting("fov") ?? nightlyProfile.FoV.Value, + ["Colors"] = () => getStringSetting("selected_colorset") ?? nightlyProfile.NoteColors.Value, + ["NoteMesh"] = () => getStringSetting("selected_mesh") ?? nightlyProfile.NoteMesh.Value, + ["NoteSize"] = () => getSetting("note_size") * 0.875 ?? nightlyProfile.NoteSize.Value, + ["NoteOpacity"] = () => getSetting("note_opacity") ?? nightlyProfile.NoteOpacity.Value, + ["CursorScale"] = () => getSetting("cursor_scale") ?? nightlyProfile.CursorScale.Value, + ["CursorRotation"] = () => getSetting("cursor_spin") ?? nightlyProfile.CursorRotation.Value, + ["CursorTrail"] = () => getSetting("cursor_trail") ?? nightlyProfile.CursorTrail.Value, + ["TrailTime"] = () => getSetting("trail_time") ?? nightlyProfile.TrailTime.Value, + ["TrailDetail"] = () => getSetting("trail_detail") ?? nightlyProfile.TrailDetail.Value, + ["SimpleHUD"] = () => getSetting("simple_hud") ?? nightlyProfile.SimpleHUD.Value, + ["HitPopups"] = () => getSetting("score_popup") ?? nightlyProfile.HitPopups.Value, + ["MissPopups"] = () => getSetting("show_miss_effect") ?? nightlyProfile.MissPopups.Value, + ["Fullscreen"] = () => getSetting("window_fullscreen") ?? nightlyProfile.Fullscreen.Value, + ["FPS"] = () => getSetting("target_fps") ?? nightlyProfile.FPS.Value, + ["VolumeMaster"] = () => 100, + ["VolumeMusic"] = () => importVolume("music_volume", 70), + ["VolumeHitSound"] = () => importVolume("hit_volume", 80), + ["VolumeMissSound"] = () => importVolume("miss_volume", 80), + ["VolumeSFX"] = () => importVolume("fail_volume", 80), + ["EnableHitSound"] = () => getSetting("play_hit_snd") ?? nightlyProfile.EnableHitSound.Value, + ["EnableMissSound"] = () => getSetting("play_miss_snd") ?? nightlyProfile.EnableMissSound.Value, + ["EnableMenuMusic"] = () => getSetting("play_menu_music") ?? nightlyProfile.EnableMenuMusic.Value, + ["AutoplayJukebox"] = () => getSetting("auto_preview_song") ?? nightlyProfile.AutoplayJukebox.Value, + ["LocalOffset"] = () => getSetting("music_offset") ?? nightlyProfile.LocalOffset.Value, + ["RecordReplays"] = () => getSetting("record_replays") ?? nightlyProfile.RecordReplays.Value, + }; + + var settingsById = typeof(SettingsProfile).GetProperties() + .Where(p => typeof(ISettingsItem).IsAssignableFrom(p.PropertyType)) + .Select(p => (ISettingsItem)p.GetValue(nightlyProfile)) + .ToDictionary(item => item.Id); + + foreach (var (id, convert) in conversions) + { + settingsById[id].SetVariant(convert()); + } // prevents overriding existing 'nightly' profile string getProfileName(string baseName) From 8347c1d2e75eea970f23718ad561798c25ca6a3e Mon Sep 17 00:00:00 2001 From: xwalfiee Date: Wed, 15 Jul 2026 01:13:14 +0200 Subject: [PATCH 07/18] chore: add xwalfie to contributor list --- scenes/main_menu.tscn | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/scenes/main_menu.tscn b/scenes/main_menu.tscn index 8801bb64..46331bb9 100644 --- a/scenes/main_menu.tscn +++ b/scenes/main_menu.tscn @@ -1730,6 +1730,15 @@ bbcode_enabled = true text = "[font_size=20]noobour [color=0f81b7][font_size=16]Contributor" +[node name="xwalfie" type="RichTextLabel" parent="Menus/Extras/Credits/ScrollContainer/VBoxContainer" unique_id=427847284] +modulate = Color(0.2627451, 1, 0.9529412, 1) +layout_mode = 2 +bbcode_enabled = true +text = "[font_size=20]xwalfie +[color=ffffffbb][font_size=16]Contributor" +fit_content = true +horizontal_alignment = 1 + [node name="Outline" type="Panel" parent="Menus/Extras/Credits" unique_id=239136532] material = SubResource("ShaderMaterial_yxnar") layout_mode = 1 From e937c11591618082a7e8a25e491ba622f890c994 Mon Sep 17 00:00:00 2001 From: xwalfiee Date: Sat, 18 Jul 2026 15:35:37 +0200 Subject: [PATCH 08/18] feat: import meshes and colorsets from nightly --- scripts/database/settings/SettingsProfile.cs | 106 +++++++++++++++++++ 1 file changed, 106 insertions(+) diff --git a/scripts/database/settings/SettingsProfile.cs b/scripts/database/settings/SettingsProfile.cs index d3bff747..0d865399 100644 --- a/scripts/database/settings/SettingsProfile.cs +++ b/scripts/database/settings/SettingsProfile.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Reflection.Metadata; using System.Text.Json; using Godot; @@ -355,6 +356,18 @@ public partial class SettingsProfile /// public SettingsItem ImportDialog { get; private set; } + [Order] + /// + /// Imports meshes from the nightly folder + /// + public SettingsItem ImportMeshesNightly { get; private set; } + + [Order] + /// + /// Imports colorsets from the nightly folder + /// + public SettingsItem ImportColorsetsNightly { get; private set; } + [Order] /// /// Toggles recording for replays @@ -1069,6 +1082,34 @@ public SettingsProfile() ] }; + ImportMeshesNightly = new(default) + { + Id = "ImportMeshesNightly", + Title = "Import Nightly Meshes", + Description = "Imports meshes from the nightly folder", + Section = SettingsSection.Other, + Buttons = + [ + new() { Title = "Import Nightly Meshes", Description = "Imports meshes from the nightly folder", OnPressed = () => { + ImportMeshesFromNightly(); + }} + ] + }; + + ImportColorsetsNightly = new(default) + { + Id = "ImportColorsetsNightly", + Title = "Import Nightly Colorsets", + Description = "Imports colorsets from the nightly folder", + Section = SettingsSection.Other, + Buttons = + [ + new() { Title = "Import Nightly Colorsets", Description = "Imports colorsets from the nightly folder", OnPressed = () => { + ImportColorsetsFromNightly(); + }} + ] + }; + DisplayFPS = new(true) { Id = "DisplayFPS", @@ -1303,4 +1344,69 @@ string getProfileName(string baseName) ToastNotification.Notify($"Created profile '{profileName}'"); } + + public static void ImportColorsetsFromNightly() + { + string nightlyColorsetsDir = $"{Constants.NIGHTLY_FOLDER}/colorsets"; + string colorsetsDir = $"{Constants.USER_FOLDER}/colorsets"; + int importedCount = 0; + + if (!Directory.Exists(nightlyColorsetsDir)) + { + ToastNotification.Notify("The nightly colorsets folder doesn't exist"); + return; + } + + Directory.CreateDirectory(colorsetsDir); + + foreach (string file in Directory.GetFiles(nightlyColorsetsDir)) + { + string fileName = Path.GetFileName(file); + string destinationPath = $"{colorsetsDir}/{fileName}"; + + if (!File.Exists(destinationPath)) + { + File.Copy(file, destinationPath); + importedCount++; + } + } + + ToastNotification.Notify($"Imported {importedCount} colorsets from nightly"); + } + + public static void ImportMeshesFromNightly() + { + string nightlyMeshesDir = $"{Constants.NIGHTLY_FOLDER}/meshes"; + string meshesDir = $"{Constants.USER_FOLDER}/meshes"; + int importedCount = 0; + + if (!Directory.Exists(nightlyMeshesDir)) + { + ToastNotification.Notify("The nightly meshes folder doesn't exist"); + return; + } + + Directory.CreateDirectory(meshesDir); + + foreach (string file in Directory.GetFiles(nightlyMeshesDir, "*.obj")) + { + string fileName = Path.GetFileName(file); + string destinationPath = $"{meshesDir}/{fileName}"; + + if (!File.Exists(destinationPath)) + { + string mtlFile = Path.ChangeExtension(file, ".mtl"); + string mtlDestinationPath = $"{meshesDir}/{Path.GetFileName(mtlFile)}"; + + File.Copy(file, destinationPath); + if (File.Exists(mtlFile)) + { + File.Copy(mtlFile, mtlDestinationPath); + } + importedCount++; + } + } + + ToastNotification.Notify($"Imported {importedCount} meshes from nightly"); + } } From 804276f56c03b7b999da75fe8179eb13500769ae Mon Sep 17 00:00:00 2001 From: xwalfiee Date: Sat, 18 Jul 2026 15:39:58 +0200 Subject: [PATCH 09/18] feat: add RefreshList helper --- scripts/ui/SettingsMenu.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/scripts/ui/SettingsMenu.cs b/scripts/ui/SettingsMenu.cs index bbb718e4..e013da89 100644 --- a/scripts/ui/SettingsMenu.cs +++ b/scripts/ui/SettingsMenu.cs @@ -434,4 +434,15 @@ private void setupButton(SettingsButton setting, Button button) setting.OnPressed?.Invoke(); }; } + + public void RefreshList(ISettingsItem setting) + { + OptionButton optionButton = settingPanels[setting.Id].GetNode("OptionButton"); + optionButton.Clear(); + + foreach (Variant item in setting.List.Values) + { + optionButton.AddItem(item.AsString()); + } + } } From 10872884525deb75caf6432a4d74c7ec89fa1a5f Mon Sep 17 00:00:00 2001 From: xwalfiee Date: Sat, 18 Jul 2026 15:40:29 +0200 Subject: [PATCH 10/18] feat: refresh mesh and colorset dropdowns after importing --- scripts/database/settings/SettingsProfile.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/database/settings/SettingsProfile.cs b/scripts/database/settings/SettingsProfile.cs index 0d865399..ea601adc 100644 --- a/scripts/database/settings/SettingsProfile.cs +++ b/scripts/database/settings/SettingsProfile.cs @@ -1092,6 +1092,8 @@ public SettingsProfile() [ new() { Title = "Import Nightly Meshes", Description = "Imports meshes from the nightly folder", OnPressed = () => { ImportMeshesFromNightly(); + SettingsManager.Instance.Settings.NoteMesh.List.Values = getAvailableMeshes(); + SettingsMenu.Instance.RefreshList(SettingsManager.Instance.Settings.NoteMesh); }} ] }; @@ -1106,6 +1108,8 @@ public SettingsProfile() [ new() { Title = "Import Nightly Colorsets", Description = "Imports colorsets from the nightly folder", OnPressed = () => { ImportColorsetsFromNightly(); + SettingsManager.Load(); + SettingsMenu.Instance.RefreshList(SettingsManager.Instance.Settings.NoteColors); }} ] }; From e336e0f1c87220fc6aa57ec055a06be10adc5251 Mon Sep 17 00:00:00 2001 From: xwalfiee Date: Sat, 18 Jul 2026 15:43:44 +0200 Subject: [PATCH 11/18] chore: remove unused import --- scripts/database/settings/SettingsProfile.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/database/settings/SettingsProfile.cs b/scripts/database/settings/SettingsProfile.cs index ea601adc..45c467a0 100644 --- a/scripts/database/settings/SettingsProfile.cs +++ b/scripts/database/settings/SettingsProfile.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Reflection.Metadata; using System.Text.Json; using Godot; From 623375cc2f71029234a42eb9b97891d306a803c4 Mon Sep 17 00:00:00 2001 From: xwalfiee Date: Tue, 21 Jul 2026 13:21:37 +0200 Subject: [PATCH 12/18] refactor: remove unnecessary .Value --- scripts/database/settings/SettingsProfile.cs | 60 ++++++++++---------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/scripts/database/settings/SettingsProfile.cs b/scripts/database/settings/SettingsProfile.cs index 45c467a0..56bac77f 100644 --- a/scripts/database/settings/SettingsProfile.cs +++ b/scripts/database/settings/SettingsProfile.cs @@ -1272,41 +1272,41 @@ double importVolume(string nightlyKey, double range) Dictionary> conversions = new() { // sensitivity scales with fov but in nightly it doesnt - ["Sensitivity"] = () => getSetting("sensitivity") * 2.16 * (70 / (getSetting("fov") ?? 70)) ?? nightlyProfile.Sensitivity.Value, - ["AbsoluteSensitivity"] = () => getSetting("absolute_scale") ?? nightlyProfile.AbsoluteSensitivity.Value, - ["AbsoluteInput"] = () => getSetting("absolute_mode") ?? nightlyProfile.AbsoluteInput.Value, - ["CursorDrift"] = () => getSetting("enable_drift_cursor") ?? nightlyProfile.CursorDrift.Value, - ["ApproachRate"] = () => getSetting("approach_rate") ?? nightlyProfile.ApproachRate.Value, - ["ApproachDistance"] = () => getSetting("spawn_distance") ?? nightlyProfile.ApproachDistance.Value, - ["Pushback"] = () => getSetting("do_note_pushback") ?? nightlyProfile.Pushback.Value, - ["CameraParallax"] = () => getSetting("parallax") * 0.025 ?? nightlyProfile.CameraParallax.Value, - ["HUDParallax"] = () => getSetting("ui_parallax") * 0.025 ?? nightlyProfile.HUDParallax.Value, - ["FoV"] = () => getSetting("fov") ?? nightlyProfile.FoV.Value, - ["Colors"] = () => getStringSetting("selected_colorset") ?? nightlyProfile.NoteColors.Value, - ["NoteMesh"] = () => getStringSetting("selected_mesh") ?? nightlyProfile.NoteMesh.Value, - ["NoteSize"] = () => getSetting("note_size") * 0.875 ?? nightlyProfile.NoteSize.Value, - ["NoteOpacity"] = () => getSetting("note_opacity") ?? nightlyProfile.NoteOpacity.Value, - ["CursorScale"] = () => getSetting("cursor_scale") ?? nightlyProfile.CursorScale.Value, - ["CursorRotation"] = () => getSetting("cursor_spin") ?? nightlyProfile.CursorRotation.Value, - ["CursorTrail"] = () => getSetting("cursor_trail") ?? nightlyProfile.CursorTrail.Value, - ["TrailTime"] = () => getSetting("trail_time") ?? nightlyProfile.TrailTime.Value, - ["TrailDetail"] = () => getSetting("trail_detail") ?? nightlyProfile.TrailDetail.Value, - ["SimpleHUD"] = () => getSetting("simple_hud") ?? nightlyProfile.SimpleHUD.Value, - ["HitPopups"] = () => getSetting("score_popup") ?? nightlyProfile.HitPopups.Value, - ["MissPopups"] = () => getSetting("show_miss_effect") ?? nightlyProfile.MissPopups.Value, - ["Fullscreen"] = () => getSetting("window_fullscreen") ?? nightlyProfile.Fullscreen.Value, - ["FPS"] = () => getSetting("target_fps") ?? nightlyProfile.FPS.Value, + ["Sensitivity"] = () => getSetting("sensitivity") * 2.16 * (70 / (getSetting("fov") ?? 70)) ?? nightlyProfile.Sensitivity, + ["AbsoluteSensitivity"] = () => getSetting("absolute_scale") ?? nightlyProfile.AbsoluteSensitivity, + ["AbsoluteInput"] = () => getSetting("absolute_mode") ?? nightlyProfile.AbsoluteInput, + ["CursorDrift"] = () => getSetting("enable_drift_cursor") ?? nightlyProfile.CursorDrift, + ["ApproachRate"] = () => getSetting("approach_rate") ?? nightlyProfile.ApproachRate, + ["ApproachDistance"] = () => getSetting("spawn_distance") ?? nightlyProfile.ApproachDistance, + ["Pushback"] = () => getSetting("do_note_pushback") ?? nightlyProfile.Pushback, + ["CameraParallax"] = () => getSetting("parallax") * 0.025 ?? nightlyProfile.CameraParallax, + ["HUDParallax"] = () => getSetting("ui_parallax") * 0.025 ?? nightlyProfile.HUDParallax, + ["FoV"] = () => getSetting("fov") ?? nightlyProfile.FoV, + ["Colors"] = () => getStringSetting("selected_colorset") ?? nightlyProfile.NoteColors, + ["NoteMesh"] = () => getStringSetting("selected_mesh") ?? nightlyProfile.NoteMesh, + ["NoteSize"] = () => getSetting("note_size") * 0.875 ?? nightlyProfile.NoteSize, + ["NoteOpacity"] = () => getSetting("note_opacity") ?? nightlyProfile.NoteOpacity, + ["CursorScale"] = () => getSetting("cursor_scale") ?? nightlyProfile.CursorScale, + ["CursorRotation"] = () => getSetting("cursor_spin") ?? nightlyProfile.CursorRotation, + ["CursorTrail"] = () => getSetting("cursor_trail") ?? nightlyProfile.CursorTrail, + ["TrailTime"] = () => getSetting("trail_time") ?? nightlyProfile.TrailTime, + ["TrailDetail"] = () => getSetting("trail_detail") ?? nightlyProfile.TrailDetail, + ["SimpleHUD"] = () => getSetting("simple_hud") ?? nightlyProfile.SimpleHUD, + ["HitPopups"] = () => getSetting("score_popup") ?? nightlyProfile.HitPopups, + ["MissPopups"] = () => getSetting("show_miss_effect") ?? nightlyProfile.MissPopups, + ["Fullscreen"] = () => getSetting("window_fullscreen") ?? nightlyProfile.Fullscreen, + ["FPS"] = () => getSetting("target_fps") ?? nightlyProfile.FPS, ["VolumeMaster"] = () => 100, ["VolumeMusic"] = () => importVolume("music_volume", 70), ["VolumeHitSound"] = () => importVolume("hit_volume", 80), ["VolumeMissSound"] = () => importVolume("miss_volume", 80), ["VolumeSFX"] = () => importVolume("fail_volume", 80), - ["EnableHitSound"] = () => getSetting("play_hit_snd") ?? nightlyProfile.EnableHitSound.Value, - ["EnableMissSound"] = () => getSetting("play_miss_snd") ?? nightlyProfile.EnableMissSound.Value, - ["EnableMenuMusic"] = () => getSetting("play_menu_music") ?? nightlyProfile.EnableMenuMusic.Value, - ["AutoplayJukebox"] = () => getSetting("auto_preview_song") ?? nightlyProfile.AutoplayJukebox.Value, - ["LocalOffset"] = () => getSetting("music_offset") ?? nightlyProfile.LocalOffset.Value, - ["RecordReplays"] = () => getSetting("record_replays") ?? nightlyProfile.RecordReplays.Value, + ["EnableHitSound"] = () => getSetting("play_hit_snd") ?? nightlyProfile.EnableHitSound, + ["EnableMissSound"] = () => getSetting("play_miss_snd") ?? nightlyProfile.EnableMissSound, + ["EnableMenuMusic"] = () => getSetting("play_menu_music") ?? nightlyProfile.EnableMenuMusic, + ["AutoplayJukebox"] = () => getSetting("auto_preview_song") ?? nightlyProfile.AutoplayJukebox, + ["LocalOffset"] = () => getSetting("music_offset") ?? nightlyProfile.LocalOffset, + ["RecordReplays"] = () => getSetting("record_replays") ?? nightlyProfile.RecordReplays, }; var settingsById = typeof(SettingsProfile).GetProperties() From 2896e7decbf3bfd5e28980c3eb14eaf0bfeecb2f Mon Sep 17 00:00:00 2001 From: xwalfiee Date: Tue, 21 Jul 2026 13:28:12 +0200 Subject: [PATCH 13/18] refactor: rename settings for consistency --- scripts/database/settings/SettingsProfile.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/scripts/database/settings/SettingsProfile.cs b/scripts/database/settings/SettingsProfile.cs index 56bac77f..6942b0aa 100644 --- a/scripts/database/settings/SettingsProfile.cs +++ b/scripts/database/settings/SettingsProfile.cs @@ -347,7 +347,7 @@ public partial class SettingsProfile /// /// Import settings from previous (nightly) version /// - public SettingsItem RhythiaImport { get; private set; } + public SettingsItem ImportNightlyProfile { get; private set; } [Order] /// @@ -359,13 +359,13 @@ public partial class SettingsProfile /// /// Imports meshes from the nightly folder /// - public SettingsItem ImportMeshesNightly { get; private set; } + public SettingsItem ImportNightlyMeshes { get; private set; } [Order] /// /// Imports colorsets from the nightly folder /// - public SettingsItem ImportColorsetsNightly { get; private set; } + public SettingsItem ImportNightlyColorsets { get; private set; } [Order] /// @@ -1049,9 +1049,9 @@ public SettingsProfile() #region Other - RhythiaImport = new(default) + ImportNightlyProfile = new(default) { - Id = "RhythiaImport", + Id = "ImportNightlyProfile", Title = "Import Nightly Settings", Description = "Imports settings from the nightly client", Section = SettingsSection.Other, @@ -1081,9 +1081,9 @@ public SettingsProfile() ] }; - ImportMeshesNightly = new(default) + ImportNightlyMeshes = new(default) { - Id = "ImportMeshesNightly", + Id = "ImportNightlyMeshes", Title = "Import Nightly Meshes", Description = "Imports meshes from the nightly folder", Section = SettingsSection.Other, @@ -1097,9 +1097,9 @@ public SettingsProfile() ] }; - ImportColorsetsNightly = new(default) + ImportNightlyColorsets = new(default) { - Id = "ImportColorsetsNightly", + Id = "ImportNightlyColorsets", Title = "Import Nightly Colorsets", Description = "Imports colorsets from the nightly folder", Section = SettingsSection.Other, From f55742ae9bcef562fc14c60aae3459ed361c837b Mon Sep 17 00:00:00 2001 From: xwalfiee Date: Tue, 21 Jul 2026 13:34:30 +0200 Subject: [PATCH 14/18] refactor: make nightly import dialog clearer and consistent --- Rhythia.csproj | 2 +- scripts/database/settings/SettingsProfile.cs | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Rhythia.csproj b/Rhythia.csproj index 94da00f6..b147a862 100644 --- a/Rhythia.csproj +++ b/Rhythia.csproj @@ -1,4 +1,4 @@ - + net10.0 net10.0 diff --git a/scripts/database/settings/SettingsProfile.cs b/scripts/database/settings/SettingsProfile.cs index 6942b0aa..c33497f2 100644 --- a/scripts/database/settings/SettingsProfile.cs +++ b/scripts/database/settings/SettingsProfile.cs @@ -353,7 +353,7 @@ public partial class SettingsProfile /// /// File dialog for the nightly import /// - public SettingsItem ImportDialog { get; private set; } + public SettingsItem NightlyImportDialog { get; private set; } [Order] /// @@ -1057,7 +1057,7 @@ public SettingsProfile() Section = SettingsSection.Other, Buttons = [ - new() { Title = "Import", Description = "", OnPressed = () => { + new() { Title = "Import", Description = "Automatically import settings from nightly", OnPressed = () => { if (Directory.Exists(Constants.NIGHTLY_FOLDER)) { ImportFromNightlySettings($"{Constants.NIGHTLY_FOLDER}/settings.json"); @@ -1067,15 +1067,15 @@ public SettingsProfile() SaveToDisk = false, }; - ImportDialog = new(default) + NightlyImportDialog = new(default) { - Id = "ImportDialog", - Title = "", + Id = "NightlyImportDialog", + Title = "", // this has no title because its supposed to be a button belonging to the field above Description = "", Section = SettingsSection.Other, Buttons = [ - new() { Title = "Choose file", Description = "", OnPressed = () => { + new() { Title = "Choose file", Description = "Import manually from a nightly settings file", OnPressed = () => { SettingsMenu.Instance.ImportNightlyDialog.PopupCentered(); }} ] From 17ae128cbd2c38b1e5049e494f9a9a611f939884 Mon Sep 17 00:00:00 2001 From: xwalfiee Date: Tue, 21 Jul 2026 13:49:01 +0200 Subject: [PATCH 15/18] refactor: make import methods that arent outside settingsprofile private --- scripts/database/settings/SettingsProfile.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/database/settings/SettingsProfile.cs b/scripts/database/settings/SettingsProfile.cs index c33497f2..24923d65 100644 --- a/scripts/database/settings/SettingsProfile.cs +++ b/scripts/database/settings/SettingsProfile.cs @@ -1090,7 +1090,7 @@ public SettingsProfile() Buttons = [ new() { Title = "Import Nightly Meshes", Description = "Imports meshes from the nightly folder", OnPressed = () => { - ImportMeshesFromNightly(); + importMeshesFromNightly(); SettingsManager.Instance.Settings.NoteMesh.List.Values = getAvailableMeshes(); SettingsMenu.Instance.RefreshList(SettingsManager.Instance.Settings.NoteMesh); }} @@ -1106,7 +1106,7 @@ public SettingsProfile() Buttons = [ new() { Title = "Import Nightly Colorsets", Description = "Imports colorsets from the nightly folder", OnPressed = () => { - ImportColorsetsFromNightly(); + importColorsetsFromNightly(); SettingsManager.Load(); SettingsMenu.Instance.RefreshList(SettingsManager.Instance.Settings.NoteColors); }} @@ -1348,7 +1348,7 @@ string getProfileName(string baseName) ToastNotification.Notify($"Created profile '{profileName}'"); } - public static void ImportColorsetsFromNightly() + private static void importColorsetsFromNightly() { string nightlyColorsetsDir = $"{Constants.NIGHTLY_FOLDER}/colorsets"; string colorsetsDir = $"{Constants.USER_FOLDER}/colorsets"; @@ -1377,7 +1377,7 @@ public static void ImportColorsetsFromNightly() ToastNotification.Notify($"Imported {importedCount} colorsets from nightly"); } - public static void ImportMeshesFromNightly() + private static void importMeshesFromNightly() { string nightlyMeshesDir = $"{Constants.NIGHTLY_FOLDER}/meshes"; string meshesDir = $"{Constants.USER_FOLDER}/meshes"; From 1ac3c99ad3344f97039057054ab2585abdd113bd Mon Sep 17 00:00:00 2001 From: xwalfiee Date: Tue, 21 Jul 2026 13:51:18 +0200 Subject: [PATCH 16/18] style: add newline for consistency --- scripts/database/settings/SettingsProfile.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/database/settings/SettingsProfile.cs b/scripts/database/settings/SettingsProfile.cs index 24923d65..e45494cd 100644 --- a/scripts/database/settings/SettingsProfile.cs +++ b/scripts/database/settings/SettingsProfile.cs @@ -1249,6 +1249,7 @@ public static void ImportFromNightlySettings(string settingsPath) { return element.GetString(); } + return null; } From 12800d613866ea9784891b29cbc9934008bc69ca Mon Sep 17 00:00:00 2001 From: xwalfiee Date: Tue, 21 Jul 2026 13:56:31 +0200 Subject: [PATCH 17/18] fix: revert accidental godot sdk version bump (sigh) --- Rhythia.csproj | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Rhythia.csproj b/Rhythia.csproj index b147a862..ced6fcc4 100644 --- a/Rhythia.csproj +++ b/Rhythia.csproj @@ -1,4 +1,4 @@ - + net10.0 net10.0 @@ -20,4 +20,3 @@ - From 6f60ae6a99b36c1bca991672ff417d2e1083afee Mon Sep 17 00:00:00 2001 From: xwalfiee Date: Wed, 22 Jul 2026 14:41:27 +0200 Subject: [PATCH 18/18] fix: add SaveToDisk = false --- scripts/database/settings/SettingsProfile.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/scripts/database/settings/SettingsProfile.cs b/scripts/database/settings/SettingsProfile.cs index e45494cd..b4c3e220 100644 --- a/scripts/database/settings/SettingsProfile.cs +++ b/scripts/database/settings/SettingsProfile.cs @@ -1078,7 +1078,8 @@ public SettingsProfile() new() { Title = "Choose file", Description = "Import manually from a nightly settings file", OnPressed = () => { SettingsMenu.Instance.ImportNightlyDialog.PopupCentered(); }} - ] + ], + SaveToDisk = false, }; ImportNightlyMeshes = new(default) @@ -1094,7 +1095,8 @@ public SettingsProfile() SettingsManager.Instance.Settings.NoteMesh.List.Values = getAvailableMeshes(); SettingsMenu.Instance.RefreshList(SettingsManager.Instance.Settings.NoteMesh); }} - ] + ], + SaveToDisk = false, }; ImportNightlyColorsets = new(default) @@ -1110,7 +1112,8 @@ public SettingsProfile() SettingsManager.Load(); SettingsMenu.Instance.RefreshList(SettingsManager.Instance.Settings.NoteColors); }} - ] + ], + SaveToDisk = false, }; DisplayFPS = new(true)