Finite State Machines in Godot | Godot Starter Kit FSM

Video Content:
----------------------------------
0:00 - Intro
1:01 - State Class
2:51 - FSM Class
5:25 - Signals
6:08 - Summary
6:22 - Transitions
7:52 - Force Change State
9 :00 - Outro
------
In this video I discuss how FSM's work in general, sort of the typical layout but also more specifically how it's set up in my Godot Top-down starter project
The second part of the video focuses more heavily on the project itself, its transitions and signals and so on
I hope you learned something or gained some insight, thank you for watching!
Github:
github.com/ForlornU/TopdownSt...
Asset library:
godotengine.org/asset-library...
My second, somewhat simpler starterkit:
• Recreating Fishy in Go...
You can buy me a coffee to make me code faster at:
www.buymeacoffee.com/forlornu
#coding #learning #godot #godotengine #gamedev #gamedevelopment

Пікірлер: 41

  • @philldev
    @philldev6 ай бұрын

    This is a very useful video for all beginners, not just godot users! It explains exactly what a FSM is and how it should work, not to mention it is well edited and easy to understand. Good job, keep up the good work :)

  • @ForlornU

    @ForlornU

    6 ай бұрын

    Thank you, means a lot coming from a fellow dev!

  • @kostanislaw
    @kostanislaw5 ай бұрын

    Лучший урок по стейтам, что я видел. Не только дал удобную ФСМ, но ещё и очень просто объяснил как всё это работает и зачем нужна каждая строчка. Блин, если бы все на ютубе объясняли как ты - я бы уже закончил свою игру. Спасибо!

  • @locke_d
    @locke_d6 ай бұрын

    tysm for this tutorial, ngl the code here is like identical to a tutorial about the same subject from Bitlytic (not sure if that's intentional or a happy accident) but like, you actually explain it in a thorough and easy to understand way? Bitlytic skims over so much important info for beginners but you hit the nail right on the head with the explanations, super comprehensive and easy to follow, tysm again king ily

  • @NikoDuong
    @NikoDuong6 ай бұрын

    You are a godsend! Explanations were short concise and easily understandable. Thank you from the bottom of my heart! I can't wait for more!

  • @ForlornU

    @ForlornU

    6 ай бұрын

    Thank you for the kind words. More videos are coming!

  • @kloa4219
    @kloa42195 ай бұрын

    I'm nearly done with porting this to Godot 3, thank you for explaining it clearly.

  • @kloa4219

    @kloa4219

    5 ай бұрын

    Finite State Machine extends Node class_name FiniteStateMachine var states : Dictionary = {} export var initial_state = NodePath() onready var initstate:State = get_node(initial_state) var current_state:State var change_state:State func _ready(): for child in self.get_children(): if child is State: states[child.name.to_lower()] = child child.connect("state_transition", self,"change_state") if initial_state: initstate.Enter() current_state = initstate func change_state(source_state:State, new_state_name:String): #redundancy checks if source_state != current_state: print("Invalid change_state trying from: " + source_state.name + "but current in: " + current_state.name) return var new_state = states.get(new_state_name.to_lower()) if !new_state: print("New state is empty") return #only relevant lines if current_state: current_state.Exit() new_state.Enter() current_state =new_state func force_change_state(new_state:State): var newState = states.get(new_state.name.to_lower()) if !newState: print(str(new_state) + " does not exist in the dictionary of states") return if current_state ==newState: print("State is same, aborting") return if current_state: current_state.call("Exit") current_state=newState newState.Enter() func _process(delta): if current_state: current_state.Update(delta) func _physics_process(delta): if current_state: current_state.Update(delta)

  • @kloa4219

    @kloa4219

    5 ай бұрын

    Player_Idle State extends State class_name Player_Idle export var sprite = NodePath() onready var _sprite :AnimatedSprite = get_node(sprite) #gets FSM node onready var fsm = get_parent() #onready var fsm = $".." onready var moving = $"../Moving" func Enter(): #_sprite.play("Idle") pass func Exit(): pass func Update(_delta:float): if (Input.get_vector("move_left","move_right","move_forward","move_backward")): print("moving") #Transition to move state fsm.change_state(self, "Moving") pass if (Input.is_action_just_pressed("attack")): #transition to attack state pass pass

  • @kloa4219

    @kloa4219

    5 ай бұрын

    extends Node class_name State signal state_transition func Enter(): pass func Exit(): pass func Update(_delta:float): pass func Physics_Update(_delta:float): pass

  • @offlinemoe
    @offlinemoe7 күн бұрын

    Just found your channel and I fell in love with it

  • @curtiss5781
    @curtiss57814 ай бұрын

    I had a project where I tried a sort of state machine but used timed animations that would trigger follow up states. I ran into issues when trying to do a forced state while animations were still running. Im pretty sure a more defined approach like what you have here would have sorted out my issues, being able to end animation delegates in the current state Exit method before killing the object. Cool explanation, thanks.

  • @PaintedCz
    @PaintedCz6 ай бұрын

    This is fantastic! Thank you so much!

  • @PaperMouseGames
    @PaperMouseGames5 ай бұрын

    Fantastic video! Very high quality and helpful, thank you!

  • @Lily-kv3rb
    @Lily-kv3rbАй бұрын

    I've been watching through a couple of different videos after finishing my player movement system in my first game and decided to switch it over to a state machine, since I plan on adding even more movement mechanics later on and I want to make it easier on myself. This is the first video I've found that explains things in such detail, so thank you! However, in every video I've watched and tried to follow along, I keep getting stuck on specific tidbits that I can't seem to find an answer to either in the video, or on specific searches on Reddit/Google/Etc. Where would be the best resource for figuring out solutions to problems like "In my Finite State Machine script, there are 'Could not parse global class "State" from "res"//Scripts/PlayerState.gd" over every mention of the variable 'initial_state'. How do I fix this?". I want to find a community or resource where I can easily look up these errors and find out why its not working. And if the reason I can't figure this out is due to a lack of very basic knowledge of GDScript, where should I start learning that basic knowledge?

  • @Altaryum
    @AltaryumАй бұрын

    Thanks for this very comprehensive tutorial about FSM. 🤗

  • @vladyerus
    @vladyerus5 ай бұрын

    This video helped me more than most to figure out state machines. thank you. Do you know if this code allows for switching scenes? For example i have a state called Driving (my character goes invisible, stops processing, etc) and i take control of another characterbody2d which has its own set of states .

  • @ForlornU

    @ForlornU

    5 ай бұрын

    Absolutely. An interaction script activates the vehicle and tells the fsm to transition to driving state which 'deactivates' the player. A player state should not be responsible for anything outsider the player i think 👍

  • @panwladca8800
    @panwladca8800Ай бұрын

    Thank you for your hard work 😊

  • @cheesymcnuggets
    @cheesymcnuggets5 ай бұрын

    I don't think I actually need a state machine but i want to learn them, this is like the third video I've watched on them and they haven't become any less intimidating. Question about your force state function, how exactly can it break your game? Aren't exit functions meant to prevent the state machine from breaking or have I misunderstood their purpose? Oh wait the problem is with decentralised state machines, right? Since each state is only accounting for it's own transitions and trying to transition to something it doesn't know how to could break things? I don't know...

  • @kloa4219

    @kloa4219

    5 ай бұрын

    Think of state machines as applying a script to each game mechanic. It isn't important for small projects but it makes doing big projects like RPGs or fighting games easier.

  • @ForlornU

    @ForlornU

    4 ай бұрын

    "Break your game" was me being a bit dramatic. Creating a system of transitions only to then override them with force can lead to unexpected behaviour I guess. I don't want to make a tutorial where I use a 'force-change' function to ignore what I am trying to teach in the video

  • @hensola
    @hensolaАй бұрын

    Lovely intro on how FSM work, as well as separating them all out to a manager function. I believe this is how Godot is meant to be programmed.

  • @1tsKayne
    @1tsKayne3 ай бұрын

    i dont know how i should transition the state for my enemy. so it detects when the player entered his territory and then it should switch to chase state. What do I have to put in there? # In the Idle State: func _on_view_area_body_entered(body): if body.is_in_group("Player"): FiniteStateMachine.change_state(State, "BaseNPCChaseState") doesnt work

  • @ykyjohn
    @ykyjohn2 ай бұрын

    Where/When the state_transition is emitted?

  • @kloa4219
    @kloa42195 ай бұрын

    How did you animate your video btw?

  • @ForlornU

    @ForlornU

    4 ай бұрын

    I use Davinci resolve for editing, the coding animations are done in good 'ol powerpoint!

  • @markaven5249
    @markaven52496 ай бұрын

    I don't know why but state machines seem so much more difficult and less straightforward than in C, C++, or C#. It must be the whole dynamic programming thing. In C like languages, I'd just create a state and subState enum, subState would have Init, Run, End and state would have animation names, then just create one long script for everything. Signals are just Events and Callbacks but they call them signals. I guess these days this isn't a modern style of programming, but I'd have as few scripts as possible as well.

  • @kloa4219

    @kloa4219

    5 ай бұрын

    You can do it with enums in Godot. It just feels messy in comparison to the node method

  • @truenincillo805
    @truenincillo8055 ай бұрын

    Tutorial swim in 2d platform game godot 4 please😣

  • @GenericInternetter
    @GenericInternetter5 ай бұрын

    "press enter to leave" huh?

  • @ForlornU

    @ForlornU

    5 ай бұрын

    That does sound strange when you point it out 😅

  • @PocketDeerBoy
    @PocketDeerBoyАй бұрын

    I feel like you sort of skipped over the part where you explain how states communicate with each other? I looked through the github to try to understand the code better and there's this line from the Idle state: state_transition.emit(self, "Moving") that was never explained. I'm sorry, I'm very new to coding and I wanted to figure out state machines, but I'm not sure how this piece of code works and how it's picked up by other codes. My guy is still not walking

  • @theseangle

    @theseangle

    12 күн бұрын

    state_transition is the signal that is defined in the IdleState's script. This line emits the signal of a transition from IdleState to MovingState to the state machine class. The state machine has `current_state.state_transition.connect(handle_transition)`. It makes the FSM subscribe to the transition event that is emitted from the current state. On that event, it calls the `handle_transition` function which is defined in the FSM. It has two arguments: previous_state and new_state. Both of them correspond to the two arguments `self` and `Moving` respectively from the IdleState's script. "Moving" is the name of the MovingState node, which plays as the accessor for the MovingState. It's used in the `handle_transition` function to get the state node by the string, like `current_state = get_children()[new_state]`

  • @HurricaneSA
    @HurricaneSA5 ай бұрын

    Please for the love of my sanity can you choose a notation and stick with it? Changing between snake and camel notation randomly is making my brain hurt.

  • @ForlornU

    @ForlornU

    4 ай бұрын

    Indeed it was getting out of hand, resolved in latest version!

  • @migueldc6845

    @migueldc6845

    2 ай бұрын

    😂 good sport

  • @bernardbrookshire7171
    @bernardbrookshire717128 күн бұрын

    not helping

  • @bsdrago
    @bsdrago5 ай бұрын

    what about unity? =)

  • @templeoftaste320
    @templeoftaste32023 күн бұрын

    Useless, you left out the most important part about how to actually trigger a state transition from the idle state class