Function-based signals tightly bind nodes together?

Hello! I’m a software developer coming from real-time control systems development and trying gamedev for the first time. I’m trying to better understand good design patterns to use with signals, as I sense similarities with control-system dev, but I’m not used to game engine architectures.

I’m working through the Getting Started docs page on using signals, specifically the “Connecting a Signal in the Editor” section. I just connected the button node’s “pressed” signal to the sprite node, causing this code to appear in the sprite node’s script:

func _on_button_pressed() -> void:
	pass # Replace with function body.

Okay, so this is a function within the “sprite” node’s script that gets called any time a “button” node is pressed (and thus emits a “pressed” signal). This means the “sprite” node and the “button” node are, in a sense, bound to one another. If I change the “button” node’s name, I’d have to update this function name in every other node who listens to the “pressed” signal from the “button” node.

This feels like overly tight binding. I’d imagine a less tightly-bound design where “button” nodes broadcast their signals not directly to other nodes, but to some generic group (i.e. “pressed_events”) which interested listeners can subscribe to. Multiple types of nodes may send to this group, and changes to the senders wouldn’t break the listeners, since the existence of the group abstracts away the senders.

Anyway - all of this is very much thinking ahead - but I’d love to hear some broader design-level insight on the signals system and how best to utilize it. I’m also practicing making a forum post for the first time :slight_smile:

Thanks in advance!

Your assumption of having to change the name of the method is wrong.

the signal is connected to the method, independent of the method-name.
The name of the method is just a godot-suggestion, which you accepted in the window the pops open when you try to connect the signal

An alternative way (and better to understand) of connecting signals is the following:

@onready var button = $MyButton

func _ready():
    button.pressed.connect(_my_random_method)

func _my_random_method():
    print("Pressed!")

As you can see the name is not bound to the button. If you change the name of the button you have to change the path in the @onready-definition. If you think thats annoying you can use @export instead, this will automatically change the path when you change the name of the referenced node

The connection is specific to the button you connected ie not all buttons.

You can connect multiple buttons to a single function and you can connect a single button to multiple functions (iirc the latter cannot be done in editor, only by code).

1 Like