Commit Graph

6 Commits

Author SHA1 Message Date
daddy dba865ae4b PC3 Phase 2.3: networked play path in the game
- Session autoload: carries {world_id, host, port} from the world browser
  to the game scene.
- world_list.gd "Enter World": POST /api/worlds/{id}/join -> Session.begin
  -> load game.tscn. On 503 (backend has no orchestration) falls back to
  local single-player; other errors surface on the card.
- api_client.gd: join_world().
- game.gd (new, on game.tscn root): local single-player by default; when
  Session.active, connects a NetworkClient to the world's dedicated server
  and runs networked -- forwards the local Player's input each physics
  frame, snaps to the server position past a generous drift threshold
  (the Player keeps predicting locally with real collision), renders other
  players from snapshots (labelled capsules, lerped -- avatar appearance
  sync is a follow-up, the server doesn't replicate loadouts yet), and
  returns to the world list on disconnect.
- player.gd: exposes net_input (the input frame it applied) and
  apply_server_correction().
- network_client.gd: send_input() + get_own_server_state() for callers that
  do their own collision-aware prediction.
- scripts/mp_game_flow_client.gd + run_game_multiplayer_test.sh: two real
  clients each register -> join via the API -> game.tscn -> networked;
  A sees B and moves. PASS.

Verified end to end against an orchestration-enabled backend. Non-networked
smokes green (enter_world 9/9, world_list 5/5, player 15/15,
avatar_in_world 10/10, main_menu_full_flow 12/12).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015jtxAiu5dAW4WxCNdGkrkJ
2026-09-05 22:07:06 +00:00
coder-bot b60480798f WIP checkpoint: PC2: Wire "Enter World" from the browse list to the playable level 2026-08-21 00:43:45 +00:00
claude-checkpoint-tooling 8fc9d378e4 Fix: world cards render at ~1px wide once real data exists
Reported directly by the user after seeding a test world through the
browse-worlds screen: "screen is blank now". Two compounding layout
bugs, both real:

1. world_list.tscn's root VBoxContainer had no anchors at all, only
   size_flags -- but its parent (the scene's root node) is a plain
   Control, not a Container, so size_flags on a Control's direct child
   are meaningless there. Without anchors it never actually filled the
   screen, so it (and everything under it) collapsed toward zero size.

2. size_flags_horizontal/vertical used the raw integer 4 everywhere
   expand-fill was clearly intended (ScrollContainer, its WorldList
   child, HeaderHBox, TitleLabel) -- but 4 is Control.SIZE_SHRINK_CENTER
   in Godot 4, not SIZE_EXPAND_FILL (which is 3). ScrollContainer with
   SHRINK_CENTER takes only its own minimum size instead of expanding,
   cascading a ~1px width down through every card and every label.
   Confirmed the actual enum values by asking Godot directly rather
   than assuming.

Both are exactly the kind of bug a headless smoke test checking only
"did cards get added to the tree" can't catch -- child_count was
correctly non-zero, nothing crashed, the content was just rendered
invisibly thin. Verified the fix is real by deliberately reintroducing
bug #2 and confirming the test now correctly fails (card width 25px,
below the 200px sanity threshold) before restoring it.

Also replaced the card background: it was a ColorRect manually moved to
child index 0 of a VBoxContainer, which doesn't work as an overlay --
a VBoxContainer lays out ALL its children in sequence, so the "moved to
front" ColorRect rendered as an empty dark bar ABOVE the text, not
behind it. Now a proper PanelContainer with a StyleBoxFlat background,
the idiomatic way to get a colored panel behind auto-laid-out content
in Godot.

smoke_test_world_list.gd strengthened to actually catch this class of
bug going forward: seeds a real world via POST /api/worlds/ first (the
checkpoint runner's fresh DB meant the populated-card path never ran in
CI at all before this, only empty-list did), and asserts each card's
real computed width, not just that cards exist.

Full checkpoint suite re-verified clean on this branch: migrations,
68/68 pytest, all 6 Godot smoke tests, both platform exports.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-20 13:35:46 +00:00
coder-bot b3227f5b78 Wire browse-worlds screen to GET /api/worlds
- main_menu.gd: Play button now navigates to world_list.tscn
- world_list.gd: fix invalid theme_override_constants property-path syntax
  (use add_theme_constant_override), fix @onready node paths missing
  /HeaderHBox/, cast Variant dict values to String to avoid type-inference
  errors when cards actually render
- world_list.tscn: wire up Back/Refresh button signal connections (scene
  had zero [connection] blocks, buttons were dead)
- backend: fix real bug where World.visibility enum sent member names
  ("PUBLIC") to Postgres instead of lowercase values, breaking both GET
  and POST /api/worlds/ for any real query
- backend: fix WorldResponse.created_at typed as str instead of datetime,
  causing a second 500 on GET once the enum bug was fixed
- add smoke_test_world_list.gd: headless scene-level smoke test that
  registers a user, instantiates the real scene, and confirms world cards
  render from live backend data (not just an API-level check)
2026-08-19 21:57:39 +00:00
coder-bot 2ba6bc6b9f WIP checkpoint: Implementation: Browse worlds screen wired to GET /api/worlds 2026-08-19 21:27:24 +00:00
coder-bot 62e15d0c87 WIP checkpoint: Implementation: Browse worlds screen wired to GET /api/worlds 2026-08-19 21:20:52 +00:00