Does my netcode truly work? + more questions and concerns. (More info in topic)

NetworkManager.gd

extends Node

const TICK_RATE = 60 # Server ticks per second
const MS_PER_TICK = 1000 / TICK_RATE
const INTERPOLATION_OFFSET = 100 # ms

var world_state_buffer =
var last_world_state = {}
var server_clock = 0.0

class WorldState:
var timestamp: float
var player_states: Dictionary

func _init(ts: float):
    timestamp = ts
    player_states = {}

func _physics_process(delta: float):
if multiplayer.is_server():
server_clock += delta
process_server_tick()

func process_server_tick():
var world_state = WorldState.new(server_clock)

# Collect all player states
for player in get_tree().get_nodes_in_group("players"):
    world_state.player_states[player.name] = {
        "position": player.global_position,
        "velocity": player.velocity,
        # Add other relevant state
    }

# Store state and broadcast to clients
world_state_buffer.append(world_state)
broadcast_world_state.rpc(world_state.timestamp, world_state.player_states)

# Cleanup old states
while world_state_buffer.size() > 1000:  # Keep last ~16 seconds
    world_state_buffer.pop_front()

@rpc(“authority”, “call_remote”, “reliable”)
func broadcast_world_state(timestamp: float, state: Dictionary):
last_world_state = state

# Interpolate positions
for player_id in state:
    var player = get_node_or_null(str(player_id))
    if player and player.name != str(multiplayer.get_unique_id()):
        var target_pos = state[player_id]["position"]
        # Implement interpolation logic here
        player.global_position = lerp(player.global_position, target_pos, 0.3)

Client-side input handling

func send_player_input(input_vector: Vector2, actions: Dictionary):
if !multiplayer.is_server():
var timestamp = Time.get_ticks_msec()
process_input.rpc_id(1, timestamp, input_vector, actions)

@rpc(“any_peer”, “call_local”, “reliable”)
func process_input(timestamp: int, input_vector: Vector2, actions: Dictionary):
if !multiplayer.is_server(): return

var player = get_node_or_null(str(multiplayer.get_remote_sender_id()))
if !player: return

# Validate input
if !validate_input(input_vector, actions):
    return
    
# Process movement with server-side validation
player.process_movement(input_vector)

# Handle actions
for action in actions:
    if actions[action]:
        player.handle_action(action)

func validate_input(input_vector: Vector2, actions: Dictionary) → bool:
# Implement validation logic
if input_vector.length() > 1.0:
return false
return true

1 Like