No video

Godot 3: Finite State Machine Code Example Overview

  Рет қаралды 87,537

GDQuest

GDQuest

Күн бұрын

Пікірлер: 96
@Gdquest
@Gdquest 6 жыл бұрын
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
@juanjesusligero391
@juanjesusligero391 6 жыл бұрын
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
@GWKTM
@GWKTM 5 жыл бұрын
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
@Timooff
@Timooff 4 жыл бұрын
After listening to this for 5 minutes, my brain exploded, I gotta rewatch it more than 10 times :D. This kinda looks hard
@josuereis6367
@josuereis6367 3 жыл бұрын
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.
@vison360
@vison360 6 жыл бұрын
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 :)
@Gdquest
@Gdquest 6 жыл бұрын
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.
@skaruts
@skaruts 6 жыл бұрын
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.
@JackieCodes
@JackieCodes 2 жыл бұрын
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
@Mirdclawer
@Mirdclawer 6 жыл бұрын
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!!
@Gdquest
@Gdquest 6 жыл бұрын
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.
@GamedevLlama
@GamedevLlama 5 жыл бұрын
Excactly what I needed for my current project. Thank you so much!
@umeshkumarasamy6608
@umeshkumarasamy6608 5 жыл бұрын
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.
@navjotsingh2251
@navjotsingh2251 5 жыл бұрын
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.
@TitlePending
@TitlePending 6 жыл бұрын
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_BetaMax
@Mr_BetaMax 10 ай бұрын
You guys are awesome! The Brackey's of Godot 😂
@oTheCendaCZo
@oTheCendaCZo 3 жыл бұрын
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
@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?
@LuccDev
@LuccDev 4 жыл бұрын
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 ?
@jonathancamarena3117
@jonathancamarena3117 6 жыл бұрын
Great video as always! keep it up man.
@filipex2000
@filipex2000 4 жыл бұрын
I don't know what to say, but I know one thing: you inspired me alot!
@turquoise7817
@turquoise7817 3 ай бұрын
any chance we'll get an updated version of this? great tutorial, but could use a remake :D
@GWKTM
@GWKTM 5 жыл бұрын
Could you please offer a step-by-step tutorial of how to exploit FSM in visual script and 3D?
@Mirkobien
@Mirkobien 5 жыл бұрын
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?
@numerical25
@numerical25 5 жыл бұрын
Godot is awesome Game Engine. I am surprised its not getting more rep
@Gdquest
@Gdquest 5 жыл бұрын
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
@learningtime4562
@learningtime4562 6 жыл бұрын
cool video helps me get a step closer to become a programmer.
@ripnox2009
@ripnox2009 3 жыл бұрын
Thanks for the vid, litterally understood 0 of what's going on but great video
@giggleghost3751
@giggleghost3751 4 жыл бұрын
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. 😓
@giggleghost3751
@giggleghost3751 4 жыл бұрын
I guess I've done it on my own.... kzbin.info/www/bejne/mKHUgqeFhd6JpdE Now I need to practice to expand the concept. 😑
@tinboiter1414
@tinboiter1414 3 жыл бұрын
I wish GODOT had a state machine.
@antanaspaskauskas9432
@antanaspaskauskas9432 6 жыл бұрын
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
@Gdquest
@Gdquest 6 жыл бұрын
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.
@antanaspaskauskas9432
@antanaspaskauskas9432 6 жыл бұрын
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
@Gdquest
@Gdquest 6 жыл бұрын
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.
@antanaspaskauskas9432
@antanaspaskauskas9432 6 жыл бұрын
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
@Gdquest
@Gdquest 6 жыл бұрын
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
@alexthompson3229
@alexthompson3229 3 жыл бұрын
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...
@fossegutten6579
@fossegutten6579 6 жыл бұрын
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:)
@Gdquest
@Gdquest 6 жыл бұрын
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.
@martlepanen7280
@martlepanen7280 3 жыл бұрын
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? :)
@brumda007
@brumda007 3 жыл бұрын
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
@IgorogI1000
@IgorogI1000 3 жыл бұрын
I hope Godot StateMachine from AnimationTree evolves. I totally hate to code states
@MalArgon
@MalArgon 5 жыл бұрын
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?
@Gdquest
@Gdquest 5 жыл бұрын
You can read gameprogrammingpatterns.com/state.html for detailed insights. It solves some common issues that lead to producing bugs.
@decrodedart2688
@decrodedart2688 5 жыл бұрын
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
@Decrosion
@Decrosion 5 жыл бұрын
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
@kirkanos771
@kirkanos771 5 жыл бұрын
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.
@MajorCooke2
@MajorCooke2 6 жыл бұрын
You should put this on AssetLib in Godot. It's right next to the 3d/2d/script/>>>assetlib
@kpswiney
@kpswiney 6 жыл бұрын
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)?
@Gdquest
@Gdquest 6 жыл бұрын
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/... #
@adamantgaming7232
@adamantgaming7232 5 жыл бұрын
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?
@adamantgaming7232
@adamantgaming7232 5 жыл бұрын
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
@Gdquest
@Gdquest 5 жыл бұрын
This is a Godot 3.0 project, that's why
@stcpimus
@stcpimus 4 жыл бұрын
This is the easy way???
@Topyy
@Topyy 5 жыл бұрын
Isn't the base state machine an abstract class ? And not an interface ?
@Gdquest
@Gdquest 5 жыл бұрын
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.
@LaVidaPrimero
@LaVidaPrimero 6 жыл бұрын
In the video of the state machines of Dan the Rabbit, you did it differently using the match function ...
@Gdquest
@Gdquest 6 жыл бұрын
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!
@Gdquest
@Gdquest 6 жыл бұрын
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 ^^
@LaVidaPrimero
@LaVidaPrimero 6 жыл бұрын
The Pro course you mention has a translation into Spanish?
@Gdquest
@Gdquest 6 жыл бұрын
No, everything I do is in English
@namename-zu8uk
@namename-zu8uk 4 жыл бұрын
Can you do in the editor like unity?
@israhina
@israhina 2 жыл бұрын
Where are your courses, are they in Spanish?
@ritzenhauf
@ritzenhauf 3 жыл бұрын
i could really use an overview diagram--i can't see in code like you can
@Comakino
@Comakino 4 жыл бұрын
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?
@Gdquest
@Gdquest 4 жыл бұрын
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
@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.
@fruitdudetv
@fruitdudetv 5 жыл бұрын
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
@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.
@melting9419
@melting9419 4 жыл бұрын
are you the same guys that made the godot demos?
@Gdquest
@Gdquest 4 жыл бұрын
No, just contributed some. And we made quite a few more in our own repository on GitHub github.com/GDQuest/godot-demos
@traviswright7558
@traviswright7558 6 жыл бұрын
Hi, can I ask why you use nodes when you can just preload the classes?
@Gdquest
@Gdquest 6 жыл бұрын
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)
@traviswright7558
@traviswright7558 6 жыл бұрын
@@Gdquest makes sense. Thank you!
@traviswright7558
@traviswright7558 6 жыл бұрын
+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.
@jamestill4172
@jamestill4172 4 жыл бұрын
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.
@deanboytime4346
@deanboytime4346 5 жыл бұрын
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?
@KaleSerpent
@KaleSerpent 5 жыл бұрын
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-rt6gd
@truelion-rt6gd 4 жыл бұрын
Horrible
@PiterTraceurFA
@PiterTraceurFA 2 жыл бұрын
I don't see the advantage of having multiple scripts instead of just one.
@iAmCodeMonkey
@iAmCodeMonkey Жыл бұрын
Code organization, and maintainability.
@LedoCool1
@LedoCool1 4 жыл бұрын
Hah. My state machine is full blown gdscript. No nodes.
@Gdquest
@Gdquest 4 жыл бұрын
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.
@LedoCool1
@LedoCool1 4 жыл бұрын
@@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.
@Gdquest
@Gdquest 4 жыл бұрын
@@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
@LedoCool1
@LedoCool1 4 жыл бұрын
@@Gdquest yeah. The time to port existing code and debug everything. And it's not like I have much in terms of spare time.
@leonpijudo6875
@leonpijudo6875 2 жыл бұрын
too overcomplicated
@jvstAsYouAre
@jvstAsYouAre 4 жыл бұрын
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.
@Gdquest
@Gdquest 4 жыл бұрын
This is a code overview, as the title says. Not a tutorial. It's intended for fellow programmers.
@jvstAsYouAre
@jvstAsYouAre 4 жыл бұрын
@@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
@pulsar1934
@pulsar1934 2 жыл бұрын
I'm disappointed in godot
@MalArgon
@MalArgon 5 жыл бұрын
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?
@vinievex
@vinievex 4 жыл бұрын
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.
6 Tips to Better Organize your Godot Projects
11:39
GDQuest
Рет қаралды 134 М.
Oh No! My Doll Fell In The Dirt🤧💩
00:17
ToolTastic
Рет қаралды 13 МЛН
Prank vs Prank #shorts
00:28
Mr DegrEE
Рет қаралды 13 МЛН
everything is open source if you can reverse engineer (try it RIGHT NOW!)
13:56
Low Level Learning
Рет қаралды 1,4 МЛН
The Most Legendary Programmers Of All Time
11:49
Aaron Jack
Рет қаралды 555 М.
Finite State Machines in Godot | Godot Starter Kit FSM
9:46
ForlornU
Рет қаралды 28 М.
When Your Game Is Bad But Your Optimisation Is Genius
8:52
Vercidium
Рет қаралды 1,5 МЛН
How Games Have Worked for 30 Years to Do Less Work
23:40
SimonDev
Рет қаралды 1,3 МЛН
Never install locally
5:45
Coderized
Рет қаралды 1,8 МЛН
How principled coders outperform the competition
11:11
Coderized
Рет қаралды 1,7 МЛН
A new way to generate worlds (stitched WFC)
10:51
Watt Designs
Рет қаралды 527 М.
Using GraphEdit and GraphNode to create flow charts
17:42
Oh No! My Doll Fell In The Dirt🤧💩
00:17
ToolTastic
Рет қаралды 13 МЛН