This demo covers the State pattern, hierarchical states, and features a pushdown automaton. It's intermediate-level material: you'll need to be quite comfortable with Godot, GDscript, and have decent Object-Oriented Programming foundations to use it. But it's also a very useful pattern in games, so that's why I wanted to open source it. If you struggle with it now, at least it'll be there in the future to learn from. The video gives a broad overview of the project. Now the code contains comments to help you understand the most important parts of the scripts. And if you have questions please leave a comment below :) There's also a chapter that covers everything step by step in the Make Pro 2d Games Godot 3 course: gumroad.com/l/godot-tutorial-make-professional-2d-games
@juanjesusligero3916 жыл бұрын
This demo is great, but as you warned us before, it really is too complicated for beginners ^^U I think I understand the concept behind it and I love it (the code is much cleaner this way, the coding of new states is less error-prone, and everything makes more sense), but I think that it could be much more understandable (I mean by beginners, like myself) if it was presented in a *much* less complicated Godot project. Probably one using only a scene, containing about 6 nodes or so, only 2 states (for example "idle" and "move"), 3 or 4 scripts, and that's it. Maybe you (or some other friendly Godot medium/advanced user reading here) could make something like that sometime in the future? :) Anyway, thank you very much for the video and the code! :D
@GWKTM5 жыл бұрын
Could you please offer a step-by-step tutorial of how to exploit FSM in visual script and 3D? This video isn't clearifying it
@Timooff4 жыл бұрын
After listening to this for 5 minutes, my brain exploded, I gotta rewatch it more than 10 times :D. This kinda looks hard
@josuereis63673 жыл бұрын
The only functions I use with the state pattern are the main ones (change_state and update). I think the code gets even more readable without adding code that wouldn't really be necessary ("enter" and "initialize" functions, arrays, etc.). I'm doing my fighting game that way. Also, GDScript is a friendly enough language and it doesn't take a lot of effort to understand its code, so any pattern applied (like solid) makes everything very readable.
@vison3606 жыл бұрын
Thank you for this video. I wrote FSM toolkit with my brother recently and we are quite happy about how it works but you example showed me some nice ways to structure our code better. It's also clear example why states stack is nice thing to have. We'll be implementing some of those ideas soon :)
@Gdquest6 жыл бұрын
It's one of the rare examples where pushdown is useful though :). It's a KS backer who suggested Stagger because I was stuck trying to find something different from the Game Programming Patterns book.
@skaruts6 жыл бұрын
Interesting timing, since I will likely benefit from implementing one of those in a near future for a stealth thing I'm doing, where the character should be able to walk slowly, walk normally, run, sprint, crawl, sneak (crouch) and stand. I had never thought of doing it with a FSM.
@JackieCodes2 жыл бұрын
u say that each state is self contained, but is it 100% so if in your move script update function, it checks if ur moving and if not it returns "idle"? Awesome tutorial btw, just a bit confused about how to encapsulate for maximum efficiency
@Mirdclawer6 жыл бұрын
Thank you so much for this, now I gotta spend few hours trying to understand how it all ties together and decipher the code, but doing the whole thing and giving it away for free and opensource is amazing, keep up the good work!!
@Gdquest6 жыл бұрын
Glad you appreciate it! There's always more coming. Actually I have to update this one: I found a way to simplify it a little bit.
@GamedevLlama5 жыл бұрын
Excactly what I needed for my current project. Thank you so much!
@umeshkumarasamy66085 жыл бұрын
I see the note you picked up from Game Programming Patterns (By Bob Nystrom) I'm barely into the book right now and I'm stoked to see that you take note from the same place I do.
@navjotsingh22515 жыл бұрын
This is really helpful. I'm not really a game developer but I am covering Finite State Machines at university and this is an excellent way to visualize it. Great video.
@TitlePending6 жыл бұрын
Thank you for this. I'm glad you went over this as this is a nice follow up from the course. Ludum Dare 41 and work have kind taken me away, but going to get back to it this weekend.
@Mr_BetaMax10 ай бұрын
You guys are awesome! The Brackey's of Godot 😂
@oTheCendaCZo3 жыл бұрын
I understand that the code & project is more readable but isn't this unnecessary overhead - decrease in performance for impractical reason? (in this case - nodes for each state having it's methods and game-update functions instead of single/few if(s) + might be harder to see/manage physics' forces integration) For readability and performance you could still use enums assigning name constants (like STATE_JUMP) and evaluate input with simple calculations
@Violation-Nikolaos Жыл бұрын
Optimization is secondary (at least) to comprehensibility, maintainability, and brevity. How many sets of state nodes (different entities with state) are you running where you think doubling, tripling, or octupling every entity to give it node based state would be a problem?
@LuccDev4 жыл бұрын
Hi, thanks for the video. In the state machine's _change_state function, you specify that if the state_name is "previous", you don't wanna "reinitialize the state" by calling the ".enter()" function. But why ? For example, if I have an idle animation, and a stagger animation, when the stagger animation is finished, it won't go back to the idle animation. This is verifiable in your project easily, by ending the stagger animation on a red frame, you'll see that it stays red after the stagger has ended. I understand that you don't want to start the animation from the beginning in some cases, but how do you go back to the previous animation ?
@jonathancamarena31176 жыл бұрын
Great video as always! keep it up man.
@filipex20004 жыл бұрын
I don't know what to say, but I know one thing: you inspired me alot!
@turquoise78173 ай бұрын
any chance we'll get an updated version of this? great tutorial, but could use a remake :D
@GWKTM5 жыл бұрын
Could you please offer a step-by-step tutorial of how to exploit FSM in visual script and 3D?
@Mirkobien5 жыл бұрын
I had a little problem with this. The problem was with the animations and the pushdown automata pattern. Just to test it, I printed out the current_animation from the animation player. When you jump, then land and keep moving without stopping, the animation stays idle instead of walking. Maybe there's a very easy solution, but of course, this happens because the walk state doesn't get to execute the 'enter' method, signaling it never plays it's animation. Any help?
@numerical255 жыл бұрын
Godot is awesome Game Engine. I am surprised its not getting more rep
@Gdquest5 жыл бұрын
It's gaining some - fastest growing game engine on GitHub this year. But without the money of a large tech company for marketing, it spreads through word of mouth and through the community, which takes time
@learningtime45626 жыл бұрын
cool video helps me get a step closer to become a programmer.
@ripnox20093 жыл бұрын
Thanks for the vid, litterally understood 0 of what's going on but great video
@giggleghost37514 жыл бұрын
Hi Nathan Do you think you could make a tutorial for this but make it as simple as possible for beginners among us. Instead of all the code for movement and jump and so on, just make a label and and have the state machine update it's text as a different button is pressed. I am trying to do just that by myself, but my code doesn't work. I am trying to understand the very basics of state machine by making the simplest working version of it. But stuck, like I said. 😓
@giggleghost37514 жыл бұрын
I guess I've done it on my own.... kzbin.info/www/bejne/mKHUgqeFhd6JpdE Now I need to practice to expand the concept. 😑
@tinboiter14143 жыл бұрын
I wish GODOT had a state machine.
@antanaspaskauskas94326 жыл бұрын
Great tutorial :) But it looks so complicated to me, probably because I never used FSM and just made my own stateful object behavior. I have 6 states in my AI but it will take more time to convert to FSM than writing few more states and debugging them if needed
@Gdquest6 жыл бұрын
If you use the pattern from the start it doesn't take more time. Often less as you tend to generate fewer bugs with it and they're easy to spot and fix. Then you can't be sure sticking to stateful objects will save you time or not. It may take less time to add 1 or 2 states to your AI script but the cost grows with every function, variable and feature you add. The biggest issue is when you have a bug you have a hard time tracking down because you have too many member variables. You can end up wasting an hour trying to figure out where you didn't reset a value on this or that state. One thing with the state pattern is it's scalable: even if you need 20 states it's still manageable (common even for simple AI) while with a stateful object you waste a lot of time. And refactoring when you have 10+ states will be a real pain compared to doing it early on.
@antanaspaskauskas94326 жыл бұрын
Ye, I understand that ;) I ended up rewriting code to a simple FSM, one which has all the code in the same script (the FSM tutorials I have checked have it all in the same file) as I run into inheritance problems. It is very simple: I have a small state machine which checks "state" variable and runs corresponding state. There can only be one state at a time. Once a state has completed, it calls the next state. E.g. wander --> (if player detected) --> chase --> (if player is reached) --> attack --> wait --> wander etc. This is FSM right? In this case player detection, distance to player etc are inputs for the enemy AI
@Gdquest6 жыл бұрын
You have the state pattern when the states encapsulate all the code that corresponds to a given action and they don't know anything outside themselves and the host/body they control. If you have issues with inheritance and you can't break them in separate scripts you may still have a stateful object. By the way one point of breaking up states is to reuse them: if they're individual objects you can reuse individual states on different monsters in the same project without having to make changes.
@antanaspaskauskas94326 жыл бұрын
Cool! Ye, I can't break them as these states depend on some common code: navigation, movement etc. So I will have to separate them first. I like your way as it is so neat
@Gdquest6 жыл бұрын
You'll also see the first time you do it it takes some time as it's a new concept and programming patterns abstract your code a little bit. But once you become comfortable with it, it had a few advantages
@alexthompson32293 жыл бұрын
this state machine worked great until it didn't and cost me three fucking days to figure out what was going on. if anyone else tries to use it in a 3D game where you need jump on moving platforms, do NOT call move_and_slide inside your state scripts, only call it in the script on your kinematic body. trust me this will save you so much time and headache...
@fossegutten65796 жыл бұрын
Cool. I prefer this over the old solution. However i want to make a system where npc and player can use the same state scripts. With the states inheriting from the motion script it will be hard. Will try to build on this though:)
@Gdquest6 жыл бұрын
Working with the inherited motion state isn't a problem: it's input events fed to a state's handle_input method that make the character work, so for the AI you can plug in a brain-like script and have it send virtual inputs (InputEvent objects you create by yourself) down this method.
@martlepanen72803 жыл бұрын
I've spent a few evenings trying to figure out a problem I have with this and I wondered if you might be able to help. If I am making a platformer, where do I put the code that applies the gravity? I am having all sorts of bad ideas (i.e create a `rising` and `falling` state, which seems super finicky). Then again, if I would put it in something more "global" (like the PlayerController), my question becomes: Who should call `move_and_slide`? I am under the impression that I should call it only once per frame. Can you point me in the right direction? :)
@brumda0073 жыл бұрын
I know I'm kinda late to the party but I'm trying to implement FSM into my game and I can't figure out, what does the for cycle in state_machine inside ready func do. It's this part: for child in get_children(): var err = child.connect("finished", self, "_change_state") if err: printerr(err) It does not work without it but when I try to use it as is, it says signal finished does not exist
@IgorogI10003 жыл бұрын
I hope Godot StateMachine from AnimationTree evolves. I totally hate to code states
@MalArgon5 жыл бұрын
I like your tutorials alot, but I see no need for a final state machine, seems like it just adds more complexity to the development. I mean, if i need to add a new feature i would have to write another state for that funktion too?
@Gdquest5 жыл бұрын
You can read gameprogrammingpatterns.com/state.html for detailed insights. It solves some common issues that lead to producing bugs.
@decrodedart26885 жыл бұрын
I loaded this in 3.1b2 and it throws an error on run at sword.gd:9 It says IDLE is not declared in current scope
@Decrosion5 жыл бұрын
solved the error thanks to link below. i broke the sword attack state because i didn't think about which enum set goes where but at least it proved that STATES.IDLE != ATTACK_INPUT_STATES.IDLE github.com/godotengine/godot/issues/23757
@kirkanos7715 жыл бұрын
Why is the demo bugged so the player cant move back and forth? The demo keep freezing and stopping the change of state at random change of keys pressed. - EDIT Nevermind, i was playing with the arrow keys and forgot than my xbox controller was already plugged in. Had to unplug it so the keyboard entries dont get interrupted by sensitive axis changes.
@MajorCooke26 жыл бұрын
You should put this on AssetLib in Godot. It's right next to the 3d/2d/script/>>>assetlib
@kpswiney6 жыл бұрын
Great video, thank you! I am curious, why is the script for the State node only visible in the folders on the left, but there is no script icon in Scene tree view on the top right or the in the inspector @ 01:39(bottom right)?
@Gdquest6 жыл бұрын
The States node is just here for visual grouping, to make it easier to find our state nodes from code, and to document our scene for our teammates: $States/... #
@adamantgaming72325 жыл бұрын
Hey there @GDQuest! Thanks for your awesome content as always, you are of immeasurable help as I try to learn Godot. Quick question... I'm running into an issue when attempting to run the FSM demo PlayerV2 scene on Godot 3.1 from a Mac. Line 9 in your sword.gd script is throwing an error... "Parser Error: Identifier 'IDLE' is not declared in the current scope" Any idea why this is happening?
@adamantgaming72325 жыл бұрын
To add to this, I completed removed the sword and attack states to see if I get work around the issue, and ran into other issues (the animation player node was not being found from the idle.gd script). Not sure what the hangup is since I'm pretty new to 3.1, and am a fairly novice programmer. But thank you for the concepts, I'll try to figure out my own FSM! Thank you again for all your killer tutorials! :D
@Gdquest5 жыл бұрын
This is a Godot 3.0 project, that's why
@stcpimus4 жыл бұрын
This is the easy way???
@Topyy5 жыл бұрын
Isn't the base state machine an abstract class ? And not an interface ?
@Gdquest5 жыл бұрын
Yes, you don't have interfaces in gdscript per say. Abstract classes and interfaces are close, and in this case, State only has methods, no state of its own, like an interface would.
@LaVidaPrimero6 жыл бұрын
In the video of the state machines of Dan the Rabbit, you did it differently using the match function ...
@Gdquest6 жыл бұрын
Yes, for a simple script you can go with a stateful object, what I show in chapters 1-4. This pattern is covered in details in chapter 10 in the course (pro version). If you do games as a hobby or have limited experience you likely won't use it at first. For small characters, monsters, simple AI this pattern is a lot of extra work for little gain. But when you have more than... say, maybe 6 states? You may start to consider it. There's always many solutions to one problem in programming, and as a developer you will have to learn many techniques and gain experience to know when to use each of them. There are yet other and possibly more advanced ways to code a character or an AI, depending on the size of your project!
@Gdquest6 жыл бұрын
I think I've mentioned it in the course but in case I didn't: when you create prototypes it's often better to go without patterns to save time. You're not going to keep the code most of the time. In this case what you saw in the course is super useful because it has some of the advantages of the State pattern but it's a lot faster to code. The only issue is it doesn't scale well. But if you code a big character the state pattern doesn't scale too well either ^^
@LaVidaPrimero6 жыл бұрын
The Pro course you mention has a translation into Spanish?
@Gdquest6 жыл бұрын
No, everything I do is in English
@namename-zu8uk4 жыл бұрын
Can you do in the editor like unity?
@israhina2 жыл бұрын
Where are your courses, are they in Spanish?
@ritzenhauf3 жыл бұрын
i could really use an overview diagram--i can't see in code like you can
@Comakino4 жыл бұрын
When I try to build a state machine this way I can't, because the player node is a KinematicBody2D and it throws an error because the State Machine nodes are of a different type. You seem to have them inheriting from your main player node somehow, could you explain what you did there?
@Gdquest4 жыл бұрын
I don't remember how we did in this video, but the general idea is that the state is an object that takes control of another, in this case the KinematicBody2D node. So the state can use a reference to the player node and call functions on it, like player.move_and_slide(). That's the general idea. If you have your states as nodes in a saved scene, the root of that scene is accessible through a member variable called owner.
@jersn5560 Жыл бұрын
This is incredibly frustrating, just came here for Finite State Machine, the the video narrows down on a lot of things, character control, animation, movement velocity. Please just narrow down on Finite State Machine without explaining how you made the prototype as we can always just read that from the sample code. I am already 6 minutes in and I am butt clenched on the climactic explanation on Finite State Machine (e.g. explaining why we are pushing and popping states, what happens when an event is emitted, etc.) and ended up peer reviewing the code. I don't want to finish entire video anymore. It doesn't even pore over pattern itself it kept on explaining the project. I'll guess I'll go straight to the resource material.
@fruitdudetv5 жыл бұрын
mh, tried to recreate the state machine from the playerv2. why won't the concept click with me ? XD nothing works and i dont know why.... its time to quit. im to dumb for it
@SavageMontreal Жыл бұрын
This is needlessly complex with its reliance on TWELVE SEPERATE SCRIPTS. You spend most of the time talking about how to pass operations between nodes and the functions of the states as opposed to explaining the operation of the state machine. I opened the demo, and most of its functions are isolated in their own scripts, making it a nightmare to track down what is going on and where.
@melting94194 жыл бұрын
are you the same guys that made the godot demos?
@Gdquest4 жыл бұрын
No, just contributed some. And we made quite a few more in our own repository on GitHub github.com/GDQuest/godot-demos
@traviswright75586 жыл бұрын
Hi, can I ask why you use nodes when you can just preload the classes?
@Gdquest6 жыл бұрын
The main reason is that it is visual and declarative code. When you open the scene, it is clear for you and your teammates what's the machine can or cannot do. As you add sequences and hierarchical States, or design behavior trees, you can also see the parent child relationships between the nodes. As a bonus you may also get some minor performance gains having your nodes serialized as binary data, loaded on the backend, vs instancing them from gdscript. Now that is if you want to use nodes and benefit from Godot's architecture. If you need a lower footprint on your objects you could use scripts that don't extend anything instead (but better rely on the engine's features imo)
@traviswright75586 жыл бұрын
@@Gdquest makes sense. Thank you!
@traviswright75586 жыл бұрын
+GDquest I have one more question, regarding Pushdown Automata, is there a reason not to reinitialize the previous state if we're going back to it? @6:18 If you're going from jump to moving, the idle animation plays. When state changes from stagger to idle, stagger animation still plays. However, the game still works fine, even if you enter the previous state. Thanks so much for answering my previous question by the way.
@jamestill41724 жыл бұрын
I had to dislike this. The overview is the part that's easy. Encapsulate code, single purpose functions. This is literally everything we don't need to know, and none of what we actually need to understand.
@deanboytime43465 жыл бұрын
Why did you split all the states into their own nodes and scripts? Wouldn't it be simpler (both programming and project-wise) to just keep all of the state information in a single enemy script and switch states using bools and if statements in the update function?
@KaleSerpent5 жыл бұрын
I'm not super knowledgeable on this, but afaik states are usually isolated code so you can just call on it, and it'll do it's thing Kinda like an object does it's own thing. Putting it together seems to kill the purpose of that.
@truelion-rt6gd4 жыл бұрын
Horrible
@PiterTraceurFA2 жыл бұрын
I don't see the advantage of having multiple scripts instead of just one.
@iAmCodeMonkey Жыл бұрын
Code organization, and maintainability.
@LedoCool14 жыл бұрын
Hah. My state machine is full blown gdscript. No nodes.
@Gdquest4 жыл бұрын
It's fine, having nodes it mostly more convenient: the Node class gives you hierarchical state machines for free, and if you're working within a team, it's nice for designers to be able to use and configure states in the inspector.
@LedoCool14 жыл бұрын
@@Gdquest yeah. Now that I'm looking at your example I'm thinking that I could benefit from redoing it, but cost vs benefit makes me stall this idea.
@Gdquest4 жыл бұрын
@@LedoCool1 Cost, you mean the time it'd take to port the code? Note we have a more recent version of this FSM, here are two projects with examples: 1. In 2d github.com/GDquest/godot-platformer-2d/ 2. In 3d github.com/GDquest/godot-3d-mannequin
@LedoCool14 жыл бұрын
@@Gdquest yeah. The time to port existing code and debug everything. And it's not like I have much in terms of spare time.
@leonpijudo68752 жыл бұрын
too overcomplicated
@jvstAsYouAre4 жыл бұрын
This was impossible for someone who doesn't already know what you are talking about to follow. I hope the tutorials people are giving you money for are not as hard to understand.
@Gdquest4 жыл бұрын
This is a code overview, as the title says. Not a tutorial. It's intended for fellow programmers.
@jvstAsYouAre4 жыл бұрын
@@Gdquest I know it's not a tutorial but i is still hard for me to follow. I guess i was looking for a more entry-level overview of state machines
@pulsar19342 жыл бұрын
I'm disappointed in godot
@MalArgon5 жыл бұрын
I like your tutorials alot, but I see no need for a final state machine, seems like it just adds more complexity to the development. I mean, if i need to add a new feature i would have to write another state for that funktion too?
@vinievex4 жыл бұрын
A Finite State Machine Adds to the Organization, also it makes things a hell of a lot easier in the future as it makes it harder for the game to fall apart with larger projects. You can use a Finite State Machine anywhere, and may require one for certain things, like for example, Special Moves in Super Smash Bros.