- Fixed double-emission bug in network_manager.gd: ENet signal connections
(peer_connected/peer_disconnected) are now only connected when netfox
NetworkEvents is NOT available, preventing duplicate player_connected/
player_disconnected signal emissions.
- Fixed stop() to only disconnect ENet signals when they were actually
connected (mirrors the conditional connection in start_server()).
- Fixed headless parse error in player_net_input.gd: replaced direct
NetworkTime.before_tick_loop reference with Engine.get_singleton()
call, avoiding unresolved type identifier in headless mode.
- netfox_bootstrap.gd added as minimal autoload placeholder.
- Dual-path architecture: netfox NetworkEvents when available (editor),
ENet fallback when netfox unavailable (headless server).
- Broadcast RPCs (spawn, round state, scores) kept as-is since they
work identically through Godot's MultiplayerAPI in both paths.
Add client-side prediction (t_p1_pred) with:
- scripts/network/snapshot.gd — lightweight snapshot resource with
to_dict/from_dict serialization for RPC. Stores position (Vector3),
rotation (Quaternion), velocity (Vector3), grounded (bool).
- scripts/network/client_prediction.gd — prediction/reconciliation
controller. 64-entry ring buffer of local snapshots, sends inputs to
server each physics tick (128Hz, ENet channel 0), detects misprediction
on server state arrival, rewinds and re-applies unconfirmed inputs.
Also supports remote player interpolation.
- scripts/network/network_manager.gd — new RPC endpoints for client
prediction: send_client_input (client->server, ch 0) and
send_server_state (server->client, ch 1). New signals for routing.
- client/characters/character/fps_character_controller.gd — prediction
hooks in _physics_process: on_before_tick() captures pre-input
snapshot, on_after_tick() sends input to server. Client prediction
path uses local movement (instant feedback) instead of reading from
SimulationServer entity.
Architecture:
Each tick: client applies input → predicts new state locally
→ sends input to server → server returns authoritative state
→ client compares and reconciles if mismatch.