State Machines: State Object versus sequential check: what are the pro/cons?

jokoon
  • State Machines: State Object versus sequential check: what are the pro/cons? jokoon

    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 ifs and/or switches

    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
    }
    

  • 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): alt text

    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 :)

Tags
c++ ai c state
Related questions and answers
  • GameSubsystems) can implement registerComponent(Component*). pro. Components and GameSubystems know nothing about each other. con. In C++ it would look like ugly and slow typeid-switch... Components. 3: Component registers itself in GameSubsystem(s). We know at compile-time that there is a GameSubsystemRenderer, so let's ComponentImageRender will call something like...I'm creating a component-based game object system. Some tips: GameObject is simply a list of Components. There are GameSubsystems. For example, rendering, physics etc. Each GameSubsystem contains

  • wrong in my frame buffer set up code, or elsewhere. But I can't see what. The FBO is set up through the following function: unsigned int fbo_id; unsigned int depth_buffer; int m_FBOWidth, m_FBOHeight..., vTexCoord); } The following is what is rendered when not using the FBO logic: What is rendered to the FBO http://k.minus.com/jiP7kTOSLLvHk.jpg ... Help? Any ideas on what I may be doing wrong... transformation has occurred somewhere. Which doesn't make sense as the object renders fine when not using my frame buffer (see bottom of post). The current result is such: Current result http://k.minus.com

  • . state_->handleEvent(event, this); } That means that I don't really ever need more than one instance of a particular entity state; doing something like entity.setState(new StandState) is therefore highly wasteful. Then again, making each entity state a singleton hardly seems appropriate. What do you suggest I do? (The same can be said about game states, so whatever the solution to this is, I guess it can be applied to game states as well.) 2. The state of the entity sprite. Most of the time, whenever the state of the entity changes, the sprite that is used to represent it must

  • Im writing a game for which, one of the models are loaded from an .obj file. It's a model of a plane, and I want to rotate the propeller. The object file is broken into groups, and the propeller is identified, so that's all good. I'm writing the game in C++ with OpenGl/GLFW The drawing function is: int win_width; int win_height; glfwGetWindowSize(&win_width, &win_height); float win... it, and then translate back. This makes the propeller spin as I want it to, but it also rotates along the origin >.< http://people.sc.fsu.edu/~jburkardt/data/obj/cessna.obj <- This is the object file. groups

  • ); // Set The Color Of The Model ( NEW ) // ORIGINAL DRAWING CODE //Draw the model as an interpolation between the two frames glBegin(GL_TRIANGLES); for(int i = 0; i... NEHE'S TUT glBegin (GL_TRIANGLES); // Tell OpenGL What We Want To Draw for(int i = 0; i < numTriangles; i++) { MD2Triangle* triangle... on screen... Since the result was kind of hacked together, I am thinking that maybe I am performing some extra steps or extra rendering tasks that maybe are not needed, and are slowing down the game

  • I want to be able to (only) define game states using Lua script, but I'm not sure how I should do it. Here's what I have in mind currently: For each state, I will create a .lua file that contains... exiting the state). So if I want to have a MainMenuState, I will have a file called "MainMenuState.lua" which will contain something like this: MainMenuState = {} MainMenuState["onEnter"] = function() end MainMenuState["onUpdate"] = function(elapsedTime) end MainMenuState["onExit"] = function() end Defined states will be exposed to the game engine via a singleton StateManager class

  • this on what I had done there, but modifying it to fit with Ogre. It is working but not correctly and I would like some help to understand what it is I am doing wrong. I have a state system and when... physics properties. I know there will be errors here as I get the items colliding with the ground but not with each other properly. So I would appreciate some input on what I am doing wrong. void... to collide with.. as follows. I expect there is issues with this as I get objects colliding with the ground but half way through it and they glitch around like crazy on collision. void GameState

  • ",10,10,100,50) toggle_control(button,false) C++: static int CreateButton(lua_State* L) { int n = lua_gettop(L); core::stringw label = lua_tostring(L,1); core::stringw tt((n>=5?lua_tostring(L,6):"")); int x... the security issues with the code (it is a very early version). So my question is this: What are some good ways of defining the control events from a script interpreter in C++? ...I'm using Irrlicht(C++) for a 3D engine, and it has a built in GUI system. The GUI events are something like this: switch(eventtype) case button_pressed:     stuff case editbox

  • I've decided I want to write a central ResourceManager/ResourceCache class for my hobby game engine, but am having trouble designing a caching scheme. The idea is that the ResourceManager has a soft target for the total memory used by all the game's resources combined. Other classes will create resource objects, which will be in an unloaded state, and pass them to the ResourceManager... in advance of first use. Here is a bit a sketch of the classes I am using: typedef unsigned int ResourceId; // Resource is an abstract data type. class Resource { Resource(); virtual

Data information