Godot 3: Finite State Machine Code Example Overview

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
welcome to this new code our view of the state programming pattern this is an open source demo that I made for the good of three course and that's available as part of the optional guru 3 demo as soon as they'll be merged again we're going to talk about the state's programming pattern a very important pattern that we use in game design you use it to separate individual States chunks of behavior in this case the movement for example from idle from jump each of them are a separate script in this demo from the system that handles the transition between states it's called a state machine and you can see in the top left corner that we have something called a pushdown automaton as well so that whenever the character jumps when it lands it goes back to the previous state whatever that was and same thing when it takes damage it gets frozen in time and space for a few moments plays the stagger animation and goes back to whatever came before so we also have some history of the states the character has been in this is not a full step-by-step tutorial as I made that as part of the pro version of the egora 3 course but we're going to look at the code and you'll find text and comments inside the source code to help you learn about this so first let's look at the advantages and the point of the state programming pattern if you look at my century in the top right of the screen you can see the character has a States container and a list of the states or chunks of behaviors it can have can the idle move jump or be staggered and each of these states has an individual script that is self-contained that doesn't know anything about the other states it just represents this behavior so for example here we are looking at the move script and this move script just handles some inputs in this case it delegates it to a parent script called ungrounded g-d and in the update method this is the equivalent of physics process if you want it's going to check the input direction from the player update the characters look Direction movie character and has a move function that calculates the velocity and moves the character each state's encapsulate the character's behavior for that action then the player has a script called state machine attached to it and this grip is going to store a reference to a current state one of these four objects I don't move jump or stagger and it's going to delegate calls to that object so let's look down a little bit at the physics process and input event methods everytime physics processes call it's going to defer the call to the update method on the current state so if the character is moving it's going to send the physics process call to remove states update method then it listens to what the state returns the states can return a keyword to transition to a new state so if there's a new state name returned by these other scripts idle or move for example you can see for example here return idle if it returns idle we're going to change the state based on this name based on this idle name changing the state happens in the change state method this one is little complicated because this is not just the pure state pattern its States and pushdown automaton keeping a history of the states we have been in and that's why we have this special previous keyword that these state subjects can return so jump and stagger use it when you land after a jump jump will return the previous key word from the update method and this will trigger a call to this change state method we'll see okay we have the previous keyword we're going to pop the first element from our stack of state and the stack is an array defined at the top of this script then there's also some rule to know when we want to keep a history or add to the history of state add to our stack and this happens when we enter some specific state so stagger or jump in this case you have to hard code these it's up to you to define when you use the pushdown automaton and when you don't want to use it we're defining these rules and the change tank method because the transitions between states how they are connected to one another is the state machines role it should not be defined in the state objects so we do two other important things in this change state method we exit the current state if the exit method has some code in it we also enter the current state so we clean up the state we were in because these are static objects we can find in the scene these nodes are never deleted so you want to make sure that you clean up some values when the character transitions to a new behavior on your action and same thing entering is initializing the state if we take the jump State for example it's going to update the input and look direction when we enter the state it's going to set the horizontal velocity of the character based on the input direction sets the character's vertical speed so this is the jump starting speed and we also play the idle animation because there's no specific jump animation in this demo okay let me go back to the state machine script we also emit a signal here that indicates to these help UI elements that the state has changed and this is how this stack of state is displayed to make the project simple there's only one scene with the player but these last elements are really helpers just to display some information on the screen when you are testing the game there's also one important thing in the demo you have a bullet spawn node and that is so the character can shoot I wanted to show you one chunk of behavior that should not be part of the characters States and state machine so you can shoot anytime when you are jumping even when you are staggered in this demo the idea is if you can think of shooting as part of a character's behaviors if you use a state here which might be tempted to do you may have micro freezes in the gameplay while instead using a separate object and letting the weapon itself all the bullets spawn fire for the character you can stack shooting bullets on top of the character's behaviors and motion it's another way to think about your system and game mechanics for that I'll let you look at the script as well so this node is fairly simple it has a cool down timer and when the timer is running when the weapon is on cooldown you can't fire it's going to return from the function otherwise if you can fire it restarts the colvin timer it spawns a new bullet and the bullet is going to move in a fixed direction that we set at this point it's based on the characters direction to define the states and hierarchical states we have to go in the layer folder state subfolder and here you will find a base state script again you have some comments in there to help you make sense of it this is called an interface it's a script that defines the base methods that the states should have you have to think of it like a small machine in a small box with a few levers all our states all our boxes that are fancier than the base one are going to have these five levers all these five methods in that case and we define them here to force us to use the right parameters when we can't be States and to make sure that we don't crash the game when we have a state that doesn't define one of these function explicitly just not going to do anything but it's not going to crash then several levels to our States we can use inheritance in Gd script to have some base super state that we can delegate calls from the child states let me explain you have move an idol in this case both have to handle input in the same way like in both states we want when we press the jump key the player to jump for that the state machine the player defer the input calls to idle or move and idle or move will send it to that parent called ungrounded Gd so you can find it in the unground folder and it's in the on-ground GD that you will have this check for the jump in production it's a very short script in this case and this one also defers the call to its parent the parent is called motion the Gd so motion is common to idle to move to jump but it would be also common to swimming to flying because it has the code to handle the input direction and you can see it also has some code to simulate the character taking damage so it's not a big inner level example this one why I'm giving you a pretty quick overview if you are not comfortable with code it's really something you should not look at just yet you need to have a decent understanding of object-oriented programming and there's a series free theories coming around that as soon as possible but this demo is open source the comments inside so I invite you to download it link in the video description you will also find a link to a free chapter from the game programming pattern ebook that's excellent and that covers the the state pattern how it works and what it's for it's in the description and if you feel comfortable with it by all means integrated to your projects if you haven't already because this is a really good tool to help improve your code structure you can see my scene at a glance we know what the character can do same thing in my project structure thanks to this state's folder we know that the character has some combat States has some stuff related to motion and it's all self-contained in short scripts that are fairly easy to manage this code is also under the MIT license so don't hesitate to reuse it as is in your projects and to build upon it thank you kindly for watching and see you in the next one bye bye
Info
Channel: GDQuest
Views: 85,412
Rating: undefined out of 5
Keywords: finite state machine, finite-state machine, godot 3 tutorial, godot game engine, open source, gamedev, game programming, GDscript, State pattern, programming patterns, game code, code architecture, godot engine, godot tutorial, game engine
Id: Ty4wZL7pDME
Channel Id: undefined
Length: 11min 40sec (700 seconds)
Published: Wed Apr 25 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.