From 22b67c628c86b1a53d640640aaa402a5dff1e6bb Mon Sep 17 00:00:00 2001 From: iisaev Date: Sun, 18 Oct 2026 19:00:34 +0200 Subject: [PATCH] Mod naming rule and engine UI in engine mods Mods are renamed by role (shell2d_base, menu_base, ui_base, live2d_base, editor_tools, cthangover_story, cthangover_murakami, cthangover_party) and every reference follows. Engine UI prefabs (dialog, answers, message, game menu, inventory, map, skills) and their panel entries moved out of the story mod into the subsystem mods; the card_novel and vn_starter_novel collections are removed. --- collections/frontend.json | 2 +- locale/en.properties | 4 ++-- locale/ru.properties | 4 ++-- manifest.json | 6 +++--- src/BaseMenuInitializer.cs | 2 +- .../hot_reload/src/HotReloadTestDriverNode.cs | 2 +- .../menu_flow/src/MenuFlowTestDriverNode.cs | 14 +++++++------- test_suites/new_game/manifest.json | 2 +- test_suites/new_game/src/NewGameTestDriverNode.cs | 12 ++++++------ .../src/SaveDormancyTestDriverNode.cs | 4 ++-- 10 files changed, 26 insertions(+), 26 deletions(-) diff --git a/collections/frontend.json b/collections/frontend.json index 4ba34a5..a7ad298 100644 --- a/collections/frontend.json +++ b/collections/frontend.json @@ -17,7 +17,7 @@ "locale": [ { "lang": "ru", "name": "Главное меню", "description": "Главное меню, настройки и панели сохранения/загрузки." } ], - "mods": ["base_menu>=1", "interface>=1", "audio_base>=1"] + "mods": ["menu_base>=1", "ui_base>=1", "audio_base>=1"] }, { "id": "mods", diff --git a/locale/en.properties b/locale/en.properties index ac34bc2..b99995d 100644 --- a/locale/en.properties +++ b/locale/en.properties @@ -1,5 +1,5 @@ -mod_base_menu_name = Base Menu -mod_base_menu_desc = Registry-driven main menu: built-in buttons, settings and save/load panels moved out of the core. +mod_menu_base_name = Menu +mod_menu_base_desc = Registry-driven main menu: built-in buttons, settings and save/load panels moved out of the core. settings/saves/purge_dormant = Data of disabled mechanics settings/saves/purge_dormant_button = Purge diff --git a/locale/ru.properties b/locale/ru.properties index f083d80..7338193 100644 --- a/locale/ru.properties +++ b/locale/ru.properties @@ -1,5 +1,5 @@ -mod_base_menu_name = Базовое меню -mod_base_menu_desc = Главное меню на реестрах: встроенные кнопки, настройки и панели сохранения/загрузки, вынесенные из ядра. +mod_menu_base_name = Меню +mod_menu_base_desc = Главное меню на реестрах: встроенные кнопки, настройки и панели сохранения/загрузки, вынесенные из ядра. settings/saves/purge_dormant = Данные отключённых механик settings/saves/purge_dormant_button = Очистить diff --git a/manifest.json b/manifest.json index 2f8f89c..e6af884 100644 --- a/manifest.json +++ b/manifest.json @@ -1,6 +1,6 @@ { - "id": "base_menu", - "name": "Base Menu", + "id": "menu_base", + "name": "Menu", "version": "1.0.0", "author": "ct", "description": "Registry-driven main menu: built-in buttons, settings and save/load panels moved out of the core.", @@ -8,7 +8,7 @@ "sources": [ "src/**/*.cs" ], - "depends": ["interface>=1"], + "depends": ["ui_base>=1"], "test_suites": [ {"id": "menu_flow", "activate": ["--itest=menu_flow"]}, {"id": "save_dormancy", "activate": ["--itest=save_dormancy"]}, diff --git a/src/BaseMenuInitializer.cs b/src/BaseMenuInitializer.cs index 73e1e7e..7d8c57a 100644 --- a/src/BaseMenuInitializer.cs +++ b/src/BaseMenuInitializer.cs @@ -17,7 +17,7 @@ namespace Cthangover.BaseMenu /// public class BaseMenuInitializer : IModInitializer { - private const string ModId = "base_menu"; + private const string ModId = "menu_base"; public void OnModLoaded(string modId) { diff --git a/test_suites/hot_reload/src/HotReloadTestDriverNode.cs b/test_suites/hot_reload/src/HotReloadTestDriverNode.cs index a93eb5c..edecc64 100644 --- a/test_suites/hot_reload/src/HotReloadTestDriverNode.cs +++ b/test_suites/hot_reload/src/HotReloadTestDriverNode.cs @@ -189,7 +189,7 @@ namespace Mods.HotReloadTest private static bool UnloadedAndLoadedBoth(ModSetReloadedEvent e) => UnloadedBoth(e) && LoadedBoth(e); - private static bool UnloadedBaseMenu(ModSetReloadedEvent e) => e.Unloaded.Contains("base_menu"); + private static bool UnloadedBaseMenu(ModSetReloadedEvent e) => e.Unloaded.Contains("menu_base"); private static bool IsRejectedForLib(ModSetReloadedEvent e) => !e.Applied && e.Errors.Any(IsLibError); diff --git a/test_suites/menu_flow/src/MenuFlowTestDriverNode.cs b/test_suites/menu_flow/src/MenuFlowTestDriverNode.cs index ac11efa..0585263 100644 --- a/test_suites/menu_flow/src/MenuFlowTestDriverNode.cs +++ b/test_suites/menu_flow/src/MenuFlowTestDriverNode.cs @@ -23,7 +23,7 @@ namespace Mods.MenuFlowTest /// public partial class MenuFlowTestDriverNode : Node { - private const string GameId = "card_novel"; + private const string GameId = "novel_template"; private const string Slot = "slot_942"; private const string DeletableId = "menu_flow_deletable"; private const float TimeoutSeconds = 90f; @@ -82,8 +82,8 @@ namespace Mods.MenuFlowTest if (GetTree().CurrentScene is not MainMenu) return; Check("front-end only", ActiveGame.IsFrontendOnly && !ActiveGame.IsActive); - Check("menu mods loaded", ModRegistry.Instance.Mods.ContainsKey("base_menu") && ModRegistry.Instance.Mods.ContainsKey("mod_manager")); - Check("game content not loaded", !ModRegistry.Instance.Mods.ContainsKey("visual_novel_core")); + Check("menu mods loaded", ModRegistry.Instance.Mods.ContainsKey("menu_base") && ModRegistry.Instance.Mods.ContainsKey("mod_manager")); + Check("game content not loaded", !ModRegistry.Instance.Mods.ContainsKey("cthangover_story")); Check("Play button shown", Menu.FindChild("play", true, false) is Button); Check("New game hidden without a game", Menu.FindChild("new_game", true, false) == null); break; @@ -158,11 +158,11 @@ namespace Mods.MenuFlowTest browser.Visible = false; var composition = GameCatalog.Composition(GameId); - Check("composition computed without loading the game", composition?.Any(m => m.Id == "card_battle") == true); + Check("composition computed without loading the game", composition?.Any(m => m.Id == "novel_template") == true); var diff = SaveCompositionDiff.Compute( - new[] { new SaveGameMod { Id = "visual_novel_core", Version = "2.0.0" }, new SaveGameMod { Id = "ghost_mechanic", Version = "1.0.0" } }, + new[] { new SaveGameMod { Id = "cthangover_story", Version = "2.0.0" }, new SaveGameMod { Id = "ghost_mechanic", Version = "1.0.0" } }, composition); - Check("comparison reports removed and added mechanics", diff.Removed.Contains("ghost_mechanic") && diff.Added.Contains("card_battle")); + Check("comparison reports removed and added mechanics", diff.Removed.Contains("ghost_mechanic") && diff.Added.Contains("novel_template")); LastSessionStore.Record(GameId, Slot); Check("Continue sees the last session", LastSessionStore.Load()?.GameId == GameId); @@ -191,7 +191,7 @@ namespace Mods.MenuFlowTest SaveId = Slot, Timestamp = DateTime.UtcNow, CoreVersion = "0.1.0", - Game = new SaveGameInfo { Id = GameId, Name = "Card Novel", Version = "1.0.0" }, + Game = new SaveGameInfo { Id = GameId, Name = "Novel Template", Version = "1.0.0" }, }; package.ModData[SavePackage.CoreSlotKey] = new ModSlot(); var dir = ProjectSettings.GlobalizePath(SaveService.GameDirectory(GameId)); diff --git a/test_suites/new_game/manifest.json b/test_suites/new_game/manifest.json index 77376a1..0ed79e0 100644 --- a/test_suites/new_game/manifest.json +++ b/test_suites/new_game/manifest.json @@ -1,6 +1,6 @@ { "name": "New Game Flow Test", - "description": "End-to-end play like a player in one process: front-end menu → Play → the cthangover card → New game → in-process mod-set switch → the prologue in prolog_alley with Marao's dialog → in-game hot reload of starter_party (session restored) → menu → card_novel → menu → cthangover again; every released mod context must be collected. Activated only by --itest=new_game (with --frontend).", + "description": "End-to-end play like a player in one process: front-end menu → Play → the cthangover card → New game → in-process mod-set switch → the prologue in prolog_alley with Marao's dialog → in-game hot reload of cthangover_party (session restored) → menu → novel_template → menu → cthangover again; every released mod context must be collected. Activated only by --itest=new_game (with --frontend).", "sources": [ "src/*.cs" ] diff --git a/test_suites/new_game/src/NewGameTestDriverNode.cs b/test_suites/new_game/src/NewGameTestDriverNode.cs index 755db86..220de28 100644 --- a/test_suites/new_game/src/NewGameTestDriverNode.cs +++ b/test_suites/new_game/src/NewGameTestDriverNode.cs @@ -20,10 +20,10 @@ namespace Mods.NewGameTest /// Front-end menu → Play → the cthangover card → New game: the /// process switches to the game, enters prolog_alley and the opening /// dialog about the hungover Marao is clicked through. - /// Hot reload inside the game (forced reload of starter_party): + /// Hot reload inside the game (forced reload of cthangover_party): /// the session is parked, the mod reloads into a new context and the game /// comes back in prolog_alley. - /// Back to the menu → card_novel: mods outside that game are + /// Back to the menu → novel_template: mods outside that game are /// unloaded and a scene of the game is entered. /// Back to the menu → cthangover again → prolog_alley. /// @@ -38,9 +38,9 @@ namespace Mods.NewGameTest public const string Flag = "--itest=new_game"; private const string MainGame = "cthangover"; - private const string SecondGame = "card_novel"; + private const string SecondGame = "novel_template"; private const string PrologScene = "prolog_alley"; - private const string HotReloadedMod = "starter_party"; + private const string HotReloadedMod = "cthangover_party"; private const float TimeoutSeconds = 420f; private readonly List failures = new(); @@ -160,7 +160,7 @@ namespace Mods.NewGameTest var reload = ModManager.Instance.LastReload; Check("in-game hot reload applied", reload?.Applied == true); Check($"hot reload reloaded '{HotReloadedMod}'", reload?.Plan?.Load.Contains(HotReloadedMod) == true); - Check("hot reload kept the front-end loaded", reload?.Plan?.Keep.Contains("base_menu") == true); + Check("hot reload kept the front-end loaded", reload?.Plan?.Keep.Contains("menu_base") == true); Check("hot reload released every old context", reload?.Leaked.Count == 0); Check($"hot reload kept the game '{MainGame}'", ActiveGame.Id == MainGame); Check($"session came back in '{PrologScene}'", true); @@ -255,7 +255,7 @@ namespace Mods.NewGameTest { var reload = ModManager.Instance.LastReload; Check($"switch into '{gameId}' applied", reload?.Applied == true); - Check($"switch into '{gameId}' kept the front-end loaded", reload?.Plan?.Keep.Contains("base_menu") == true); + Check($"switch into '{gameId}' kept the front-end loaded", reload?.Plan?.Keep.Contains("menu_base") == true); if (expectUnload) Check($"switch into '{gameId}' unloaded mods outside the game", reload?.Plan?.Unload.Count > 0); Check($"switch into '{gameId}' released every old context", reload?.Leaked.Count == 0); diff --git a/test_suites/save_dormancy/src/SaveDormancyTestDriverNode.cs b/test_suites/save_dormancy/src/SaveDormancyTestDriverNode.cs index 97dfd9c..a7c481c 100644 --- a/test_suites/save_dormancy/src/SaveDormancyTestDriverNode.cs +++ b/test_suites/save_dormancy/src/SaveDormancyTestDriverNode.cs @@ -76,7 +76,7 @@ namespace Mods.SaveDormancyTest var absentSlot = new ModSlot { Metadata = new ModMetadata { ModId = AbsentMod, ModVersion = "1.1.0" } }; absentSlot.Data["marker"] = new DataBlob(1, new Dictionary { ["value"] = "42" }); package.ModData[AbsentMod] = absentSlot; - package.ModData.Remove("base_menu__save_dormancy"); + package.ModData.Remove("menu_base__save_dormancy"); File.WriteAllText(pathA, JsonSerializer.Serialize(package, JsonOptionsProvider.WriteCompactOptions)); SaveDormancyProbe.Joined = false; @@ -93,7 +93,7 @@ namespace Mods.SaveDormancyTest && marker.ReadJson>().GetValueOrDefault("value") == "42"); Check("live mods still saved", resaved?.ModData?.ContainsKey(SavePackage.CoreSlotKey) == true); - var message = ModSettingsRegistry.RunAction("base_menu", "purge_dormant"); + var message = ModSettingsRegistry.RunAction("menu_base", "purge_dormant"); Check("purge action runs from the save settings", !string.IsNullOrEmpty(message)); Check("purge removed dormant data from the save", Read(FilePath(SlotB))?.Dormant == null);