Commit Graph

5 Commits

Author SHA1 Message Date
algodoogle 96ea2dd1ea mp fix 2026-07-28 19:41:31 +01:00
algodoogle 23ec41c1d6 Fix five multiplayer sync bugs, add automated two-instance test
Adds test/multiPlayerTest.tscn plus a driver that runs the kitchen flow
across two game instances: grab/drop, dirt station, sink washing, hob
cooking, counter combining and plating. Runs headless (run_mp_test.ps1),
in two visible windows (run_mp_test_windowed.ps1), or by hand with
keyboard controls (play_mp_test.ps1). 108 checks, exits non-zero on
failure.

After every step both peers snapshot every item's position and rendered
state and the server diffs them. Targeted assertions only look at the
thing a step touched, which misses desyncs elsewhere - that audit is
what caught the last bug below.

Bugs found and fixed:

- net_pickable: apply_held_state() only wrote `enabled` in its
  non-authority branch, so once a client grabbed an item every other
  peer set enabled=false and regaining authority never restored it. The
  server could then never pick that item up again, and a station would
  "snap" it (emitting has_picked_up, so a plate still got marked dirty)
  while pick_up() bailed out on the disabled item - leaving the zone
  holding an item with no grab driver.

- network_manager: station gating only happened in the spawn path, so
  stations baked into a scene file kept running their snap zones on
  clients and grabbed items straight out of the local hand. Added
  gate_existing_stations().

- network_manager: despawn_item() only freed the server's copy. Items
  baked into a scene aren't tracked by the MultiplayerSpawner, so
  consuming one left a ghost on every client, which then blocked the
  station it sat in and got grabbed instead of its replacement.

- network_manager: the snap-into-station decision read the server's own
  copy of the item position, but the reliable release RPC routinely
  overtakes the synchronizer's unordered position updates - so it acted
  on a stale position and teleported items back into the station they
  had just been carried away from. The releasing peer now sends its
  final transform and the server adopts it first.

- container: contained_ids.append()/erase() mutate the array in place,
  which never fires the setter that rebuilds the plate's visuals. The
  peer that put food on a plate was the only peer that never redrew it;
  remote peers looked right because the synchronizer assigns there.

Also null-guards XRServer.get_tracker() in the vendored xr-tools hand
grab point, which threw on every successful grab without an XR runtime,
and adds multiplayer_world.populate_from_layout so debug scenes can bake
their own content instead of spawning the whole kitchen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-26 02:00:50 +01:00
algodoogle 4ca0a05d1b Fix world population race and add multiplayer diagnostics
The world was populated before NetworkManager.world_ready() actually
called host()/join(), so owns_world() read true for every peer
(including a joining client) and each one built its own local,
unreplicated copy instead of the client receiving the server's spawn
through the MultiplayerSpawner. Population now happens after the
session is actually established.

Also adds net-log coverage for spawn/despawn, station gating, item
authority handoff, station snapping, avatar spawn/despawn, and scene
transitions, so multiplayer behavior is visible in
%TEMP%\vryhungry_net_<pid>.log instead of failing silently.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-25 19:42:49 +01:00
algodoogle 596d777fae asd 2026-07-25 19:26:43 +01:00
algodoogle f7024db98d added multi 2026-07-25 18:20:12 +01:00