acdream/memory/project_session_2026_04_17.md
Erik ff325abd7b feat(ui): debug overlay + refined input controls
Adds the first on-screen HUD for the dev client plus today's mouse-control
refinements. Also lands yesterday's scenery-alignment changes that were
left uncommitted in the working tree.

Overlay:
- BitmapFont rasterizes a system TTF via StbTrueTypeSharp into a 512x512
  R8 atlas at startup (Consolas on Windows, DejaVu/Menlo fallbacks)
- TextRenderer batches 2D quads in screen-space with ortho projection;
  one shader + two draw calls (rect then text) for panel backgrounds
  under glyphs
- DebugOverlay composes info / stats / compass / help panels on top of
  the 3D scene; toggles via F1/F4/F5/F6; transient toasts for key events
- DebugLineRenderer and its shaders (carried over from the scenery work)
  are properly committed in this commit

Controls:
- Per-mode mouse sensitivity (Chase 0.15, Fly 1.0, Orbit 1.0); F8/F9 to
  adjust the active mode multiplicatively (x1.2)
- Hold RMB to free-orbit the chase camera around the player; release
  stays at the new angle (no snap-back)
- Mouse-wheel zooms chase distance between 2m and 40m
- Chase pitch widened to [-0.7, 1.4] so mouse-Y tilts both ways from
  the default neutral angle

Scenery alignment (carried from yesterday's session):
- ShadowObjectRegistry AllEntriesForDebug + Scale field
- SceneryGenerator uses ACViewer's OnRoad polygon test + baseLoc +
  set_heading rotation
- BSPQuery dispatchers accept localToWorld so normals/offsets transform
  correctly per part
- TransitionTypes.CylinderCollision rewritten with wall-slide + push-out
- PhysicsDataCache caches visual-mesh AABB for scenery that lacks
  physics Setup bounds
2026-04-17 18:45:38 +02:00

4.9 KiB
Raw Blame History

Session 2026-04-17 — Debug Overlay + Control Tuning

Headline result

On-screen HUD overlay and refined input controls for the dev client.

  • TTF-based font atlas rendered via stb_truetype
  • Screen-space text + rect batcher (TextRenderer)
  • Composite overlay with panels for position / heading / collision / FPS / compass / keybind help
  • Per-mode mouse sensitivity (Chase, Fly, Orbit)
  • RMB-held free-orbit around the player (no snap-back on release)
  • Mouse-wheel zoom in chase mode
  • Extended chase pitch range so mouse-Y moves both ways

Files added

  • src/AcDream.App/Rendering/BitmapFont.cs — TTF atlas (stb_truetype)
  • src/AcDream.App/Rendering/TextRenderer.cs — 2D quad batcher for text + rects
  • src/AcDream.App/Rendering/DebugOverlay.cs — composed HUD panels
  • src/AcDream.App/Rendering/Shaders/ui_text.{vert,frag} — ortho-proj text shader
  • src/AcDream.App/Rendering/Shaders/debug_line.{vert,frag} — wireframe shader (carried from yesterday's scenery-alignment session but not committed then)

Files modified

  • src/AcDream.App/AcDream.App.csproj — added StbTrueTypeSharp 1.26.12
  • src/AcDream.App/Rendering/Shader.cs — added SetVec2 / SetVec4
  • src/AcDream.App/Rendering/ChaseCamera.cs
    • Added YawOffset for RMB free-orbit
    • Added AdjustDistance for mouse-wheel zoom
    • Widened pitch clamp from [0.05, 1.4] to [-0.7, 1.4] (mouse-Y now moves camera in both directions from neutral)
    • DistanceMin=2f, DistanceMax=40f zoom envelope
  • src/AcDream.App/Rendering/GameWindow.cs
    • Field block: _textRenderer, _debugFont, _debugOverlay, _sensChase/_sensFly/_sensOrbit, _rmbHeld, _lastFps, _lastFrameMs
    • OnLoad: load Consolas → BitmapFont → TextRenderer → DebugOverlay (silently skips if no system font)
    • Keyboard: F1/F2/F4/F5/F6 panel toggles; F8/F9 sensitivity (multiplicative ×1.2 steps, per-mode)
    • Mouse: MouseDown / MouseUp track RMB; MouseMove routes to the active mode's sensitivity; RMB release does NOT snap YawOffset
    • OnRender: snapshot builder (player pos, heading, nearest-obj dist, colliding flag) passed to DebugOverlay.Draw

Yesterday's scenery work (finally committed in this session's commit)

The untracked files show that yesterday's scenery-alignment fixes lived on disk but hadn't been committed. This session's commit includes:

  • src/AcDream.Core/Physics/BSPQuery.cslocalToWorld rotation params
  • src/AcDream.Core/Physics/PhysicsDataCache.csGfxObjVisualBounds
  • src/AcDream.Core/Physics/ShadowObjectRegistry.csScale + debug iter
  • src/AcDream.Core/Physics/TransitionTypes.cs — rewritten cylinder / BSP
  • src/AcDream.Core/World/SceneryGenerator.cs — 64-cell, ACViewer OnRoad, baseLoc + set_heading rotation
  • src/AcDream.Core/World/WorldEntity.csScale field

Sensitivity defaults (current)

Mode Default F8 step F9 step
Chase 0.15x ÷ 1.2 × 1.2
Fly 1.0x ÷ 1.2 × 1.2
Orbit 1.0x ÷ 1.2 × 1.2

Effective rate at chase 0.15x: 0.15 × 0.003 rad/px = 0.00045 rad/px ≈ 0.026°/pixel. 1000 pixels → 26° rotation.

Fly at 1.0x is 0.003 rad/px ≈ 0.172°/px.

Keybinds (full, current)

Key Action
F1 Toggle keybind help panel
F2 Toggle collision wireframes
F3 Console dump (pos + nearby objects)
F4 Toggle HUD info panel
F5 Toggle HUD stats panel
F6 Toggle compass
F8 / F9 Active-mode mouse sensitivity slower / faster
F Toggle fly camera
Tab Toggle player mode (live session only)
WASD Move (player mode) / fly
Space Jump (hold to charge, release to fire)
Shift Run
Mouse Turn character / look
Hold RMB Free-orbit camera around player (stays on release)
Wheel Zoom chase distance
Escape Exit fly / player / close window

Open issue (parked for follow-up)

User reports mouse "feels like you can only move one way" at low sensitivity. Diagnosed + fixed: chase PitchMin was clamping at 0.05f, preventing any upward tilt. Widened to -0.7f. Needs visual verification next session.

Pickup for next session

MAJOR TASK PARKED HERE: user has asked for a deep investigation

  • port of the retail AC client's GUI subsystem. User explicitly directed Opus 4.7 with extra-high effort for this work. The agents are dispatched in this session and their output lives in docs/research/2026-04-17-retail-ui-*.md. See that set of files for the in-depth UI research + C# scaffold.

After the retail-UI port is in place:

  1. Hook the retail chat window to the existing WorldSession message stream
  2. Port the health/stamina/mana globes to real player stats (need CharacterCreate/InqStats wire parsing first)
  3. Port the inventory panel (needs CreateObject item parsing)