Teaches the deep, interlocking loop — especially the inverted win condition (you win by CLEARING EXPEDITIONS, not by surviving base sieges; DR-042/DR-043). - OnboardingSystem: client-only observe-only PresentationSystemGroup overlay (own UIDocument @ sortingOrder 60), soft-gated 10-beat coach-mark sequence with a world-space ▶ pointer; never mutates sim / never destroys a ghost. - OnboardingStepMath: pure, unit-tested step machine (snapshot + IsSatisfied + scheme-aware prompts + pointer kinds + persisted-mask helpers). - HowToPlayPanel: tabbed reference card (Controls / The Loop / Build / Threats / Win-Lose), reachable from the main menu and the pause overlay. - Per-client client-local state in GameSettings (TutorialHints + OnboardingMask bitmask, additive) — a Join client keeps its own; a host save-wipe never re-teaches. Settings toggle + menu "Replay Tutorial". - Dev "Force Each Launch" toggle (GameSettings.ForceOnboardingEachLaunch): SettingsService.Boot wipes the mask + forces hints on in-memory every launch so the tutorial always replays fresh. - HudSystem suppresses its own location hint while onboarding is active (single prompt voice), via OnboardingState + [UpdateAfter(OnboardingSystem)]. Validated green: 20/20 EditMode; Play smoke confirmed overlay render, clean U+25B6 pointer glyph, no system sort-cycle, and the force-wipe end-to-end. Docs: DR-043 + session log; reusable lesson archived in the build-gotchas note. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
5.4 KiB
title, date, tags, permalink
| title | date | tags | permalink | |||||||
|---|---|---|---|---|---|---|---|---|---|---|
| First-Run Onboarding — design decision-tree + offline build (Unity GPU-crash session) | 2026-06-28 |
|
gamevault/07-sessions/2026/2026-06-28-first-run-onboarding |
First-run onboarding — session
/dots-dev session on the operator's brief: "This game needs an onboarding style type of thing, plan something that makes sense." Full decision: DR-043_First_Run_Onboarding.
How it went
- Ground — 5-agent read-only fan-out (
wf_670a0cdf-832) mapped the onboarding-relevant surfaces (HUD/UITK, controls, the macro loop, economy/build, frontend lifecycle) + an exhaustive search confirming no onboarding/tutorial/help exists anywhere. (2 of 5 mappers returned degenerate stubs; the 3 working ones triangulated the rest, so no re-run was needed.) - Forks — operator asked to drive it decision-tree style. Two rounds of
AskUserQuestion(3 + 4 forks) locked the 7 design decisions (table in DR-043). A genre-precedent research pass (wf_f41c8423-68b, NN/g + CHI-2012 + DRG/Riftbreaker/CotL/Hades/Helldivers/Remnant) backed every recommendation; the operator chose the recommended option on all 7. - Build — mid-session the editor began crashing randomly. Diagnosed from
Editor.log: empty managed stack + faultingdxgi.dll, GPU = RTX 5060 Ti, driver 32.0.16.1062 → a GPU/driver (TDR) fault, not project code (recurringUnity.exe.*.dmp). Operator chose "peek at the crash, then code." Pivoted to building the whole feature via the filesystem (decoupled from the unstable bridge), with a singlerefresh_unity forcedeferred to when the editor is back. - Static review in lieu of a compiler — 3-lens adversarial review (
wf_d804925a-f7b) verified every symbol against source: Lens 1 compile/API = clean PASS. Fixed 1 major (the v1→v2 migration dropped returning players' graphics settings) + 4 minors (Esc/pause copy + self-skip, pause-freeze for timed beats, static reset on teardown, same-frame HUD suppression ordering).
What shipped (code-complete, NOT yet validated)
Contextual coach-marks (OnboardingSystem — client-only observe-only, own UIDocument @ sortingOrder 60) running the full first lap soft-gated, a world-space ▶ pointer, a tiny welcome strip naming the inverted win goal, a tabbed How-to-Play card (menu + pause), a Settings Tutorial Hints toggle + Replay Tutorial, all per-client via a client-local GameSettings.OnboardingMask (v1→v2 additive). Pure logic in OnboardingStepMath with OnboardingStepTests. Zero netcode/replication/bake surface. Files in DR-043.
Validation — DONE (2026-06-29, editor stable)
Green. refresh_unity force → console clean → 20/20 EditMode (incl. 2 new ForceOnboardingEachLaunch cases) → Play smoke proved the new dev toggle (seeded a veteran int.MaxValue mask + force=1 → Boot wiped it → tutorial replayed from Welcome), confirmed no system sort-cycle from HudSystem's [UpdateAfter(OnboardingSystem)], and verified the ▶ pointer renders as a clean U+25B6 triangle (not tofu) + HUD hint suppression. Also shipped this session: a dev Force Each Launch onboarding toggle (GameSettings.ForceOnboardingEachLaunch + SettingsService.Boot per-launch wipe + a Settings cycle row). The deferred CLAUDE.md gotcha was parked in _Meta/CLAUDE_Build_Gotchas_Archive.md (file at cap; one-time pattern doesn't earn inline space). Full detail in DR-043_First_Run_Onboarding.
Original plan (for the record — now executed)
Not compiled/tested/Play-run yet. When the editor is stable: refresh_unity scope=all mode=force (the 5 new .cs have no .meta) → read_console clean → run_tests EditMode ProjectM.Tests.EditMode → Play smoke (welcome+step1 on a fresh client; dormant when hints off / mask full; per-client; no sort-cycle from the new [UpdateAfter]) → L3 screenshots (strip / pointer / card; confirm the ▶ glyph renders). Then add the deferred CLAUDE.md gotcha line (first-run flags → client-local GameSettings, not host SaveData) once green.
Gotchas worth remembering
- Unity random/idle crashes on this machine = the RTX 5060 Ti driver (
dxgi.dll), not code. Fix path: DDU + NVIDIA Studio driver / disable HAGS /-force-d3d11. (Native memory:gpu-crash-dxgi-driver.) - When the editor is unstable, write Assets
.csvia the filesystem + onerefresh_unity forcelater instead of per-edit MCPcreate_script— the bridge dies with the editor; a static adversarial review can stand in for the compiler. - A version bump on an additive settings/save struct re-activates the migration path for every existing file — migrate by carrying forward the old value and seeding only new fields, never by rebuilding from
Defaults()(else you silently reset untouched fields). Caught by the post-impl review.
Next-session intent
Get the editor stable (driver), run the verify ladder for DR-043 — done 2026-06-29 (green). Remaining: the operator fun-gate — a real first-run playthrough to feel whether the welcome framing lands, the pointers read, and it stays un-naggy (and to confirm the Welcome→Move→Mine→Build→Fabricator→Gate→Clear→Return→Defend→Done cascade paces well with actual input). The dev Force Each Launch toggle (Settings → Onboarding) makes that repeatable.