Emitting custom Signals with Parameters throws Method Argument Count Error.

Godot Version

4.1.2

Question

I am utilizing a version of the mediator pattern using Godot’s built in signals. I have a main parent Node with children that act as components for physics, rendering, etc. The structure of my Scenetree is to practice some design patterns in Godot and GDScript.

Whenever a component needs to communicate data with another component, it does so by speaking with the parent “Game” Node. The Game node then sends out the data to all of its components. The component that is meant to use that data then observes it and processes it.

All of these nodes inherit from a generic component class that has includes a basic send signal and a _receive() function. Both list the same number of parameters in the same order, and all inheriting classes of that class have nearly the same pattern. The singular difference are the names of the arguments in the header of the original class and the inheriting class, something I did to make it easier to connect things properly. None of the parameters in any signal or function is typed, so that can’t be the issue.

The send signal of a component is connected to another node’s _receive() function. In every connection, I did it via the interface instead of code. Because it is a custom receiving function for a signal, I use the “Pick” option in the editor. The _receive() function appears in the list of options that are viable according to the editor. I haven’t experimented with connecting the signals in code since the editor’s interface should accomplish the same thing.

I require the use of parameters/arguments in this for: 1. the data contents that are being communicated, 2. a String purpose which components can choose themselves what they do based on it.

Unfortunately, whenever I emit the send signal from any component, usually like so:

send.emit(“set_input_vector”, input_vector)

it results in the same kind of error:

component.gd:154 @ method(): Error calling from signal ‘send’ to callable: ‘Node(game.gd)::_receive’: Method expected 0 arguments, but called with 2.

I am passing one or more parameters, but the receiving method expects zero arguments, regardless of what node is sending and what node is receiving. In all nodes, the receiving method has defined arguments in its header, so I am confused. Is this a bug or am I missing something?

Does the “_recieve”-method in game.gd have arguments?

Yes. It has the same number of arguments in the same order they are sent in a send signal.

HI,

Have you added the arguments to the Signal definition? And I assume you’re connecting to it where needed as well

For Example:

signal my_signal(property: String, value: int)

Kindly

Ryn

Yes, both the send signal and the _receive method that the signal connects to have arguments/parameters in their defintion/header. None of these arguments are typed in either the signal or the receiver method as in your example, Ryn.

Thanks,

Can you post the code of the signal declaration, the code where you are emitting it, the code where you connect to it and finally the method you are calling from the connect routine.

Kindly

Ryn

This is the script for the basic component. It extends Base Object which just contains methods used to update input, physics, and rendering each frame.

The declaration of the send signal:

class_name Component
extends BaseObject
signal send(purpose, param1, param2)
func _receive(_purpose, _param1, _param2):
[indent] pass

The control (input), physics, and renderer components are scripts that extend the basic component. This means they automatically have the send signal as declared in the basic component script. The param1 and param2 arguments are loosely typed so I can pass Ints, Vector2s, and Arrays.

Each specialized component has its own local version of the _receive function, which receives the send signal when it is emitted by a node that connects its signal to the receiving node. This connection is not declared in any script at the moment. The connection is done via the engine interface. So, I don’t have any code to show for that. I describe how I connect it via the interface in more detail in my original post.

The declaration of the unique _receive method which another node’s send signal connects to:

func _receive(_purpose, _paramX, _paramY):
[indent] match _purpose:

In the original _receive method of the basic component script, the names of the two data parameters are _param1 and _param2. But in all of the components that extend from the basic component, the _receive method’s data parameters are defined as _paramX and _paramY. The reasons for this are: 1. That it makes more sense for the physics and rendering components. And 2. It makes it easier to distinguish which _receive method I’m connecting to in the interface, since the basic component script has one as does the inheriting component.

The current signal connections are that the control, physics, and renderer component connect their send signal to their shared parent’s, "Game"s, receive method. All of these child component nodes have the singular connection to the parent. The Game node has its send signal connected to multiple of its children.

I cannot say if there are any bugs in any of the other processes of my codebase because this message system is throwing too many bugs on its own for me to observe my work’s functionality.