Return of the States... not the United States...
Announcement
I'm very happy to say that Diego Pontes is going to help me with SFX and Music and he'll be giving us, in the form of devlogs, right here, some insights into how he produces his awesome audio files! Very excited to work with him, he's the person that made the already awesome music for the GodotJam 2018 prototype.
States... not the United States
First, let's see where we are in terms of mechanics. The patterns are back! And this time better than ever. Alright... lame commercial :) followed by a lame state of affairs:
The States ah... managing the States. It's a pain frankly, keeping track of everything that happens is pretty much a pain. Where to place code that manages state of certain Nodes or other instances of custom classes - it's not an easy task, that's why there's very highly payed positions for software engineering. And in a game engine such as Godot which gives you a lot of flexibility which simplifies the thinking process on the high level, there's still a problem of organizing the code. Where do you put the code that changes state for certain things? Because of interdependence it isn't an easy task.
Ah... interdependence. For this little game here, being turn based, FSM (finite state machines) seem to be a good fit. Now FSMs can get out of hand easily because there's no clean way of being in two or more states at the same time. Why might you want to be in multiple states simultaneously? Well because say you have a platformer character that can duck and move at the same time. The basic FSM for this kind of character might start with having the separate states:moving
& ducking
(among other ones). Now the problem is what happens if you want move while ducking? Not so easy to fix. What do you do? Do you create other states that reuse code from both moving
and ducking
or do we handle ducking
behavior inside of moving
directly? What would that mean for moving
and jumping
? So you can see, duplication of code and behavior with FSM is very easy to achieve. Not nice at all!
FSM in Godot
Still, FSM isn't completely useless, especially in a game that's turn based where you can only be in one state at a time. With that in mind, what I'd normally do is make a hierarchy of the sorts from Fig. 2.
States
, Idle
, Moving
, Gathering
, etc.This works and gives you some advantages. You can define (in attached scripts) properties on the nodes that are available for you to tweak in the inspector. And what I'd normally do is keep track of the "parent" by having something like onready var entity = $"../.."
inside the states themselves in order to have easy access to the thing we want to attach behavior. This... turns out is messy.
Separation of concerns is not easy. For example the above states would not work on their own, they necessarily have to be attached to nodes in the specific format from Fig. 2. in order for them to do anything useful and not crash the game.
Introducing FSM 2.0
It turns out that for personal projects at least, I don't really need to change custom properties in the inspector, I'm more comfortable with tweaking the things from within the script and creating clever interdependence that goes one way in order for the bottom nodes (components) would depend on the parent and set appropriate properties on themselves if need be instead of me tweaking them manually. There's actually a strong case that properties you'd normally declare as const
ants are very good candidates for exposed var
iables in the inspector, because these are often the ones you need tweaking. Lars Kokemohr makes a good case for this.
Alright, back to figuring out this interdependence. I scratched the idea of having states as nodes and have them reference the entity (onready var entity = $"../.."
) and instead I'm trying a new approach with the states being custom classes and all their methods require the entity parameter to be passed in. At first I tried a similar approach as having the entity stored as a member variable and have the state constructor take this entity and set up properly the variable. This would be very similar to what's happening in Fig. 2. and here's my reasons why I decided against it:
- having the entity as a member variable inside the states would mean that there's extra... state to the state to keep track of. There's a couple of ways around this. For example you might want to create and destroy states from scratch on every transition between them. It's an OK method, but I think it's cleaner to just pass in the state which brings me to the second point
- being a turn based game it means that I can (and want to) reuse the same exact states where possible. For example, the AI brain (or controller) will actually be stored in the
Idle
state, that's where the decision is take to move or to pass the turn or any other behavior. Which means that for example, in the case of movement, we just need to pass in the appropriate info so that theMoving
executes properly. TheMoving
state doesn't actually figure out the move, it just executes. So with this set-up, theMoving
state can be identical for both AI and Player, the only difference is that the player controller is stored in a separateIdlePlayer
state, while the AI has it's ownIdleAI
state, but theMoving
state is identical and entirely reusable. So with passing in the entity instead of storing it in the state itself makes for a cleaner interface. At least that's what I think - I have to admit that some of this thinking rubbed off from haskell and functional programming in general, that is minimizing state changing & tracking as much as possible
Next time
Next time we'll get into some debugging, a bit more on states probably and how I manage the very simple turn-based loop in a real time engine like Godot.
Get MunchIt
MunchIt
Munch or get munched or die of heat deprivation! For GodotJam June 2018
Status | Released |
Authors | razcore-rad, Indie Hunter! |
Genre | Puzzle, Survival |
Tags | cool, godotengine, godotjam, heat, jumping, Procedural Generation, temperature |
More posts
- FSM2.0 details and implementationJul 01, 2018
- Making an relaxing song 101Jun 25, 2018
- Towards MunchIt v0.01Jun 20, 2018
Leave a comment
Log in with itch.io to leave a comment.