Unexpected _physics_process functionality in multiplayer

Godot Version

4.3

Question

Hi all, I’m wondering if anybody could help with some strange rpc issues I am encountering inside _physics_process :pensive:

Before I start I should preface my main game dev experience is using UE5 which I believe handles multiplayer and tick slightly differently. This could be throwing me off.

So in my _process_physics function I am creating a move that is simulated on the client and then sent to the server via rpc where the location, rotation and velocity are replicated back down to the clients:

func _physics_process(delta: float) -> void:
	if network_role == network_role_enum.ROLE_AUTONOMOUSPROXY:
		var move = create_move(delta)
		unacknowledged_moves.append(move)
		simulate_move(move)
		server_send_move.rpc_id(1, move)
	if network_role == network_role_enum.ROLE_AUTHORITY and get_is_locally_controlled():
		var move = create_move(delta)
		server_send_move.rpc_id(1, move)
	if network_role ==  network_role_enum.ROLE_SIMULATEDPROXY:
		simulate_move(server_state["last_move"])
@rpc("any_peer", "call_local")
func server_send_move(move: Dictionary):
	simulate_move(move)
	
	server_state["last_move"] = move
	server_state["location"] = global_position
	server_state["rotation"] = _skin.global_rotation.y
	server_state["velocity"] = velocity
func simulate_move(move: Dictionary):
	var y_velocity:= velocity.y
	velocity.y = 0.0
	velocity = velocity.move_toward(move["move_direction"] * move_speed, acceleration * move["delta"])
	velocity.y = y_velocity + _gravity * move["delta"]
	
	if network_role == network_role_enum.ROLE_AUTONOMOUSPROXY:
		print("auto - pos: " + str(global_position) + "vel: " + str(velocity) + "time: " + str(Time.get_ticks_msec()))
	elif network_role == network_role_enum.ROLE_AUTHORITY and not get_is_locally_controlled():
		print("auth - pos: " + str(global_position) + "vel: " + str(velocity) + "time: " + str(Time.get_ticks_msec()))
	
	move_and_slide()

The issue I am seeing is the position on the server is moving at about half the speed of what is simulated on the client, which is strange because printing the velocity returns the same on both. Maybe move_and_slide is working diffrently on the server? Locking the framerate to the same as the _physics_process rate makes the characters move at the same speed too which I can’t understand why.

If I put the code inside of _process instead, the movement works fine. This works for now but will probably cause issues later when interacting with other physics objects.

Can anyone explain to me what is going wrong? Have I set up my movement the complete wrong way to work with Godot? Why does my _physics_process behave differently depending on fps

Thanks for your time