Godot Version
4.6.2
Question
Hi! The game I’m creating is two PlayerBody2D’s pushing a RigidBody2D ball around. The issue is that on the server, the ball is in the correct position, but the client’s screen has the ball changing between the correct truth position that the server sees, and a different position, which I’m assuming is the client’s perceived truth position.
I’m not sure why the multiplayer_syncronizer position that I have inside the Coconut’s scene tree is swapping between two values. I’m new to this and any help would be appreciated, thanks!
EDIT: I’ve added linear_velocity to the multiplayer synchronizer and the position of the objects are closer, but they still jitter. I think now the client is modeling more accurately to the server, but I don’t know why the position keeps snapping instead of just being overwritten from the server. Here’s what that update looks like:
Here are some relevant code files:
coconut_spawner.gd
extends MultiplayerSpawner
@export var coconut_scene : PackedScene
var coconut_count : int = 0
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(_delta: float) -> void:
if Input.is_action_just_pressed("ui_accept"):
spawn_coconut.rpc_id(1) # Send the input only to the server.
# Call local is required if the server is also a player.
@rpc("any_peer", "call_local", "reliable")
func spawn_coconut() -> void:
if not multiplayer.is_server():
return
# The server knows who sent the input.
#var sender_id : int = multiplayer.get_remote_sender_id()
# Process the input and affect game logic.
coconut_count += 1
var coconut : Coconut = coconut_scene.instantiate()
coconut.position = Vector2(600, 300)
coconut.name = "Coconut_" + str(coconut_count)
#$YSortedSprites.add_child(coconut)
get_node(spawn_path).call_deferred("add_child", coconut)
player.gd
class_name player extends CharacterBody2D
var player_number : int
const SPEED = 500.0
func _enter_tree() -> void:
set_multiplayer_authority(name.to_int())
func _physics_process(_delta: float) -> void:
if not is_multiplayer_authority():
return
var direction : Vector2 = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
velocity = direction * SPEED
move_and_slide()
# After move_and_slide() we apply "impulses" to physics objects
var push_force : float = 60.0 # represents the player's inertia
for i in get_slide_collision_count():
var c : KinematicCollision2D = get_slide_collision(i)
if c.get_collider() is RigidBody2D:
c.get_collider().apply_central_impulse(c.get_normal() * -1 * push_force)