Why doesn't the bullet deal damage to the players?

Godot Version

Godot 4.6.2

Question

I create a bullet, and both players see it. It flies, crashes into another player, but the player doesn’t take any damage, and errors occur.

Bullet code:

extends CharacterBody3D

@export var SPEED = 1
@export var target_position = position
@export var attack = 10
@export var attack_type = []
var parent = null

@rpc("any_peer","call_local")
func rpcattack():
	if target_position != null:
		var look_position = Vector3(target_position.x, target_position.y, target_position.z)
		look_at(look_position, Vector3.UP)
		target_position.y = position.y
		var direction_to_target = target_position - position
		direction_to_target = direction_to_target.normalized()
		if direction_to_target.length() > 0:
			velocity.x = direction_to_target.x * SPEED
			velocity.z = direction_to_target.z * SPEED
		if position.distance_to(target_position) <= 0.2:
			queue_free()
	
	move_and_slide()
	
	# Уничтожаем пулю при столкновении с чем угодно
	if get_slide_collision_count() > 0:
		var collision = get_slide_collision(0)
		var collider = collision.get_collider()
		
		# Урон мобам
		if collider.name == "Mob" or collider.name == "Player":
			if collider != parent:
				collider.HP -= attack
		
		queue_free()
var count = false
func _physics_process(delta):
	if !count:
		count = true
		rpc("rpcattack")
		await get_tree().create_timer(0.1).timeout
		count = false

Errors (they repeat themselves):

E 0:00:16:099   get_node: Node not found: "Map/Bull" (relative to "/root").
  <C++ Error>   Method/function failed. Returning: nullptr
  <C++ Source>  scene/main/node.cpp:1963 @ get_node()
E 0:00:16:099   get_cached_object: Failed to get cached node from peer 1 with cache ID 3.
  <C++ Error>   Parameter "node" is null.
  <C++ Source>  modules/multiplayer/scene_cache_interface.cpp:291 @ get_cached_object()
E 0:00:16:099   process_rpc: Invalid packet received. Requested node was not found.
  <C++ Error>   Parameter "node" is null.
  <C++ Source>  modules/multiplayer/scene_rpc_interface.cpp:209 @ process_rpc()

Is the bullet on the correct physics layer and mask to detect all players?

very very strange control flow you have here. using await in _physics_process is almost always a bad idea, if you want something to fire every 0.1 seconds it should use a timer. But your 0.1 function rpcattack uses move_and_slide which should run every frame in _physics_process, and not through an @rpc. Keep your @rpc as small as possible, do movement in _physics_process and only @rpc when something is hit and the bullet needs to be destroyed/do damage.

Actually you shouldn’t use a Timer or get_tree().create_timer() if you want something to reliably run at an interval of less than half a second. You’ll need to decrement the code in the physics frame by delta and tack the time that way, then fire off you code.

EDIT: Nvm, it’s 0.05 seconds, not 0.5 seconds.

I changed it so that the player dies, but there are errors.

Code:

@rpc("any_peer","call_local")
func rpcattack(collider):
	if collider != null:
		collider.HP -= attack
var count = false
func _physics_process(delta):
	if target_position != null:
		var look_position = Vector3(target_position.x, target_position.y, target_position.z)
		look_at(look_position, Vector3.UP)
		target_position.y = position.y
		var direction_to_target = target_position - position
		direction_to_target = direction_to_target.normalized()
		if direction_to_target.length() > 0:
			velocity.x = direction_to_target.x * SPEED
			velocity.z = direction_to_target.z * SPEED
		if position.distance_to(target_position) <= 0.2:
			queue_free()
	
	move_and_slide()
	
	# Уничтожаем пулю при столкновении с чем угодно
	if get_slide_collision_count() > 0:
		var collision = get_slide_collision(0)
		var collider = collision.get_collider()
		
		# Урон мобам
		if collider is CharacterBody3D:
			if collider != parent:
				rpc("rpcattack", collider)
		
		queue_free()

Errors:

E 0:00:15:577   get_node: Node not found: "Map/Bull" (relative to "/root").
  <C++ Error>   Method/function failed. Returning: nullptr
  <C++ Source>  scene/main/node.cpp:1963 @ get_node()
E 0:00:15:577   process_simplify_path: Parameter "node" is null.
  <C++ Source>  modules/multiplayer/scene_cache_interface.cpp:116 @ process_simplify_path()
E 0:00:15:577   _process_get_node: Failed to get path from RPC: Map/Bull.
  <C++ Source>  modules/multiplayer/scene_rpc_interface.cpp:146 @ _process_get_node()
E 0:00:15:577   process_rpc: Invalid packet received. Requested node was not found.
  <C++ Error>   Parameter "node" is null.
  <C++ Source>  modules/multiplayer/scene_rpc_interface.cpp:209 @ process_rpc()
E 0:00:15:577   process_simplify_path: Parameter "node" is null.
  <C++ Source>  modules/multiplayer/scene_cache_interface.cpp:116 @ process_simplify_path()
E 0:00:17:543   rpcattack: Invalid access to property or key 'HP' on a base object of type 'EncodedObjectAsID'.
  <GDScript Source>bull.gd:12 @ rpcattack()
  <Stack Trace> bull.gd:12 @ rpcattack()

I don’t quite understand what they mean, can you explain them to me?

This error mean one of your players cannot find the bullet (assuming it’s name is “Bull”), how are you spawning bullets? Do you make sure to give them readable names?

This error means the rpc’s collider is null, which will happen if you try to feed Resource and Node types to an RPC. You cannot send the whole collider through the network, and if you could it would be a different collider than the other machines. This is why so much of the High-level Multiplayer is based on paths and keeping them the same, if all players have the exact same scene tree you can pass node paths through the network and clients can discern which nodes to use without sending a ton of data.

@rpc("any_peer","call_local")
func rpcattack(collider_path: NodePath):
	var collider: Node = get_node(collider_path)
	if collider != null:
		collider.HP -= attack

## etc ...
		if collider is CharacterBody3D:
			if collider != parent:
				rpcattack.rpc(collider.get_path())

Even with this approach, the errors remain. Can you suggest a way to get rid of them? I have no idea how to fix this.

P.s. The errors do not affect the execution of the code, so can they be hidden somehow?

I’m trying to figure out where I’m making mistakes, but I’m finding more and more flaws in my game that are related to multiplayer. I’ve come to the conclusion that my knowledge level is still far from online gaming. I’m going to try to redo the project with a focus on multiplayer from the start, but I don’t think it’s going to work out. I’m going to try making small 2D games with multiplayer to get better at it.