DRIFTLANDS co-op survival on drifting tides — studio progress

HUD Design: Driftlands

Status: Reviewed — APPROVED (/ux-review final pass 2026-08-31: 0 blocking, 1 cosmetic advisory — applied) · v0.4
Author: Jeroen + ux-designer
Last Updated: 2026-08-31
Template: HUD Design (project template .claude/docs/templates/hud-design.md)
Platform Target: PC 16:9 baseline (1080p / 1440p); KB/M primary, gamepad secondary; no touch
Requirements input: art bible §7.1 closed screen-space list (verbatim in ui-hud quick-spec Rule 1); combat, harvesting, crafting, base-building, tide UI Requirements; ui-hud quick-spec Rules 2–7; camera quick-spec forward ref (ultrawide/letterbox policy)
Patterns used: #7 Honest No-Op Cue · #14 Edge Indicator · #15 World Ping · #16 Compass Tide-Glint · #17 Carry Meter · #18 Confirmed Number Flyout · #19 Feedback Split — plus the HUD-owned gaps this spec closes: hotbar / equipped-tool row, dash-cooldown glyph, party HP row, equipped-gear wear indicator
Related specs: design/ux/inventory.md (APPROVED), design/ux/interaction-patterns.md, design/accessibility-requirements.md


HUD Philosophy

The world says it; the HUD says only what the world can't. Tide state is the palette, danger is a telegraph, base status is the base, richness is prop density (art bible §7.1). Screen space earns an element only by failing the two-part test — not visible from where the player stands, or needs precision the silhouette can't carry — and the resulting list is closed: own health, dash cooldown, equipped-tool/hotbar, party health, off-screen party status, carry capacity, compass tide-glint. Adding to it is an art-bible amendment, not a UI ticket.

"Minimal HUD" is never read literally in combat: the seven items are the combat floor, not a maximum to whittle down. Everything else (flyouts, the bag pulse, the Downed banner, a ping, the interact prompt, the revive ring) is a cue, not an element. The test is anchored to a world cause, not short-lived: a cue lives at the interactable, the hit point, or the screen edge nearest its cause — never at a screen anchor — so an interact prompt that persists while you stand at a chest is still outside the screen-space closed list. It leaves without a trace when its cause does. No element ever fades in or out with game state (§7.5: nothing animates that gates an input; nothing the player might need is hidden by a density rule). The HUD carries no numbers the GDDs keep hidden and no timers the tide forbids.


Information Architecture

Full Information Inventory

Every item the GDDs say must reach the player on screen, with its source:

# Information Source
1Own HPcombat UI Requirements
2Dash cooldown — glanceable, never a numbercombat UI Requirements
3Equipped weapon / armor, incl. wear statecrafting UI Requirements; closed list "equipped-tool/hotbar"
4Party HP (2–5 players)combat UI Requirements
5Off-screen ally direction + identityart bible §7.2
6Carry capacityharvesting UI Requirements; art bible §7.1
7Tide direction + temperature when the shore is off-screentide UI Requirements; §7.1
8Downed ally — where and whocombat UI Requirements
9Damage dealt / taken; harvest yieldcombat + harvesting UI Requirements
10Bag-full no-opharvesting OQ6
11Ping markerart bible §7.2
12Enemy telegraph / threatcombat
13Enemy HP / staggercombat
14Node richness / depletion / locationharvesting
15Tide timer / countdown / progresstide AC-27
16Base status / structure statebase building
17Build-mode ghost, grid, reason strings, pickerbase building
18Recipe reasons, craft progress, maker's markcrafting
19Interact prompt ("E: open")inventory / crafting / BB interactables
20Input-scheme glyphsADR-0007 (InputFrame.Scheme)

Categorization

