State machines and state charts in Godot

Sdílet
Vložit
  • čas přidán 15. 06. 2024
  • Hello Godotneers! With the Godot State Charts library you can easily create complex behaviour in your game with very little code. In this video I'm giving you an overview on the features and how to use them.
    Links:
    -------
    - State Charts library - github.com/derkork/godot-stat...
    - Manual - github.com/derkork/godot-stat...
    00:00 Introduction
    00:30 Installation of Godot State Charts
    01:21 Scene Setup
    04:26 Adding the state chart
    07:02 Switching States with Transitions
    08:24 Using the state charts debugger
    11:12 Running code during a state
    13:44 Running code when entering a state
    14:31 Delayed transitions
    15:38 Using parallel states
    18:48 Running transitions conditionally
    21:03 Immediate transitions
    23:26 Conclusion

Komentáře • 218

  • @commentingexistentialcrisi9564

    This is probably the best addon in the asset store. I have used it in every single one of my projects.

  • @GregX999
    @GregX999 Před 9 měsíci +95

    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).

    • @TheLastPhoen1x
      @TheLastPhoen1x Před 8 měsíci +9

      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.

    • @hiiambarney4489
      @hiiambarney4489 Před 8 měsíci +10

      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

    • @gonderage
      @gonderage Před 5 měsíci

      ​@@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

    • @romanperry3385
      @romanperry3385 Před 4 měsíci +1

      ​@@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.

    • @otapic
      @otapic Před 3 měsíci

      @@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

  • @chutney88
    @chutney88 Před 3 měsíci +3

    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.

  • @Pettfej
    @Pettfej Před 9 měsíci +17

    This is my new favourite Godot tutorial channel! Keep it up!

  • @localvoidlander8093
    @localvoidlander8093 Před 6 měsíci +5

    Finding tools like this is exactly why I fell in love with Godot, thank you so much for making this!

  • @4.0.4
    @4.0.4 Před 7 měsíci +5

    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.

  • @ChrisTutorialsYT
    @ChrisTutorialsYT Před 7 měsíci +3

    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.

  • @tsplitart
    @tsplitart Před 9 měsíci +5

    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

  • @woodenfences
    @woodenfences Před 2 měsíci

    Really enjoyed the zoom in on 'delay'. Made me go "Ooooooh..." But, I hadn't seen the parallel states at that point. Great stuff!

  • @willd2609
    @willd2609 Před 2 měsíci +1

    i have been coding state machines by hand, this is SO MUCH BETTER!

  • @adammikulis6211
    @adammikulis6211 Před 8 měsíci +4

    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.

  • @Android480
    @Android480 Před 4 měsíci +1

    Pretty powerful. I discovered states as entities, and nested FSMs, but transitions as entities is clever. That and parallel states.

  • @MHellman
    @MHellman Před 8 měsíci +1

    Leaving a well deserved like and comment on your excellent work to help the growth of your channel. Really well explained! 😀

  • @mohamedmoh5789
    @mohamedmoh5789 Před 9 měsíci +2

    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

  • @Asguardian22
    @Asguardian22 Před 9 měsíci +4

    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
      @godotneers  Před 9 měsíci +1

      Glad you like the video! Regarding additional videos are there some subjects you would be particularly interested in?

    • @flora265
      @flora265 Před 9 měsíci

      @@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.

    • @Asguardian22
      @Asguardian22 Před 9 měsíci +1

      @@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.

    • @godotneers
      @godotneers  Před 9 měsíci +5

      @@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 ;).

    • @Asguardian22
      @Asguardian22 Před 9 měsíci

      @@godotneersGreat explanation. Thank you for taking the time!

  • @Standbackforscience
    @Standbackforscience Před 9 měsíci +9

    you make amazing guides, please keep it up!

  • @tabatecuenta7192
    @tabatecuenta7192 Před 4 měsíci +1

    Such great news for me! Yeah. State Machines look so menacing, Im glad there is something to make it easier. Love the color also 😂

  • @netlooker5841
    @netlooker5841 Před 9 měsíci +6

    Respect! Quality content here :) I cannot wait for more.

  • @juanch.1484
    @juanch.1484 Před 8 měsíci +1

    I'm very impressed with this asset. Thanks for the tutorial man, keep it up 😊

  • @BigWin24410
    @BigWin24410 Před 7 měsíci

    Thank you for showing State Charts, looking forward to seeing what I can do with that.

  • @_asyncawait_
    @_asyncawait_ Před 8 měsíci

    This is brilliant! I’m already thinking about how this is going to make my code a lot simpler.

  • @bananabarddev
    @bananabarddev Před 6 měsíci +4

    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!

  • @Anonyross
    @Anonyross Před 9 měsíci +1

    Love this, and I'm especially grateful for the manual!

  • @kentang5103
    @kentang5103 Před 9 měsíci

    happy to see plugin helps writing state machine.

  • @SattarPahlavan
    @SattarPahlavan Před měsícem

    one of best teachers I've ever seen . thank u so much

  • @olson5000
    @olson5000 Před měsícem

    Great addon and tutorial - subbed!

  • @zedmanul7472
    @zedmanul7472 Před 9 měsíci +4

    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)

    • @godotneers
      @godotneers  Před 9 měsíci +3

      I'm glad you found it useful. What kind of game are you working on?

    • @zedmanul7472
      @zedmanul7472 Před 9 měsíci +2

      @@godotneers A 2D platformer with a combat system!
      The state machine is for the enemy ai

  • @manligheten
    @manligheten Před 9 měsíci

    Very nice job, thank you for the guide and the addon!

  • @Notreal76
    @Notreal76 Před 6 měsíci

    Thank you for this very informative tutorial.

  • @norvelx1
    @norvelx1 Před 6 měsíci

    Amazing tool. I am currently use it to implement enemy logic in my game.

  • @BazSupport
    @BazSupport Před 8 měsíci

    This is my go to FSM now, thank you!

  • @ghostradiogames
    @ghostradiogames Před 7 měsíci

    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!

  • @SirPigeonz
    @SirPigeonz Před 9 měsíci

    Amazing Addon and great tutorial!

  • @larrylevandowski8023
    @larrylevandowski8023 Před 7 měsíci

    Really good stuff. Well explained.

  • @accumulator4825
    @accumulator4825 Před 8 měsíci

    Incredible plugin, thank you!

  • @oliviermalige1733
    @oliviermalige1733 Před 8 měsíci

    Thanks you for this clear explain for this addon and state charts in generaly

  • @red3tango
    @red3tango Před 9 měsíci

    This looks super interesting, can't wait to refactor my code and find new ways to use this haha

  • @maxmustermann3938
    @maxmustermann3938 Před 9 měsíci +13

    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

  • @zemeio1184
    @zemeio1184 Před 8 měsíci +26

    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?

    • @Demozo_
      @Demozo_ Před 8 měsíci +1

      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.

    • @Interfacetypeseven
      @Interfacetypeseven Před 7 měsíci +1

      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.

    • @jasonm911
      @jasonm911 Před 7 měsíci

      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

    • @satyayuga0
      @satyayuga0 Před 7 měsíci +2

      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

  • @georgezimmer5622
    @georgezimmer5622 Před 4 měsíci +1

    This is the most impressive plugin in the entire AssetLib, it's almost an auto include in every projects.

    • @godotneers
      @godotneers  Před 4 měsíci

      Thank you very much, I'm glad it is this useful to you!

    • @georgezimmer5622
      @georgezimmer5622 Před 4 měsíci

      @@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.

    • @godotneers
      @godotneers  Před 4 měsíci

      Yes I'm the author. I created this video for people who like to learn visually rather than reading a manual.

  • @ilyashinaurov4846
    @ilyashinaurov4846 Před 8 měsíci

    Great guide, thank you.

  • @ahurafsfsa
    @ahurafsfsa Před 9 měsíci

    I've been using own state maschines for godot all the way. But for my new project I will be using this one.

  • @TheValkire
    @TheValkire Před 3 měsíci

    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.

    • @godotneers
      @godotneers  Před 3 měsíci

      Glad this is useful for you! Could you give me a bit more details about what you mean with "smooth transitions"?

    • @Crabtorias
      @Crabtorias Před 3 měsíci

      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

    • @godotneers
      @godotneers  Před 3 měsíci +1

      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.

    • @Crabtorias
      @Crabtorias Před 3 měsíci

      @@godotneers well hot dang, thanks!

  • @friendlyfox2189
    @friendlyfox2189 Před 9 měsíci +1

    thank you for this!!!

  • @MemeMand1996
    @MemeMand1996 Před 2 měsíci

    Amazing vid!

  • @justyoutubin
    @justyoutubin Před 7 měsíci +2

    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.

    • @godotneers
      @godotneers  Před 7 měsíci +4

      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.

    • @davvedp9309
      @davvedp9309 Před 4 měsíci

      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 ❤

    • @godotneers
      @godotneers  Před 4 měsíci +1

      @@davvedp9309 The state charts plugin actually has C# support, so you can also use it in C# based projects.

  • @AgustinQuetto
    @AgustinQuetto Před 8 měsíci

    Wtf, it's super easy! Thanks man!

  • @tayete
    @tayete Před 7 měsíci +15

    Simply fantastic. This addon should be included with Godot core (as Beehave and YAFSM). Awesome work.

  • @DerSolinski
    @DerSolinski Před 9 měsíci

    Well, lets feed the algorithm...
    Good work keep it up.

  • @Musicalcode313
    @Musicalcode313 Před 9 měsíci +3

    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.

  • @gadmas2670
    @gadmas2670 Před 9 měsíci

    Great video!

  • @Manu0jedi
    @Manu0jedi Před 5 měsíci

    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

  • @Bigsperg
    @Bigsperg Před 3 měsíci

    really cool. Talented!

  • @egormeno
    @egormeno Před 8 měsíci

    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

  • @BarcelonaMove
    @BarcelonaMove Před 8 měsíci

    Props to you master!

  • @apoorvpandey3D
    @apoorvpandey3D Před 9 měsíci +1

    wow wow wow. This is a gamechanger

  • @Zane_2029
    @Zane_2029 Před 2 měsíci

    I'll be taking that

  • @ivysly
    @ivysly Před 9 měsíci

    This is so cool

  • @comaharmonium3807
    @comaharmonium3807 Před 6 měsíci

    OMG! god tier! thx u

  • @iamsecrets
    @iamsecrets Před 9 měsíci

    i'll check this out!

  • @zachnewby4739
    @zachnewby4739 Před 5 měsíci

    Thanks man.

  • @HomeFrogGames
    @HomeFrogGames Před 4 měsíci

    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!

    • @godotneers
      @godotneers  Před 4 měsíci

      It never hurts trying build something yourself to really understand how it works and why it works, so go for it!

  • @OneCSeven
    @OneCSeven Před 8 měsíci

    holy shit ive been hyperfocusing on figuring out how to build a state chart addon for godot !! what are the chances !! hell yeah

  • @bbsnake01
    @bbsnake01 Před 9 měsíci +1

    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!

    • @godotneers
      @godotneers  Před 9 měsíci +6

      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.

  • @owenlloyd2528
    @owenlloyd2528 Před 8 měsíci

    Thanks :)

  • @goblinslayer5404
    @goblinslayer5404 Před 8 měsíci +2

    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?)

    • @Korn1holio
      @Korn1holio Před 14 dny

      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.

  • @ElNightmareYT
    @ElNightmareYT Před 6 měsíci +1

    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.

  • @KIBERTAIM
    @KIBERTAIM Před měsícem

    Thanks add More Videos

  • @lalalala99661
    @lalalala99661 Před 2 měsíci

    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?

    • @lalalala99661
      @lalalala99661 Před měsícem

      I had the same question, finaly i just testet it yes you can use multible state Charts.

  • @DizzyTurtlz
    @DizzyTurtlz Před 7 měsíci

    Could you make a video showing how the animation features of statechart work? Its hard to wrap my head around it.

  • @FromNewRadius
    @FromNewRadius Před měsícem

    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?

    • @godotneers
      @godotneers  Před měsícem

      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).

    • @FromNewRadius
      @FromNewRadius Před měsícem

      @@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.

  • @NeZversSounds
    @NeZversSounds Před 9 měsíci +3

    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?

    • @godotneers
      @godotneers  Před 9 měsíci +2

      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.

  • @intropret
    @intropret Před měsícem

    Thanks man..
    Can you make a tutorial how to implement this to player control and manage animation

  • @kindavacant7843
    @kindavacant7843 Před 4 měsíci

    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, CZcams needs a 10sec rewind button.." Otherwise great tutorial and I'm going to explore using this add-on in more complex ways!

    • @ScumlordStudio
      @ScumlordStudio Před 3 měsíci +1

      Double tap your screen on the left side or press your left arrow key to rewind

    • @kindavacant7843
      @kindavacant7843 Před 3 měsíci +1

      @@ScumlordStudioHey thanks, I only use a computer the the left arrow key is a rewind! You're awesome!

    • @ScumlordStudio
      @ScumlordStudio Před 3 měsíci

      @@kindavacant7843 no worries!!

  • @rhyspuddephatt
    @rhyspuddephatt Před 5 měsíci

    Is there a good way to sync with an animation or animationtree?

  • @byj5970
    @byj5970 Před 3 měsíci

    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?

    • @godotneers
      @godotneers  Před 3 měsíci

      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).

  • @vcd200044
    @vcd200044 Před 8 měsíci

    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!

    • @godotneers
      @godotneers  Před 8 měsíci +1

      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()" - CZcams 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.

    • @vcd200044
      @vcd200044 Před 8 měsíci

      @@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.

  • @RealPigeonz
    @RealPigeonz Před 9 měsíci

    I rly love this State Machine Addon!

  • @lucazfc
    @lucazfc Před 9 měsíci

    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 =)

    • @godotneers
      @godotneers  Před 9 měsíci +2

      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.

  • @scottwelfare9267
    @scottwelfare9267 Před měsícem

    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?

    • @godotneers
      @godotneers  Před měsícem +1

      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

  • @bennicus4901
    @bennicus4901 Před 2 měsíci

    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.

    • @godotneers
      @godotneers  Před 2 měsíci +1

      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 ;).

  • @americoperez810
    @americoperez810 Před 8 měsíci

    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?

    • @godotneers
      @godotneers  Před 8 měsíci +1

      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).

    • @americoperez810
      @americoperez810 Před 8 měsíci

      @@godotneers oh I like that idea! That's a good one 😈. Thank you!!

  • @lassipls
    @lassipls Před 3 měsíci

    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.

  • @brabes76
    @brabes76 Před 7 měsíci

    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.

    • @godotneers
      @godotneers  Před 7 měsíci

      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.

    • @brabes76
      @brabes76 Před 7 měsíci

      @@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

    • @godotneers
      @godotneers  Před 7 měsíci +1

      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.

    • @brabes76
      @brabes76 Před 7 měsíci

      @@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

  • @elderdragon7856
    @elderdragon7856 Před 4 měsíci

    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)?

    • @godotneers
      @godotneers  Před 4 měsíci +1

      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.

  • @boozebeard9501
    @boozebeard9501 Před 4 měsíci

    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?

    • @godotneers
      @godotneers  Před 4 měsíci +1

      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.

  • @jehree9850
    @jehree9850 Před 9 měsíci +1

    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.

    • @godotneers
      @godotneers  Před 9 měsíci +1

      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.

    • @jehree9850
      @jehree9850 Před 9 měsíci

      ​@@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!

    • @GregX999
      @GregX999 Před 9 měsíci +1

      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.

    • @jehree9850
      @jehree9850 Před 9 měsíci

      @@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.

  • @woolydrool
    @woolydrool Před 9 měsíci

    This plugin is really cool but for me send_event() returns null, as if the StateChart node doesn't exist. I've tried every way I can think of to get reference it (via code, via the inspector etc) and the plugin is installed and enabled in project settings. I actually can't send any methods to it (set_expression_property etc). Have you ever encountered this issue? thanks! Godot version 4.1

    • @godotneers
      @godotneers  Před 9 měsíci +1

      It's hard to say without knowing your setup. Since the CZcams comments are rather limited, could you please open an issue at github.com/derkork/godot-statecharts/issues/new and show your code and some screenshot of how your tree is set up? Thanks!

  • @Rioni
    @Rioni Před 8 měsíci

    In 20:12 it transitions to idle despite the body being entered, I guess it can transition when there is a delay and the event it lost. Isn't there a way to cancel the transition? Like assuming we are in the target state listening to it transition and when it's fulfilled, cancel the current delay and move to that new state. Not sure if that makes sense. But what I would expect in 20:12 is at least going inmedeately to observing state again. Is there some way to fix that?

    • @godotneers
      @godotneers  Před 8 měsíci

      Yes this was a small oversight on my end. I overlooked the possibility that you can re-enter the observing state while you are having a delayed transition running. You can fix this by adding a transition on the "enemy_entered" event in the Observing stating that transitions to Observing state. This will cancel the running transition to normal state as there can only ever be one transition active per state.

    • @Rioni
      @Rioni Před 8 měsíci

      @@godotneers That's the first thing I tried out of curiosity! And while it can be a little cumbersome it works well, I don't think you'll have lots of transition states to face this problem so I wouldn't consider this a priority, but would be nice if it can be automated somehow in the future

  • @williamking1008
    @williamking1008 Před měsícem

    Hi, i have been testing this add on with good success. However one thing i cannot work out is how to change the delay seconds to a variable is this possible?

    • @williamking1008
      @williamking1008 Před měsícem

      I have worked it out you can just reference the transition node with $transitionnode.delay_seconds = whatever time you want to set

  • @0MVR_0
    @0MVR_0 Před 7 měsíci

    nice asset
    all this can be done with godot two dimensional nodes with scripts
    yet the debugger is very convenient

    • @godotneers
      @godotneers  Před 7 měsíci

      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.

  • @vettie
    @vettie Před měsícem

    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.

    • @godotneers
      @godotneers  Před měsícem

      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.

  • @ManuCGDev
    @ManuCGDev Před 3 měsíci

    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

    • @godotneers
      @godotneers  Před 3 měsíci +2

      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.

    • @ManuCGDev
      @ManuCGDev Před 3 měsíci

      ​@@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!

    • @godotneers
      @godotneers  Před 3 měsíci

      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.

  • @DucktatorD
    @DucktatorD Před 5 měsíci

    Any plans to make one of these that work for 3D? stuff like the debugger wont work for 3D

    • @godotneers
      @godotneers  Před 5 měsíci +2

      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.

  • @ajinkyax
    @ajinkyax Před 6 měsíci

    can we not write state specific code in separate files ?

    • @godotneers
      @godotneers  Před 6 měsíci

      You can. The library does not impose any rules on how you organize your code. You can put the code in various nodes and just link the state signals to the node of your liking. If you do it this way you will need to find a way to access shared data (like position, health, etc.) though, that's why I usually keep everything in one file. I also think it helps with readability, but as I said, you can organize it any way you like.

  • @Korn1holio
    @Korn1holio Před 14 dny

    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?

    • @godotneers
      @godotneers  Před 14 dny +1

      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

    • @Korn1holio
      @Korn1holio Před 7 dny

      @@godotneers thank you!

  • @niko887ify
    @niko887ify Před 7 měsíci

    Hey im having issues with the part where the watchman goes bersek when the enemy entered more than 2 times. I followed everything and I'm still at normal

    • @godotneers
      @godotneers  Před 7 měsíci

      CZcams comments really are not suitable for getting help with something. I would need to see your tree and the code you wrote - both of which cannot be posted here. If you'd like you can open an issue at github.com/derkork/godot-statecharts/issues/new and describe your problem there, maybe with a screenshot of your tree and the matching code. Then we can have a look at it :-)

    • @niko887ify
      @niko887ify Před 7 měsíci

      @@godotneers OH NO SORRY I ACTUALLY FORGOT TO DELETE THIS COMMENT(i managed to fix it lol

  • @fifi88Choreograf
    @fifi88Choreograf Před 8 měsíci

    I try this plugin, and send_event didin't work for me can't change states

    • @godotneers
      @godotneers  Před 8 měsíci

      Please open an issue at github.com/derkork/godot-statecharts/issues/new and post your setup and the code you are using, then I can have a look at it. CZcams comments really aren't suited for giving support as you cannot send screenshots or code examples.

  • @PunCala
    @PunCala Před 6 měsíci

    I really tried using this state chart, but there is not enough here to get me started. Like, there is a big, big need for a comprehensive tutorial on how to build a state machine to control the player character in Godot 4. Could you please consider making a tutorial, where you build a typical top-down 2D player character with this state machine? I'm talking about, say, idle, run, melee attack, ranged attack, and dash.
    Most tutorials are either too brief like this, or the more detailed ones are for 2D side scrollers, and I found out the hard way that they don't always translate well to top-down 2D movement. For example: I moved my movement logic to a state, and the character stopped moving. Or: my character has 8 directions of movement, and I found it hard to maintain the direction after returning to idle. My character would stop and turn to face south despite having been moving east. Or my character would face east, but when I press attack, the character would attack south.

    • @user-tr6lg8vw5w
      @user-tr6lg8vw5w Před 5 měsíci

      This tutorial is quite simple and enough to make: idle, run, attack and so on.
      Let me to show how it looks for my Skeleton mob (this is a dumb mob. he can idle, chase a Player and attack with a short range). And Skeleton can expel (deleted) when collides with the special Node2D.
      StateChart looks like:
      Root (CompoundState)
      Idle (Node)
      To Chasing (Transition): event = player_entered
      Chase (Node)
      To Idling (Transition): event = player_lost
      To Attacking (Transition): event = attack_player
      Expelling (Transition): event = expelling
      Attack (Node)
      To Chasing (Transition): event player_entered
      Expelled (Node)
      -----
      event on Transition used for manual transition between States (Nodes).
      And I have Area2D AttackDetector with following connected signals:
      AttackDetector._on_attack_detector_area_entered() - send state event "expelling". We need to expel our Skeleton here.
      AttackDetector._on_attack_detector_body_entered() - send state event "attack_player". We are ready to attack our Player.
      AttackDetector._on_attack_detector_body_exited() - send state event "player_entered". Player go away from our attack Zone and we need to chase him
      Also we have Area2d Detector (useful for checking collision with Player Node). Connected signals:
      Detector._on_detector_body_entered() - send state event "player_entered". Skeleton ready to chase our Player
      Detector._on_detector_body_exited() - send state event "player_lost". We are lost our Player
      ^^^ it's enough for changing our State Machine. But nothing really happened on the game level.
      So. This is a time for adding logic based on our State Machine states. State entered signals:
      _on_idle_state_entered() - play "Idle" Skeleton animation and stop his movements.
      _on_chase_state_entered() - play "Walk" Skeleton animation.
      _on_attack_state_entered() - stop Skeleton and play "Attack" animation.
      _on_expelled_state_entered() - delete Skeleton node from our tree.
      At the last we need to add ability to move. For that add logic that invokes each times while Skeleton stays on "Chase" State:
      _on_chase_state_processing() - define direction and movements speed.
      That's all!
      Check GDScript for Skeleton:
      -----
      extends CharacterBody2D
      var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")
      const SPEED = 100
      @onready var player = $"../../Player"
      @onready var animation = $AnimatedSprite2D
      @onready var stateChart = $Skeleton_StateChart
      func _physics_process(delta):
      if not is_on_floor():
      velocity.y += gravity * delta
      move_and_slide()
      # ======================================================
      func _on_attack_detector_area_entered(area):
      if area.name == "ExpellZone":
      stateChart.send_event("expelling")
      func _on_detector_body_entered(body):
      if body.name == "Player":
      stateChart.send_event("player_entered")
      func _on_detector_body_exited(body):
      if body.name == "Player":
      stateChart.send_event("player_lost")
      func _on_attack_detector_body_entered(body):
      if body.name == "Player":
      stateChart.send_event("attack_player")
      func _on_attack_detector_body_exited(body):
      if body.name == "Player":
      stateChart.send_event("player_entered")
      # ======================================================
      func _on_idle_state_entered():
      animation.play("Idle")
      velocity.x = move_toward(velocity.x, 0, SPEED)
      func _on_chase_state_entered():
      animation.play("Walk")
      func _on_attack_state_entered():
      animation.play("Attack")
      velocity.x = move_toward(velocity.x, 0, SPEED)
      func _on_expelled_state_entered():
      queue_free()
      # ======================================================
      func _on_chase_state_processing(delta):
      var direction = (player.position - self.position).normalized()
      velocity.x = direction.x * SPEED
      animation.flip_h = velocity.x > 0
      #player.player_attacked.emit()

    • @ScumlordStudio
      @ScumlordStudio Před 3 měsíci

      ​@@user-tr6lg8vw5wyo thank you for this example snippet, helped me understand!

  • @Ichthyoid
    @Ichthyoid Před 6 měsíci

    Around 20:09, the enemy re-enters the watchman area, but due to the delay time, the watchman goes back to the idle state anyways instead of switching back to the observe state. Is this a bug? I did this tutorial on my own and can replicate this behavior.

    • @godotneers
      @godotneers  Před 6 měsíci +1

      This is an oversight, it can be fixed by adding an additional transition to the observe state to remain in observe state when something is entering. This will cancel the timed transition that would otherwise transition back to the normal state.

    • @Ichthyoid
      @Ichthyoid Před 6 měsíci

      @@godotneersthanks for responding! Would you need to check which state the statechart is in to do that? what would the code for that look like?

    • @Ichthyoid
      @Ichthyoid Před 6 měsíci

      @@godotneersnevermind, figured it out, haha. I just named the event the same as the idle transition to observing (enemy_entered). thanks for the state chart addon! I'll definitely be using it in place of coding my own most of the time!