A complete game shell built on Luna + the CupkekGames sibling packages — a save-aware main menu, a persistent in-game HUD with reactive currency/XP chips, a session-scoped pause menu, a two-area scene loop with a small combat encounter, an inventory + equipment screen with drag-and-drop and a drop-table loot loop, a save/load screen, and a tabbed settings panel with input rebinding — all wired through Luna's navigation graphs, the Sequencer, and Newtonsoft JSON saves.

This is the "what does a real Luna game look like?" demo. Heavier than Showcase — it requires the full CupkekGames sibling-package set, installed via the Package Manager window.

Lives at Samples~/GameFull/ in com.cupkekgames.luna.

Quick start

Four steps after importing Luna from the Asset Store. The order matters: packages first, sample import second (the warning below explains why).

  1. Install the CupkekGames Package Manager window. It is a separate bootstrap package, not bundled with Luna: in Window > Package Manager, choose + > Install package from git URL and paste https://github.com/Cupkek-Games/CupkekGames-PackageManager.git.
  2. Open Tools > CupkekGames > Package Manager and click Install GameFull Packages. It adds the CupkekGames UPM scoped registry (https://www.docs.cupkek.games/upm) to your Packages/manifest.json and installs the required CupkekGames sibling packages atomically (one manifest write, one domain reload). From then on, the window auto-opens on project load if any sibling packages are missing.
  3. Import the Essentials sample, then GameFull in Window > Package Manager > In Project > LunaUI > Samples. GameFull's UXML references Essentials sample assets (theme, fonts, Panel Settings, prefab LunaUIManager.prefab, UXML primitives, audio) via sibling-relative paths, so both samples must land as siblings under Assets/Samples/LunaUI/<version>/.
  4. Open 00_LunaUIDemoFullInitialization.unity (at the GameFull sample root, sorts first) and press Play. The Sequencer registers services, then loads the main menu; New Game / Continue / Load then transitions into the game scene.

⚠️ Do not import the GameFull sample before step 2. GameFull's scripts compile against the sibling packages; importing the sample into a project that doesn't have them fills the Console with compile errors. Unity then refuses to load any newly installed tooling (including the Package Manager window itself) until the errors are gone, and reopening the project lands in Safe Mode. Recovery is simple: delete Assets/Samples/LunaUI/<version>/GameFull, do steps 1 and 2, then re-import. See Troubleshoot.

The Tools > CupkekGames > LunaUI Panel window auto-opens on sample import. Its "Extra: GameFull" card tracks this whole flow: a live count of the sibling packages, a warning if the sample was imported before installing them, and one-click Add/Remove of the demo scenes in Build Settings once everything is present.

GameFull main menu scene — save-aware Continue/Load buttons over the Luna theme

Required packages

The GameFull feature packages are not transitively pulled by the Luna dependency graph — com.cupkekgames.luna only declares its foundation/data deps (data, graphs, services, singletons, pool, fadeables, keyvaluedatabases, prefabloaders, assetfinder, editorui, editorinspector, input). The game-feature packages below are installed by the Package Manager window's Install GameFull Packages button (which also adds the CupkekGames scoped registry); the window itself is a separate bootstrap package installed via git URL (step 1 above).

RequiredWhat it provides
Luna's bundled deps (data, graphs, services, singletons, pool, fadeables, keyvaluedatabases, prefabloaders, assetfinder, editorui, editorinspector, input)bundled with Luna (declared + transitive)
com.cupkekgames.packagemanagerthe Tools > CupkekGames > Package Manager window — the bootstrap installer itself, added via git URL (step 1 above)
com.cupkekgames.lunathe UI toolkit itself — views, navigation, HUD, transitions
com.cupkekgames.resourcesWallet (currencies) + ExperienceTracker (XP/level) — the reactive save fields
com.cupkekgames.gamesave + com.cupkekgames.gamesave.lunasave manager + save-list / AutoSave UI
com.cupkekgames.newtonsoftNewtonsoft JSON adapter (SerializationManager / IDataSerializer)
com.cupkekgames.inventoryInventory / InventoryItem / IInventoryItemDatabase + the full inventory/equipment UI (InventoryViewPagination, EquipmentRackController, drag-drop, tooltips) — part of the save payload and the on-screen inventory screen
com.cupkekgames.rpgstatsequipment stat module (IEquipableFeatureRpgModule) + attribute definitions (Attack/Health/Defense) — drives the live equip stat comparison
com.cupkekgames.data (Data.DropTable)DropTableSO / DropResult — the loot table rolled by the Find Loot button
com.cupkekgames.addressableassetsaddressable prefab/asset loading used by save data + menus
com.cupkekgames.scenemanagementSceneLoader + SceneTransition (scene loads + fade/circle transitions)
com.cupkekgames.sequencerthe boot pipeline — every scene runs a SequenceRunner
com.cupkekgames.settingssettings persistence + settings UI controls

Plus Unity registry packages: com.unity.nuget.newtonsoft-json, com.unity.localization, com.unity.addressables, com.unity.inputsystem. These install transitively with the CupkekGames packages above (newtonsoft, addressableassets, and settings declare them), so no manual step is needed.

Scenes (canonical order)

The scene-index convention used throughout the scripts: scene 1 = main menu, scene 2 = gameplay.

OrderSceneWhat it does
100_LunaUIDemoFullInitialization.unity (sample root)Boot scene. Runs the Sequencer to register services, then loads the main menu (start scene index 1). Sorts first in the Hierarchy so build settings pick it up.
2Scenes/01_LunaUIDemoFullMainMenu.unityMain menu — Continue, New Game, Load, Credits, Settings, Quit.
3Scenes/02_LunaUIDemoFullBase.unityArea 1 — the in-game HUD scene; hosts the GameShell screen (HUD bar + a "Save Summary" card).
4Scenes/03_LunaUIDemoFullArea2.unityArea 2 — a second in-game area with a small combat encounter.

Boot and scene loads run the sequencer-driven loading screen: the startup load is deferred, then in the loaded scene's sequence Boot Nav GraphsActivate Game ObjectReveal Loading Screen boot the nav hosts and fade the loader out once they report ready (the demo uses a press-to-continue FadeWithInput transition).

GameFull's UI is organized into four navigation graphs. A NavGraphSO asset carries no channel string — it's a forest of NavNode destinations; channels are derived at runtime from node ids, and a node with NavChildMode.Switched acts as a tab container. Each graph is mounted onto a layer by a NavHost, and all mounted hosts merge into a single navigable index, so a "global" graph mounted by an always-loaded host is reachable from any scene.

GraphMounted byDestinationsScope
0_...GlobalLunaUIDemoFullDependencies.prefab (always-loaded, DontDestroyOnLoad)saveload, settings (Switched container → settings.game / .video / .audio / .controls), confirm (the shared choice popup)Global — reachable from the menu and in-game
1_...MainMenuthe main-menu scenemainmenu (boot-visible), mainmenu.credits, mainmenu.quitMenu-only
2_...Global_InGameGameScope.prefab (in-game scope host)pause (Switched container) + inventory — both Dim-backdrop overlays, hidden until pushedIn-game-only overlays
3_...GameScenethe game scenegamescene (boot-visible GameShell)In-game scene content

Graph prefabs live under Navigation/<graph>/. Because settings and saveload sit in the global graph, the pause menu can push them in-game with the same destination keys the main menu uses.

The in-game HUD

The Area-1 screen is a single GameShell.prefab (Navigation/3_...GameScene/) — one PanelRenderer hosting UXML/Screens/GameHud.uxml, with four cooperating MonoBehaviours that resolve elements by name against the same rendered tree:

  • GameHudView (Scripts/UI/GameHudView.cs, a UIViewComponent) — the structural/navigation controller. It sets the AreaName label, wires the PauseButton to LunaNavigation.Push(_pauseDest) (destination pause), the InventoryButton to LunaNavigation.Push(_inventoryDest) (destination inventory), and the NextAreaButton to SceneLoader.LoadScene(_nextSceneName, …). The Next-Area button hides itself when _nextSceneName is empty.
  • ResourceChipBinder (Scripts/UI/ResourceChipBinder.cs) — the reactive top-bar binding. It reads the active GameFullSaveData and subscribes to Wallet.OnChanged (Gold/Gem chips roll to the new value via Label.PlayCountTo()) and ExperienceTracker.OnExperienceChanged / OnLevelUp (the XP luna:ProgressBar self-animates via PlayTo(); a level-up plays a scale-punch + shine burst on the level chip). Like the other HUD binders here (SaveSummaryBinder, LootCardController), it extends Luna's PanelRendererBinder, which owns the async panel-delivery lifecycle.
  • SaveSummaryBinder (Scripts/UI/SaveSummaryBinder.cs) — a one-shot binder for the Area-1 center card, showing item count (Inventory.Items.Count), equipped count (EquippedItems.Count), and the save date/version from Metadata.
  • LootCardController (Scripts/UI/Loot/LootCardController.cs) — the loot pipeline. Its optional LootCard (Find Loot) button + LastDropLabel live on Area 1's Loot content card, not the top bar (reward particles fly content → header, never header → header); Area 2 triggers the same pipeline from enemy kills via RollAndGrant. Detailed under Inventory, equipment & loot below.

The shared top bar itself is UXML/Shared/HudBar.uxml, instanced into both GameHud.uxml (Area 1) and Area2.uxml (Area 2). It exposes the element-name contract the binders query: GoldAmount, GemAmount, HeroLevel, HeroLevelChip, HeroXpBar (luna:ProgressBar), PlayerName, AreaName, PauseButton, NextAreaButton, InventoryButton. The GoldChip / GemChip carry UIAttractorTargets so loot currency can fly into them, and InventoryButton carries the Items target for item drops. (The loot UI itself — LootCard + LastDropLabel — lives in GameHud.uxml's content card, not the bar.) Styling for the bar, chips, the emerald XP bar and red HP bar, the clay panels, and responsive breakpoints all live in UXML/Screens/GameHud.uss.

Game scope & the pause lifecycle

The in-game pause menu is owned by a "game scope" whose lifetime is tied to the save session, not the scene — so it survives an Area 1 ↔ Area 2 swap but is torn down and rebuilt when you load a different save (which prevents a stale pause menu from surviving a load).

  • GameScopeNodeSO (Scripts/UI/GameScopeNodeSO.cs) — a SequencerNodeSO with a Mode { Ensure, Dispose }. It tracks the live scope in statics (s_live = the GameObject, s_liveSession = the GameFullSaveManager.CurrentSave.Data reference it was spawned for), reset at SubsystemRegistration so nothing leaks across play sessions when domain reload is disabled.
    • Ensure (in every game-scene runner): if the save-session reference changed since the scope was spawned, it destroys the old scope, yields one frame (so the old NavHost fully unregisters the pause graph before the new one mounts — otherwise you get a duplicate pause destination), then respawns. If no scope is alive, it spawns one and DontDestroyOnLoads it. A same-session scene swap (Next Area) leaves it untouched.
    • Dispose (first in the menu / init runners): destroys the live scope, so the pause host is absent in the menu.
  • GameScope.prefab (Navigation/2_...Global_InGame/) is the scope host: a PauseEscapeTrigger (Scripts/UI.Generic/Pause/PauseEscapeTrigger.cs) that re-arms its EscapeAction and then pushes the pause destination on Esc, plus a NavHost mounting graph 2 with _persistAcrossScenes = true.

The pause node points at PauseMenu.prefab (PauseMenuViewExample), a Dim-backdrop overlay whose Continue/Load/Settings/Main Menu/Quit buttons push into the global graph (Load → saveload, Settings → settings); Main Menu confirms through the global confirm destination (PushAsync<int> + ChoicePopupArgs) before leaving the session.

Area 1 ↔ Area 2 and the encounter demo

Scenes 02 and 03 use the identical 6-node runner; the only difference is which screen prefab is instanced under the (initially inactive) SceneParent:

  • Area 1 (02) instances GameShell.prefabGameHud.uxml + the SaveSummaryBinder card, _areaName = "Area 1", _nextSceneName = 03_LunaUIDemoFullArea2.
  • Area 2 (03) instances Area2.prefabArea2.uxml + an EncounterController, _areaName = "Area 2", _nextSceneName = 02_LunaUIDemoFullBase.

The Next Area button on either HUD calls SceneLoader.LoadScene (by scene name) with the Fade transition, forming the loop.

EncounterController (Scripts/UI/EncounterController.cs) is a deliberately tiny combat demo whose only job is to make save persistence observable. It queries #EnemyName, #EnemyHpBar (a red luna:ProgressBar), #AttackButton, and #RewardLabel. Each Attack drains the enemy's HP (max 30, 10 per hit); on defeat it awards Wallet.Add("Gold", 25) and Experience.AddExp("Hero", 40), shows +25 Gold +40 XP, and spawns the next enemy from { Slime, Bat, Goblin, Wolf }. Those Wallet / Experience mutations fire the same events the HUD's ResourceChipBinder listens to, so the top bar's Gold / XP / Level update live — no polling.

Inventory, equipment & loot

The inventory destination (graph 2, Dim overlay, reachable via the HUD Inventory button or the Pause menu) opens InventoryScreen.prefab (Navigation/2_...Global_InGame/) — one PanelRenderer hosting UXML/Screens/InventoryGameFull.uxml, driven by EquipmentViewPagination (Scripts/UI/Inventory/, a UIViewComponent). It wires the Inventory package UI against the live save:

  • Paginated item grid — an InventoryViewPagination bound to CurrentSave.Data.Inventory, using the InventoryItemSlot.uxml slot template, a page-button strip, and explicit filter buttons (All / Weapon / Shield / Armor / Potion, all named FilterItemType). The filters are plain functions in EquipmentViewPagination.FilterItems — deliberately not descriptor indices, so button labels can't drift from catalog key order.
  • Equipment rack — an EquipmentRackController over seven equipment slots (SlotHand / SlotShield / SlotOffhand / SlotHelmet / SlotChest / SlotLeggings / SlotBoots) plus a consumable slot (SlotPotion), bound to CurrentSave.Data.EquippedItems so equipping persists. Each equipment type maps to its UXML slot by name via GameFullEquipmentSlotMap (never by catalog order); slot targeting + accept rules come from the RPGStats bridge (RpgEquipmentSlotTargeting, RpgEquipmentSlotAcceptPolicies).
  • Drag-and-drop + click — drag an item onto a slot (or click it) to equip; click an equipped item to unequip. Drop targets highlight via LunaInventoryDragDefaults.
  • Live stat comparisonRpgStatComparisonProvider + ItemStatDataController render the Attack / Health / Defense delta a candidate item would apply into StatsContainer, aggregated by IEquipableFeatureRpgModule.Aggregation.
  • Feature tooltips — each item's IItemFeature.BuildTooltipContent composes its tooltip; equipped items gain an (Equipped) footer via LunaInventoryTooltipHelpers.

Item data lives in ScriptableObjects/Items/: seven InventoryItemDefinitionSOs (Armor, Axe, Shield, Sword, WoodenSword, PotionHealth, PotionMana), each composed from an EquipableFeature (equipment type + AttributeEffect) or a ConsumableFeature (cooldown), plus an ItemTierFeature (rarity). Icons resolve through ItemSpriteDatabase (a SpriteCatalog) and attributes through the RPGStats/ attribute definitions — all registered at boot via ServiceRegistrySOs.

The loot loop

The Find Loot button on Area 1's Loot content card drives a reward loop that makes the economy observable — and in Area 2, defeating an enemy triggers the exact same pipeline (EncounterControllerLootCardController.RollAndGrant, bursting from the Attack button):

  • LootCardController (Scripts/UI/Loot/LootCardController.cs, on the HUD prefab) rolls DropTable.asset (ScriptableObjects/Items/Droptable/ — a 10-entry table of Gold/Gem currency, Hero XP, and item drops) on each roll, guaranteeing at least one drop.
  • DropResultRouter (Scripts/UI/Loot/) splits results by catalog id — CurrenciesWallet, ExperiencesExperienceTracker, everything else → Inventory.
  • Data first, animation second: every reward is applied and autosaved before any animation plays, so nothing is lost if the player changes scene (or quits) while particles are in flight. Then each Gold/Gem burst (UXML/Components/Atoms/UIAttractorParticleGold/Gem.uxml particles + the LootRewardMotion preset) flies decoratively from the loot card to the chip's UIAttractorTarget — the commit point is the data write, never the animation.
  • Every reward pushes a NotificationHistory toast and LastDropLabel summarizes the roll.

Boot & sequencer flow

Every scene has a SequenceRunner (_runOnAwake). The node assets live in ScriptableObjects/SequenceRunner/.

  • Init / boot (00): Game Scope DisposeInit group (Register Services → Instantiate Dependencies [LunaUIDemoFullDependencies.prefab, DontDestroyOnLoad] → Game Services [registers IInventoryItemDatabase + IEquipableFeatureRpgModule]) → Scene Loader Startup (loads scene index 1 with a deferred FadeWithInput transition).
  • Game scene (02, 03): Init group → Ensure Save LoadedGame Scope EnsureBoot Nav GraphsActivate Game Object (SceneParent) → Reveal Loading Screen.
  • Main menu (01): Game Scope Dispose → Init group → Activate Game ObjectBoot Nav GraphsReveal Loading Screen.

Node roles: Ensure Save Loaded guards that a save session is loaded before the game scene reads it (see below); Game Scope Ensure / Dispose manage the pause scope; Boot Nav Graphs mounts the scene's NavHosts; Activate Game Object reveals the scene content held inactive during boot; Reveal Loading Screen waits for nav-ready then completes the deferred loading transition.

Save & serialization (end-to-end)

GameFull is the place to see the full save loop driven by Newtonsoft JSON.

  • GameFullSaveData (Scripts/SaveSystem/GameFullSaveData.cs) implements IGameSaveData, IData. Fields: Metadata ([JsonProperty(Order = -100)] so it serializes first for a fast metadata read), PlayerName, Wallet, Experience (ExperienceTracker), Inventory, NotificationHistory, and EquippedItems ([JsonProperty(NullValueHandling = NullValueHandling.Ignore)]). The default constructor seeds nothing — it also runs during deserialization, and pre-seeding the read-only Wallet/Experience collections would collide with the values the loader adds on top. Seeding lives in OnNewSaveCreated(): Wallet.Add("Gold", 500), Wallet.Add("Gem", 100), Experience.AddExp("Hero", 865), and 50 random items from IInventoryItemDatabase.
  • GameFullSaveManager (GameSaveManager<GameFullSaveData, GameFullSaveMetadata>) writes one JSON file per slot under Application.persistentDataPath/saves_gamefull/, serializing via ServiceLocator.Get<SerializationManager>(). Autosaves raise GameSaveEvents.AutosaveStart / AutosaveComplete. GameFullSaveMetadata carries a Gold snapshot plus the inherited save date / version / autosave flag.
  • EnsureSaveLoadedNodeSO (Scripts/SaveSystem/EnsureSaveLoadedNodeSO.cs) is the cold-start guard in the game-scene runner, built on the manager's session-save API: if a save was already chosen this play session (HasSessionSave — set by the menu's New Game / Continue / Load through SetSessionSave) it no-ops; otherwise it loads the newest save from disk (TryLoadNewestIntoSession), or seeds a fresh one (StartNewSession) — so you can press Play directly in a game scene without going through the menu. Note it deliberately does not test CurrentSave.Data != null: the save DataSO clones its default template every play session, so data presence can't distinguish "player picked a save" from "seeded template".
  • Serialization wiring (ScriptableObjects/Serialization/): GameFull Service Registry Newtonsoft.asset registers the Newtonsoft IDataSerializer adapter and the SerializationManagerRegistrar, which stands up the SerializationManager and merges known types from the Luna default provider + GameFull Serialization Types SO.asset (which registers GameSaveMetadata, GameFullSaveMetadata, and GameFullSaveData for polymorphic deserialization).

Scene transitions & loading

  • SceneLoadTransitionFadeWithInput / SceneLoadTransitionCircleWithInput (Scripts/UI/SceneTransition/) extend Luna's plain fade/circle transitions and override FadeOut() to raise SceneTransition.LoadingScreenContinueRequested instead of exiting immediately — a press-to-continue gate. This is a policy/mechanism split: the transition decides when to exit; the LoadingScreen component owns the prompt UI and the input wait, communicating only through static Actions.
  • SceneLoadProgressBinder drives the loader's determinate RadialProgressBar from SceneLoader.OnLoadProgress (which self-animates via its TargetValue setter) and restores the indeterminate RadialLoading spinner between loads.
  • LoadingGameFull.uxml provides the spinner, the #LoadingProgress bar, and the InputPromptContinue prompt that the press-to-continue path binds. See the loading screen page for the full sequencer-driven reveal flow.

Screens

ScreenScriptNotes
Main menuMainMenuViewExample : MainMenuView<…>Continue / New Game / Load / Credits / Settings / Quit; staggered entry animations; Discord + Wishlist buttons; Quit uses the awaitable PushAsync<int> choice popup.
Pause menuPauseMenuViewExample : PauseMenuViewContinue / Inventory / Load / Settings / Main Menu / Quit; Return-to-menu confirms via the global confirm destination (PushAsync<int> + ChoicePopupArgs).
Inventory / equipmentEquipmentViewPagination : UIViewComponentPaginated item grid + 6-slot equipment rack + consumable slot; drag-drop equip, live Attack/Health/Defense comparison, feature tooltips. Opened from the HUD or Pause menu.
Save / LoadGameSaveViewListExample : GameSaveViewList<…>Custom two-part slot layout; save is disabled in the main menu (IsInGame() = not on scene 1); overwrite/delete confirm through the global confirm destination; Load sets the session save and transitions to the game scene.
Confirm / ChoiceConfirmPopupGameFull.prefab (ChoicePopupController)One global confirm destination for the whole game — pushed with per-call ChoicePopupArgs via PushAsync<int>, index 0 = affirmative, resolved through LunaNavigation.Pop(int). See Confirmation Popup.
NotificationsNotificationViewToasts from NotificationHistory (max 5), with a link to the full history modal.
SettingsSettingsGameFull.uxml (luna:TabView)Four tabs (Game / Video / Audio / Controls) as separate prefabs in the global graph; input rebinding on Controls; a language dropdown on Game.

Folder layout

GameFull/ ├── README.md ├── CupkekGames.Luna.Demo.Game.Full.asmdef ├── 00_LunaUIDemoFullInitialization.unity ← boot scene (sample root, sorts first) ├── Scenes/ │ ├── 01_LunaUIDemoFullMainMenu.unity │ ├── 02_LunaUIDemoFullBase.unity ← Area 1 (HUD + Save Summary) │ └── 03_LunaUIDemoFullArea2.unity ← Area 2 (encounter demo) ├── Navigation/ ← the 4 nav graphs + their screen prefabs │ ├── 0_GameFullNavGraphSO_Global/ ← SaveLoadGameFull, SettingsGameFull, ConfirmPopupGameFull, Tabs/ │ ├── 1_GameFullNavGraphSO_MainMenu/ ← MainMenu, Credits, MainMenuQuit │ ├── 2_GameFullNavGraphSO_Global_InGame/ ← GameScope, PauseMenu, InventoryScreen │ └── 3_GameFullNavGraphSO_GameScene/ ← GameShell (Area 1), Area2 ├── Scripts/ │ ├── GamePrefabs.cs ← scene-lifecycle prefab spawner │ ├── SaveSystem/ ← GameFullSaveData (+ SO + Metadata + Manager │ │ + SerializationTypesSO) + EnsureSaveLoadedNodeSO │ ├── UI/ ← GameHudView, ResourceChipBinder, SaveSummaryBinder, │ │ │ GameScopeNodeSO, EncounterController, │ │ │ MainMenuViewExample, PauseMenuViewExample, GameSaveViewListExample │ │ ├── Inventory/ ← EquipmentViewPagination + LunaInventoryDragDefaults / TooltipHelpers │ │ ├── Loot/ ← LootCardController + DropResultRouter │ │ └── SceneTransition/ ← SceneLoadProgressBinder + fade/circle-with-input presets │ └── UI.Generic/ ← nested asmdef; NotificationView + Pause/PauseEscapeTrigger ├── ScriptableObjects/ │ ├── Items/ ← item defs + database + providers + Droptable (loot), registered at boot │ ├── UIAttractor/ ← LootRewardMotion (loot-burst motion preset) │ ├── Resources/ ← Currencies (Gold, Gem) + Experiences (Hero curve) │ ├── RPGStats/ ← equipment attribute data + provider (registered at boot) │ ├── SequenceRunner/ ← boot chain + game-scene nodes (Ensure Save Loaded, Game Scope, Boot Nav Graphs, …) │ ├── Serialization/ ← Newtonsoft service registry + registrar + types SO │ └── Settings/ ← SettingsCurrent + SettingsDefault ├── Sprites/ ← Items/ + UI/ — sample-owned item/slot/chip icons (no cross-sample refs) ├── UXML/ │ ├── Screens/ ← MainGameFull, GameHud (+ .uss), PauseMenu, SettingsGameFull, Area2, LoadingGameFull, │ │ InventoryGameFull (+ .uss), Credits, AutoSave, LoadingTransitionCircleHole │ ├── Shared/ ← HudBar.uxml (the shared top bar) │ └── Components/ ← ChoicePopup, InventoryItemSlot, Atoms/ (UIAttractor particles) ├── Audio/ ← demo audio └── URP/ ← render-pipeline configs

Known caveats

  • Localization is feature-only. The Settings panel has a language dropdown and Luna's runtime locale-class switcher is wired, but the UXMLs ship plain English — authoring the Unity Localization data (Locales, String Tables, LocalizedString bindings) is left to you. See the UI Toolkit Localization guide. The JP SDF font and the .locale-ja styling hook already ship in the Essentials theme.
  • Main Menu + Settings are functional but unpolished — the planned UI Effects passes (per-button stagger, CTA shine, tab transitions, etc.) haven't been applied yet. Purely cosmetic.

See also

Settings

Theme

Light

Contrast

Material

Dark

Dim

Material Dark

System

Sidebar(Light & Contrast only)

Light
Dark

Font Family

DM Sans

Wix

Inclusive Sans

AR One Sans

Direction

LTR
RTL