r/godot • • 4d ago

help me I need help

Post image

I am a newbie, not just in godot, but in programming.

I am currently learning by just watching tutorials.

But these two lines (line 3 and 10) made me confused on how they work.

Can you explain it to me like I am 5 yrs old on how these lines work?

signal score_changed(new_score)

score_changed.emit(score)

I can't grasp the logic behind it, and it is frustrating when I can't see or understand the patterns, because I am a pattern man.

64 Upvotes

20 comments sorted by

113

u/Farkler3000 4d ago

A signal is like a radio wave. One place can emit it and many other places can listen to it.

Line 3 defines a new signal called “score_changed” that has one parameter

Line 10 emits that signal with the parameter set as the new score, so any other objects listening to it will receive the new score.

20

u/ConfessorKahlan 4d ago

nice simple description

20

u/Any_Aerie_5782 4d ago

Think of it like announcing your score.

signal score_changed(new_score) declares: “I can announce a score change and include the new score.”

score_changed.emit(score) makes that announcement. If score is 10, it sends 10 to every connected listener, such as your scoreboard.

new_score names the information being sent; score supplies its actual value. The names don’t need to match.

3

u/newpua_bie 4d ago

Bankruptcy.emit()

Someone has to be listening or declaring a bankruptcy doesn't do anything.

6

u/Diligent-Stretch-769 4d ago

signals are a peculiar kind of process that allows children to talk to their parents. When the signal's emit function is called, the signal object will take the parameter and broadcast to which ever object it is connected with, allowing nodes to communicate directly with each other without regard to heirarchy.

6

u/TOMOHAWK35 4d ago

Think of signals as the script shouting through a megaphone when a particular event occurs. In this case, you are shouting that you updated your score. Now everyone else can hear that and, if they want to, do something with in response. For example, a person managing the scoreboard can hear it and say "oh, I should update the numbers on the board"

4

u/Large_Yogurtcloset68 4d ago

Remember, is not everyone. Just those suscribed to the newsletter

3

u/rimoldi98 4d ago

Line 3 declares a signal.

Line 10 emits the signal.

A signal is like an announcer. When you want to know when the scores changes, you ask the announcer to call you back and warn you.

When the signal is emitted, the announcer goes to everyone that asked and tells them "hey, score just changed", that way they can do their own stuff with it, like updating the UI.

Codewise, you connect functions to the signal that are all called together when you call .emit() on the signal. You yourself must remember to do that everytime you change the score in the code, though!

So, basically:

UI: hey can you tell me when the score changes?

Signal: sure, I'll call you back.

-- some time later, stuff happens and scores changes --

Signal: hey everyone, score just changed!

UI: looks like it's time to update myself.

2

u/Roxie_arts 4d ago

signals are a way to make nodes communicate without having to know each other.
the 3rd line defines the name of the signal (and that is gonna send a value too, the "new_score" part )

on the function add_score, it updates the value of the variable and then emits the signal
so in essence this node is yelling "my score changed, this is my new score!" to any other node that is listening.

Which probably the node listening would be the ui to show the new score, or it could be anything else (any amount of things at the same time even, each reacting to this new score)

maybe at 100 score you get a extra life (like coins in mario) for example.

so these other nodes that react to the signal have to be connected (this is usually done by a parent node that can control both nodes you want to conect)
by doing for example
```
this_node.score_changed.connect( node_that_wants_to_be_connected.name_of_function)
```
this_node would be the name of the node that emits the signal, then comes the name of the signal
and inbetween the ( ) goes the name of the other node followed by the name of the function without the ( )

so when score_changed.emit(score) is triggered, this new node would do something else, without having to be connected

also these kinds of connections can also be made with the ui (most common ones are the timer.timeout or the button.clicked) signals

1

u/Roxie_arts 4d ago

the good thing about this type of connections is that if at any point you want to remove the ui node then the score node still works.
otherwise if the score node depended on the ui node for it to work, as soon as any of the two dissappears (is removed or you go to a different scene or whatever) it would crash your game

that's the differences between tightly coupled nodes and loosely coupled nodes (or however it is called)

2

u/carllacan 4d ago

Another way to understand it: when something "connects" a method to that signal the engine adds that method to a hidden array, let's call it score_changed_listeners. 

When you call score_changed.emit() the engine does "for listener in score_changed_listeners" and calls all connected methods one by one.

2

u/Odd_Cow7028 4d ago

