I'm very impressed with this asset. I've made various different state machines (and even a state tree) from scratch in Godot and Unity, but would totally use this one instead for anything I would ever need states for. I'd love to see more videos covering more advanced use cases (even if just an overview rather than a step-by-step tutorial).
I am not a big fan of adding 3rd party addons for things I can do myself, but damn this one looks tidy and organized, like a better version of state machine.
I think the icons and all make it pretty professional. I'm just wondering. If you write all your code in signal called methods, wouldn't this get super jarring, quickly? Like for a larger (say like a Fighting Game or Metroidvania, etc.) Player Character, I could imagine this to be a script filled with 100+ of these signal methods in the end. @@TheLastPhoen1x
@@hiiambarney4489 If that's the case, then you should probably split that logic into its own script and node and connect the signals from the state machine to that new node
@@hiiambarney4489 like what romanperry mentioned, you can split the script into nodes like the usual FSM. the tool really just comes down to making the initial setup quicker and having that parallel state is a massive plus compared to an fsm
When I think of state machines, I either imagine a chart or code, but here they're represented in nodes which looks like the native Godot way of doing everything 😅 I love the debugger! It really tells you all you need, and so easy to add.
I noticed this in the assetlib tab a while ago but didn't get a chance to read through the documentation. This video is VERY helpful. Thanks for taking the time to create it. It makes me want to use your addon for my game. More videos would be very welcome. You did a really comprehensive job at creating this asset.
@@godotneers I think a guide on the behavior tree addon Beehave would be useful, there are very little guides on it and none for the current version, the documentation is not very good with basically no examples.
@@godotneersI wouldn't mind understanding the differences between a state chart and a behavior tree? When I saw the Parallel node, that was the first thing I thought of. Also, some more examples outlining each different node type in the state chart would be beneficial I think. And, of course, more examples of implementing a state chart is always helpful. Your presentation style is very clear and I think it saves people a lot of guessing.
@@Asguardian22 behaviour trees and state machines/state charts have some overlap in that they are concepts for running a process in a stateful manner. The execution method is different though. Behaviour trees have a concept of "success", e.g. they run actions and these can succeed or fail. Then the nodes react to the success by switching to other parts of the behaviour tree. On the other hand a state chart has no such concept of "success". It just reacts to whatever events it receives and switches states according to the events and the configured transitions. In a behaviour tree the node type is some hard-coded behaviour, e.g. a parallel node in a behaviour tree will run all its children for as long as they are successful, a sequential node will always run its children in sequence, etc. In a state chart the behaviour is more fluidly defined by the transitions and the events that come from outside of the state chart. In the end both are tools in the arsenal and you can probably model a wide range of problems in either one of them, so one isn't necessarily better than the other. As for additional tips, I'm going to make a few more videos on the state charts library, one of them will be a deep dive on how the controller in the platformer was made and why it was modeled the way it is. Making these videos takes a good while though, so it will probably not come up tomorrow ;).
Really cool plugin. Love the parallel states concept and will be trying this out in my projects. Also the tutorial is really well explained and makes it easy to understand. Thanks for the guide.
Thank you for making this! I am currently using Godot State Charts to make a neolithic village simulator game. It makes adding/controlling behaviors a lot easier and modular.
I am making a metroidvania and my character controller is a mess, I have a lot of verifications to see if I can move the player, like if is not getting attacked, if it is alive, if is not dashing, etc. Your videos are making the process x100 faster and easier, thank you a lot!
Amazing plugin! One thing though, at 20:11 the AlertState switches to Idle, even though you are currently within range. I think you might have had a bug there?
This happens because the transition is already running, I assume there would be some way to configure the transition to reset when the event fires again though.
This moment jumped out at me as well. It highlights the problems we run into with complex state interactions all the time. I'm not persuaded that scattering it across multiple nodes, which I have to dig for in the editor interface, is more convenient than doing it in a few consolidated blocks of code, where I can quickly surmise the bigger picture at a glance. I was hoping to see something more "chart"-like ala a state machine diagram I might create in advance of writing the code I use today. The star of this plugin is the visual debugger, which beats the heck out of my print(state)'s everywhere.
I think that is due to the delay, it's tough to really understand what you are dealing with when you don't know the back-end well enough. This plugin definetly looks useful though
Thats because the timer does not get reset when you go back into the collision zone and it will still count down. Timer are always very hackish in my opinion
I have seen many different tutorials and addons for state machines. For me this is the best statemachine addon there is. This tutorial is also perfect. For the first time after months of back and forth from one implementation to another, I finally understand statemachines perfectly and can implement them onto anything I need. Not only that, but I because of this tutorial and addon something just clicked in my head and I can code my own statemachine now also. Thank you for this tutorial. Just subbed because your an amazing teacher!
This is perfect. It feels just so much more organized than using any other state machine. It would be great to see smooth transitions between states and handling animations.
I think you want more a way of scaling with parameters like the PLC world or the node would be called Map Range in blender. took some time messing around with spreadsheets but this maps one range of numbers to another, I use it to map my characters velocity to stand -> walk -> run animation # remap ranges of variable, good for leveling mechanics and scaling numbers, quite a bit of math so staticly typed func map_range_float( range_input: float, out_clamp: bool, in_low: float, in_high: float, out_low: float, out_high: float ): return (clamp((((range_input-in_low)/(in_high-in_low))*(out_high-out_low)+out_low),out_low,out_high) if out_clamp else (((range_input-in_low)/(in_high-in_low))*(out_high-out_low)+out_low)) wish this was built in to godot like it is blender, its so handy
There is actually docs.godotengine.org/en/stable/classes/class_%40globalscope.html#class-globalscope-method-remap which seems like it's doing the same thing.
This is a very good tutorial/video. Amazing job, thanks! This addon is very interesting, but seems like it moves all the code for the different states back into the base class (Watchman), instead of having the state specific code compartmentalized in the various state nodes.
Yes, this is actually intentional. It makes accessing of shared variables (like health, position, etc.) a lot easier without having a lot of up and down communication between single nodes. Also for smaller examples like this I feel that having all code in a single script aids in understanding how everything works. Because the library uses signals to call into your code it doesn't prescribe any way in which you organize the code. So if you want a separate node per state, then you can add some per-state nodes below the watchman, attach scripts there and then connect the signals to these nodes.
I second this. Since exposing mutable state is seen in many other tutorials and examples, it’s great to see someone actually displaying some good architecture! A shame that these plugins can’t be ported to c# for now, but one day we’ll get there. I’ve been using partial classes to nest the states directly in the context class in c#, which ruins modilarity. Seeing it all as nodes really opened my eyes. Especially how you serialized guard expressions in the editor. Performance-wise im not sure if the events are cached and the expressions pre-evaluated, but I’d imagine that it isn’t that relevant for most projects. Great work ❤
You sir have earn yourself a subscribe. This has to be one of the easiest to follow and well explained. Gonna try and test it out. Will be back for a follow up comment once I experiment this! Great tutorial
Love this video. Thank you for the great work. Can you please do second video, where you explain some of the other state nodes and a more advanced state game example. Would love that.
thank you for this, I love this addon now. I always waste a lot of time implementing my own state machines for AI characters because I keep introducing bugs, this makes it so much better to work with
@@godotneers Wait I'm confused you're the author ? That's quite impressive, your channel has few videos but they're very qualitative, thank you very much for what you're doing.
After a delay state could be invalid. Same happened in video - "To Normal" while enemy was inside. So my only question is how to cancel timer or override transition?
Nicely spotted! In this case this could be fixed by adding another transition to the "Observing" state which listens to "enemy_entered" and transitions to the "Observing" state (e.g. itself). There can only be one delayed transition active at any time in a state (you can have multiple transitions concurrently active in multiple states though). Running any other transition for a state will automatically cancel any running delayed transition in that state. Also when you leave a state and it still has a transition pending this will be automatically cancelled. This could be the case if some parent state transitions and deactivates its child state.
More than anything, I think relying so much on signals is a very 'Godot way' of implementing state machines and it just feels so natural. I have been learning state machines recently and been trying to implement them on my own. This feels so much easier to use so far, especially parallel states are such a great simplifier. I'm already okay doing simple state machines with the enum and match statements. I wonder if you would still recommend to learn implementing finite state machines (like node-based) the traditional way just to get better at programming. I assume you would. Thank you so much for your great asset!
Thanks! I was recently had worked in a similar solution! But this add-on seems to be very solid! But my solution needed to inherit from a "StateManaged2D" node that, is an Area2D
Hello and thank you for all your high quality tutorials. I have a question: I have a car and a player , both are its own scene. I want to give each scene a own StateChart to make the car and the player as well indepnendent to which Parent scene they are used in. Is it possible to use own state charts for each indibidual (subscene) or is that not how the system is meant to be used?
I'm not sure I understand the question but you basically get the reference when the body enters as parameter to the `body_entered` signal. You can save that reference to a field and use it later for attacking (the video does this as well starting at 12:06, but only uses the reference to look at the enemy).
@@godotneers Thank you, thats what i meant. But didn't look clean to me saving the reference since there may be multiple enemies or only 1 and managing that reference/s when enemies enter or die didn't seem to belong to player node responsability. But i'll do it that way.
It took me about a day of studying and copying the example projects, but I think I've gotten the hang of this now, and I'm already loving it. EDIT: Coming back to this comment after about a week using it. I want to start by saying the dev is very kind, responsive and patient, and helped me understand the system when I was struggling with it. However... I've come to the conclusion that statecharts aren't for me. I have a number of problems with this system, starting with the fact that all the code gets dumped into a single script file, which is a massive pain to work with. Sure, you can separate it out into different scripts, but then you have to start adding more nodes to the tree to hold those scripts, and the state chart is already a giant spaghetti mess, now I'm having to add even MORE nodes just to keep the code separate and readable? Another issue I have with it is the examples that come with the addon. You'd think you could get started by studying these... Well, I tried, and from an end-user perspective they're pretty awful. I was primarily using the "anthill" example to try to create a creature behaviour. So I looked at how the nodes are named, and they're all these very simple, shorthand names like "On Next Destination", "On Dropped", etc. So naturally, I copied this pattern in my own project because I didn't know any better. But as soon as my chart started getting more complex, I look at all these nodes and my eyes just glaze over like... wtf am I even looking at? This all means nothing to me! ESPECIALLY because, most of the nodes don't have any scripts or signals attached. Most of the signals happen higher up in the Compound or Parallel nodes that are handling all the subnodes. So I might have a deeply-buried transition node "On Food Picked Up", but if I'm following the anthill example, that transition uses no signals, has no script, so I'm staring at it having no idea how it's triggered or when, and I have to look further up the node chain, to "Picking Up", which has a state_entered signal to call _on_picked_up(), but this script STILL doesn't mention the "On Picked Up" transition anywhere, so I'm still left wondering how and why it's ever triggered, and more importantly, why my own project attempting to mimic this behaviour doesn't work correctly. Now, don't get me wrong: If I stare at it long enough, I can figure out when "On Picked Up" gets triggered, and I did get my behaviours working after hours and hours of troubleshooting. But it's so convoluted and not naturally-occurring at all, and the whole point of using an addon is supposed to make it easier to handle, not harder. My experience has been that this has made creating a state behaviour tree so much LESS manageable than even just doing it fully in code would be! Another thing that repeatedly tripped me up is how transitions can have a Delay, but regular state nodes can't. And the Delay doesn't seem to correspond with when the associated signals get triggered, so you end up with things being mis-timed because you expected the delay to happen *before* the code, not after. I'm not 100% on this because honestly I never really figured it out, it was too confusing. And maybe I missed something in the documentation, but nowhere does it seem to state the UTTER IMPORTANCE of what order the nodes are placed in the heirarchy. Not knowing the importance of this caused me so many headaches. Lastly, the lack of colour-coding on the node icons is a surprisingly big issue, too. They all sort of blend together being the same dull orange. Sure the pictures are different, but they're not massively different, all some variation of circles inside a bevelled box, and it takes a few more CPU cycles in the ol' brain to recognize what they are and understand what they're supposed to be doing. Ultimately, I think I'm not going to be using state charts moving forward. They may work for somebody else, but now that I have a slightly deeper understanding of how to use them (beyond the "ooh shiny!" stage I was at when I first saw this) it's just not for me. I wish the creator luck and I don't want to say this addon is "bad" by any means. It's just not for me.
I'm pretty sure I'm never making another state machine again in godot. this is so much cleaner looking.. I'm at that point with my enemy ai that I'm running into conflicting situations and my code is full of "If this and this and not this" type stuff and it makes it hard to read coherently. Plus this addon might take some of the headache out of thinking over those edge cases. i don't think ill change what i got but i will use it for future scenes that require states.
It looks great, but I have a question. After using this plugin in Godot ', do I need to make additional annotations or apply to the original author? If you want to publish a game that has used this plugin, what specific steps do you need to take?
The library is provided under MIT license, so the only thing you need to do is put the copyright notice somewhere alongside with your software. Most programs solve this with a LICENSE-3RD-PARTY.txt file where they list all the libraries they use and which licenses these libraries are provided under. Some programs also have a similar list in their _About_-dialog (e.g. Godot itself has a 3rd-party licenses tab in their about dialog).
Thanks for the video! I was looking into state machines and state charts recently, from my understanding state charts helps solve certain problems that occur with finite state machines (state explosion) and it overall makes things a bit clearer and easier to understand. My question is, is there a reason to use FSMs over state charts? (perhaps performance reasons?)
AFAIK, ease of use. If you're only going to be at one state at a time, you don't really need state charts. State charts have been really useful for me to combat so-called 'state explosion', when you need separate states for every combination of atomic states.
I'm having trouble reusing basic states such as Wander or Chase, where any enemy does basically the same. Since the code is handled in the main script of the enemy and not on the State itself. Any suggestions on how to use this addon whilst being able to reuses states effectively, without having to duplicate code? Many thanks for the addon and the tutorial.
Very well done visual explanation of this add-on. While reading the add-on docs it was recommended to watch this. You're using version 0.3.1 and I'm using 0.13.0 and all of this is still valid which is amazing in itself. My only qualm is keep the name of the states and add *_whatever*. IE: AtomicState_idle. This allows the viewers to understand what line/state is what all the time instead of only when added and completely renamed. So many tutorial vids rename all the nodes that even 2 minutes in I'm like, "f-m, wth was that "fluffy_bunny_burps" node again?" Followed by, "Geez, TH-cam needs a 10sec rewind button.." Otherwise great tutorial and I'm going to explore using this add-on in more complex ways!
do you know if synchronizing the states with godot built in multiplayer would work? I got the state chart working with my movement animations and some combat states. trying to know if this is usable in multiplayer. Thanks so much!
Hey, great video. I had a slight problem while using it though, which is if I check for an Input inside of a state"s _physics_process, if the state transitions, there seems to be a short window in which the Input is not being acknowledged by either of the states. Is there a way around this?
State transitions are usually done within the same frame so there should not be any delay during state transitions. Could you maybe open up an issue at github.com/derkork/godot-statecharts/issues/new and give some more details about your case?
@@godotneers Hey sorry I haven't had much time recently, but I found a workaround. I spent a while trying to replicate what was happening and couldn't so I probably messed something up really badly on my end lol. Also I haven't really used github before but if I get the time I'll try to put something up But just in case there's a simple answer I'm missing, what I was trying to do was set up a coyote jump mechanic for a platformer, but whenever I changed states from wall to air or from floor to air, there would be a couple frames where the jump input wouldn't be registered by my states, but it would be registered by the normal _physics_process. Whenever I would check to see if the state was active whenever I jump, it would return active, but the state physics_process wouldn't detect any Inputs. My workaround was just to put the coyote jump logic in the main _physics_process, and it works well enough. Either way, this addons made my time in godot way better, so I'm not complaining lol
Great tutorial as always! The only downside I can see here is that with a complicated character, you would end up with a very long script. Is there any easy way to break the code for each state into its own script?
Because the library uses signals to call into your code, you have a lot of freedom how to organize your code. You can write everything into one script like done in this video, you can have scripts dealing with certain aspects (e.g. movement, attacking) and call into these, or you can make one script per state and call into that. Whatever way works best for your game. See also this discussion here: github.com/derkork/godot-statecharts/issues/113
Nice tutorial. By the way, even though I understand that I shouldn't track the current state in my code, is it possible to access it? Also, can there be two (or more) nodes directly under the StateChart? Thanks!
The thing is, that in a state chart there can be multiple states active at the same time. If you really want to know whether a particular state is currently active, you could get the node of this state using a node path or scene unique node and then check its `active` property (e.g. "var some_state = %SomeState; if some_state.active: do_things()" - TH-cam comments really aren't great for posting code). Then again I think doing so is sort of bypassing the library as you now introduce if/else code regarding states. So if I could help it, I would not do it - but in the end it needs to work for you, and if this is an easy and maintainable way to solve your problem, then go for it. You cannot have multiple states directly below the state chart node, but you can put a parallel state below the root and then add multiple compound states below that, which effectively gives you what you're after.
If you have more than a single expression in there it can be, yes. Usually there should be only a simple expression in there like `health > 0`. If you need complex logic in your guards, it may be better to put this in your code and just send an event as the result of this complex logic which will trigger a state change.
Hey this is an amazing plugin! Thanks for creating this! I'm having one issue. How do I make it so after an animation plays it goes back to the idle animation. I'm trying to add an attack animation to your frog from your platformer example but I'm having some issues. I added the attack animation to the animation tree and added the required nodes for the attack state but I'm not sure how to make it so the attack only goes back to the idle state after the animation finishes. The only thing that's working for me right now is if I add a delay to go back to the idle state which is the exact length of the attack animation. Any help would be appreciated.
Would you mind opening up an issue at github.com/derkork/godot-statecharts/issues and posting some screenshots of what you have set up and what the goal is? Just from a textual description it's really not possible to give solid advice.
Thanks for this great tutorial and the dive into this Plugin. If you decide to do a second part to this, I was wondering how I could implement the following: 1. Take the traditional body mechanics states, like idle, move, jump, attack etc. but then also take mindset states like, normal, wounded, low profile, aggressive, etc. With a traditional state machine someone would need to create a state for each combination. But I was wondering how these multiple state chart would help solving that issue. That way different animations could be played when a character is moving aggressive vs move wounded. 2. As an alternative it could be interesting to have a character who is controlled by the player but then can become an autonom character in a scripted sequence (in a cut scene for example) and then return the control to the player. Thanks again!
1. You don't necessarily need to use different states to blend animations. Godot's animation tree can blend different animations together, so you could for example just calculate a "hurt" value, maybe current_health / health and use that as a blending value in a Blendspace1D which blends the hurt animation with the normal animation. I'm not an expert on the animation blending, but this seems easier than trying to do this with a state machine. 2. I feel this would also be easier to do with a smoke and mirrors solution. E.g. you can insert a copy of the player with a different script for animation in a cutscene and then just delete the copy when the cutscene is done, while suppressing player input in the meantime.
If you didn't have parallel states, could you get the same functionality by implementing them as another state tree? Apart from having to mirror the events and expression properties to two trees rather than one, it would do the same thing right? Also, is it possible to write scripts on the actual states themselves? In some cases it might make sense to contain it there rather than having to put all logic into one large parent script. They have a script icon in the tree, but blue rather than white, I wonder what that means.
Yes, depending on what you're trying to do you might be able to model this with multiple trees as well. If you need state changes across the trees this might become a bit more difficult. As for your script layout you can pretty much use any layout you want because the library uses signals to call into your code rather than requiring you to derive from some base class. E.g. you can also put components on the root node and each component can be called by the state chart depending on which state it is in (e.g. a movement component, a targeting component, etc.). Technically you can also extend from the AtomicState class and write your code directly into each state - just be careful to call "super" when you override functions otherwise you may see _interesting_ behaviour ;).
amazing addon. i hope i am not asking something that is in the documentation, i just got finished watching the video. can you add the signals to enter or exit each state to the state node themselves or should everything always be added to the primary script. i am guessing that the State chart nodes inherit from the primary script but if the signals for enter and exit are attached to one of the states would the State chart still work. i guess i am trying to compartmentalize all of the code separately into different scripts so when the character enter into a particular state i can drill down to that states script to add more functions or correct existing functions. i hope this makes sense. even if that is not the case this addon seems amazing. thank you for all of your hard work.
The state nodes (atomic state, parallel state, compound state) have scripts from the library attached to do their work, so you cannot directly add signal handling code to them. But you could create your own script deriving from say "AtomicState" and then put your signal handling in there. Then you would need to assign the correct script to the state node. Because the add-on uses signals to drive your code rather than mandating that you derive from a class, you are free to organize code in any way that works for you. I personally like having everything in a single script because it simplifies accessing shared state (like health points, position, etc.) and it also makes for easier re-use of common functionality (e.g. if i want the same function to run in multiple states, i can just write it once and call it from the other functions without having to figure out where I would put it). With Godot 4.2 there will be code regions in GDScript so you can then put everything regarding to a single state into a region, fold it away and have a drill-down this way. But in the end you are free to do whatever works best for you and your game, so if you rather have separate scripts on separate nodes, you can totally do this.
@@godotneers ok thank you for your response. Thanks for clarifiying my question and thank you for letting me know that there is another approach i can take if it feels more comfortable in the end. I think these state charts are great and much cleaner than implementing a state machine the traditional way. Last question do you have any plans or ideas about any future revisions to state macines that could combine or drive the state machine in the animation tree with with these state charts. I think the upcoming node in 4.2 that combines the animation player & animation tree sparked this idea
There are some helper nodes which can start animations as part of a state change and also can travel within an animation state machine, however these are marked experimental and I'm actually inclined to remove them again. Controlling animations is somewhat tricky and there are also conflicting workflows. Some people like a workflow where the end of an animation triggers a state change and so the animation has a direct influence on gameplay. Others treat animations as pure visuals and all timings are determined by the game code and animations just have to match these timings. Also in some cases animation states and gameplay states have no direct 1:1 mapping. E.g. there may be different animations for walking and running but internally there could be only one state for walking and which animation is picked depends on the speed of the player. As such it is very difficult to provide an integration between state charts and the animation system that provides an ease of use advantage over just doing stuff yourself but at the same time is powerful enough to not only work in a few simple cases. I currently have no good idea on this topic so I rather not recommend anything half-baked.
@@godotneers thanks for the explanation again. I may check out those helper nodes just to see how they work. They may be good for quick prototyping. Thanks once again
So I am trying to learn Godot and gdscript and I'm having a bit of an issue.. how do you manage the auto complete being so weak? In something like C# I can heavily rely on intellisense to code, so I don't have to remember every bit of syntax for everything. But in gdscript, like at 6:49 for example, it isn't always there to help. Is this resolved with stricter typing? If so, why is it that SO MANY tutorials don't type nearly any of their vars? Thank you for the video though, state charts look super useful.
GDScript's autocomplete can be a bit hit and miss. I found that adding type information (e.g. var some_area:Area2D = some_value) generally helps with autocomplete, but even then it's often hit and miss. If you take shortcuts like the $-Notation the editor will often not be able to give you autocomplete as it cannot resolve the type. It's just something one has to get used to with a weakly typed language like GDScript. As for why people don't type their code in videos I can only speculate it's probably to keep the video shorter and not confuse people with additional syntax.
@@godotneers That makes perfect sense and is what I have also found to be true myself in the few days since I left that comment. Thank you so much for the reply and for your SUPER high quality videos!
If you put the following at the top of your script (instead of accessing $StateChart every time), autocomplete will then work: @onready var state_chart: StateChart = $StateChart as StateChart ...but yeah, kind of annoying - I wish Godot would fix that.
@@GregX999 Good to know, I have used that in some cases and it works sometimes and doesn't others :/. I have just come to terms with the fact that I'll have to deal with it only working sometimes. For sending events to the state chart I've just been making wrapper functions that hold them so I can just call those functions to call the events.
Hi, I'm considering using your state chart plugin but was wondering if there was a way to implement random behavior. Would it be as simple as just sending a random event to the state chart?
There are a few ways in which you could implement this, but sending random events seems to be a nice and simple solution, so that's what I would go with. Another option would be guards that calculate a random number and only let the transition happen if the number exceeds a certain threshold. This would be useful if there is a certain chance that a state switch should happen (e.g you have a 55% chance to get poisoned on a hit).
I just found out about this amazing tool. I usually use a node tree for the state machine so every state gets there own code. But in the video you use a single script for all logic? I still would like to have a script for every state for better organisation. Should I make a separate States Node (as sibling to the State Chart) with all states (as children)?
Well the library is somewhat opinionated in that regard. You can of course divide your script up into multiple scripts which you add to additional nodes and the library will happily work with it, because it uses signals to communicate with your nodes. Godot also now has code regions with 4.2 so you might not even need multiple scripts anymore to keep things organized.
Hi im very thankful for this tool but im currently confused as to how to set up historystate nodes. the docs says i just put them under a compound state and set a transition to it. But I did that, I had a movement compount state with atomic states (walk, sprint, idle, jump). I want to be able to go back to the last state after transitioning to jump. so I transition to my history state after the player is on floor yet the historystate keep going to the default state.
Not really. Memory leaks are somewhat difficult to trace in Godot as the profiler only gives you object amounts but no breakdown of the type of these objects, so its often very hard to say which part of the code causes a leak. From a cursory inspection of the examples that come with the project I couldn't find any memory leak. If you happen to be able to reproduce one I would like to know about it. github.com/derkork/godot-statecharts/issues/new
I was trying to use the other nodes/methods based on the provided documentation but they are not functioning for me at all. _run_transition specifically isn't working. I assume that since you did not show any of the other nodes/methods in this video, that not everything has been fully implemented/tested, but perhaps I'm just misunderstanding the documentation.
The only node you need to interact with is the root state chart node and there you basically only need one method - `send_event`. If you have two states A and B and want to switch between those, you will first create a transition in the editor below A that transitions to B and reacts to some event, e.g. `some_event`. Then from your code you just call `send_event("some_event")` and the state chart library will switch from A to B if A is currently active. So you never call `_run_transition` manually. In general all methods and fields starting with an `_` are intended to be private and not be called/used from outside.
Nice tutorial, it took some effort for me to follow along for the first time as I'm using C# but I got a working example. Few notes; This part isn't necessary if the signals are setup in the godot editor: for the state_processing equivalent in C# when I was setting up the signals, I was getting an error trying to pass the delta, the manual didn't give C# example with a parameter but I got it working looking like this under the _Ready() - 'state.Connect(StateChartState.SignalName.StateProcessing, Callable.From((float delta) => OnObservingStateProcessing(delta))); Where state is the 'Observing' node state and OnObservingStateProcessing is my callable method that does the LookAt(enemy.Position). As that event is processing on every frame the callable method should look like that to accept a parameter. The callable method can also be used more verbosely like this: new Callable(this, nameof(OnObservingStateProcessing)) One other thing that threw me off which is not C# related specifically, but that by leaving the Delay in Seconds value of the transition blank instead of 0.0, I was getting an expression exception in the console debugger, but I thought that was a problem with the ExpressionGuard set in the ToBerserk transition. After some trial and error thinking I needed to call or defer SetExpressionProperty of the enemyentercount it was just me assuming a blank value was being handled. That's my oversight but would be good if the debugger could spit out a more direct message. Also introducing the parallel state and restructuring the nodes broke my GetNode calls for the Idle and Observing nodes, returning null as it couldn't find them until I changed the path to include the StateChart/Root/Alertstate. Might be a language difference with godot but that can be fixed with a singleton or something to manage the node paths, plenty of tutorials for that I'm sure. Besides all that I can't wait to expand on it further for more states, and hope the C# support continues!
Do you lose perfomance by using a signal as a process? Like, in Unity i wouldnt use a Actions or UnityEvents invoked on a Update, because as far as i know its slower. I could use the process on the main script and check the current state instead, or someting to avoid using that signal, but im curious
Emitting a signal is simply a method call, so this will cost you as much performance as calling a method from _process will cost you. This overhead is usually negligible. If you want to find out for your particular use case there is a performance testing setup which ships with the project. You can set up the state machine as you'd like it and then have a thousand copies of it running at the same time. Then you can use the profiler to identify bottlenecks. The bottlenecks will likely be not in the signal emitting part.
@@godotneersOooh thanks, i normally use unity at work and im trying to swap to godot at home. When i read about signals i always imagine them as c# Actions since thats what im used to. Thanks for the info!
They are similar to C# events. What's really nice about them is that they automatically disconnect themselves if one side is destroyed. This takes away a lot of the bookkeeping you'd normally have with C# events.
Maybe I missed something, but I don't really like the states knowing how/what to transition to. I prefer to have a parent notice what's going on and transition to different states without the states knowing about other states. But maybe I'm getting too deep into decoupling, and I should be okay with states knowing about each other. I do end up with a decent amount of code in the parent object going through logic deciding which state to be in 🤷
Well in the "classic" way of doing things, there is usually code which actively activates/deactivates states, like you said. In such implementations the concept of a "transition" doesn't even exist. Which as you observed translates in a lot of if/else if you control everything from a central parent. Alternatively you have code in states which directly transitions to other states. In this case the states also know about other states. With the transitions this logic moves into the state chart. You just send an event and based on the current state that event can lead to different things. Nothing could happen, or one or more transtions could fire. The states themselves don't really know about other states. They just send events and the state chart is reacting onto it. The state chart is the entity that knows all the rules. So you basically replace your big if/else with a bunch of nodes in the scene. If you rather control stuff in code there is nothing wrong with that and you can just do that as well and don't use the library. I personally find the separation quite beneficial and things like delayed transitions are quite useful as well and putting these into a big if/else is probably a bit more difficult. But just because it works for me doesn't mean it works for everyone. So if you rather roll your own because that works better for your project and your personal preferences, that is totally fine - in the end we just want to make a game and nobody really cares how its done internally as long as it works.
You can put the debugger in a canvaslayer (like any other UI), it will work just fine in a 3D game as well. The latest version also has the debugger integrated in the editor, so you can have the debugger open in your editor on one screen and have the game running on a second screen.
Is it possible to have a new script inherit from "State" and override virtual methods for state_entered and state_exited? Or does it only work with signals? When traits become available in gdscript it would also be even nicer to use a trait and implement a method override for that =)
Technically nothing is stopping you from deriving your custom class from `AtomicState` and then overriding the methods, but this is not how the library is intended to be used. Using the signals has multiple benefits: - you can more easily re-use code across states e.g. by connecting two different state signals to the same method. Also helper functions can be used more easily this way. The platformer example shows this by having the jump code only in one place even if it is used by multiple states. - you can have all code regarding an entity neatly in the same script instead of having it scattered across multiple small state scripts - access to data is simplified: if you have multiple state scripts in a nested tree structure you would need a way of accessing entity data usually by some calls to `get_parent()` which is a maintenance burden and prone to breakage if you reorder states. - library surface is minimized - there are only two functions your code will ever use to interact with the state chart (`send_event` and `set_expression_property`). This makes it a lot easier to reorganize internals e.g. for improved performance without breaking existing code. As for traits, I cannot really comment on that as the discussion on this feature on the Godot issue tracker seems to be going nowhere right now, so it's currently unclear if and when such a feature would materialize and how the implementation would actually look.
I agree that this example can probably also be easily implemented with a few scripts and without a library. In fact it _should_ be done without a library if it is that easy. But the idea behind this video was to show how the library works in general and what features it provides and how to use them. A more complicated game logic would probably have made a better case for using this library over hand-written code to simplify things. On the other hand it would have gotten in the way of understanding the concepts. So I decided to go for a simpler example. If you want to see some more complex examples, have a look at the bundled example projects.
I'm very impressed with this asset. I've made various different state machines (and even a state tree) from scratch in Godot and Unity, but would totally use this one instead for anything I would ever need states for. I'd love to see more videos covering more advanced use cases (even if just an overview rather than a step-by-step tutorial).
I am not a big fan of adding 3rd party addons for things I can do myself, but damn this one looks tidy and organized, like a better version of state machine.
I think the icons and all make it pretty professional.
I'm just wondering. If you write all your code in signal called methods, wouldn't this get super jarring, quickly? Like for a larger (say like a Fighting Game or Metroidvania, etc.) Player Character, I could imagine this to be a script filled with 100+ of these signal methods in the end. @@TheLastPhoen1x
@@hiiambarney4489 If that's the case, then you should probably split that logic into its own script and node and connect the signals from the state machine to that new node
@@hiiambarney4489 late to the party, but i feel like you could have a node for each state (or group of states) that holds the logic.
@@hiiambarney4489 like what romanperry mentioned, you can split the script into nodes like the usual FSM. the tool really just comes down to making the initial setup quicker and having that parallel state is a massive plus compared to an fsm
This is probably the best addon in the asset store. I have used it in every single one of my projects.
Indubitably! ☝
This is such an elegant solution! I've wanted something like this ever since I started using state machines and you absolutely nailed it. Thank you.
This is my new favourite Godot tutorial channel! Keep it up!
Finding tools like this is exactly why I fell in love with Godot, thank you so much for making this!
When I think of state machines, I either imagine a chart or code, but here they're represented in nodes which looks like the native Godot way of doing everything 😅 I love the debugger! It really tells you all you need, and so easy to add.
i have been coding state machines by hand, this is SO MUCH BETTER!
I noticed this in the assetlib tab a while ago but didn't get a chance to read through the documentation. This video is VERY helpful. Thanks for taking the time to create it. It makes me want to use your addon for my game. More videos would be very welcome. You did a really comprehensive job at creating this asset.
Glad you like the video! Regarding additional videos are there some subjects you would be particularly interested in?
@@godotneers I think a guide on the behavior tree addon Beehave would be useful, there are very little guides on it and none for the current version, the documentation is not very good with basically no examples.
@@godotneersI wouldn't mind understanding the differences between a state chart and a behavior tree? When I saw the Parallel node, that was the first thing I thought of. Also, some more examples outlining each different node type in the state chart would be beneficial I think. And, of course, more examples of implementing a state chart is always helpful. Your presentation style is very clear and I think it saves people a lot of guessing.
@@Asguardian22 behaviour trees and state machines/state charts have some overlap in that they are concepts for running a process in a stateful manner. The execution method is different though. Behaviour trees have a concept of "success", e.g. they run actions and these can succeed or fail. Then the nodes react to the success by switching to other parts of the behaviour tree. On the other hand a state chart has no such concept of "success". It just reacts to whatever events it receives and switches states according to the events and the configured transitions. In a behaviour tree the node type is some hard-coded behaviour, e.g. a parallel node in a behaviour tree will run all its children for as long as they are successful, a sequential node will always run its children in sequence, etc. In a state chart the behaviour is more fluidly defined by the transitions and the events that come from outside of the state chart. In the end both are tools in the arsenal and you can probably model a wide range of problems in either one of them, so one isn't necessarily better than the other.
As for additional tips, I'm going to make a few more videos on the state charts library, one of them will be a deep dive on how the controller in the platformer was made and why it was modeled the way it is. Making these videos takes a good while though, so it will probably not come up tomorrow ;).
@@godotneersGreat explanation. Thank you for taking the time!
Really cool plugin. Love the parallel states concept and will be trying this out in my projects. Also the tutorial is really well explained and makes it easy to understand. Thanks for the guide.
Thank you for making this! I am currently using Godot State Charts to make a neolithic village simulator game. It makes adding/controlling behaviors a lot easier and modular.
Really enjoyed the zoom in on 'delay'. Made me go "Ooooooh..." But, I hadn't seen the parallel states at that point. Great stuff!
I am making a metroidvania and my character controller is a mess, I have a lot of verifications to see if I can move the player, like if is not getting attacked, if it is alive, if is not dashing, etc.
Your videos are making the process x100 faster and easier, thank you a lot!
Pretty powerful. I discovered states as entities, and nested FSMs, but transitions as entities is clever. That and parallel states.
Amazing plugin!
One thing though, at 20:11 the AlertState switches to Idle, even though you are currently within range. I think you might have had a bug there?
This happens because the transition is already running, I assume there would be some way to configure the transition to reset when the event fires again though.
This moment jumped out at me as well. It highlights the problems we run into with complex state interactions all the time. I'm not persuaded that scattering it across multiple nodes, which I have to dig for in the editor interface, is more convenient than doing it in a few consolidated blocks of code, where I can quickly surmise the bigger picture at a glance. I was hoping to see something more "chart"-like ala a state machine diagram I might create in advance of writing the code I use today. The star of this plugin is the visual debugger, which beats the heck out of my print(state)'s everywhere.
I think that is due to the delay, it's tough to really understand what you are dealing with when you don't know the back-end well enough. This plugin definetly looks useful though
Thats because the timer does not get reset when you go back into the collision zone and it will still count down. Timer are always very hackish in my opinion
I have seen many different tutorials and addons for state machines. For me this is the best statemachine addon there is. This tutorial is also perfect. For the first time after months of back and forth from one implementation to another, I finally understand statemachines perfectly and can implement them onto anything I need. Not only that, but I because of this tutorial and addon something just clicked in my head and I can code my own statemachine now also.
Thank you for this tutorial. Just subbed because your an amazing teacher!
I HAVE SUBSCRIBED. Saw another video of yours. I believe you should keep it coming and this channel will be big. Godot is going to be big
Respect! Quality content here :) I cannot wait for more.
This is perfect. It feels just so much more organized than using any other state machine. It would be great to see smooth transitions between states and handling animations.
Glad this is useful for you! Could you give me a bit more details about what you mean with "smooth transitions"?
I think you want more a way of scaling with parameters like the PLC world or the node would be called Map Range in blender. took some time messing around with spreadsheets but this maps one range of numbers to another, I use it to map my characters velocity to stand -> walk -> run animation
# remap ranges of variable, good for leveling mechanics and scaling numbers, quite a bit of math so staticly typed
func map_range_float( range_input: float, out_clamp: bool, in_low: float, in_high: float, out_low: float, out_high: float ):
return (clamp((((range_input-in_low)/(in_high-in_low))*(out_high-out_low)+out_low),out_low,out_high) if out_clamp else (((range_input-in_low)/(in_high-in_low))*(out_high-out_low)+out_low))
wish this was built in to godot like it is blender, its so handy
There is actually docs.godotengine.org/en/stable/classes/class_%40globalscope.html#class-globalscope-method-remap which seems like it's doing the same thing.
@@godotneers well hot dang, thanks!
This is a very good tutorial/video. Amazing job, thanks!
This addon is very interesting, but seems like it moves all the code for the different states back into the base class (Watchman), instead of having the state specific code compartmentalized in the various state nodes.
Yes, this is actually intentional. It makes accessing of shared variables (like health, position, etc.) a lot easier without having a lot of up and down communication between single nodes. Also for smaller examples like this I feel that having all code in a single script aids in understanding how everything works.
Because the library uses signals to call into your code it doesn't prescribe any way in which you organize the code. So if you want a separate node per state, then you can add some per-state nodes below the watchman, attach scripts there and then connect the signals to these nodes.
I second this. Since exposing mutable state is seen in many other tutorials and examples, it’s great to see someone actually displaying some good architecture! A shame that these plugins can’t be ported to c# for now, but one day we’ll get there. I’ve been using partial classes to nest the states directly in the context class in c#, which ruins modilarity. Seeing it all as nodes really opened my eyes. Especially how you serialized guard expressions in the editor. Performance-wise im not sure if the events are cached and the expressions pre-evaluated, but I’d imagine that it isn’t that relevant for most projects. Great work ❤
@@davvedp9309 The state charts plugin actually has C# support, so you can also use it in C# based projects.
Simply fantastic. This addon should be included with Godot core (as Beehave and YAFSM). Awesome work.
Such great news for me! Yeah. State Machines look so menacing, Im glad there is something to make it easier. Love the color also 😂
You sir have earn yourself a subscribe. This has to be one of the easiest to follow and well explained. Gonna try and test it out. Will be back for a follow up comment once I experiment this! Great tutorial
you make amazing guides, please keep it up!
That's a really neat tutorial!
I wish i found that addon earlier, although writing my own state machine was a useful experience in the end anyway x)
I'm glad you found it useful. What kind of game are you working on?
@@godotneers A 2D platformer with a combat system!
The state machine is for the enemy ai
Love this video. Thank you for the great work. Can you please do second video, where you explain some of the other state nodes and a more advanced state game example. Would love that.
Wow I dunno why I haven't heard of this till now it's simple and easy to get started with thanks for showing it out
Great asset and an underrated channel. Thank you.
happy to see plugin helps writing state machine.
one of best teachers I've ever seen . thank u so much
Thank you for showing State Charts, looking forward to seeing what I can do with that.
Amazing tool. I am currently use it to implement enemy logic in my game.
thank you for this, I love this addon now. I always waste a lot of time implementing my own state machines for AI characters because I keep introducing bugs, this makes it so much better to work with
This is the most impressive plugin in the entire AssetLib, it's almost an auto include in every projects.
Thank you very much, I'm glad it is this useful to you!
@@godotneers Wait I'm confused you're the author ? That's quite impressive, your channel has few videos but they're very qualitative, thank you very much for what you're doing.
Yes I'm the author. I created this video for people who like to learn visually rather than reading a manual.
After a delay state could be invalid. Same happened in video - "To Normal" while enemy was inside. So my only question is how to cancel timer or override transition?
Nicely spotted! In this case this could be fixed by adding another transition to the "Observing" state which listens to "enemy_entered" and transitions to the "Observing" state (e.g. itself). There can only be one delayed transition active at any time in a state (you can have multiple transitions concurrently active in multiple states though).
Running any other transition for a state will automatically cancel any running delayed transition in that state. Also when you leave a state and it still has a transition pending this will be automatically cancelled. This could be the case if some parent state transitions and deactivates its child state.
Leaving a well deserved like and comment on your excellent work to help the growth of your channel. Really well explained! 😀
This is brilliant! I’m already thinking about how this is going to make my code a lot simpler.
More than anything, I think relying so much on signals is a very 'Godot way' of implementing state machines and it just feels so natural. I have been learning state machines recently and been trying to implement them on my own. This feels so much easier to use so far, especially parallel states are such a great simplifier. I'm already okay doing simple state machines with the enum and match statements. I wonder if you would still recommend to learn implementing finite state machines (like node-based) the traditional way just to get better at programming. I assume you would. Thank you so much for your great asset!
It never hurts trying build something yourself to really understand how it works and why it works, so go for it!
Love this, and I'm especially grateful for the manual!
Wow and finally I learned to thank you, the sweetest person❤❤❤
I'm very impressed with this asset. Thanks for the tutorial man, keep it up 😊
This looks amazing. I'll sure try it on my next project
Thank you for this very informative tutorial.
Thanks! I was recently had worked in a similar solution! But this add-on seems to be very solid! But my solution needed to inherit from a "StateManaged2D" node that, is an Area2D
This is my go to FSM now, thank you!
I've been using own state maschines for godot all the way. But for my new project I will be using this one.
I'm not sure if I have a use for this but in a future game I might give it a go and see if I can apply it. Nice tutorial!
Thanks you for this clear explain for this addon and state charts in generaly
Incredible plugin, thank you!
Great addon and tutorial - subbed!
Hello and thank you for all your high quality tutorials.
I have a question:
I have a car and a player , both are its own scene.
I want to give each scene a own StateChart to make the car and the player as well indepnendent to which Parent scene they are used in.
Is it possible to use own state charts for each indibidual (subscene) or is that not how the system is meant to be used?
I had the same question, finaly i just testet it yes you can use multible state Charts.
You might also want a guard on the timed transition from berserk to normal so that it only happens if it is also currently in the Idle state
This is a godsend. Ty
What would be the correct wat to implement the attack state on area/body entered during that state since you don't have the enemy reference?
I'm not sure I understand the question but you basically get the reference when the body enters as parameter to the `body_entered` signal. You can save that reference to a field and use it later for attacking (the video does this as well starting at 12:06, but only uses the reference to look at the enemy).
@@godotneers Thank you, thats what i meant. But didn't look clean to me saving the reference since there may be multiple enemies or only 1 and managing that reference/s when enemies enter or die didn't seem to belong to player node responsability. But i'll do it that way.
wow wow wow. This is a gamechanger
It took me about a day of studying and copying the example projects, but I think I've gotten the hang of this now, and I'm already loving it.
EDIT: Coming back to this comment after about a week using it. I want to start by saying the dev is very kind, responsive and patient, and helped me understand the system when I was struggling with it. However... I've come to the conclusion that statecharts aren't for me. I have a number of problems with this system, starting with the fact that all the code gets dumped into a single script file, which is a massive pain to work with. Sure, you can separate it out into different scripts, but then you have to start adding more nodes to the tree to hold those scripts, and the state chart is already a giant spaghetti mess, now I'm having to add even MORE nodes just to keep the code separate and readable?
Another issue I have with it is the examples that come with the addon. You'd think you could get started by studying these... Well, I tried, and from an end-user perspective they're pretty awful. I was primarily using the "anthill" example to try to create a creature behaviour. So I looked at how the nodes are named, and they're all these very simple, shorthand names like "On Next Destination", "On Dropped", etc. So naturally, I copied this pattern in my own project because I didn't know any better. But as soon as my chart started getting more complex, I look at all these nodes and my eyes just glaze over like... wtf am I even looking at? This all means nothing to me!
ESPECIALLY because, most of the nodes don't have any scripts or signals attached. Most of the signals happen higher up in the Compound or Parallel nodes that are handling all the subnodes. So I might have a deeply-buried transition node "On Food Picked Up", but if I'm following the anthill example, that transition uses no signals, has no script, so I'm staring at it having no idea how it's triggered or when, and I have to look further up the node chain, to "Picking Up", which has a state_entered signal to call _on_picked_up(), but this script STILL doesn't mention the "On Picked Up" transition anywhere, so I'm still left wondering how and why it's ever triggered, and more importantly, why my own project attempting to mimic this behaviour doesn't work correctly.
Now, don't get me wrong: If I stare at it long enough, I can figure out when "On Picked Up" gets triggered, and I did get my behaviours working after hours and hours of troubleshooting. But it's so convoluted and not naturally-occurring at all, and the whole point of using an addon is supposed to make it easier to handle, not harder. My experience has been that this has made creating a state behaviour tree so much LESS manageable than even just doing it fully in code would be!
Another thing that repeatedly tripped me up is how transitions can have a Delay, but regular state nodes can't. And the Delay doesn't seem to correspond with when the associated signals get triggered, so you end up with things being mis-timed because you expected the delay to happen *before* the code, not after. I'm not 100% on this because honestly I never really figured it out, it was too confusing.
And maybe I missed something in the documentation, but nowhere does it seem to state the UTTER IMPORTANCE of what order the nodes are placed in the heirarchy. Not knowing the importance of this caused me so many headaches.
Lastly, the lack of colour-coding on the node icons is a surprisingly big issue, too. They all sort of blend together being the same dull orange. Sure the pictures are different, but they're not massively different, all some variation of circles inside a bevelled box, and it takes a few more CPU cycles in the ol' brain to recognize what they are and understand what they're supposed to be doing.
Ultimately, I think I'm not going to be using state charts moving forward. They may work for somebody else, but now that I have a slightly deeper understanding of how to use them (beyond the "ooh shiny!" stage I was at when I first saw this) it's just not for me. I wish the creator luck and I don't want to say this addon is "bad" by any means. It's just not for me.
thank you for this!!!
I'm pretty sure I'm never making another state machine again in godot. this is so much cleaner looking.. I'm at that point with my enemy ai that I'm running into conflicting situations and my code is full of "If this and this and not this" type stuff and it makes it hard to read coherently. Plus this addon might take some of the headache out of thinking over those edge cases. i don't think ill change what i got but i will use it for future scenes that require states.
It looks great, but I have a question. After using this plugin in Godot ', do I need to make additional annotations or apply to the original author? If you want to publish a game that has used this plugin, what specific steps do you need to take?
The library is provided under MIT license, so the only thing you need to do is put the copyright notice somewhere alongside with your software. Most programs solve this with a LICENSE-3RD-PARTY.txt file where they list all the libraries they use and which licenses these libraries are provided under. Some programs also have a similar list in their _About_-dialog (e.g. Godot itself has a 3rd-party licenses tab in their about dialog).
Thanks for the video! I was looking into state machines and state charts recently, from my understanding state charts helps solve certain problems that occur with finite state machines (state explosion) and it overall makes things a bit clearer and easier to understand. My question is, is there a reason to use FSMs over state charts? (perhaps performance reasons?)
AFAIK, ease of use. If you're only going to be at one state at a time, you don't really need state charts. State charts have been really useful for me to combat so-called 'state explosion', when you need separate states for every combination of atomic states.
Amazing Addon and great tutorial!
I'm having trouble reusing basic states such as Wander or Chase, where any enemy does basically the same. Since the code is handled in the main script of the enemy and not on the State itself.
Any suggestions on how to use this addon whilst being able to reuses states effectively, without having to duplicate code?
Many thanks for the addon and the tutorial.
Very nice job, thank you for the guide and the addon!
Great guide, thank you.
Wtf, it's super easy! Thanks man!
Very well done visual explanation of this add-on. While reading the add-on docs it was recommended to watch this. You're using version 0.3.1 and I'm using 0.13.0 and all of this is still valid which is amazing in itself. My only qualm is keep the name of the states and add *_whatever*. IE: AtomicState_idle. This allows the viewers to understand what line/state is what all the time instead of only when added and completely renamed. So many tutorial vids rename all the nodes that even 2 minutes in I'm like, "f-m, wth was that "fluffy_bunny_burps" node again?" Followed by, "Geez, TH-cam needs a 10sec rewind button.." Otherwise great tutorial and I'm going to explore using this add-on in more complex ways!
Double tap your screen on the left side or press your left arrow key to rewind
@@ScumlordStudioHey thanks, I only use a computer the the left arrow key is a rewind! You're awesome!
@@kindavacant7843 no worries!!
do you know if synchronizing the states with godot built in multiplayer would work? I got the state chart working with my movement animations and some combat states. trying to know if this is usable in multiplayer. Thanks so much!
This looks super interesting, can't wait to refactor my code and find new ways to use this haha
Hey, great video. I had a slight problem while using it though, which is if I check for an Input inside of a state"s _physics_process, if the state transitions, there seems to be a short window in which the Input is not being acknowledged by either of the states. Is there a way around this?
State transitions are usually done within the same frame so there should not be any delay during state transitions. Could you maybe open up an issue at github.com/derkork/godot-statecharts/issues/new and give some more details about your case?
@@godotneers Hey sorry I haven't had much time recently, but I found a workaround. I spent a while trying to replicate what was happening and couldn't so I probably messed something up really badly on my end lol. Also I haven't really used github before but if I get the time I'll try to put something up
But just in case there's a simple answer I'm missing, what I was trying to do was set up a coyote jump mechanic for a platformer, but whenever I changed states from wall to air or from floor to air, there would be a couple frames where the jump input wouldn't be registered by my states, but it would be registered by the normal _physics_process. Whenever I would check to see if the state was active whenever I jump, it would return active, but the state physics_process wouldn't detect any Inputs. My workaround was just to put the coyote jump logic in the main _physics_process, and it works well enough.
Either way, this addons made my time in godot way better, so I'm not complaining lol
Great tutorial as always! The only downside I can see here is that with a complicated character, you would end up with a very long script. Is there any easy way to break the code for each state into its own script?
Because the library uses signals to call into your code, you have a lot of freedom how to organize your code. You can write everything into one script like done in this video, you can have scripts dealing with certain aspects (e.g. movement, attacking) and call into these, or you can make one script per state and call into that. Whatever way works best for your game. See also this discussion here: github.com/derkork/godot-statecharts/issues/113
Well, lets feed the algorithm...
Good work keep it up.
Nice tutorial. By the way, even though I understand that I shouldn't track the current state in my code, is it possible to access it? Also, can there be two (or more) nodes directly under the StateChart? Thanks!
The thing is, that in a state chart there can be multiple states active at the same time. If you really want to know whether a particular state is currently active, you could get the node of this state using a node path or scene unique node and then check its `active` property (e.g. "var some_state = %SomeState; if some_state.active: do_things()" - TH-cam comments really aren't great for posting code). Then again I think doing so is sort of bypassing the library as you now introduce if/else code regarding states. So if I could help it, I would not do it - but in the end it needs to work for you, and if this is an easy and maintainable way to solve your problem, then go for it.
You cannot have multiple states directly below the state chart node, but you can put a parallel state below the root and then add multiple compound states below that, which effectively gives you what you're after.
@@godotneers I appreciate your tutorials and replies; they have helped me learn a lot. I can't wait for getting more from your next video.
holy shit ive been hyperfocusing on figuring out how to build a state chart addon for godot !! what are the chances !! hell yeah
Props to you master!
Looks useful, but doesn’t having that transition guard code hidden away in the inspector, rather then being part of the script get a bit confusing?
If you have more than a single expression in there it can be, yes. Usually there should be only a simple expression in there like `health > 0`. If you need complex logic in your guards, it may be better to put this in your code and just send an event as the result of this complex logic which will trigger a state change.
Hey this is an amazing plugin! Thanks for creating this!
I'm having one issue. How do I make it so after an animation plays it goes back to the idle animation. I'm trying to add an attack animation to your frog from your platformer example but I'm having some issues. I added the attack animation to the animation tree and added the required nodes for the attack state but I'm not sure how to make it so the attack only goes back to the idle state after the animation finishes.
The only thing that's working for me right now is if I add a delay to go back to the idle state which is the exact length of the attack animation. Any help would be appreciated.
Would you mind opening up an issue at github.com/derkork/godot-statecharts/issues and posting some screenshots of what you have set up and what the goal is? Just from a textual description it's really not possible to give solid advice.
Thanks for this great tutorial and the dive into this Plugin.
If you decide to do a second part to this, I was wondering how I could implement the following:
1. Take the traditional body mechanics states, like idle, move, jump, attack etc. but then also take mindset states like, normal, wounded, low profile, aggressive, etc. With a traditional state machine someone would need to create a state for each combination. But I was wondering how these multiple state chart would help solving that issue. That way different animations could be played when a character is moving aggressive vs move wounded.
2. As an alternative it could be interesting to have a character who is controlled by the player but then can become an autonom character in a scripted sequence (in a cut scene for example) and then return the control to the player.
Thanks again!
1. You don't necessarily need to use different states to blend animations. Godot's animation tree can blend different animations together, so you could for example just calculate a "hurt" value, maybe current_health / health and use that as a blending value in a Blendspace1D which blends the hurt animation with the normal animation. I'm not an expert on the animation blending, but this seems easier than trying to do this with a state machine.
2. I feel this would also be easier to do with a smoke and mirrors solution. E.g. you can insert a copy of the player with a different script for animation in a cutscene and then just delete the copy when the cutscene is done, while suppressing player input in the meantime.
If you get errors like "Must be a child of StateChart" while the node clearly is a child of one, restart Godot and it will work.
If you didn't have parallel states, could you get the same functionality by implementing them as another state tree? Apart from having to mirror the events and expression properties to two trees rather than one, it would do the same thing right?
Also, is it possible to write scripts on the actual states themselves? In some cases it might make sense to contain it there rather than having to put all logic into one large parent script. They have a script icon in the tree, but blue rather than white, I wonder what that means.
Yes, depending on what you're trying to do you might be able to model this with multiple trees as well. If you need state changes across the trees this might become a bit more difficult. As for your script layout you can pretty much use any layout you want because the library uses signals to call into your code rather than requiring you to derive from some base class. E.g. you can also put components on the root node and each component can be called by the state chart depending on which state it is in (e.g. a movement component, a targeting component, etc.). Technically you can also extend from the AtomicState class and write your code directly into each state - just be careful to call "super" when you override functions otherwise you may see _interesting_ behaviour ;).
Amazing vid!
OMG! god tier! thx u
amazing addon. i hope i am not asking something that is in the documentation, i just got finished watching the video. can you add the signals to enter or exit each state to the state node themselves or should everything always be added to the primary script. i am guessing that the State chart nodes inherit from the primary script but if the signals for enter and exit are attached to one of the states would the State chart still work. i guess i am trying to compartmentalize all of the code separately into different scripts so when the character enter into a particular state i can drill down to that states script to add more functions or correct existing functions. i hope this makes sense. even if that is not the case this addon seems amazing. thank you for all of your hard work.
The state nodes (atomic state, parallel state, compound state) have scripts from the library attached to do their work, so you cannot directly add signal handling code to them. But you could create your own script deriving from say "AtomicState" and then put your signal handling in there. Then you would need to assign the correct script to the state node. Because the add-on uses signals to drive your code rather than mandating that you derive from a class, you are free to organize code in any way that works for you.
I personally like having everything in a single script because it simplifies accessing shared state (like health points, position, etc.) and it also makes for easier re-use of common functionality (e.g. if i want the same function to run in multiple states, i can just write it once and call it from the other functions without having to figure out where I would put it). With Godot 4.2 there will be code regions in GDScript so you can then put everything regarding to a single state into a region, fold it away and have a drill-down this way.
But in the end you are free to do whatever works best for you and your game, so if you rather have separate scripts on separate nodes, you can totally do this.
@@godotneers ok thank you for your response. Thanks for clarifiying my question and thank you for letting me know that there is another approach i can take if it feels more comfortable in the end. I think these state charts are great and much cleaner than implementing a state machine the traditional way.
Last question do you have any plans or ideas about any future revisions to state macines that could combine or drive the state machine in the animation tree with with these state charts. I think the upcoming node in 4.2 that combines the animation player & animation tree sparked this idea
There are some helper nodes which can start animations as part of a state change and also can travel within an animation state machine, however these are marked experimental and I'm actually inclined to remove them again. Controlling animations is somewhat tricky and there are also conflicting workflows. Some people like a workflow where the end of an animation triggers a state change and so the animation has a direct influence on gameplay. Others treat animations as pure visuals and all timings are determined by the game code and animations just have to match these timings. Also in some cases animation states and gameplay states have no direct 1:1 mapping. E.g. there may be different animations for walking and running but internally there could be only one state for walking and which animation is picked depends on the speed of the player. As such it is very difficult to provide an integration between state charts and the animation system that provides an ease of use advantage over just doing stuff yourself but at the same time is powerful enough to not only work in a few simple cases. I currently have no good idea on this topic so I rather not recommend anything half-baked.
@@godotneers thanks for the explanation again. I may check out those helper nodes just to see how they work. They may be good for quick prototyping. Thanks once again
So I am trying to learn Godot and gdscript and I'm having a bit of an issue.. how do you manage the auto complete being so weak? In something like C# I can heavily rely on intellisense to code, so I don't have to remember every bit of syntax for everything. But in gdscript, like at 6:49 for example, it isn't always there to help. Is this resolved with stricter typing? If so, why is it that SO MANY tutorials don't type nearly any of their vars?
Thank you for the video though, state charts look super useful.
GDScript's autocomplete can be a bit hit and miss. I found that adding type information (e.g. var some_area:Area2D = some_value) generally helps with autocomplete, but even then it's often hit and miss. If you take shortcuts like the $-Notation the editor will often not be able to give you autocomplete as it cannot resolve the type. It's just something one has to get used to with a weakly typed language like GDScript.
As for why people don't type their code in videos I can only speculate it's probably to keep the video shorter and not confuse people with additional syntax.
@@godotneers That makes perfect sense and is what I have also found to be true myself in the few days since I left that comment. Thank you so much for the reply and for your SUPER high quality videos!
If you put the following at the top of your script (instead of accessing $StateChart every time), autocomplete will then work:
@onready var state_chart: StateChart = $StateChart as StateChart
...but yeah, kind of annoying - I wish Godot would fix that.
@@GregX999 Good to know, I have used that in some cases and it works sometimes and doesn't others :/. I have just come to terms with the fact that I'll have to deal with it only working sometimes. For sending events to the state chart I've just been making wrapper functions that hold them so I can just call those functions to call the events.
Great video!
Hi, I'm considering using your state chart plugin but was wondering if there was a way to implement random behavior. Would it be as simple as just sending a random event to the state chart?
There are a few ways in which you could implement this, but sending random events seems to be a nice and simple solution, so that's what I would go with. Another option would be guards that calculate a random number and only let the transition happen if the number exceeds a certain threshold. This would be useful if there is a certain chance that a state switch should happen (e.g you have a 55% chance to get poisoned on a hit).
@@godotneers oh I like that idea! That's a good one 😈. Thank you!!
This is so cool
I'll be taking that
I just found out about this amazing tool. I usually use a node tree for the state machine so every state gets there own code. But in the video you use a single script for all logic? I still would like to have a script for every state for better organisation. Should I make a separate States Node (as sibling to the State Chart) with all states (as children)?
Well the library is somewhat opinionated in that regard. You can of course divide your script up into multiple scripts which you add to additional nodes and the library will happily work with it, because it uses signals to communicate with your nodes. Godot also now has code regions with 4.2 so you might not even need multiple scripts anymore to keep things organized.
Hi im very thankful for this tool but im currently confused as to how to set up historystate nodes. the docs says i just put them under a compound state and set a transition to it. But I did that, I had a movement compount state with atomic states (walk, sprint, idle, jump). I want to be able to go back to the last state after transitioning to jump.
so I transition to my history state after the player is on floor yet the historystate keep going to the default state.
thanks master now i can aply it☕️🌹
I've another question, if you don't mind. Have you noticed, or have any knowledge of, any situations that cause memory leaks with this addon?
Not really. Memory leaks are somewhat difficult to trace in Godot as the profiler only gives you object amounts but no breakdown of the type of these objects, so its often very hard to say which part of the code causes a leak. From a cursory inspection of the examples that come with the project I couldn't find any memory leak. If you happen to be able to reproduce one I would like to know about it. github.com/derkork/godot-statecharts/issues/new
@@godotneers thank you!
I was trying to use the other nodes/methods based on the provided documentation but they are not functioning for me at all. _run_transition specifically isn't working. I assume that since you did not show any of the other nodes/methods in this video, that not everything has been fully implemented/tested, but perhaps I'm just misunderstanding the documentation.
The only node you need to interact with is the root state chart node and there you basically only need one method - `send_event`. If you have two states A and B and want to switch between those, you will first create a transition in the editor below A that transitions to B and reacts to some event, e.g. `some_event`. Then from your code you just call `send_event("some_event")` and the state chart library will switch from A to B if A is currently active. So you never call `_run_transition` manually. In general all methods and fields starting with an `_` are intended to be private and not be called/used from outside.
i'll check this out!
Is there a good way to sync with an animation or animationtree?
Nice tutorial, it took some effort for me to follow along for the first time as I'm using C# but I got a working example. Few notes;
This part isn't necessary if the signals are setup in the godot editor: for the state_processing equivalent in C# when I was setting up the signals, I was getting an error trying to pass the delta, the manual didn't give C# example with a parameter but I got it working looking like this under the _Ready() -
'state.Connect(StateChartState.SignalName.StateProcessing, Callable.From((float delta) => OnObservingStateProcessing(delta)));
Where state is the 'Observing' node state and OnObservingStateProcessing is my callable method that does the LookAt(enemy.Position).
As that event is processing on every frame the callable method should look like that to accept a parameter. The callable method can also be used more verbosely like this: new Callable(this, nameof(OnObservingStateProcessing))
One other thing that threw me off which is not C# related specifically, but that by leaving the Delay in Seconds value of the transition blank instead of 0.0, I was getting an expression exception in the console debugger, but I thought that was a problem with the ExpressionGuard set in the ToBerserk transition. After some trial and error thinking I needed to call or defer SetExpressionProperty of the enemyentercount it was just me assuming a blank value was being handled. That's my oversight but would be good if the debugger could spit out a more direct message.
Also introducing the parallel state and restructuring the nodes broke my GetNode calls for the Idle and Observing nodes, returning null as it couldn't find them until I changed the path to include the StateChart/Root/Alertstate. Might be a language difference with godot but that can be fixed with a singleton or something to manage the node paths, plenty of tutorials for that I'm sure.
Besides all that I can't wait to expand on it further for more states, and hope the C# support continues!
Thanks man.
Do you lose perfomance by using a signal as a process?
Like, in Unity i wouldnt use a Actions or UnityEvents invoked on a Update, because as far as i know its slower.
I could use the process on the main script and check the current state instead, or someting to avoid using that signal, but im curious
Emitting a signal is simply a method call, so this will cost you as much performance as calling a method from _process will cost you. This overhead is usually negligible. If you want to find out for your particular use case there is a performance testing setup which ships with the project. You can set up the state machine as you'd like it and then have a thousand copies of it running at the same time. Then you can use the profiler to identify bottlenecks. The bottlenecks will likely be not in the signal emitting part.
@@godotneersOooh thanks, i normally use unity at work and im trying to swap to godot at home. When i read about signals i always imagine them as c# Actions since thats what im used to.
Thanks for the info!
They are similar to C# events. What's really nice about them is that they automatically disconnect themselves if one side is destroyed. This takes away a lot of the bookkeeping you'd normally have with C# events.
Maybe I missed something, but I don't really like the states knowing how/what to transition to. I prefer to have a parent notice what's going on and transition to different states without the states knowing about other states. But maybe I'm getting too deep into decoupling, and I should be okay with states knowing about each other. I do end up with a decent amount of code in the parent object going through logic deciding which state to be in 🤷
Well in the "classic" way of doing things, there is usually code which actively activates/deactivates states, like you said. In such implementations the concept of a "transition" doesn't even exist. Which as you observed translates in a lot of if/else if you control everything from a central parent. Alternatively you have code in states which directly transitions to other states. In this case the states also know about other states.
With the transitions this logic moves into the state chart. You just send an event and based on the current state that event can lead to different things. Nothing could happen, or one or more transtions could fire. The states themselves don't really know about other states. They just send events and the state chart is reacting onto it. The state chart is the entity that knows all the rules. So you basically replace your big if/else with a bunch of nodes in the scene.
If you rather control stuff in code there is nothing wrong with that and you can just do that as well and don't use the library. I personally find the separation quite beneficial and things like delayed transitions are quite useful as well and putting these into a big if/else is probably a bit more difficult. But just because it works for me doesn't mean it works for everyone. So if you rather roll your own because that works better for your project and your personal preferences, that is totally fine - in the end we just want to make a game and nobody really cares how its done internally as long as it works.
Any plans to make one of these that work for 3D? stuff like the debugger wont work for 3D
You can put the debugger in a canvaslayer (like any other UI), it will work just fine in a 3D game as well. The latest version also has the debugger integrated in the editor, so you can have the debugger open in your editor on one screen and have the game running on a second screen.
Is it possible to have a new script inherit from "State" and override virtual methods for state_entered and state_exited? Or does it only work with signals? When traits become available in gdscript it would also be even nicer to use a trait and implement a method override for that =)
Technically nothing is stopping you from deriving your custom class from `AtomicState` and then overriding the methods, but this is not how the library is intended to be used. Using the signals has multiple benefits:
- you can more easily re-use code across states e.g. by connecting two different state signals to the same method. Also helper functions can be used more easily this way. The platformer example shows this by having the jump code only in one place even if it is used by multiple states.
- you can have all code regarding an entity neatly in the same script instead of having it scattered across multiple small state scripts
- access to data is simplified: if you have multiple state scripts in a nested tree structure you would need a way of accessing entity data usually by some calls to `get_parent()` which is a maintenance burden and prone to breakage if you reorder states.
- library surface is minimized - there are only two functions your code will ever use to interact with the state chart (`send_event` and `set_expression_property`). This makes it a lot easier to reorganize internals e.g. for improved performance without breaking existing code.
As for traits, I cannot really comment on that as the discussion on this feature on the Godot issue tracker seems to be going nowhere right now, so it's currently unclear if and when such a feature would materialize and how the implementation would actually look.
Could you make a video showing how the animation features of statechart work? Its hard to wrap my head around it.
nice asset
all this can be done with godot two dimensional nodes with scripts
yet the debugger is very convenient
I agree that this example can probably also be easily implemented with a few scripts and without a library. In fact it _should_ be done without a library if it is that easy. But the idea behind this video was to show how the library works in general and what features it provides and how to use them.
A more complicated game logic would probably have made a better case for using this library over hand-written code to simplify things. On the other hand it would have gotten in the way of understanding the concepts. So I decided to go for a simpler example.
If you want to see some more complex examples, have a look at the bundled example projects.