diff --git a/examples/multiplayer-fps/scripts/player-spawner.gd b/examples/multiplayer-fps/scripts/player-spawner.gd index da8f38b..c66d6fd 100644 --- a/examples/multiplayer-fps/scripts/player-spawner.gd +++ b/examples/multiplayer-fps/scripts/player-spawner.gd @@ -173,6 +173,15 @@ func _spawn(id: int): if rollback_sync and rollback_sync.has_method("process_settings"): rollback_sync.process_settings() + # On the client side, initialize weapon loadout locally so the player + # has weapons immediately. The server will reconcile via rollback state sync. + if not multiplayer.is_server(): + var weapon_mgr = avatar.find_child("WeaponManager") + if weapon_mgr and weapon_mgr.has_method("set_default_loadout"): + # Default to T team — server will correct via state sync + weapon_mgr.set_default_loadout(1) # TeamManager.Team.T = 1 + print("[Spawner] Client-side weapon loadout initialized for peer %s" % id) + func get_team_spawn_point(peer_id: int, spawn_idx: int = 0) -> Vector3: var team := team_manager.get_team(peer_id) var points: Array[Marker3D] diff --git a/examples/multiplayer-fps/scripts/weapon_manager.gd b/examples/multiplayer-fps/scripts/weapon_manager.gd index ea7c529..8b4b7a6 100644 --- a/examples/multiplayer-fps/scripts/weapon_manager.gd +++ b/examples/multiplayer-fps/scripts/weapon_manager.gd @@ -158,10 +158,13 @@ func give_weapon(weapon_id: int): NetworkRollback.mutate(self) func _rollback_tick(delta: float, tick: int, _is_fresh: bool): - if rollback_synchronizer.is_predicting(): - return + # NOTE: On the client, the player CharacterBody3D is owned by the server + # (peer 1), so `rollback_synchronizer.is_predicting()` may return true + # on early ticks when input history hasn't been built up yet. + # We process weapon actions anyway — the server reconciles via rollback. + # Only skip if the player is dead or frozen (checked below). - # DEBUG: weapon switching + # Skip if player dead if input and (input.slot_1 or input.slot_2 or input.slot_3 or input.slot_4): print("[WEAPON DEBUG] _rollback_tick tick=%d slots=[s1=%s s2=%s s3=%s s4=%s] active=%d inv=%s" % [tick, input.slot_1, input.slot_2, input.slot_3, input.slot_4, active_slot, inventory])