@@baconandgames Also worth noting is you can't pass lamda's from within static methods, or rather you can but they lack object information or any reference to object they came from.
A lambda function is an anonymous function. If you give it a name, then it's no longer a lambda. It could be a closure, if it carries the surrounding state with it. Otherwise, it's just a regular function.
@@skaruts Okay got it, so any lamda is by also anonymous, naming them makes it a function even if the rest of syntax is similar. So: var foo = func bar(x): return 0 Is a regular function, while without bar would be an anonymous function or a lamda or anonymous lamda.
Man, you are a great teacher. This video helped me synthesize some concepts that were sort of floating around in my head but not fitting together quite yet. Thanks for the education as always.
it's good to see some of the lesser known things explained in tutorials. good on ya. In my game I have a SignalManager class, which is my implementation of EventBus pattern but for C#. For anyone making a C# Godot game, using a static ref of your signal class allows you to call signals from Interfaces or anything else that doesn't include Godot.
In my game I have a "Team Select" and I have a lot of different teams. I had gone through and connected all the signals through the interface and it made the code very long. I used your button binding method using a reference to a button container and a loop and it cleaned up my code so much. Thank You! Just had a thought that the way I did it would make a quick and simple level selector that would only take a few lines of code using your scene manager!
One thing I would love to see more videos on is how to make the communication between popups and the relevant parts of the application. I've built a couple apps for my own personal usage in Godot, and I did come up with something, but it seems hacky. My popups don't change the data immediately either. They take in a dictionary with the settings through a custom function to "popup" the popup, and when you click ok they poop out the dictionary through a signal (or null if you cancelled, iirc). The code that calls the popup "awaits" for that signal and then checks the dictionary for changes. I wonder what other ways there are to do this kind of stuff though. It took me a while to wrap my head around how to work with popups.
Could you not simply pass the real dictionary object to the node/scene that implements the popup? Then the popup can change values directly, and you can use signals additionally when other nodes have to be notified to update. Alternatively, if you want a Cancel/Apply/OK-like system where you have to specifically click a button to save the modified settings, you could store both the real dictionary object and a copy of it (dict.duplicate()), then when Apply/OK is clicked you could go key-by-key and copy data from the duplicate dictionary to the real dictionary. You should also consider using resources instead of dictionaries. You can create a script that `extends Resource`, and that resource can have @export fields which you can both edit through the Godot editor and also save/serialize just like any other object in Godot.
Oh gotcha. I think I cover how I made that in my SceneManager video (the first one with the red knife in the thumb, not the yellow one). It’s not exhaustive and it’s certainly not the ONLY way to do it… there are many, but that might be a start for you. It really depends on how/when/how often you need to access something like this that determines how “complicated” or maybe robust/extensible your implementation needs to be. The example in my SceneManager is probably the bare minimum.
The method track and await tricks are really nice, when I discovered that I can track methods it made so many things easier, absolutely one of my favourite features when working in Godot. The lambda part was new to me, maybe because I was a bit scared to mess with them in the past, but for the example use case here I think it's gonna be worth a shot in my projects too.
I appreciate that 🥹 though there are some great godot tutorial makes on YT. Are there any specific topics you’re after? I might be able recommend a channel or two.
Well I’m making as a serious hobby a relatively classic point&click game with godot in my spare time after my day job and I’m still relatively uncertain how I’m going to implement the dialog system. All the best from Finland!
@speggeri90 you might want to check out Dialogic (there’s a second one in the works that’s in alpha so you probably don’t want to mess with that). I don’t think it’ll solve the UI portion of your dialog windows (though maybe) but if you have a lot of talking in your game it might save you a ton of time.
Holy cow that last tip of awaiting animation player is exactly what I was looking for weeks ago, I've even used the await ...timeout syntax before - thank you for connecting those dots
I never thought of the bind thing - that's neat. Something that trips me up is the Event/Signal Bus. Ultimately, knowing when to use one. I've heard counter-arguments to the pattern such as: "Personally, I would avoid using an event bus. It just circumvents the hierarchical tree structure that is purposefully built to control the flow of data. Parents have children, and can call their methods. Children are unaware of their parents, so they emit signals to communicate back up the tree. When you sidestep that, you end up with spaghetti code that is hard to maintain and reason about. Suddenly things “just happen” implicitly, and it becomes a nightmare to troubleshoot."
Here's my personal opinion, which you may take or leave :) Most things in life are OK in moderation. So I would NEVER tell someone to use only the Event bus patterns nor would I tell then to NEVER use it at all. But whether it's "OK to use" generally comes down to a few things: 1. Scope of the project 2. Whether you're working with a team 3. Whether you intend to reuse the code from this project 4. Other constraints like time or budget 5. What the purpose of a project is (which might just be to learn and grow as a developer so you can make more informed decisions in future projects) I could go on. But the thing is, there is no universal answer to this debate. The choices you would make when creating a tiny clicker game by yourself would probably not be the same choices you'd make if designing an MMO with a team of 50 people. And I'm not trying to be hyperbolic, but if you look to the extremes you'll find reasons to use or not use just about any approach. Paying someone by writing a check seems fine when you pay them once a month... but if you're writing checks by hand daily or more... you'll probably start wondering about digital auto-pay solutions. So to bring it back around... if you're putting every damn signal on an event bus, yes you're overdoing it. There's no reason to not have a parent listening for signals from its child. That's what they're made for and I do that all the time (as you saw in the video through the hero power ups example) But for a few, game-wide stuff I don't see any problem with it. Anyone who tells you otherwise is getting into a purist debate about what's "the right way" the same may some developers will die on the hill of "the MVC model is the only way to organize your project". It's not, there are many ways. The truth is, programming and game design are arts, not sciences. Pretty much every option should be at your disposal and only by considering YOUR specific use case and trying different patterns out for yourself will you find what's best for you and your project. And you can only gain that knowledge by trying out different combinations of techniques out there and deciding for yourself what's ok and what's not... which again, depending on the application, might be OK for some games and less OK for others. The best thing you can do is to focus on understanding the tradeoffs you have to accept when choosing any approach. Less important is finding the universal answer to whether or not something is OK, or correct, or best. If you understand what you gain or lose with any choice, you will make the right decision more often than not (and when you don't, you'll carry that knowledge forward into your next project). Focus on what you give up or gain when you make a choice rather than a universal right or wrong way to do something. This debate will never go away, bit's an important thing to talk about and ponder. The fact that you're curious about it is a good sign ❤️
@3db- The example in the video is a decent one, globally a listening for a setting change that affects the whole game. I often have at least one Autoload to make it easy to access some static classes or things like a save file, so I don’t use this pattern a TON but for some game-wide stuff I find it helpful without much or any drawback.
Thank you, I love these tutorials. I'm often worried that someone is showing me a sloppy way to get a specific result instead of a clean way to apply a flexible concept. Never the case here! I'd be interested to see how you'd set up the effects manager you referenced; that's the kind of thing I always feel like I'm doing incorrectly.
@@baconandgames She's a budding 21 yr old these days. She was around 4 in that pic. Time flies when we're having fun developing and raising kiddos. Hope all is well with you and your family and look forward to more content from you in the future sir!
@KevinIndreland holy cow. That photo is a teenager! Thank you, my friend. Doing well enough. I’m enjoying making the content. Thank you for watching and saying hello. Best to you and yours!
It's funny because I felt most of them were new to me but then I get to Await and there's not a single script I don't use it. It feels like such a key component to ensuring polish in games (i.e. await after a tween call to ensure animations are allowed to execute gracefully)
The longer I operate this channel the more I realize how diverse our skills and modes of thinking are. Half the time I think I'm sharing something nobody knows and many do and the other half the time I think I might be sharing something too basic and then I get flooded with thank-you's. So I tend to focus not on what I think people don't know and more on what I find useful. I'm glad you got something out of this - and thanks for the message! It's always neat hearing which parts of a video land for whom.
Handy, indeed! I found a use for await timer a day after watching this. (giving bullets a lifetime so they don't escape the world geometry and live in memory forever)
That could certainly work, though it might be safe to just check their position and free them if they go “out of bounds” You probably don’t want to halt code execution waiting for that signal.
Hello, thank you for the informative video. I have one question to ask, if you don't mind. How to distinguish cases when bubling up signals is ok and when event bus should be used? At which node such decision should be made? E.G. shot from a gun ideally should emit signal locally - to play player anims, effects,etc. - as well emit event bus signal - to alert montsers or enemies .
It's more of an art than a science, but it often comes down to how many things need to know about a certain action and where they are in the game (ie how hard it will be to drill you want into a signal to connect to it) So I tend to use event bus for big, game-level stuff like changing the music volume, pausing the game, or writing data. But for more local stuff, like a child node reporting to a parent node, tends to be managed without a bus. Does that help?
@@baconandgames hello and thank you. I'm gathering a list of "rule of thumb" for godot - switched from unity3d some time ago but still trying to get used to it. And static or global signals is one of those things. I use classes inherited from resource classes this way don't have to hardcode name autoload in code and it's just a matter of dropping instance of event-bus resource from project assets. The issue with both approaches - autoload, resource - is that both emitter and receiver need to know about difference between local and global signals. Anyway, thank you for your answer.
I'd be careful with using await in game entity logic, however a good application I think are things like scripted sequences where anything other than the sequence is halted
Yeah. You saw the face I made at the beginning of the segment 🤣 I use it sparingly and only in places where I know the wait will always be very brief and VERY unlikely to fail. But since it falls under “lesser known signal stuff” I wanted to mention it. Perhaps I should have made my disclaimer for that segment stronger 😜
My hot take on this is that I agree that await is generally something you want to avoid in most cases. However, awaiting signals, animations and etc is super important. I get into some of this in a couple of my videos and demo projects. await is a game changer.
@@graydwarf22 listening for signals is important, not necessarily using the await keyword. pretty much all cases where one may use `await my_signal` can be solved in a cleaner way with a signal connection. await causes coroutines to be kicked off (functions being kept alive across several ticks asynchronously) and if not being fully aware of that, this can easily become a source of unexpected behavior and bugs. still, fully agree that await occasionally comes in handy :)
Why not connect to the functions directly? Why use the handle_menu_press.bind() instead? It works without it. I fail to see the advantage of this intermediary function. Apologies if you explained why and I missed it.
Both are valid approaches. I like this method because connecting stuff through the interface hides logic in sub-menus, your signals will break if you rename your code, I don’t like having to create a new signal every time I add a button, and it’s easier to collapse one signal to hide code than having to collapse one for each button (plus when you collapse it into one like rather than the number of signals you have). This is not really the primary use case for bind, but it was staring me in the face when making the video so it’s the one I used. No worries. Fair question. As I say in the video, it’s hardly a game changer. Mostly about preference. Many people prefer lots of clicking and property setting in the inspector. I prefer to do as much through code as I can so I don’t have to hunt through menus to see my intent.
It’s a best practice to disconnect signals when you know you no longer need them however I’m told the reference counting in godot does a pretty good job of figuring out what can be freed for you. I usually create a method that disconnects all my signals before I destroy an object. It’s also a good practice to check that a signal is not connected before connecting and that it is before attempting to disconnect, to avoid errors. You’re generally safe to skip this in onready as it’s JUST being created but I still tend to do it. I didn’t cover those in this video due to wanting to keep it short and different from other “this is the basics of signals” tutorials. Great question! 👏
Didn't know about bind() so that's cool. I might pass an enum in that situation. Enums.ButtonTypes.Start, handle_menu_press(buttonType : Enums.ButtonType), match buttonType:, ... Enums.ButtonType.Start
I had actually started with an enum but it was just extra code to show on screen. I couldn’t come up with a good enough reason not to just pass the button itself in this particular scenario
I believe your lamda's are anonymous lamda's you can do the same thing with a name and well it would be a lamda no?
@@baconandgames Also worth noting is you can't pass lamda's from within static methods, or rather you can but they lack object information or any reference to object they came from.
@dibaterman I never thought about that but it makes sense that you can’t. Great tip 👏
A lambda function is an anonymous function. If you give it a name, then it's no longer a lambda. It could be a closure, if it carries the surrounding state with it. Otherwise, it's just a regular function.
@skaruts oh good, then I didn’t mess that up 😅 I tend to second guess myself too quickly.
@@skaruts
Okay got it, so any lamda is by also anonymous, naming them makes it a function even if the rest of syntax is similar.
So:
var foo = func bar(x): return 0
Is a regular function, while without bar would be an anonymous function or a lamda or anonymous lamda.
Man, you are a great teacher. This video helped me synthesize some concepts that were sort of floating around in my head but not fitting together quite yet. Thanks for the education as always.
Nick, you flatter me. Thank you so much. 🙏
it's good to see some of the lesser known things explained in tutorials. good on ya. In my game I have a SignalManager class, which is my implementation of EventBus pattern but for C#. For anyone making a C# Godot game, using a static ref of your signal class allows you to call signals from Interfaces or anything else that doesn't include Godot.
👏👏👏
Oh how I miss interfaces… I might find my way back to C# one day just over those alone.
This is genuinely amazing!! I hated signals but man this just made so much sense, especially with bind!
❤️
In my game I have a "Team Select" and I have a lot of different teams. I had gone through and connected all the signals through the interface and it made the code very long. I used your button binding method using a reference to a button container and a loop and it cleaned up my code so much. Thank You!
Just had a thought that the way I did it would make a quick and simple level selector that would only take a few lines of code using your scene manager!
I'm glad that helped you! Good point about the level selector too. I like that!
One thing I would love to see more videos on is how to make the communication between popups and the relevant parts of the application. I've built a couple apps for my own personal usage in Godot, and I did come up with something, but it seems hacky. My popups don't change the data immediately either. They take in a dictionary with the settings through a custom function to "popup" the popup, and when you click ok they poop out the dictionary through a signal (or null if you cancelled, iirc). The code that calls the popup "awaits" for that signal and then checks the dictionary for changes.
I wonder what other ways there are to do this kind of stuff though. It took me a while to wrap my head around how to work with popups.
When you say pop up, are you talking about an “are you sure want to quit” kind of dialog with an ok/cancel set of buttons? That’s sort of thing?
@@baconandgames more like the one you had there with the game settings. That sort of thing.
Could you not simply pass the real dictionary object to the node/scene that implements the popup? Then the popup can change values directly, and you can use signals additionally when other nodes have to be notified to update. Alternatively, if you want a Cancel/Apply/OK-like system where you have to specifically click a button to save the modified settings, you could store both the real dictionary object and a copy of it (dict.duplicate()), then when Apply/OK is clicked you could go key-by-key and copy data from the duplicate dictionary to the real dictionary.
You should also consider using resources instead of dictionaries. You can create a script that `extends Resource`, and that resource can have @export fields which you can both edit through the Godot editor and also save/serialize just like any other object in Godot.
@freenull I second the Resources implementation +
Oh gotcha. I think I cover how I made that in my SceneManager video (the first one with the red knife in the thumb, not the yellow one). It’s not exhaustive and it’s certainly not the ONLY way to do it… there are many, but that might be a start for you. It really depends on how/when/how often you need to access something like this that determines how “complicated” or maybe robust/extensible your implementation needs to be. The example in my SceneManager is probably the bare minimum.
lots of great tips/reminders! the method track is such a handy feature
That’s a sleeper feature for sure 😜
The method track and await tricks are really nice, when I discovered that I can track methods it made so many things easier, absolutely one of my favourite features when working in Godot. The lambda part was new to me, maybe because I was a bit scared to mess with them in the past, but for the example use case here I think it's gonna be worth a shot in my projects too.
That’s wonderful 🙏 It’s my hope people find at least one useful nugget in this little vids. If I can do that much for people, it’s all worth it. ❤️
Another great tutorial! There are very few advanced godot tutorial makers out there, so your channel is a gold piece in amongst the dirt.
I appreciate that 🥹 though there are some great godot tutorial makes on YT. Are there any specific topics you’re after? I might be able recommend a channel or two.
Well I’m making as a serious hobby a relatively classic point&click game with godot in my spare time after my day job and I’m still relatively uncertain how I’m going to implement the dialog system. All the best from Finland!
@speggeri90 you might want to check out Dialogic (there’s a second one in the works that’s in alpha so you probably don’t want to mess with that). I don’t think it’ll solve the UI portion of your dialog windows (though maybe) but if you have a lot of talking in your game it might save you a ton of time.
@@baconandgamesI’ll definately check it out. :)
There is also Dialogue Manager addon, but it's more focused on the script part. I'd have a hard time choosing between the two
Holy cow that last tip of awaiting animation player is exactly what I was looking for weeks ago, I've even used the await ...timeout syntax before - thank you for connecting those dots
You’re welcome! ☺️
Great video, some excelent ideas, some is too advanced for me, but definitely will come back for future references
I never thought of the bind thing - that's neat.
Something that trips me up is the Event/Signal Bus. Ultimately, knowing when to use one. I've heard counter-arguments to the pattern such as:
"Personally, I would avoid using an event bus. It just circumvents the hierarchical tree structure that is purposefully built to control the flow of data. Parents have children, and can call their methods. Children are unaware of their parents, so they emit signals to communicate back up the tree. When you sidestep that, you end up with spaghetti code that is hard to maintain and reason about. Suddenly things “just happen” implicitly, and it becomes a nightmare to troubleshoot."
Here's my personal opinion, which you may take or leave :) Most things in life are OK in moderation. So I would NEVER tell someone to use only the Event bus patterns nor would I tell then to NEVER use it at all. But whether it's "OK to use" generally comes down to a few things:
1. Scope of the project
2. Whether you're working with a team
3. Whether you intend to reuse the code from this project
4. Other constraints like time or budget
5. What the purpose of a project is (which might just be to learn and grow as a developer so you can make more informed decisions in future projects)
I could go on. But the thing is, there is no universal answer to this debate. The choices you would make when creating a tiny clicker game by yourself would probably not be the same choices you'd make if designing an MMO with a team of 50 people. And I'm not trying to be hyperbolic, but if you look to the extremes you'll find reasons to use or not use just about any approach. Paying someone by writing a check seems fine when you pay them once a month... but if you're writing checks by hand daily or more... you'll probably start wondering about digital auto-pay solutions. So to bring it back around... if you're putting every damn signal on an event bus, yes you're overdoing it. There's no reason to not have a parent listening for signals from its child. That's what they're made for and I do that all the time (as you saw in the video through the hero power ups example) But for a few, game-wide stuff I don't see any problem with it. Anyone who tells you otherwise is getting into a purist debate about what's "the right way" the same may some developers will die on the hill of "the MVC model is the only way to organize your project". It's not, there are many ways. The truth is, programming and game design are arts, not sciences. Pretty much every option should be at your disposal and only by considering YOUR specific use case and trying different patterns out for yourself will you find what's best for you and your project. And you can only gain that knowledge by trying out different combinations of techniques out there and deciding for yourself what's ok and what's not... which again, depending on the application, might be OK for some games and less OK for others.
The best thing you can do is to focus on understanding the tradeoffs you have to accept when choosing any approach. Less important is finding the universal answer to whether or not something is OK, or correct, or best. If you understand what you gain or lose with any choice, you will make the right decision more often than not (and when you don't, you'll carry that knowledge forward into your next project).
Focus on what you give up or gain when you make a choice rather than a universal right or wrong way to do something. This debate will never go away, bit's an important thing to talk about and ponder. The fact that you're curious about it is a good sign ❤️
@@baconandgames Great response, thank you! Curious what would be examples of times you'd use an Event/Signal bus.
@3db- The example in the video is a decent one, globally a listening for a setting change that affects the whole game. I often have at least one Autoload to make it easy to access some static classes or things like a save file, so I don’t use this pattern a TON but for some game-wide stuff I find it helpful without much or any drawback.
Thank you, I love these tutorials. I'm often worried that someone is showing me a sloppy way to get a specific result instead of a clean way to apply a flexible concept. Never the case here! I'd be interested to see how you'd set up the effects manager you referenced; that's the kind of thing I always feel like I'm doing incorrectly.
That’s very kind of you. Thank you!
Quickest subscribe of my life! Great content. Your attitude inspires me to try new things :)
What a lovely thing to have pop up on my phone. Thank you so much, for all of that 🙏
loving these wee vids. nice work
Thank you 🙏
Amazing explanation, thanks a lot!
Aww, thank you!
I learned more in 5 minutes about Godot than in 10 hours of tutorials.
always a pleasure to watch and learn your videos!
Thank you so much, that’s very kind of you to say! I see a little one in your photo. Are they a budding gamer/developer? 😀
@@baconandgames She's a budding 21 yr old these days. She was around 4 in that pic. Time flies when we're having fun developing and raising kiddos. Hope all is well with you and your family and look forward to more content from you in the future sir!
@KevinIndreland holy cow. That photo is a teenager! Thank you, my friend. Doing well enough. I’m enjoying making the content. Thank you for watching and saying hello. Best to you and yours!
It's funny because I felt most of them were new to me but then I get to Await and there's not a single script I don't use it. It feels like such a key component to ensuring polish in games (i.e. await after a tween call to ensure animations are allowed to execute gracefully)
The longer I operate this channel the more I realize how diverse our skills and modes of thinking are. Half the time I think I'm sharing something nobody knows and many do and the other half the time I think I might be sharing something too basic and then I get flooded with thank-you's. So I tend to focus not on what I think people don't know and more on what I find useful. I'm glad you got something out of this - and thanks for the message! It's always neat hearing which parts of a video land for whom.
global signals are a lifechanger ngl, never occured to me to use an autoload like that
Handy, indeed! I found a use for await timer a day after watching this. (giving bullets a lifetime so they don't escape the world geometry and live in memory forever)
That could certainly work, though it might be safe to just check their position and free them if they go “out of bounds” You probably don’t want to halt code execution waiting for that signal.
great vid, do more
Thank you very much! I will do more 😀
Hello, thank you for the informative video. I have one question to ask, if you don't mind. How to distinguish cases when bubling up signals is ok and when event bus should be used? At which node such decision should be made? E.G. shot from a gun ideally should emit signal locally - to play player anims, effects,etc. - as well emit event bus signal - to alert montsers or enemies .
It's more of an art than a science, but it often comes down to how many things need to know about a certain action and where they are in the game (ie how hard it will be to drill you want into a signal to connect to it)
So I tend to use event bus for big, game-level stuff like changing the music volume, pausing the game, or writing data. But for more local stuff, like a child node reporting to a parent node, tends to be managed without a bus. Does that help?
@@baconandgames hello and thank you. I'm gathering a list of "rule of thumb" for godot - switched from unity3d some time ago but still trying to get used to it. And static or global signals is one of those things. I use classes inherited from resource classes this way don't have to hardcode name autoload in code and it's just a matter of dropping instance of event-bus resource from project assets. The issue with both approaches - autoload, resource - is that both emitter and receiver need to know about difference between local and global signals. Anyway, thank you for your answer.
I'd be careful with using await in game entity logic, however a good application I think are things like scripted sequences where anything other than the sequence is halted
Yeah. You saw the face I made at the beginning of the segment 🤣 I use it sparingly and only in places where I know the wait will always be very brief and VERY unlikely to fail. But since it falls under “lesser known signal stuff” I wanted to mention it. Perhaps I should have made my disclaimer for that segment stronger 😜
My hot take on this is that I agree that await is generally something you want to avoid in most cases. However, awaiting signals, animations and etc is super important. I get into some of this in a couple of my videos and demo projects. await is a game changer.
@@graydwarf22 listening for signals is important, not necessarily using the await keyword. pretty much all cases where one may use `await my_signal` can be solved in a cleaner way with a signal connection. await causes coroutines to be kicked off (functions being kept alive across several ticks asynchronously) and if not being fully aware of that, this can easily become a source of unexpected behavior and bugs.
still, fully agree that await occasionally comes in handy :)
Why not connect to the functions directly? Why use the handle_menu_press.bind() instead? It works without it.
I fail to see the advantage of this intermediary function. Apologies if you explained why and I missed it.
Both are valid approaches. I like this method because connecting stuff through the interface hides logic in sub-menus, your signals will break if you rename your code, I don’t like having to create a new signal every time I add a button, and it’s easier to collapse one signal to hide code than having to collapse one for each button (plus when you collapse it into one like rather than the number of signals you have). This is not really the primary use case for bind, but it was staring me in the face when making the video so it’s the one I used. No worries. Fair question. As I say in the video, it’s hardly a game changer. Mostly about preference. Many people prefer lots of clicking and property setting in the inspector. I prefer to do as much through code as I can so I don’t have to hunt through menus to see my intent.
When you connect a signal, is there no need to disconnect it manually?
It’s a best practice to disconnect signals when you know you no longer need them however I’m told the reference counting in godot does a pretty good job of figuring out what can be freed for you. I usually create a method that disconnects all my signals before I destroy an object. It’s also a good practice to check that a signal is not connected before connecting and that it is before attempting to disconnect, to avoid errors. You’re generally safe to skip this in onready as it’s JUST being created but I still tend to do it. I didn’t cover those in this video due to wanting to keep it short and different from other “this is the basics of signals” tutorials. Great question! 👏
Didn't know about bind() so that's cool. I might pass an enum in that situation. Enums.ButtonTypes.Start, handle_menu_press(buttonType : Enums.ButtonType), match buttonType:, ... Enums.ButtonType.Start
I had actually started with an enum but it was just extra code to show on screen. I couldn’t come up with a good enough reason not to just pass the button itself in this particular scenario
Something I do is bind a buttons text (I have dynamically loaded and named buttons in my ui) so I can see what the user pressed.
@iamsecrets oh nice, there you go! 👍
I like my signals to be very verbose, so I always do things like:
some_button.pressed.connect(on_some_button_pressed)
func on_some_button_pressed:
Very readable. I dig that. 🫡