Finite State Machines, cont. Chad Hogg Sections 5.3 & 5.4 of AI Game Programming Wisdom 2 What is an FSM ? • To theoreticians, a Finite State Machine or Automaton is an abstract model of a computer. • In the context of this course, an FSM is not so abstract. Rather, each state of the machine corresponds to a piece of code. • Is anyone unfamiliar with automata theory? Defining an FSM • Simplest type of FSM is a Deterministic Finite State Automaton ( DFA ). • A DFA is defined as 5-tuple ( Q, ∑, δ, q0, F ), where – – – – – Q is a finite set of states. ∑ is a finite set of symbols ( the alphabet ). δ : Q x ∑ → Q is the transition function. q0 Q is the start state. F Q is the set of accept states. So What ? • Traditional approaches describe FSMs in code. • But the definition of an FSM consists of 5 simple pieces of data. • Therefore, it should be possible to create a generic FSM engine that operates on this data. • This is known as a data-driven model. Advantages of datadriven model • • • • • Separate program control logic from FSM logic. Reduce duplicate code. AI designer does not need to know how it works. Easy update / testing of AI without recompile. If desired, AI can be changed by modders and level designers without exposing critical source code. Game Modifications • End-users are able to modify an existing game and distribute their changes. • Level / graphic / AI design are expensive, so why not let the customer do some of it? • Famous example: Half-life, CS, NS, TFC, DOD • Simpler data-driven example: Civilization II – Plain text files allow modifications of almost all game rules. Ex: Civilization II … ( Technologies ) Advanced Flight, Alphabet, 4,-2, 5, 1, Rad, Too, 3, 4 nil, nil, 0, 3 ; ; … ( Personalities / Goals ) Caesar, Livia, 0, 1, 1, Romans, Roman, 0, 1, 1 Montezuma, Nazca, 0, 4, 0, Aztecs, Aztec, 0,-1, 1 … This is not very intuitive, but is welldocumented. However … • Not as customizable as it would sound. – You still need to provide a set of state names and variables that may be queried by the transition function. – Associating a state and specific code that runs while you are in, entering, or exiting that state remains in source code. – Creating a robust system for the AI designers to work with will require a significant time investment. Implementing FSM Data • Q, the set of states is enumerated in code. • ∑, the set of input symbols ( conditions ) is enumerated in code. • δ, the transition function is defined in an external data file. • q0, the initial state is set by the individual FSM objects in code. • F, the set of accepting or final states is set by the individual FSM objects in code. Data-driven Example: Light Bulb (LB) • Demo provided on textbook CD. • Models an electric light circuit that is controlled by a timer to turn on or off every second. • Not very Game AI-like, but simple enough to demonstrate the ease of implementation. Ex(LB) State Definition • The light is either on or off, so we have two states, FSMS_ON and FSMS_OFF. • States are represented as values of an enumerated type and strings. Ex(LB) More C Work • We need to define any variables that should be exposed to the data file. In this case, the only thing necessary is the value of a timer. • We need to define any operators that should be exposed to the data file. In this case, we use simple comparison operators for integers ( ==, >, < ). Ex(LB) CLightBulb class CLightBulb { TFSM<CLightBulb> m_stateMachine; CTimer m_timer; void BeginOnState() {} void UpdateOnState() { cout << "\n--Light Bulb is On--\n" << endl; } void ExitOnState() { m_timer.Reset(); } void BeginOffState() {} void UpdateOffState() { cout << "\n**Light Bulb is Off**\n" << endl; } void ExitOffState() { m_timer.Reset(); } int GetTime( ) { return m_timer.GetTimeElapsed( ); } CLightBulb() { m_stateMachine.LoadStateMachine("light_bulb.fsm"); m_stateMachine.AddStateFunctions(this, FSMS_ON, BeginOnState, UpdateOnState,ExitOnState); m_stateMachine.AddStateFunctions(this, FSMS_OFF, BeginOffState, UpdateOffState,ExitOffState); m_stateMachine.AddVariableFunction(this, TIME, GetTime); } void Update( ) { m_timer.Update( ); m_stateMachine.EvaluateCurrentStateTransitions( ); m_stateMachine.ExecuteStateMachine(); } }; void BeginOnState() int GetTime() TFSM<CLightBulb> void UpdateOnState() m_stateMachine; void ExitOnState() There must also be a function for each variable These three functions that the datafile can The remaining functionality perform whatever action is query. of interfacing with the associated with entering, datafileorand calling the exiting, continuing in a In this case, there is only class functions is through state. one. this member. Ex(LB) The Data File ; Light Bulb Transition Definition Data File [STATE_0] STATE = FSMS_ON CONDITION_0_VAR = TIME CONDITION_0_FUNC = GREATER_THAN CONDITION_0_VAL = 1000 OUTPUT_STATE_0 = FSMS_OFF ; ; ; ; When in state FSMS_ON there is a transition to state FSMS_OFF whenever the condition TIME > 1000 is met. [STATE_1] STATE = FSMS_OFF CONDITION_0_VAR = TIME CONDITION_0_FUNC = GREATER_THAN CONDITION_0_VAL = 1000 OUTPUT_STATE_0 = FSMS_ON ; ; ; ; When in state FSMS_OFF there is a transition to state FSMS_ON whenever the condition TIME > 1000 is met. Ex(LB) Watch Demo But this example is trivial and boring … … so I wrote my own demo of how data-driven FSMs could be used to control units in a Real Time Strategy game such as Warcraft II. Ex(WC2) Game Mechanics •Human and computer players control armies of various types of units and buildings. •Micromanagement of units is possible, but even units controlled by humans need some AI. •Goal is to destroy all units / buildings controlled by enemy players. •My demo models the actions of 2 hostile groups of 3 units that meet while following orders to go to a location. Ex(WC2) FSM Diagram Ex(WC2) Watch Demo • There are 6 units, each of which is controlled by an instance of an FSM. • Units take turns performing actions associated with their current states and possibly transitioning between states. • Note: the demo does not work exactly like the previous diagram: it is difficult to fit all the details in a diagram. Ex(WC2) Limitations • There are several missing transitions, because this should really be based on a push-down automaton. • Game units aren’t actually autonomous: transitions may be mandated by a higher intelligence as well. • Simplistic: a unit may run from one enemy straight to another. Data-driven Summary • The Data-driven FSM model works great actions from decisions, and you expect to spend lots of time tweaking the decision-making ( state transitioning ) process. • Not a very flexible system. • Development time for engine is still much higher than development time for AI. • A more robust scripting engine answers most of these problems. Scripted FSM • Rather than a data file that is read by the architecture, an entire language that will be compiled to bytecode. • Much more flexible. – Variables and functions for the transitions to query still need to be defined outside of the scripts, but you can now add new states very easily. – Actions still need to be defined outside of the scripts, but connecting a state and an action now occurs in the script. Script Syntax Behavior ( name of state ) begin variable ( list of local variables ) transition ( conditions to be checked each round ) sequence ( what you do in this state ) end Sample Script behavior Test begin variable integer lastState = 0 transition if PlayerState != lastState then begin if PlayerState = 0 then log "Player's State: Standing" else log "Player's State: Moving" log "Player's Location: ",PlayerLocation set lastState to PlayerState end sequence log "Testing 'test' script'" do forever begin goto 10,0,250 idle 3 goto 6,0,100 stack "IdleForASecond" end end Scripted Demo: Movement • Very simple demo for very complex project. • 6500 lines of code vs. 2000 lines of code, most of which would not need to be altered. • Does include support for remembering and returning to previous states. • Building / updating the architecture will require significant resources. AI designers will need to be trained in the new language. Conclusions Traditional Data-driven Scripted Code Complexity High Moderate High Script Complexity N/A Low Moderate Time To Implement High Moderate High Ease Of Change Low Moderate High Flexibility High Low High References • Civilization II, MicroProse Software, 1995. • Du, Ding-Zu, and Ko, Ker-I, Problem Solving in Automata, Languages, and Complexity, Wiley, 2001. • Fu, Dan, and Houlette, Ryan, “The Ultimate Guide to FSMs in Games,” AI Game Programming Wisdom 2, Charles River Media, 2004. • Rosado, Gilberto, “Implementing a Data-Driven Finite-State Machine,” AI Game Programming Wisdom 2, Charles River Media, 2004. • Sipser, Michael, Introduction to the Theory of Computation, PWS, 1997. • Warcraft II, Blizzard Entertainment, 1995. • Yiskis, Eric, “Finite-State Machine Scripting Language for Designers,” AI Game Programming Wisdom 2, Charles River Media, 2004. • Screenshots taken from Warcraft II, illustrations by Chad Hogg in MS Paint. • This presentation and my demos are available at www.lehigh.edu/~cmh204/.