Advertisement

state machine question

Started by March 01, 2006 12:30 AM
5 comments, last by phew 18 years, 8 months ago
Hi there : my question is in our game character's AI is based on a Finite State Machine which is hard-coded and all the rules for state transitions are embeded within the states themselves, so far it works fine, but now im demanded to separate AI data (or logic) (for example, state translation rules) from code so game designers can quickly adjust character's behavior without recompile any source code, i dont have too much experience about this, so i want to know how you guys implement this in your game developing, for example : which part can be exposed to designers etc. more in detail and better ~~~ and thanks for sharing~~~
In the AI demo Im working on, *all* AI rules are stated in an XML file written from a custom editor. The AI system read the XML at game initialisation and setup its equivalent of your transitions from it. So all behavior definitions are outside the engine but all behavior implementation is inside.

Simplified example:

Let say I have a rule to run away when health is at 80%
in the XML I have a rule that looks like

<Rule Action = "Run Away"> </HealthLowerThan Arg1 = 0.8> </Rule>

Thats the definition.
Now in the engine I need to implement the RunAway() action and the HealthLowerThan() query. Thats the implementation...

The AI engine read the rule in the XML, add a "transition" , match things with the game engine and will call the implmentations are the appropriate time.

Hope thay helps!
Advertisement
Thanks Steadtler, your reply is very enlightening and it should be very convenient to tweak role's behavior. anyway i have another consideration : if the character owns too many states and the logic outside exposed to designers becoming complicated, will this method still appliable? isnt it time for us to move those logics back to our source code? if this assumption is valid, how complicated is cmoplicated? thanks
The first thing you need to do is sit down with the designers and talk to them about what kinds of things they want to be able to control. Then you can figure out how to modify your source-code to give them that control. AI should be developed hand-in-hand with design.

1) Design defines what they want the role of the AI to be.
2) you offer implementations solutions
3) you work together to figure out what control design will have over the AI.

the answers to 3 are going to be specific to the game you are making. Maybe all they need to control is "aggression", maybe they need to actually be able to control the AI in a "scripted" way, maybe they just need to be able to tweak the "aggression". It's up to them and the type of game you are creating what those controls will be.

-me
Quote: Original post by phew
Thanks Steadtler, your reply is very enlightening and it should be very convenient to tweak role's behavior. anyway i have another consideration : if the character owns too many states and the logic outside exposed to designers becoming complicated, will this method still appliable? isnt it time for us to move those logics back to our source code? if this assumption is valid, how complicated is cmoplicated? thanks


Palidine's comments are valuable, consider putting his advice to good use.
Apart from that, if the agent ('character') has too many states, I would say it means it is time for another level of abstraction. You need to come up with a way such that the designers will be able to define the behavior without knowing all of the possible states.

It can still end up to a state machine. An analogy would be a syntaxic analyser. One does not define every possible state, just a syntaxic grammar. Yet you end up with a state machine from that grammer that allows you to efficiently compile your code...
While I agree whole-heartedly with Paladine on working hand-in-hand with the design team, I'd also recommend that you separate the logic from the implementation as a matter of course, because not only is this good programming practice, but it will make life FAR easier when you come to debug the system after the designers have gotten to it! ;) If you know the code works perfectly (and here I recommend test-driven design for FSM development), then behavioural bugs can only be logic bugs. Furthermore, you can reuse the FSM code in a different project with little or no redesign necessary.

As for the designers...

Golden rule: expose only those parts of the system necessary to give the designer control in the manner they require. So that means giving the designers a means of changing the state machines behaviour to match their design doc for the behaviour of the thing driven by the machine (usually a game character or dynamic object).

Having lots of states in the machine isn't a problem provided that the number of behaviours is finite and manageable. There might be 50 different weapons that an FPS bot can wield, but the actions that the bot can perform to change state are basically equip/unequip, load/unload, aim/lower and fire. Thus, the behaviours possible involving a weapon are those arising from the subset of states generated by application of these seven actions.

One final point that I think is relevant here... if you're dealing with complicated FSMs (with large state spaces and action sets), I would recommend separating out the state machine from the event system that triggers behavioural changes. I've seen a lot of FSMs in games that combine them so that events trigger state changes. This is all well and good for small FSMs. You'll find it far easier to debug and manage a larger FSM if you implement an action model that maps states to states given an action. So, that means, if the states are
X={X1,X2,...,Xn}
and the actions are
A={A1,A2,...,Am}
then
for all Ak in A, Xi in X:Xj=S(Xi,Ak) and Xj is in X

and S is an action model. Such a model may be represented by the input and output set of states corresponding to a set of action functions. For instance, an action function like
WEAPON_STATE = LoadWeapon(WEAPON_UNLOADED)
might have possible return values of WEAPON_LOADED (for success of the action) and WEAPON_UNLOADED (for failure, perhaps because no ammo was held). This function would correspond to two arcs in the FSM originating from the WEAPON_UNLOADED state. One arc connects to the WEAPON_LOADED state and the other loops back to the WEAPON_UNLOADED state.

Now, to trigger actions, you need events, which can easily be written in the form of production rules of the form
if condition then action

where condition is an event within the game and action may be either a single action, a set of actions or an ordered sequence of actions where completion of the sequence is conditional on completion of each step in the sequence. You may be able to make things more abstract, as Steadtler suggested, by abstracting actions (using sets and sequences). Do this in consultation with the design team. They may want abstract actions like PatrolArea() for quickly building the system, but they may also want to be able to alter the way individual bots patrol an area by getting at the subactions that make up the PatrolArea() action.

If you've separated the event and action systems these are separate from the code implementation of the FSM then it's far easier for you to make changes in any of the layers without having to change the others. The workload saving here can be quite considerable down the track when the deadline is looming!

I hope this helps. Good luck with your project!

Timkin
Advertisement
thanks timkin and all the replys. i was reading documents about scripting found on the internet in the past days and discuss possible implementions with other programmers in the team, basiclly we've decided to use scripts (thanks again) for the logic and i believe we'll benefit because this decision in the long run.
go sleep now and have a nice dream everybody~~~

This topic is closed to new replies.

Advertisement