- api_client.gd: get_avatar_loadout() / save_avatar_loadout()
- main_menu.gd: on successful auth (fresh or session-restore), load the
catalog + fetch the saved loadout into AvatarSystem so the in-world
player renders as the player's avatar. Best-effort: a slow/failed prime
never gates getting in (UI goes authenticated first, prime runs after).
New "Customize Avatar" button (enabled only when signed in).
- avatar_system.gd: local-player convenience API -- ensure_catalog(),
set_loadout_from_dict() (from the backend's GET shape), has_loadout(),
build_current_avatar().
- player.gd: swaps the placeholder capsule for the assembled avatar
(feet-aligned to the capsule bottom) when a loadout is primed; silent
fallback to the capsule otherwise. Camera stays first-person for now
(third-person is a noted follow-up).
- avatar_visualizer.gd: rewrote it -- the old version referenced
AvatarLoader.SlotResult / load_slot() which never existed, so it didn't
compile and took avatar_customization_ui.gd down with it. Now a thin
wrapper over AvatarLoader for the preview.
- avatar_customization_ui.gd: seeds from the live loadout, saves through to
AvatarSystem + PUT /api/avatar/loadout (local file kept as fallback),
fixed a Camera3D.look_at() before-in-tree crash.
- scenes/avatar_customization.tscn rebuilt (old one used the Godot-3
`ViewportContainer` node type) + avatar_customization_screen.gd wrapper
that returns to the menu on close.
- smoke_test_avatar_in_world.gd: primed loadout -> game.tscn -> player
shows the assembled avatar, capsule hidden, rig + bone mounts present.
Verified: cold-cache smokes green (player 15/15, avatar_system 14/14,
avatar_in_world 10/10, main_menu_ui 13/13); against a live backend
main_menu_full_flow 12/12, main_menu_back 20/20, world_list 4/4,
enter_world 9/9, e2e 4/4; plus a manual register->default-loadout->
customize->save->re-fetch-persisted round trip.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015jtxAiu5dAW4WxCNdGkrkJ
- scenes/avatar_customization.tscn: script_extense -> script (typo meant
the customization UI script was never actually attached to the scene)
- scripts/avatar/avatar_loadout.gd: add missing class_name AvatarLoadout
(avatar_system.gd references the type everywhere; only this file among
the avatar scripts lacked its class_name)
- scripts/main_menu.gd: _ready() referenced _customize_button/_settings_button/
_quit_button but the @onready vars are named without the leading
underscore