Godot can't synchronize spawned nodes

Godot Version

4.2.1-stable

Question

basically when I spawn a bullet node in my multiplayer godot game I get these errors:get_node: Node not found and get_cached_object: Failed to get cached path: /root/main/607851477/Bullet/MultiplayerSynchronizer. my bullets code is:


@onready var sprite2d = $Sprite2D
@onready var deathtimer = %deathtimer
var speed = -560
# Called when the node enters the scene tree for the first time.
func _ready():
	sprite2d.show()
	deathtimer.start()


# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
	position += transform.x * speed * delta


func _on_body_entered(body):
	if not body.is_in_group("player"):
		queue_free()


func _on_deathtimer_timeout():
	sprite2d.hide()
	queue_free()```




**PLAYER CODE**




extends CharacterBody2D
var health = 10
@onready var cooldown = %Cooldown
var canshoot = true
func _enter_tree():
	set_multiplayer_authority(str(name).to_int())

@onready var camera = %Camera2D
const SPEED = 330.0
const JUMP_VELOCITY = -400.0
@onready var main = $"."

# Get the gravity from the project settings to be synced with RigidBody nodes.
var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")


func _physics_process(delta):
	if not is_multiplayer_authority(): camera.enabled = false
	if is_multiplayer_authority(): 
		if Input.is_action_pressed("use_shoot") && canshoot == true:
			rpc("shoot")
			canshoot = false
			cooldown.start()
			
		
	#if not is_multiplayer_authority(): return
	# Add the gravity.
	if not is_on_floor():
		velocity.y += gravity * delta

	# Handle jump.
	if is_multiplayer_authority(): 
		if Input.is_action_pressed("i_up") and is_on_floor():
			velocity.y = JUMP_VELOCITY

	# Get the input direction and handle the movement/deceleration.
	# As good practice, you should replace UI actions with custom gameplay actions.
		var direction = Input.get_axis("i_left", "i_right")
		if direction:
			velocity.x = direction * SPEED
		else:
			velocity.x = move_toward(velocity.x, 0, SPEED)
		move_and_slide()
					
func take_damage(amount):
	print("YOUCH")
	print("YOUCH")
	health -= amount
	if health <= 0:
		queue_free()
		
@rpc("any_peer", "call_local", "reliable")
func shoot():
	var bullet = preload("res://scenes/bullet.tscn").instantiate()
	add_child(bullet)
	bullet.position = self.global_position
	bullet.rotation = bullet.global_position.angle_to_point(get_global_mouse_position())
	bullet.rotation_degrees += -90



func _on_area_2d_body_entered(body):
	if body.is_in_group("Arbullet"):
		queue_free()


func _on_cooldown_timeout():
	canshoot = true

my bullets have a multiplayer synchronizer, and are on the autospawn list, and my players spawn perfectly normally and fine, I made a stack overflow post on this b but I could not get an awnser (I just flagged something random as a solution because I didn’t want people to keep trying on there [windows - godot how to spawn 2d bullet and sync it for multiplayer, I have spent a very long time about 10 hours working on this issue and I can’t find a awnser https://stackoverflow.com/questions/76517753/multiplayersynchronizer-error-in-godot4-when-building-spawn and I read this post and it did not help me[Problem with MultiplayerSynchronizer and spawn object - #8 by zdrmlpzdrmlp]

anybody?

Are the errors always immediate or does it ever work normally? My guess is that maybe it’s trying to synchronize something that’s been deleted already.

it’s always immediate

the bullets appear but it’s in the wrong direction

I’m boutta give up and just not do godot anymore this sucks and it’s legit been 4 weeks, I’m so mad.

after some revisions it works normal for a few seconds and then breaks

I’ve seen in other posts and vidoes where people use the main scene to spawn the bullets and other stuff, but I can’t figure it out (example):

image

That’s how I handled spawning in a recent multiplayer project:

You might not need to worry about it if using a MultiplayerSpawner but I ran into issues related to the automatic Node-naming Godot performs. Basically the names of Nodes created in-game would sometimes become out of sync for some clients which would cause errors calling RPC methods. I was able to fix it by just manually naming any Nodes with scripts containing RPC methods.

1 Like

so I have to spawn them as peers? in the videos I watch they don’t do that, but I’ll try.

I can’t figure out a way to apply this to my code, I don’t understand how I would give the bullets unique Id’s

If you’re manually spawning the bullets, you’d need some kind of authority (such as on the server) that just assigns a number as an id. It can be incremented for each bullet spawned. A lot more annoying than using the MultiplayerSpawner so I’d exhaust that option first but is something you could try.

If you don’t need to sync the bullet position exactly, you could also just send out an event that a bullet was spawned at some position, angle, and speed. Kind of just depends on the use case.

well I know but how would I add the ID to the bullets.

I don’t know how I would add an Id, because of the way I’m spawning them, like using .id on them doesn’t work. and etc

So for RPC methods or the synchronizer node, the ID is just the name of the Node.

bullet.name = "Bullet%s" % bullet_id

Ok, I think I can make this work, this may be my solution, thanks so much, ok so I kinda do what you did for meatball games? your thing installs a different ID for every player?

ok so I added some code but this still happens

@rpc("authority", "call_local", "reliable")
func shoot():
	if multiplayer.is_server():
		var bullet_id = 1
		var bullet = preload("res://scenes/bullet.tscn").instantiate()
		bullet.name = "Bullet%s" % bullet_id
		add_child(bullet,true,1)
		bullet.position = self.global_position
		bullet.rotation = bullet.global_position.angle_to_point(get_global_mouse_position())
		bullet.rotation_degrees += -90
		bullet_id += 1

I know this code is crappy but it was quickly made to see if giving Id’s would fix the problem, spawning them from the root seems to not work.

I don’t know whats wrong with me, I’ve spent weeks and weeks on this, I don’t know what is going on… I simply just can’t do this.

Well making even simple games in general can be tricky and adding multiplayer complicates things quite a bit so don’t beat yourself up too much. There’s nothing wrong with you.

@rpc("authority", "call_local", "reliable")
func shoot():
	if multiplayer.is_server():

A couple of things here: Declaring the variable bullet_id in this function will happen each time the function is called. This means that it will always equal 1. Second, it checks if the game is the server before creating the bullet so noone but the server will ever create any bullets.

Here’s a basic example that can hopefully help out. The bullets positions aren’t synced constantly, only when they are created but they still sync pretty well.

1 Like