Тёмный
No video :(

Godot 3: Finite State Machine Code Example Overview 

GDQuest
Подписаться 263 тыс.
Просмотров 87 тыс.
50% 1

Опубликовано:

 

24 авг 2024

Поделиться:

Ссылка:

Скачать:

Готовим ссылку...

Добавить в:

Мой плейлист
Посмотреть позже
Комментарии : 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
@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.
@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
@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.
@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.
@GamedevLlama
@GamedevLlama 5 лет назад
Excactly what I needed for my current project. Thank you so much!
@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.
@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.
@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.
@Mr_BetaMax
@Mr_BetaMax 10 месяцев назад
You guys are awesome! The Brackey's of Godot 😂
@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.
@jonathancamarena3117
@jonathancamarena3117 6 лет назад
Great video as always! keep it up man.
@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 ?
@filipex2000
@filipex2000 4 года назад
I don't know what to say, but I know one thing: you inspired me alot!
@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?
@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...
@learningtime4562
@learningtime4562 6 лет назад
cool video helps me get a step closer to become a programmer.
@GWKTM
@GWKTM 5 лет назад
Could you please offer a step-by-step tutorial of how to exploit FSM in visual script and 3D?
@turquoise7817
@turquoise7817 2 месяца назад
any chance we'll get an updated version of this? great tutorial, but could use a remake :D
@tinboiter1414
@tinboiter1414 3 года назад
I wish GODOT had a state machine.
@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
@ripnox2009
@ripnox2009 3 года назад
Thanks for the vid, litterally understood 0 of what's going on but great video
@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?
@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.... ru-vid.com/video/%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE-bpqQtOPyVoo.html Now I need to practice to expand the concept. 😑
@IgorogI1000
@IgorogI1000 3 года назад
I hope Godot StateMachine from AnimationTree evolves. I totally hate to code states
@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
@MajorCooke2
@MajorCooke2 6 лет назад
You should put this on AssetLib in Godot. It's right next to the 3d/2d/script/>>>assetlib
@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.
@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.
@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? :)
@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.
@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
@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.
@stcpimus
@stcpimus 4 года назад
This is the easy way???
@israhina
@israhina 2 года назад
Where are your courses, are they in Spanish?
@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/... #
@ritzenhauf
@ritzenhauf 3 года назад
i could really use an overview diagram--i can't see in code like you can
@namename-zu8uk
@namename-zu8uk 4 года назад
Can you do in the editor like unity?
@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.
@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.
@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.
@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
@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
@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
@truelion-rt6gd
@truelion-rt6gd 4 года назад
Horrible
@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.
@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.
@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
@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.
@PiterTraceurFA
@PiterTraceurFA 2 года назад
I don't see the advantage of having multiple scripts instead of just one.
@iAmCodeMonkey
@iAmCodeMonkey Год назад
Code organization, and maintainability.
@leonpijudo6875
@leonpijudo6875 2 года назад
too overcomplicated
@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.
@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
Просмотров 134 тыс.
Starter state machines in Godot 4
10:58
Просмотров 46 тыс.
Programming a BETTER state machine
10:16
Просмотров 71 тыс.
Harder Drive: Hard drives we didn't want or need
36:47
How do non-euclidean games work? | Bitwise
14:19
Просмотров 2,4 млн
Where Does Bad Code Come From?
42:21
Просмотров 190 тыс.
Learn Godot by creating Pong
2:07:47
Просмотров 123 тыс.