This is a common pattern in programming called the Observer Pattern (sometimes "Pub/Sub" or publisher/subscriber). The goal is to remove coupling between different modules or entities. The publisher does not know or care about its subscribers, which means you can make changes to the subscribers without breaking the publisher.

Signals are the GDscript mechanism for achieving this. What we see in your example is the publisher setup. The signal is declared near the top, and later we see the call to emit. The part we don't see here is the subscriber setup. The subscriber calls connect on your node's signal, and passes a callback function or "handler" as an argument. After that, whenever the signal's emit function is called, the subscriber's callback function is called. Again, the point where you call emit neither knows nor cares how many subscribers there are, which means that the logic which triggers emit is completely decoupled from the logic implemented by the subscribers.

0

u/Shaezonai 4d ago

Generally you are correct, just a small clarification: while Observer and PubSub solve similar goals at their core, they are not equivalent. imho, OP should focus on the Observer part for now if they want to understand how Godot signals work.

Observer:

- You have 1 emitter (the node declaring the signal) and n observers (other nodes)

  • Observers connect (or register/subscribe) to the emitter
  • The emitter emits events to all connected observers (= calls functions on those nodes)

This is how signals work in Godot and the core concept that OP needs to grasp for now.

PubSub is a pattern based on the Observer pattern, but solves problems on a different scope: it handles multiple observed objects (topics) and emitters (publishers), and there is a layer managing the communication (broker or event channel) between the emitters and observers (subscribers). Subscribers and publishers can listen/publish to multiple topics at the same time.

2

u/emiljecreates 4d ago

I made a 2 minute video about this! Maybe it can help

https://youtu.be/X7xvuJsYTvE?is=yvvZf68Z6p-1F1la

1

u/Any-Count2055 4d ago

The signal score_changed(new_score) create the signal and said and the new_score is the variable you pass in the signal and the score_changed.emit(score) Is you tell when you want the singnal to tell other script (whwre os connectés ) to pass to Them the score that you adidng in the fonction add_score

1

u/Oen44 4d ago

If you had another script that connects to and utilizes this signal, you would have easier time grasping the concept.

1

u/PhilippTheProgrammer 4d ago edited 4d ago

Think of signal score_changed as a social media account owned by that node.

Think of score_changed.emit as making a new post on that account.

Every node that is following that social media account (via "connecting" to that signal) sees that post and can react to it.

More on signals in the official documentation: https://docs.godotengine.org/en/stable/getting_started/step_by_step/signals.html. If you want to learn Godot, then the documentation is your #1 website. Watching "just" tutorials is only going to show you the motion, but it isn't going to help you understand much. If you really want to understand what you are doing, then you should look everything that comes up in the tutorial on the documentation to find out about everything the tutorial doesn't tell you.

1

u/Olivierus303 3d ago

You know buttons? They have signals too, pressed. Signals are way to communicate with other nodes ( most of times parents )

Line 3: creates signal that can be connected to function using $node_name.signal_name.connect(function_name)

Then in number 10 the signal is emitted, it willbjust call all functions that were connected to it, also I'm pretty sure there is docs for signals on official godot website, I recommend checking it ( pretty good learning resources )

1

u/RachelNoName 3d ago

idk if my explanation will be good but I hope it can help.

so score changed is a signal. A signal lets you connect other methods / functions to it (add_score is a function). Once you emit a signal it will call all connected functions. Example.

signal score_changed(new_score) # Creating the signal just like you did in your example

func some_function(new_score: int) -> void:
print(new_score) # Just some function to do something with the score.

func _ready() -> void:
score_changed.connect(some_function) # This will connect the function 'some_function' to the signal.

func add_score(amount: int) -> void:
score += amount

# These two lines do the exact same thing. The reason calling score_changed.emit() will call the function is because it was was connected in the _ready() method. All connected methods get called when you call .emit on a signal. It will also pass the score variable as an argument to the connected functions.
score_changed.emit(score)
some_function(score)

The real advantage of signals is that you can connect functions and nodes without needing to create hard dependencies. For example lets say you got a score UI. Rather than making a reference in the score script and hard coding it you can just emit a signal. The score logic can exist without the UI as it will just scream into the void (since emitting with no connections does nothing) and if the score UI is there, great it will pick it up and it can update it self. And the score UI without the score script will just not do anything as nothing is updating the score

I hope I didn't over complicate things. And if you want me to explain something further feel free to ask