From bae326e14c3c02d6ff5a2f1887452a876cbd3ad9 Mon Sep 17 00:00:00 2001 From: coder-bot Date: Fri, 21 Aug 2026 01:18:34 +0000 Subject: [PATCH] WIP checkpoint: Client-side position sync + prediction/reconciliation --- .godot/editor/filesystem_cache10 | 32 ++++++++++++++-------------- scripts/network_client.gd | 1 + scripts/smoke_test_network_client.gd | 5 +++++ 3 files changed, 22 insertions(+), 16 deletions(-) diff --git a/.godot/editor/filesystem_cache10 b/.godot/editor/filesystem_cache10 index 05c94a4..85e1158 100644 --- a/.godot/editor/filesystem_cache10 +++ b/.godot/editor/filesystem_cache10 @@ -1,5 +1,5 @@ 63f7b34db8d8cdea90c76aacccf841ec -::res://::1787275033 +::res://::1787275036 export_presets.cfg::TextFile::-1::1787272930::0::1::::<><><>0<>0<><>:: README.md::TextFile::-1::1787272930::0::1::::<><><>0<>0<><>:: ::res://addons/::1787272930 @@ -31,20 +31,20 @@ PC1.md::TextFile::-1::1787272930::0::1::::<><><>0<>0<><>:: client-server-wiring.md::TextFile::-1::1787272930::0::1::::<><><>0<>0<><>:: economy.md::TextFile::-1::1787272930::0::1::::<><><>0<>0<><>:: social.md::TextFile::-1::1787272930::0::1::::<><><>0<>0<><>:: -::res://docs/testing/::1787274081 +::res://docs/testing/::1787275036 README.md::TextFile::-1::1787272930::0::1::::<><><>0<>0<><>:: -test_inventory.md::TextFile::-1::1787274081::0::1::::<><><>0<>0<><>:: -::res://scenes/::1787274081 +test_inventory.md::TextFile::-1::1787275036::0::1::::<><><>0<>0<><>:: +::res://scenes/::1787275036 game.tscn::PackedScene::-1::1787272930::0::1::::<><><>0<>0<><>::res://scenes/worlds/test_level.tscn<>res://scenes/player.tscn main.tscn::PackedScene::-1::1787272930::0::1::::<><><>0<>0<><>::res://scripts/chunk_stream_manager.gd main_menu.tscn::PackedScene::-1::1787272930::0::1::::<><><>0<>0<><>::res://scripts/main_menu.gd player.tscn::PackedScene::-1::1787272930::0::1::::<><><>0<>0<><>::res://scripts/player.gd -server.tscn::PackedScene::-1::1787274081::0::1::::<><><>0<>0<><>::res://scripts/server.gd -server_player.tscn::PackedScene::-1::1787274081::0::1::::<><><>0<>0<><>::res://scripts/player_spawner.gd +server.tscn::PackedScene::-1::1787275036::0::1::::<><><>0<>0<><>::res://scripts/server.gd +server_player.tscn::PackedScene::-1::1787275036::0::1::::<><><>0<>0<><>::res://scripts/player_spawner.gd world_list.tscn::PackedScene::-1::1787272930::0::1::::<><><>0<>0<><>::res://scripts/world_list.gd ::res://scenes/worlds/::1787272930 test_level.tscn::PackedScene::-1::1787272930::0::1::::<><><>0<>0<><>:: -::res://scripts/::1787275024 +::res://scripts/::1787275098 api_client.gd::GDScript::5412288119287126975::1787272930::0::1::::<>Node<><>0<>0<><>:: chunk.gd::GDScript::7364239597441807588::1787272930::0::1::::Chunk<>Node3D<><>0<>0<><>:: chunk_data_decoder.gd::GDScript::3922068956043581888::1787272930::0::1::::ChunkDataDecoder<>RefCounted<><>0<>0<><>:: @@ -52,20 +52,20 @@ chunk_scene.gd::GDScript::9207602004456600331::1787272930::0::1::::ChunkScene<>N chunk_stream_manager.gd::GDScript::2366645676568508746::1787272930::0::1::::ChunkStreamManager<>Node<><>0<>0<><>:: dynamic_object_node.gd::GDScript::8863349716576659118::1787272930::0::1::::DynamicObjectNode<>Node3D<><>0<>0<><>:: main_menu.gd::GDScript::2834562513277893052::1787272930::0::1::::<>Control<><>0<>0<><>:: -network_client.gd::GDScript::5408296350353838185::1787274976::0::1::::NetworkClient<>Node<><>0<>0<><>:: -network_player_proxy.gd::GDScript::4787436336771232797::1787274812::0::1::::<>Node<><>0<>0<><>:: -network_receiver_proxy.gd::GDScript::6742760436861380520::1787275024::0::1::::<>Node<><>0<>0<><>:: -player.gd::GDScript::4510795778937304264::1787274081::0::1::::Player<>CharacterBody3D<><>0<>0<><>:: -player_spawner.gd::GDScript::3637338339553764865::1787274081::0::1::::PlayerNode<>CharacterBody3D<><>0<>0<><>:: -server.gd::GDScript::6336910781803684784::1787274081::0::1::::<>Node<><>0<>0<><>:: +network_client.gd::GDScript::5408296350353838185::1787275098::0::1::::NetworkClient<>Node<><>0<>0<><>:: +network_player_proxy.gd::GDScript::4787436336771232797::1787275036::0::1::::<>Node<><>0<>0<><>:: +network_receiver_proxy.gd::GDScript::6742760436861380520::1787275036::0::1::::<>Node<><>0<>0<><>:: +player.gd::GDScript::4510795778937304264::1787275036::0::1::::Player<>CharacterBody3D<><>0<>0<><>:: +player_spawner.gd::GDScript::3637338339553764865::1787275036::0::1::::PlayerNode<>CharacterBody3D<><>0<>0<><>:: +server.gd::GDScript::6336910781803684784::1787275036::0::1::::<>Node<><>0<>0<><>:: smoke_test_api.gd::GDScript::1760923834350699002::1787272930::0::1::::<>SceneTree<><>0<>0<><>:: smoke_test_auth.gd::GDScript::3027816090663230577::1787272930::0::1::::<>SceneTree<><>0<>0<><>:: smoke_test_e2e.gd::GDScript::9086409960595132737::1787272930::0::1::::<>SceneTree<><>0<>0<><>:: -smoke_test_enter_world.gd::GDScript::4171815758762850910::1787274081::0::1::::<>SceneTree<><>0<>0<><>:: +smoke_test_enter_world.gd::GDScript::4171815758762850910::1787275036::0::1::::<>SceneTree<><>0<>0<><>:: smoke_test_main_menu_back.gd::GDScript::4436937414562273157::1787272930::0::1::::<>SceneTree<><>0<>0<><>:: smoke_test_main_menu_full_flow.gd::GDScript::1948803640558784862::1787272930::0::1::::<>SceneTree<><>0<>0<><>:: smoke_test_main_menu_ui.gd::GDScript::396938597300585484::1787272930::0::1::::<>SceneTree<><>0<>0<><>:: -smoke_test_network_client.gd::GDScript::3109386529184855644::1787274351::0::1::::<>SceneTree<><>0<>0<><>:: +smoke_test_network_client.gd::GDScript::3109386529184855644::1787275067::0::1::::<>SceneTree<><>0<>0<><>:: smoke_test_player.gd::GDScript::3497042634752676337::1787272930::0::1::::<>SceneTree<><>0<>0<><>:: smoke_test_test_level.gd::GDScript::2607555612829866949::1787272930::0::1::::<>SceneTree<><>0<>0<><>:: smoke_test_world_list.gd::GDScript::4300757286283894147::1787272930::0::1::::<>SceneTree<><>0<>0<><>:: @@ -73,5 +73,5 @@ static_object_node.gd::GDScript::5276389741929225897::1787272930::0::1::::Static tile_def.gd::GDScript::2430528079284085109::1787272930::0::1::::TileDef<>RefCounted<><>0<>0<><>:: tile_layer.gd::GDScript::4797906255131447844::1787272930::0::1::::TileLayer<>RefCounted<><>0<>0<><>:: tile_layer_node.gd::GDScript::9033225196818247616::1787272930::0::1::::TileLayerNode<>Node3D<><>0<>0<><>:: -world_list.gd::GDScript::6119591848847211153::1787274081::0::1::::<>Control<><>0<>0<><>:: +world_list.gd::GDScript::6119591848847211153::1787275036::0::1::::<>Control<><>0<>0<><>:: world_object.gd::GDScript::6429674491464200335::1787272930::0::1::::WorldObject<>RefCounted<><>0<>0<><>:: diff --git a/scripts/network_client.gd b/scripts/network_client.gd index c9a1df4..6e1ef80 100644 --- a/scripts/network_client.gd +++ b/scripts/network_client.gd @@ -196,6 +196,7 @@ func _handle_snapshot(snapshot_data: Dictionary) -> void: # RPC payloads can arrive as String or int depending on the transport # encoding, so check both rather than assuming. var my_state: Variant = players.get(my_id, players.get(str(my_id), null)) + print("DEBUG _handle_snapshot my_id=", my_id, " my_state=", my_state, " buffer_size=", _prediction_buffer.size(), " net.position=", position) if my_state == null or not (my_state is Dictionary): return diff --git a/scripts/smoke_test_network_client.gd b/scripts/smoke_test_network_client.gd index ddebe8a..413862d 100644 --- a/scripts/smoke_test_network_client.gd +++ b/scripts/smoke_test_network_client.gd @@ -73,6 +73,11 @@ func _run() -> void: var reconcile_handler := func(err): reconciled_this_round = true; correction_seen = err net.reconciled.connect(reconcile_handler) for i in 60: + # Keep predicting (with no movement input) so the prediction buffer's + # latest entry actually reflects the desynced position -- without + # this, the buffer either empties out or keeps stale pre-desync + # entries, and _handle_snapshot has nothing real to compare against. + net.predict_and_send(1.0 / 30.0, 0.0, 0.0, false) await process_frame if reconciled_this_round: break