I dont know much about finite state machine in AI or other game behaviors in game, except this quick tutorial with a Miner: http://www.ai-junkie.com/architecture/state_driven/tut_state1.html which is object oriented.
I don't really know if this tutorial describes the State pattern or not, what do you think ?
I'm not speaking about other more arithmetic-oriented stuff like steering or physics or path-finding or collisions, but rather about game logics, state-driven AI, and things that involves a lot of simultaneous states and if
s and/or switch
es
What are the pro/cons of using either a State Pattern or a sequential check of a plain state structure like this:
struct States
{
bool is_walking, is_running, holds_a_weapon, is_crouch;
int weapon_id, int id_team;
};
void HandleStates (States state)
{
//etc
}
Answer
I will try to answer this as best as I can, but there are certain "best practices" which I am unsure on, but I'll try to break it down as cleanly as possible.
FSMs
Firstly, the Miner tutorial is from Programming Game AI by Example by Mat Buckland (which I do recommend you get as an introduction to AI). He uses an enum for each state, NOT a struct. With the struct in your example you have booleans as the states, so you could have any number of these on at the same time. This might lead to behaviour you want, but more often than not with FSMs (Finite State Machines) it leads to undesirable behaviour.
For example:
enum
{
WANDER_AROUND,
ATTACK,
RUN_AWAY,
};
Secondly, that's not the only way he describes states. The way I personally prefer (depending on the situation) is to create an abstract class called State that has an Enter(), Exit() and Update() functions. Then create my states as subclasses of the State class.
Like this picture (found on page 2 of that link actually):
State Pattern
In my personal opinion, the state pattern is just a part of software design where the software has a number of states. The implementation is down to the developer. I don't feel there's a proper difference between using a big switch statement or creating a complete state machine to run all your states like I've outlined above. They're essentially doing the same thing. So in that respect, the answer to one of your questions is yes, I do believe that page describes the state pattern.
Pros/Cons
There are pros and cons to any method you use to implement a state-driven design.
Using an If/Else or Switch Statement
Pros:
- Very easy to add and check conditions of states
- Can be prototyped very quickly
Cons:
- When you've got a load of states, it can turn very ugly, very quickly.
- Keeping track of transitions, effects when the state is entered/exited or anything specific to the state is difficult
Using an object-oriented state machine
Pros:
- Highly extensible - the only thing you need to do is create a new state that inherits the abstract State class
- Easily maintainable - You don't have to worry about spaghetti looking code as each state resides in its own class. You can easily see the conditions associated with that state without worrying about the other states.
- Intuitive - If you're working on a team project with this sort of state machine, it will be so much easier for the person reading your code. They won't have to read through lines upon lines of code just to get to a certain state ("Always program as if the programmer maintaining your code is a psychopath who knows where you live!" :))
Cons:
- Slight learning curve - This design may take a while to get your head completely round when implementing it
- I honestly can't think of any more, since I do prefer this way, but if anyone wishes to add to it, just comment and I'll add them.
I hope that answers all your questions. In fact, I've just opened up my copy of Programming Game AI by Example and Mat does mention that the state machine is known as the "state design pattern". Personally, I disagree, but to each his own.
Hope it helps :)
No comments:
Post a Comment