This commit is contained in:
2026-06-07 13:28:25 -07:00
parent 0df0b45163
commit 25b53cb062
25 changed files with 1573 additions and 125 deletions
@@ -48,4 +48,4 @@ Catalog of the Synty Polygon packs under `Assets/Synty/`, produced by the [[DR-0
2. **Quadruped Swarmer** — PolygonDog as a separate Rukhanka rig + dog controller (its bundled Attack/Death clips enable a real death anim).
3. **Ruined-city / off-world maps** — Kaiju destroyed-city + NatureBiomes Arid_Desert for the base + expedition regions.
4. **Combat/heal/portal VFX** — wire PolygonParticleFX into `VFXConfig`.
5. **HUD polish**bake PolygonIcons + harvest Interface* sprites/fonts into the UITK HUD ([[DR-021_HUD_UITK_BuildPalette]]).
5. **HUD polish**✅ DONE ([[DR-024_HUD_Synty_Skin_Theme]]): harvested Interface* sprites/fonts (status/map/inventory icons, HUD panels/bars/pips/gradients/glow, 640 input glyphs, Orbitron + Exo 2.0) into the UITK HUD via a build-safe `HudTheme` ScriptableObject. PolygonIcons (3D meshes) still un-baked — a future render-to-sprite option if more icon variety is wanted.
@@ -0,0 +1,45 @@
---
date: 2026-06-07
type: session
tags: [session, hud, ui-toolkit, synty, presentation, juice, build, dots]
---
# Session 2026-06-07 — Expansive HUD visual pass (Synty sci-fi-soldier kit → UITK)
## Goal
Operator (via `/dots-dev`, ultracode): *"Do a pass on the HUD using the new assets that were imported. Use everything you can and make it look good and follow good design principles (both game and visual). This should be an expansive and large pass."*
The in-game HUD (DR-021) was code-built UITK but flat-colour + system font + text-only. The newly-imported **InterfaceSciFiSoldierHUD** + **InterfaceCore** kits (status/map/inventory icons, HUD panel/bar/pip/gradient/glow sprites, 640 input glyphs, Orbitron + Exo 2.0 fonts) are a complete on-theme HUD kit — harvest them into the existing observe-only `HudSystem`.
## Process
- **Verify+design Workflow (4 parallel agents):** (1) UITK runtime API correctness — empirically confirmed on the live editor: `Background.FromSprite`, `unityBackgroundImageTintColor` MULTIPLIES, code-set `unitySlice*` works even on border-0 sprites (but OVERRIDES an authored border), `FontAsset.CreateFontAsset(Font)`+`FontDefinition.FromSDFFont` is the reliable runtime SDF path; (2) build-safety — a serialized ScriptableObject-in-Resources is the build-safe way to pull curated `Assets/Synty/...` sprites into the player build (the Synty sprites are NOT in a Resources folder, so a name-string `Resources.Load` would fail); (3) exact asset manifest (real prefixed filenames verified on disk); (4) HUD layout/design spec.
- **Plan → "go" (fonts applied to shared MenuUi too) → serial implementation** through the one focused editor.
- **Adversarial review Workflow (3 lenses)** post-build → shippable, no blockers; applied the worthwhile fixes (below).
## Done
- **`HudTheme` ScriptableObject** (`Assets/_Project/Resources/HudTheme.asset`, 31 curated Synty Sprite/Font refs) — build-safe via serialized refs, loaded null-safe via `HudTheme.Get()` (mirrors `MenuUi.LoadPanelSettings`). Fonts applied as cached SDF `FontAsset`s built once-per-font-per-session via `ApplyDisplay/ApplyBody/ApplyBodyLight`; static cache + FontAssets reset on `[RuntimeInitializeOnLoadMethod(SubsystemRegistration)]`. **Every consumer is null-safe → falls back to the flat HUD if the asset/ref is missing.**
- **`HudVisualMath`** (pure, +6 EditMode tests) — low-health vignette intensity ramp + hurt-flash decay.
- **`HudUi` expansion** — null-safe skinned factories: `Panel` (9-sliced Synty box, tinted), `Bar` (skinned track), `Icon`, `Glyph` (input prompt or text keycap), `Text`/`Display` (Exo body / Orbitron display fonts). `MenuUi` Title/Caption/Button now apply the theme fonts → **menu/pause/settings re-fonted too** (one visual language).
- **`HudSystem` reworked** — framed, iconified, theme-driven layout: bottom-left vitals (health icon + skinned bar + Orbitron number, cooldown row that dims when ready, shield chip); top-left resource strip (Aether/Ore/Bio icons + counts); top-right threat (skull + count, **hidden at zero/calm**, warms+reddens under siege); center-top mission banner (Orbitron phase + countdown + **CYCLE N**, phase-coloured underline) + location sub-line + **hex-pip goal meter** (bar fallback for Target>12); bottom-center build palette with **per-structure icons** + per-resource cost icon/affordability + selection glow; **scheme-aware build-mode control-hint bar** (KBM/gamepad glyphs) with a **live conveyor-facing arrow** gated to conveyors; full-screen **low-health vignette + hurt-flash** + re-skinned downed overlay.
- **Resolves the [[DR-021_HUD_UITK_BuildPalette]] open items**: per-buildable icons + a build-mode hint line + the conveyor-facing indicator. → [[DR-024_HUD_Synty_Skin_Theme]].
## Validation (runtime, real Server+Client)
- Compiles clean; EditMode **214/214** (incl. 6 new `HudVisualMath`). Console clean of HUD errors (only benign server-tick-batching + an unrelated FMOD audio-device note).
- **4 Play states screenshotted + verified**: base HUD, build-mode (palette icons + selection glow + hint bar), low-health (red edge vignette + depleted bar), conveyor-facing (live arrow + conveyor-gated ROTATE/FACING + CYCLE readout). Theme + all 31 refs loaded non-null; HUD tree built (8 root clusters).
- Adversarial review: client-only observe-only (no sim mutation/structural change), null-safety + picking modes correct, font cache once-per-session, hurt-flash `prevHp` resets on despawn.
## Gotchas captured (→ CLAUDE.md + [[DR-024_HUD_Synty_Skin_Theme]])
- **Synty HUD frame/bar sprites ship authored 9-slice borders** (Box_Glass=25, Bar_Angled=80/0). Code-set `unitySlice*` OVERRIDES them and logs a `"borders … overridden by style slices"` ERROR per element → for bordered skins, assign the sprite + tint and let the **art border drive slicing** (no `unitySlice*`); only set slices for border-0 sprites.
- **Some Synty sprites import as Sprite *Multiple* mode** (e.g. `Gradient_Outwards`) → `LoadAssetAtPath<Sprite>` returns null silently. Verify import mode; convert to Single when curating a single-image sprite. Always verify each theme ref non-null after authoring (a wrong/odd path is a silent null, which the null-safe fallback hides).
- **Build-safe asset harvest** = serialized refs in a ScriptableObject-in-Resources, NEVER `Resources.Load("Synty/…")` (those live outside Resources → stripped from the build).
- `execute_code` safety-checks block `AssetDatabase.DeleteAsset` (use `safety_checks=false` or skip when the asset is new).
## Next-session intent
- Eyeball the HUD at a true 1920 game-view (the narrow ~945 editor window overlaps vitals↔palette — resolution artifact, fine at target res).
- Confirm the conveyor-facing arrow's compass mapping vs the world placement ghost (a 1-line `FacingDegrees` offset if the arrow art's default vector differs); optional polish: cooldown radial, throughput visuals (needs a replicated machine field — DR-020 open).
@@ -0,0 +1,49 @@
---
id: DR-024
title: HUD reskinned with the Synty sci-fi-soldier kit via a build-safe HudTheme ScriptableObject (icons, fonts, panels, vignette, scheme-aware hints)
status: accepted
date: 2026-06-07
tags:
- decision
- hud
- ui-toolkit
- synty
- presentation
- juice
permalink: gamevault/07-sessions/decisions/dr-024-hud-synty-skin-theme
---
# DR-024 — HUD Synty skin + HudTheme (build-safe asset harvest into the code-built UITK HUD)
## Context
[[DR-021_HUD_UITK_BuildPalette]] put the HUD on UI Toolkit but flat-colour, system-font, text-only, and left open: per-buildable icons, a build-mode hint line, a conveyor-facing arrow. The imported **InterfaceSciFiSoldierHUD** + **InterfaceCore** packs ([[Synty_Asset_Inventory]]) are a complete on-theme HUD kit (status/map/inventory icons, HUD box/frame/bar/pip/gradient/glow sprites, 640 input-prompt glyphs, Orbitron + Exo 2.0 fonts). Operator: *"expansive, large pass … use everything you can, make it look good, good design principles."*
## Decision
1. **Curated, serialized `HudTheme` ScriptableObject is the build-safe asset bridge.** The Synty sprites/fonts live under `Assets/Synty/…`, NOT a `Resources/` folder, so a runtime name-string `Resources.Load("Synty/…")` would be stripped from the player build. Instead, `Assets/_Project/Resources/HudTheme.asset` holds ~31 **serialized** Sprite/Font references (the dependency walker pulls them into the build); it's loaded once, null-safe, via `HudTheme.Get()` (mirroring `MenuUi.LoadPanelSettings`). **Every consumer null-checks the theme AND each field and falls back to the flat-colour HUD** — a missing asset/ref never breaks or magenta-s the HUD, and EditMode stays green without the asset.
2. **Tint the white kit into the Aether palette; don't adopt the kit's stock colours.** `unityBackgroundImageTintColor` MULTIPLIES the (light-grey) Synty skins, so one panel sprite (`Box_Glass_01`) tinted per-cluster (panel-dark, warm-dark under siege) reads as a coherent system. Aether-cyan = friendly/charge/selection + structure icons; Blight-orange→red = threat/low-HP/siege; Ore-amber / Bio-green for resources. Orbitron-ExtraBold (SDF) for numerics + phase words; Exo 2.0 for labels/hints — applied through `MenuUi`'s shared factories so **menu/pause/settings re-font too**.
3. **Fonts = cached runtime SDF FontAssets.** `FontAsset.CreateFontAsset(Font)` + `FontDefinition.FromSDFFont` is the reliable runtime path (crisp at any scale, supports outlines). Built **once per font per session**, cached statically, and reset — together with the theme cache — on `[RuntimeInitializeOnLoadMethod(SubsystemRegistration)]` so a fast-enter-playmode session never references a destroyed atlas (matches the `VFXConfig`/`BuildPaletteState` static-reset rule). A tiny per-editor-session atlas leak is accepted.
4. **Let the art's authored 9-slice border drive slicing.** The Synty HUD frame/bar sprites ship borders (Box_Glass=25, Bar_Angled=80/0). Setting `unitySlice*` in code OVERRIDES them and logs a `"borders … overridden by style slices"` error per element. So `HudUi.Panel`/`Bar` assign the sprite + tint and set NO `unitySlice*` — the art border 9-slices correctly and the console stays clean. (Code slices are only needed for border-0 sprites — verified separately.)
5. **Layout follows HUD spatial convention; only data-backed elements are surfaced.** Persistent self-state hugs the corners (health bottom-left, resources top-left, threat top-right, build deck bottom-center); transient mission state is center-top (phase + countdown + CYCLE N + hex-pip goal). Conditional elements appear only when live (shield chip, threat panel hidden at zero/calm, control hints only in build mode) so the resting HUD is clean. No fake minimap/ammo/oxygen despite the kit shipping those sprites.
6. **Resolves the DR-021 opens.** Per-buildable icons (from `HudTheme.StructureIcon`, cost icon + affordability now keyed off `StructureCatalogEntry.CostResourceId` so it stays correct as the catalog grows); a **scheme-aware** build-mode control-hint bar (KBM vs gamepad glyphs via `AimPresentation.Scheme`, text keycaps where no glyph exists); and a **live conveyor-facing arrow** (rotated by `BuildPaletteState.Direction`) gated to conveyors. Low-health screen **vignette + hurt-flash** (`HudVisualMath`, pure + unit-tested) is the new unmissable damage signal.
## Consequences
- **No netcode / asmdef / ghost-hash change.** Pure client presentation: a new managed ScriptableObject + Resources asset + the rewritten observe-only `HudSystem` (client `PresentationSystemGroup`), `HudUi`/`MenuUi` factories, and `HudVisualMath`. `HudSystem` reads ECS read-only and mutates nothing; it adds `EntityManager.CompleteDependencyBeforeRO<T>()` for the components it reads, matching the sibling presentation systems.
- **Validated on 6.4.7** (real Server+Client): EditMode **214/214** (+6 `HudVisualMath`); 4 Play states screenshotted (base / build-mode / low-health / conveyor-facing); console clean. Screenshots: `HudSyntyPass_Base/BuildMode/LowHealth/ConveyorFacing.png`.
- New durable conventions folded into `CLAUDE.md` (build-safe HudTheme harvest; art-border-drives-slicing; verify Synty sprite import-mode).
## Open / deferred
- Conveyor-facing arrow's absolute compass mapping vs the world placement ghost (a 1-line `FacingDegrees` offset if the arrow art's default vector differs) — confirm in natural play.
- Narrow-window vitals↔palette overlap (resolution artifact; fine at 1920) — responsive layout deferred.
- Cooldown radial treatment; throughput-on-belt visuals (needs a replicated machine field — the [[DR-020_M7_Automation_Production_Chains]] open item).
- `HudTheme` icon picks are operator-tunable in the one asset (e.g. Wall uses the Armor glyph — no dedicated wall icon in the kit).
Builds on [[DR-021_HUD_UITK_BuildPalette]] (the UITK HUD + palette this skins) and [[DR-019_Frontend_Menu_Settings_Saves_Build]] (shared `MenuUi`/PanelSettings). Consumes [[Synty_Asset_Inventory]]'s "HUD polish" hook. Serves the co-op base-building + game-feel [[Pillars]].