I have a CharacterBody2D that is spawned multiple times, each with a NetworkSynchronizer attached. The problem happens when two or more players are stacked on top of each other: if the player on the bottom moves, the one on top takes about half a second to update its velocity accordingly.
extends CharacterBody2D
const MOVE_SPEED = 1000
const JUMP_FORCE = 900
const GRAVITY = 1200
func _physics_process(delta):
if not is_on_floor():
velocity.y += GRAVITY * delta
else:
if velocity.y > 0:
velocity.y = 0
if is_multiplayer_authority():
var direction = 0
if Input.is_action_pressed("ui_right"):
direction += 1
if Input.is_action_pressed("ui_left"):
direction -= 1
velocity.x = direction * MOVE_SPEED
if Input.is_action_just_pressed("ui_accept") and is_on_floor():
velocity.y = -JUMP_FORCE
move_and_slide()
I don’t think I’m the only one having this issue. I haven’t found much documentation about this, and I don’t want to imagine that Godot doesn’t have an option to make the movement exactly match the player underneath.
I really appreciate any help you can provide. Thank you very much!
Why is this a problem? Does your gameplay require players to carry one another? If so the problem is more likely that you’re synching incorrectly. Your server should be telling everyone where they are and what their velocity is - you shouldn’t be replying on the players to update their own position. They should update their position, but if the server tells them to fix it they should fix it.
First of all, thank you for replying. And yeah, it’s really important that the players stay aligned without delays.
Regarding sync, it should be handled by the MultiplayerSynchronizer attached to my player scene, where I specify that the velocity should be synchronized.
As you can see in the code, the players’ positions are based on their velocity. I’m not really sure how I can fix this behavior. Like I said before, I’m sure I’m not the first one to encounter this issue.
UPDATE
This behavior also happens without MultiplayerSynchronizer
This is useful. CharacterBody3D nodes do not respond to outside physics unless you code that into them. So what I would do is track player_on_my_head: CharacterBody3D = player2 and update player2’s velocity changes to match player1’s velocity changes. (NOTE: Changes, not actual velocity.)
You realize that over the internet, if that gameplay is crucial, you’re going to need to code prediction and paradox fixing code for what is the worst roundtrip ping acceptable for your use case.
With more than a 100ms delay, you’re going to get a lot of those undesirable side effect.
Granted, not fluent on Godot multiplayer workings but this is not trivial work and cannot be easily made for the general case, e.g a lot of tuning is necessary for whatever multiplayer code stack you’ll be using for a particular game.
Have fun,
Cheers !
Yes, I am fully aware that there can be ping, but locally I don’t understand how something as basic as two players stacked on top of each other has a delay of 0.5s.
I can’t find any solution
I have uploaded the code to github by the way, in case you have any comments.
I think you are expecting the CharacterBody3D nodes to interact by default in a way that they do not - I.E. they do not move each other. See my above post for my suggested solution.
Have you had a chance to look at the code? because what I use is CharacterBody2D.
As for the movement, it is a basic movement, where the only thing that is done is: apply gravity, and a lateral movement in the X axis.
The behavior of the two characters is as expected (if the one below moves to the left, the one above also does so). The only problem, as I mentioned previously, is the time it takes to “copy” the movement of the one below.
I have tested this without multiplayer and it has the same behavior.
I find it hard to believe that something so basic doesn’t have a documented solution, or at least I didn’t find one. Thank you!