Files
cthangover/docs/concepts/ui-and-shell.md
T
cthangover b9dd464bd1 Zip shader cache belongs to its mod and follows its content
Extracted shaders were cached on disk by shader name only, the cache was
consulted before the owning mod was known and a cached file was never
rewritten: an updated zip mod kept its old shader across launches, a removed
mod's copy beat the mod serving the name now, and another mod's same-named
shader could overwrite it. The cache is now per mod, files are rewritten
when their bytes change and the resolver picks the owning mod first.
Concept docs for interactives, effects and Live2D, UI and shell.
2026-10-21 10:58:45 +02:00

3.5 KiB

UI, shell and menus (Core/UI, mods/ui_base, mods/shell2d_base, mods/menu_base)

The core draws almost nothing itself. It owns the GUI pipeline: manifest ui declarations, a session-wide host, the menu registry and theme tokens. The engine mods provide the widgets, the 2D shell scene and the main menu. Layout lives in .tscn prefabs; code finds nodes and binds behaviour (see skill-code, "GUI: layout lives in scenes").

Pipeline (core)

  • UiRegistry collects, validates and orders every mod manifest's ui entries: panels with a toolbar button (icon, locale, index), overlays, scene binding, once, show_on_start, priority. A bad entry is logged with its mod id and skipped. The registry is cleared and rebuilt on mod reload.
  • UiHost is a persistent autoload with its own CanvasLayer. It caches panel instances by entry id and builds them lazily (TscnScenes). It hides scene-bound entries on scene exit and restores them on entry (SceneEntered priority 30), so panels survive a trip to a battle route. It learns the shell root from ShellReadyEvent and calls UiBuilder.Build there.
  • MenuRegistry holds the main menu: blocks and buttons bound to a mod scene or a code handler. It is filled declaratively (manifest main_menu) and by initializers (menu_base registers new game, load, settings, exit and their panels).
  • Theme: CthangoverTheme/UiTokens (boot window, so in the core); UiThemeBridge and NotificationBridge connect to ui_base. The core sees ui_base only through IWidget, IBackgroundView, IToolbarHost, ISaveIconHost and IUiLazyConstruct.

ui_base (toolkit)

  • Widget (with a Show/Hide pipeline and visibility interception) and the lighter ModWidget (Construct/Destruct). ModNode/InputHandlerNode forward lifecycle and input for mod nodes.
  • ViewBox: background and foreground with the shared timed_sprite lighting shader, crossfade through a black overlay, zoom, 9-point alignment, and interactive layers between background and foreground, plus a ui layer above.
  • ToolBox (TopView) shows panel buttons handed to it by UiBuilder, self-registering tool buttons and the save icon (refreshed by SceneManager on every switch).
  • ToolWindow (developer windows: chrome, drag/resize/maximize, dirty state, shortcuts, the denser ToolTheme), GameMenu/SaveIcon, NotificationPanel/MessagesHelper, DeviceInput, UiKit, lists.

shell2d_base and menu_base

  • shell2d_base is data only: the 2D shell scene (BaseScene) with the view box, toolbar, panel slots, notification and dialog canvases. It is the parent of every 2D content mod.
  • menu_base holds the launcher menu "Continue / Play / Load / Mods / Settings":
    • the game picker (GamePickerPanel: cards from GameCatalog, readiness, installing missing mods, saves, collection editor);
    • settings and save/load panels;
    • GameFlow, which switches games in-process, with a composition diff and a backup before loading a save into a changed game;
    • LastSessionStore for Continue.
  • The test suites menu_flow, collection_edit, new_game, save_dormancy and hot_reload live in menu_base.

Tests

Integration: menu, menu_flow, skills_panel, inventory, tools_windows (every tool window opens with no engine errors), scene_builder, tscn. xUnit: the menu registry, UI registry validation and the theme.

No defects specific to the UI pipeline were found in this review; the save-icon refresh fixed in SceneManager is listed in the scenes concept.