Physics process happening twice, maybe somthing to do with pathfinding

Godot 4.5

Really dont know how to describe this well, and i dont really even know what code is relevant, so this might be messy sorry.

Im prototyping a basic real time auto-battling system thing, specifically the unit behaviour currently. I have two spawn points set up, where i can spawn units which will then pathfind to the enemy spawn point. This kind of thing.

As concisely as possible, what is happening is that i’ll spawn one unit, it’ll pathfind to the enemy base as intended, and begin attacking it, which should just print a debug message every second. but if i then spawn an enemy from the other base, which it’s currently “attacking”, the first unit will inexplicably double the rate at which it prints the message. Note that: There is no interaction between any of the units or bases. The newly spawned unit is briefly “seen” by the attacker, but currently this does not do anything, the code just sets their target as the enemy base, they do not change each other’s behavior, except for pathfinding avoidance, which is also shouldnt be a factor here since as long as the enemy base is within range, the unit is setting its target position at its own position. This only happens in the specific case where one unit is already pathfound to the enemy base and is attacking it, and a new one is spawned there. As the new unit moves by, it does briefly nudge the attacking unit, but if thats related I have no idea how or why.

Right now all that happens when they reach the other point is start “attacking” it, which means calling a function in a separate script
Its pretty ugly, as I am just prototyping / learning how to make this kind of thing in general, all thats doing is checking if its in range and not already in the “attacking” state, setting its movement to zero and calling the function in that other script

elif not not_in_range && state != States.ATTACKING:
	state = States.ATTACKING
	target_pos = global_position # Stay still
	movement_component.move(target_pos, speed)
	attack_component.attack(target)

and all that that script does is wait a second and then signal the main script that its done attacking

signal done_attacking()

# Not doing anything with the target currently
func attack(_target) -> void:
	await get_tree().create_timer(1.0).timeout
	done_attacking.emit()

and that done_attacking signal connects to this function in the main script. the call deferred stuff is there because I thought maybe the problem has something to do with the state changing in the middle of the process or something? but it made no difference

func _attack_done():
	attack_done_deferred.call_deferred()

func attack_done_deferred() -> void:
	print(self, "beep")
	state = States.IDLE

so after spawning the second guy while the first one is attacking, that (self, “beep“) starts happening twice instead of once per second. And if I spawn two guys on opposite sides at the same time, before either one is attacking, this doesnt happen.

something I noticed while writing this post: If i spawn two guys on the same side, let them go attack the enemy base and then spawn an enemy there, this doesnt happen. They keep attacking at the same rate, once per second each. So this only seems to happen in this specific situation:

  1. Guy is already attacking

  2. Second guy is spawned in front

This does not happen if there are two guys attacking, or the enemy unit is spawned before the first one has started attacking.

I’m mystified, I really dont understand what could cause this when there shouldnt even be any way for the message to be printed more often than once per second because of the states. Theres lots more code and Im guessing this is not enough to solve whatever’s happening here, but I really dont know what else coudl possibly be relevant.

Start by getting rid of awaits

1 Like

yup, doesnt happen after I get rid of it. still no idea what happened but I guess i’ll just stay away from those :stuck_out_tongue:

1 Like