Multiplayer Sync AnimatableBody2D with AnimationPlayer

Godot Version 4.3

I have a little multiplayer physics platformer working nicely, both players are rigidbodies and are synced up with a MultiplayerSyncronizer node. Can see eachother fall, die, jump, and it’s pretty accurate. However, in the main node, I tried adding moving platforms which are AnimatableBody2D scenes. Theres are controlled by AnimationPlayers in their scenes. They intereact with both players well, but they are in different positions for each player. Syncing the rotation or position of these doesn’t seem to work. Any help would be appreaciated!

Only the multiplayer authority should run the animation if you have a sychronizer attached.

Thanks for that!! Do I attach a script to the Sync to declare that?

You may have to attach a script to the moving platforms, preferably your moving platform scene’s root node for simplicity, as the animatable body and animation player will need to be ready when you call

if is_multiplayer_authority():
    animator.play("new_animation")

Thanks again, but doesn’t seem to work… here is the code for each player scene for MP:

func _enter_tree():
set_multiplayer_authority(name.to_int())

and here it is for the root level node:

var peer = ENetMultiplayerPeer.new()

func _on_host_pressed():
	peer.create_server(7777)
	multiplayer.multiplayer_peer = peer
	multiplayer.peer_connected.connect(_add_player)
	_add_player()
	
 
func _add_player(id = 1):
	var player = player_scene.instantiate()
	player.name = str(id)
	call_deferred("add_child",player)
	print(player.name)

func _on_join_pressed():
	peer.create_client("MY IP", "PORT")
	multiplayer.multiplayer_peer = peer

So I have the 2 players that are scenes on the level node, with a spinning platform as an AnimatableBody2D scene. Within that scene is that a syncronizer that is bound to it’s rotation, as well as the script you sent before. The platform is spinning for both players, but not synced up.

I got that code somewhere online, and I SORT of understand it… is the problem that both players have authority?

For syncing with AnimationPlayer, the client only needs to copy the rotation/position information from the server using MultiplayerSynchronizer. There is no need for client to run the animation because its hard to sync. Do the animation on server.

Also, if animating using AnimationPlayer, animate a RemoteTransform2D and set it’s remote_path property to AnimatableBody2D.Don’t animate AnimatableBody2D directly, which will cause weird results.

Your tree should be like this. (same with 2d)
image

I would sync the animation player playback position. To do this sync the playaback_position in a different variable, once it arrives on the client use the signal synchronized to update the client position with the seek() function. (I dont think you can just set the playback_position directly, it looks like it is only a monitor.)

Otherwise do not play the animation on the client and just sync the position of the animatablebody2d.

1 Like

thanks. How do I make the animation only play for the server? right now there is one big level node and the platform is a scene within it… So I think it just plays for both clients

Use @gertkeno suggestion, or its inverse, on who ever the authority is, if that be the server or not.

Or just if multiplayer.is_server():

Ok let’s finish this problem. I make a small 3d platform scene using the official project under Godot 4.3. And it works well on both client and host. Same for 2d.

Hello! Thanks. I have looked over this project and applied it to my own… I think my method for multiplayer before was pretty busted and has some issues.

After implementing this, I get a crash/error when my player scene is added to the level. Basically, I’m getting a null instance on the character scene’s own child nodes…

The player node contains a lot of code and child nodes with hitboxes, cosmetic sprites, etc. However it seems to throw a null error when the scene tries to load in using that multiplayer code

EDIT: Okay I reverted my multiplayer code to my own janky one to get it back to normal… BUT I think I may have found the problem: PAUSING

Both players start in a paused state, which actually pauses everything in the tree. by doing NODE_PROCESS_ALWAYS on the platform, I think I finally was able to sync it up. However further testing is needed.