One child class does not see inherited signals, while other children classes work fine

Godot Version

4.6

Question

I ran into an issue while working with some custom classes. Here is the code for PlayerDetectingArea, a class i wrote for keeping track of players inside of an Area2D:

extends Area2D

class_name PlayerDetectingArea

signal player_entered(plr: PlayerController)
signal player_exited(plr: PlayerController)

@export var stack = []

@rpc("any_peer", "call_local", "reliable")
func append_to_stack(obj):
	stack.append(obj)

@rpc("any_peer", "call_local", "reliable")
func remove_from_stack(obj):
	stack.remove_at(stack.find(obj))

func _on_body_entered(body: Node2D):
	if !multiplayer.is_server(): return
	if not body is PlayerController: return
	if body in stack: return
	
	append_to_stack.rpc(body)
	General.emit_signal_to_all_peers(player_entered, [body])
	

func _on_body_exited(body: Node2D):
	if !multiplayer.is_server(): return
	if not body is PlayerController: return
	if not body in stack: return
	
	remove_from_stack.rpc(body)
	General.emit_signal_to_all_peers(player_exited, [body])

func _ready():
	if !multiplayer.is_server(): return
	
	body_entered.connect(_on_body_entered)
	body_exited.connect(_on_body_exited)
	
	for body in get_overlapping_bodies():
		_on_body_entered(body)


basically, it keeps track of players inside it in the stack variable and fires custom signals, player_entered and player_exited when a player joins or leaves the stack.

Now, i have a class that inherits from this:

extends PlayerDetectingArea

class_name StealthArea

func _ready():
	
	super._ready()
	
	if !multiplayer.is_server(): return
	
	player_entered.connect(_on_plr_entered)
	player_exited.connect(_on_plr_exited)
	
	for plr in stack:
		_on_plr_entered(plr)

func _on_plr_entered(plr: PlayerController):
	if !multiplayer.is_server(): return
	
	plr.change_stealth.rpc(true)

func _on_plr_exited(plr: PlayerController):
	if !multiplayer.is_server(): return
	
	plr.change_stealth.rpc(false)

the problem i have is that with this class specifically, when i instantiate a stealth area, the events player_entered and player_exited never fire. I’ve already checked that the stealth area’s CollisionShape2D is not disabled and monitoring and all that jazz, and also other scripts that inherit from PlayerDetectingArea work just fine. I’m really confused as to why these events won’t fire

Just for clarity’s sake, here’s the stealth area’s scene tree:

immagine

and this is what it looks like in the editor:

how does this function work? Sounds like it’s only called on the server and only emits to other clients; meanwhile you only connect to player_entered on the server, which may not receive such events if I’m correct about this function.

here is the function, sorry i should have posted this right away:


@rpc("any_peer", "call_local", "reliable")
func emit_signal_to_all_peers(my_signal: Signal, args = []):
	#print("Called remote signal", my_signal.get_name(), " to ", multiplayer.get_unique_id())
	var signal_owner = my_signal.get_object()
	var signal_name = my_signal.get_name()
	
	var thing = [signal_name] + args
	signal_owner.callv("emit_signal", thing)
	#apparently this already replicates the call on the peer who invoked the function
	#maybe due to "call_local"? i dont understand this yet but it might be it

i also realized now that in PlayerDetectingArea i was supposed to call this function with .rpc at the end and i didnt, so i corrected it now but it still doesn’t work.

For reference, here is also another script that works just fine and inherits from PlayerDetectingArea:

extends PlayerDetectingArea

@export var bound_plr: int
const SLOWDOWN = -100
var unique_id = "yarn"

func _ready():
	super._ready()
	unique_id = unique_id + str(int(floor(Time.get_unix_time_from_system()))%99999)
	modulate = Lobby.team_colors[Lobby.player_teams[bound_plr]]

func _on_player_entered(plr: PlayerController) -> void:
	if !multiplayer.is_server(): return
	
	var modif = SpeedModif.new(unique_id, SLOWDOWN)
	plr.apply_unique_speed_modif.rpc(modif)


func _on_player_exited(plr: PlayerController) -> void:
	if !multiplayer.is_server(): return
	
	plr.remove_speed_modif_by_id.rpc(unique_id)


i dont believe the details are very important, it calls some function on the player that changes how its moving speed is calculated, and i can confirm it works

also one more thing, the signals in this case are connected from the inspector tab

This is not the first time this has happened, but the logic was all correct. I fixed it by deleting the StealthArea and re-instancing it. I have no idea what caused this