Complete Front-End Project: Build a Game State Machine
Transcript from the "State Machine" Lesson
>> So I'm gonna take a second. This is the most computer science we're gonna get, and it's not gonna be that computer sciency. But I wanna talk about kind of some thought process that kind of revolutionized the way that I thought about writing code, and particularly, user interface kind of facing code/front-end development.
[00:00:18] So there's a thing called a Finite State Machine, or an FSM, as it's often abbreviated. But let's stick to a state machine, this is what I'm gonna call it. It's a methodology of writing code, and how to track variables that prevents a lot of styles of bugs. So I think the best way to illustrate what a finite state machine is is to use an example.
[00:00:40] And I'm gonna borrow this example from xdate docs, because it's a great library that does finite state machines, and they have good docs. So you as a human being are either asleep, or awake at any given time. And let's just assume that that's the case. I'm sure that you can come up with some medical reason that's not the case.
[00:01:00] But for now, just bear with me, I suppose. Okay, so you're either awake, or you're asleep. There's no in between state there. And you are never both awake and asleep, and you are neither awake nor asleep. You're either awake, or you are asleep, and you're always in exactly one of those states.
[00:01:22] This is kind of what a finite state machine does for you, is it's saying here are my various different states. I can only be in one of these states at a time. And I can only go from this state to this state, and this state to this state.
[00:01:36] So using our fox as the example, our fox is idling. Then they become hungry. Then they become fed. Then they poop, and then they get cleaned up, and they're back to idling, right? And so they're in one of these distinct states at any given time. So we're gonna kind of model our code in the sense.
[00:01:54] A lot of people will use like Booleans to track these, like is awake, is asleep, is feeding, is fed. And it's really easy to get out of sync using these Booleans. So we're gonna use something called an enumerated type, is what you would call it. If you're using programming terms, it's basically a variable that can only be one of these separate things, right?
[00:02:19] So you can see here, I have a list of here. These are actually all of the states that our game can be in at any given time. Our game can only be in one of these states at any given time, right? It can only be in it hashing, idling, sleeping, eating, pooping, hungry, celebrating, or dead, and that is it.
[00:02:35] And so our game will constantly go through these various different states at different points, right? And those will have derived states, right? So a good example of a derived state, like our eyes closed, right? If you're asleep, your eyes are closed. And if you're awake your eyes are, in general, open, right?
[00:02:55] So that's what these kind of derived states, is you look at the master state of this, and then you look at the derived states from there. The person that talks a lot about finite state machines in the front-end development communities is David Khourshid, or davidkpiano on Twitter. Definitely worth following him.
[00:03:13] He has an upcoming course on Frontend Masters about finite state machines, and I am going to watch it, because it's something that I wanna get better at. So I would definitely take a look at that. By the time that you watch this, it might have already happened, or it might already be recorded.
[00:03:43] So keep that in mind. Maybe give it a shot. If you do, put it on GitHub and show me. So we're gonna kind of approximate this, and I think we might offensively do it to David, cuz he is a bit of a purist when it comes to these kind of things.
[00:03:57] But we're gonna have this thing called current, which is going to be basically the state of our finite state machine. So your game is going to start in the state called init, right? Which means that in init, you can't be fed, right? So it's a really easy thing that we [INAUDIBLE] wait, can I do this right now?
[00:04:14] No I can, or yes I can, or something like that. So what I want you to do is I want you to pop back over to your editor, okay? Now I want you to create a new file. And I want you to put it in fox game source, inside of the source directory.
[00:04:34] And this is gonna be called gamestate.js okay? Inside of gamestate, I want you to put const gamestate =, and then it's an object, and it's gonna have a value called current. And that state is going to be in net. Okay, we're gonna keep track of what clock tick we're on, so we can kind of keep track over time.
[00:05:07] So we're gonna start at one. You could start at zero, you could start at whatever you want. I'm just gonna start at one, doesn't really matter. We're gonna write our own tick function in here, and then we're gonna use it in the other place. And then whenever it ticks, we're gonna say at this.clock++, right?
[00:05:26] ++ meaning it's going to increment every single time that tick gets called. For now, we're just gonna say console.log. And we're gonna say clock, this.clock. And then you can return this.clock. I tend to return it, but I don't think we ever use it anymore, so it doesn't matter.
[00:05:52] Okay, and then we're gonna say at the bottom, Export default on a clock, but gamestate. Okay, so I think in my notes there, I actually had it as module or exports. Really, what you want is export default, cuz we're gonna use the latest ES6 style modules. Okay, so now I've made this module, and I'm gonna go then import this inside of init, and use it inside of init.
[00:06:26] Okay, so we're gonna go over to our init.js. And at the very, very top, we're gonna say import gamestate from "./gamestate". So now that module, I just wrote in the other library, or in the other file is now available to be used here inside of init.js. So we can delete our tick function, cuz we now have reimplemented that inside of gamestate.
[00:07:03] Here inside of where we have tick, we're just gonna put gamestate.tick And actually, my notes here just to say stay consistent with my notes. I have game, it doesn't really matter. It's just a variable name. But game.tick, doesn't matter. Both of them work. Okay, so now, if we save it, and we go back over to our running game over here, which, you should still have parcel running, if not, go restart that.
[00:07:33] And I refresh my page, which I don't, you can see that I don't have it running. So let's just do that npm run dev. Okay, and now we can go back over here and run it. And you can see down at the bottom, you will have our clock running.
[00:07:49] So you can see it says 234, and it's pretty consistent at every three seconds. It's going to log out the current state of our clock. And now with our clock, we can say if this is the correct number, then do this thing, right? If it's clock is equal to 10, then make the fox hungry, right?
[00:08:07] We're kind of making that clock work now.