Category Items Rationale
Must Show (7 — exactly the closed list)1 own HP · 2 dash cooldown · 3 hotbar (weapon/armor + wear) · 4 party HP · 5 off-screen allies (#14, when off-screen) · 6 carry capacity (#17) · 7 tide-glint (#16, when the shore is off-screen)art bible §7.1 inclusion list; no conflict with the philosophy
Contextual8 Downed ally (#14 variant + 3 s banner) · 9 flyouts (#18, world-space) · 10 bag-full pulse (#7 family a, on #17) · 11 ping (#15 world-space + edge glyph) · 17 build-mode overlay (owned by the build-mode spec, queue ③ — not this document) · 19 interact prompt (defined in this spec, pattern gap #24) · 20 scheme glyphs (inside prompts only)event-driven cues; appear at their cause
On Demand18 recipe / craft / maker's-mark detailpanels (inventory.md, crafting spec) — never HUD
Hidden (diegetic or banned)12 telegraphs (pose + crimson) · 13 enemy HP (banned at MVP) · 14 node values / minimap (banned) · 15 tide timer (impossible by API) · 16 base status (the base itself)art bible §7.1; GDD bans

Conflict check: Must Show count = 7 = the closed list. Nothing on the HUD is uncategorised.


Layout Zones

Arrangement: corner clusters, centre clear (ruled 2026-08-31).

┌──────────────────────────────────────────────────────────────┐ safe margin 32 px @1080p
│ Z3 PARTY column           Z7 BANNER (transient, top-centre)   │
│ ◉ Jo   ████░                                        Z5 ▲ ally │
│ ◉ Alex ██░░░                                         edge band │
│ ◉ Mara █████                                  (24–56 px band) │
│▓ Z6 TIDE GLINT band (edge glow, 0–24 px, outside Z5's band)   │
│▓                                                              │
│▓            CENTRE 60 % × 60 % — never occupied               │
│                                                               │
│                                                               │
│ Z1 VITALS + Z2 HOTBAR                          Z4 CARRY       │
│ ♥♥♥♥♡  ◔   [⚔ axe][🛡 cloth]                    🎒 7/10       │
└──────────────────────────────────────────────────────────────┘
Zone Position (anchor) Contents Priority
Z1 Vitalsbottom-left, anchored to the safe marginown HP (E1), dash glyph (E2)1
Z2 Hotbarright of Z1, same baselineweapon slot, armor slot + wear accent (E3)2
Z3 Partytop-left columnone row per other player: hat glyph + HP (E4)3
Z4 Carrybottom-rightcarry meter (E6, #17)2
Z5 Ally edge bandall four edges, 24–56 px from the 16:9 frame edge (glyphs centred at 40 px)#14 ally / Downed glyphs (E5), #15 off-screen ping glyph3
Z6 Tide bandall four edges, 0–24 px from the frame edge — strictly outside Z5, incl. at corners (a glint is an edge glow, a glyph is inset; they never share a pixel)#16 glint (E7)4
Z7 Bannertop-centre"[Name] is down" (E8, 3 s)transient
Worldat the cause's positionflyouts (E9), ping marker (E10), interact prompt (E11), revive ring (E12)transient

Safe zone: 32 px at 1080p (scales with UI scale). The centre 60 % × 60 % box is a hard exclusion for Z1–Z7 at every UI scale and aspect — measured as box intersection, not x-extent: Z1 + Z2 sit in the bottom 20 % band and clear the box vertically, so their horizontal reach (≈ 420 px at 150 %, past the box's 384 px left edge) is expected and harmless; Z3 clears it from the top band; Z4 from the bottom-right corner. (Corrected 2026-08-31 — the earlier "fits left of the exclusion" sentence was wrong.)

Aspect / ultrawide policy (camera quick-spec forward-ref, ruled here): 21:9 and wider render the world at full width — no pillarboxing; more world is harmless for a top-down camera at integer zoom — but all HUD anchors (Z1–Z7) stay on a 16:9-equivalent frame centred on screen, so corners never drift into far periphery. 4:3 / 16:10 letterbox to 16:9 at the nearest integer zoom (camera Rule 1). Edge bands (Z5/Z6) clamp to the 16:9 frame, not the physical edge. More visible world on ultrawide is not a fairness concern: the game is co-op with no PvP and no per-player comparison (ui-hud Rule 5); the alternatives (pillarboxing or non-integer zoom) would break camera Rule 1's silhouette calibration — a readability regression for everyone.


HUD Elements

# Element Category Zone Form Update Pattern
E1Own HPMust ShowZ1segmented pipshost-confirmed Hp—
E2Dash cooldown / bleed-out arcMust ShowZ1sweep ringlocal dash state / replicated BleedOutRemaining—
E3Hotbar (weapon, armor + wear)Must ShowZ2two 48 px slotsequip / wear-flip eventscloses gap "wear indicator"
E4Party HPMust ShowZ3hat glyph + pipsreplicated Hp per player—
E5Ally / Downed edge indicatorMust Show (off-screen)Z5hat / prone glyphper frame#14
E6Carry meterMust ShowZ4slate fill + n/NCARRY change#17
E7Compass tide-glintMust Show (shore off-screen)Z6edge glowper frame TintFloats#16
E8Downed bannerContextualZ7one text line, 3 sPlayerDowned—
E9FlyoutsContextualworldrising digitsSwingLanded / DamageAbsorbed / HarvestResolved#18
E10PingContextualworld + Z5diamond + hatping event#15
E11Interact promptContextualworldglyph + verb + nounnearest interactable in range#24 (new)
E12Revive prompt / ringContextualworldring fill + promptrevive channel#10

E1 Own HP — Segmented pips, one per maxHp / 20 (cloth-tier 100 HP → 5; the count follows maxHp, never a fixed number), filled slate-light, empty = outline only. Pips over a bar: they read at a glance and scale with tier HP bands without a number. Hard bound (ruled 2026-08-31): maxHp / hpPerPip ≤ 8 is a load-validation rule (ADR-0006 stage 9, reject) — the two knobs are constrained jointly, like combat's swingWindup + swingActive; a tier whose HP band would exceed 8 pips must raise hpPerPip, never grow the strip. Losing a pip = a Stagger White one-frame flash on the pip (the shared impact language) + settle; gaining (home heal / revive) = pips fill in sequence 100 ms apart. Never a number, never red. Downed: pips grey, the bleed-out arc appears on E2. Dead / respawning: Z1 hidden until spawn.

E2 Dash cooldown — A small ring (◔) sweeping empty → full over dashCooldown (0.45 s), popping to a solid ring when ready; no number, no bar (combat UI Requirements: glanceable without reading numbers). Reduced-motion: two-state (hollow = cooling, solid = ready). While Downed the same position shows the bleed-out arc draining over bleedOutTimer — one glyph, two meanings, never simultaneous (Downed cannot dash). The arc is a world timer (combat Rule 9; accessibility-requirements.md Motor → "Input timing adjustments" rules it outside the tier's timed-input clause), not a tide readout — tide AC-27's no-timer ban is tide-scoped; it is non-textual and non-actionable, so it is not an auto-dismiss inventory item.

E3 Hotbar / equipped slots — Two 48 px slots (weapon, armor) with the item's tier-shaped ink icon (art bible §7.4). Wear indicator (closes the pattern-library gap): a frayed-corner accent on the slot outline while the item is worn — shape, never hue. Empty slot = dashed outline (unarmed 14 / no armor). Updates on equip / unequip and on the host-confirmed wear flip. Not interactive from the HUD (equip happens in the bag, inventory.md).

E4 Party HP — One row per other connected player (0–4): the player's hat silhouette glyph (§5.1) + E1's pip strip at 75 % scale. Downed = pips grey + prone glyph; Dead / at home = row stays, pips refill on respawn; disconnected = row removed. Order = join order, stable for the session. No names on persistent rows at MVP (the hat is the name for a friend group); names appear only in event copy — the Downed banner (combat UI Requirements, binding), storage tags (#13), maker's marks (#12).

E5 Ally / Downed edge indicator — pattern #14 exactly. E6 Carry meter — pattern #17 exactly. E7 Compass tide-glint — pattern #16 exactly (Z6 sits outside Z5 so glints and glyphs never overlap).

E8 Downed banner — "[Name] is down", Medium size, 3 s, world-fact tone; if two players go down within 3 s the lines stack (max 2, oldest on top). Reduced-motion: no fade.

E9 Flyouts — pattern #18; cull rule: when more than flyoutCap are live, cull the oldest globally, but never one anchored to the local player's own sprite (own damage-taken is decision-relevant; ally damage-dealt is not); #18's 100 ms offset-stacking applies before culling. E10 Ping — pattern #15 — BLOCKED on the ADR-0007 Ping amendment; if it does not land for MVP the element simply does not render (no layout or budget change — Z5 scales with occupancy). E12 Revive — pattern #10.

E11 Interact prompt (new pattern #24) — World-space, anchored 24 px above the nearest interactable while within interaction range and not in build mode: "E open chest" / "West-button glyph use workbench" — the glyph is resolved from the live binding of Interact in InputFrame.Scheme (ADR-0007: E / West by default; rebinding changes it — never an authored character), verb + noun in world-fact tone, Small size with the ink outline; exactly one prompt at a time (nearest candidate; ties → lowest instanceId); gone the frame the target leaves range or a panel opens. Never for enemies or nodes (strike is aim-driven; a prompt would imply a separate interact verb). Reduced-motion: no fade.


HUD States by Gameplay Context

Context Z1 Vitals Z2 Hotbar Z3 Party Z4 Carry Z5 Edge Z6 Glint Z7 / cues
Home, calm✓✓✓✓✓ if any ally off-screen✓ if shore off-screeninteract prompts near chests / stations
Docked land, exploring✓✓✓✓✓✓yield flyouts; bag pulse
Docked land, combat✓✓✓✓✓✓damage flyouts; nothing added, nothing removed — the closed list is the combat HUD
Downed (self)pips grey; E2 = bleed-out arc✓ (greyed)✓✓✓✓own banner suppressed (you know); revive ring appears when an ally channels
Dead / respawningZ1 hidden until spawnhidden✓✓✓✓—
Build mode✓✓✓✓✓✓interact prompt suppressed; ghost / grid / picker are the build-mode spec's overlay
Panel open (bag / storage / pause)✓ never dimmed (ruled 2026-08-31; pattern #3 layering)✓✓✓✓✓flyouts continue (the world is live); interact prompt hidden
Tide soft-close depositunchangedviolet heldno cue beyond the world (tone rule); the deposit is a hard camera cut
Late-join / spawning inZ1–Z4 appear with the spawn; Z3 populates from the snapshotno loading spinner — the HUD is absent until the player exists

No context hides a Must Show element except death (no body → no vitals). Nothing fades with combat state.


Dynamic Behaviors


Information Hierarchy

Priority tiers for the persistent HUD — what must survive every setting, context and conflict, and what replaces an element if it is ever suppressed.

Tier Elements May be suppressed by If suppressed, what carries the information
MUST KEEP — never suppressibleE5 Downed / ally edge glyphs (Z5), E8 Downed banner (Z7), E7 tide glint (Z6), E1 own HP, E2 while it shows the bleed-out arcnothing — not opacity, not build mode, not panels, not any future density rule— (a downed friend, your own HP and your own bleed-out are the Fellowship and survival floors; the glint is the only off-screen tide read)
SHOULD KEEP — player-adjustable onlyE2 dash ring (when not Downed), E3 hotbar, E4 party HP, E6 carry meterthe HUD-opacity slider (50 % floor, never 0 %) — element-scoped, not zone-scoped: within Z1, E1 is exempt (ruled 2026-08-31)still visible at 50 %; the world carries nothing equivalent, so they never fully hide
CUES — cause-boundE9 flyouts, E10 ping, E11 interact prompt, E12 revive ring, bag pulsetheir own lifetime / cause; the flyout cap; E11 also by build mode and any open panel (States table)the world event itself (impact flash, the chest, the downed ally)
HIDDEN — never on screentelegraphs, enemy HP, node values, tide timer, base status—the world (pose, silhouette, palette, structures)

Cue collision order: Downed banner > interact prompt > flyouts; Z5 same-point order: Downed ally > ping > ally. The HUD-opacity slider is scoped to the SHOULD-KEEP tier by construction — i.e. E2 (not Downed), E3, E4, E6; never E1, never the bleed-out arc, never Z5 / Z6 / Z7.


Visual Budget


Feedback & Notification Systems

There are no notifications. The HUD has exactly four feedback channels, all governed by pattern #19's authority table:

No queueing beyond the banner (max 2 lines) and the flyout cap; nothing persists past its lifetime; no log, history, or toast tray. The HUD owns zero sounds — every HUD change is the visual half of a world event that already carries its own sound (#19).


Platform & Input Variants


Accessibility

Tier: Standard (design/accessibility-requirements.md).


Tuning Knobs

Knob Default Range Player-facing? Owner
uiScale1.01.0 / 1.25 / 1.5Yes (Settings)accessibility-requirements
reducedMotionoffon / offYesaccessibility-requirements
flashReductionoffon / offYesaccessibility-requirements
hudOpacity (E2-not-Downed, E3, E4, E6 only)1.00.5–1.0Yes — ruled 2026-08-31; needs an accessibility-doc row + the Slider patternthis spec
hpPerPip2010–25Nocombat (pip count = maxHp / hpPerPip; load rule: quotient ≤ 8)
safeMarginPx3224–48Nothis spec
centreExclusionFrac0.600.5–0.7Nothis spec
flyoutCap84–12Nothis spec
bannerSecs32–5Nothis spec
glintBandPx / glyphBandPx0–24 / 24–5616–32 wide / 24–40 wideNothis spec (bands never overlap; validated: glyph band starts at glintBandPx)
partyPipScale0.750.6–1.0Nothis spec

All values live in assets/data/ui.json — a new file for ADR-0006's manifest (stage 9 rows: the ranges above as warnings). Nothing is hardcoded.


Acceptance Criteria


Open Questions