From Bohemia Interactive Community
Jump to: navigation, search

OK, I know this is highly preliminary and full of assumption but I am hoping to spur some more testing or release of hard facts from BIS regarding this file structure. Heck, I am going off second hand info to get this. --CrashDome 08:06, 4 December 2006 (CET)

Hello Crashdome. From here : , it looks like, at least in .cpp, the condition/actions may not be a simple script, but takes argument :

  class MoveCompleted {
   priority = 1.000000;
   to = "SetRandom3";
   class Condition {
     function = "moveCompleted";
     parameters = {};
     threshold = 0;
   class Action {
     function = "nothing";
     parameters = {};
     thresholds = {};

probably referencing a function defined somwhere else in the cpp. - Whisper 18:30, 6 December 2006 (CET)

Thanks Kronzky, but I think those are config specific and useful for addons. However, all mission examples are different and more simplistic, BUT it is still important. I wish I had a copy of ArmA to do tests. When I get one, I will elaborate - if not already done so by someone else. --CrashDome 23:41, 6 December 2006 (CET)

A first detailed view of the soldier FSM, very simplified, by SoldierIsNotHistory : (from forums) - Whisper 16:57, 7 December 2006 (CET)

Nice work there on that chart! Pretty impressive job decoding it, and pretty interesting what kind of things this might enable scripters to do.

For now though, I have decided not to waste anymore time into "reverse-engineering" FSM...
BIS has a different attitude towards the community than they did when they released OFP. They know now that the addon and mission-makers are one of their strongest assets (that's why the Wiki), so unlike back then, where one *had* to figure stuff out yourself if you wanted to get into modding/scripting, I am sure this time around we will get some sort of documentation pretty soon.
So I could either spend the next few weeks trying to decypher FSM, only to have it then verified by the released documentation, or I could spend that time enjoying ArmA, familiarizing myself with the new concepts that are already documented, and then fully dive into FSM once the documentation is out.
(But I also know the thrill to trying to figure something out by yourself - without any outside help or documentation, so I do understand if other people chose not to wait...) --Kronzky 17:20, 7 December 2006 (CET)

The thing I'm afraid, is that more than documentation will be required. It looks really uneasy to built FSM files with a simple text editor, a bit like it's not easy to create a functionnal mission.sqm with only notepad ;) I think we'll need a tool to edit/create FSMs. And BIS doesn't look like they're gonna release FSMEditor tool, so someone will probably have to do it (like the first released mission editor for OFP demo where created by players) -- Whisper 17:39, 7 December 2006 (CET)

I hopefully will have good news for both of you. Kronsky, yes I have same feeling that BIS will release more information when the time is right. Whisper, I've already half created a graphical FSM editor. Great work on the graph btw. Here's to hoping that all goes as we expect - cheers! --CrashDome 07:50, 8 December 2006 (CET)


finalStates: This property takes an array of string arguments.
Current purpose unkown.
Each String is a "final State" there can be more than one!(for example: ["unit_dead","destination_reached","unit_captured"])

A final state stops the execution of a FSM. Let's say you have a FSM which orders a soldier to move from point A to point B. You can have 2 states then:

STATE 1: Move to B.
STATE 2: B reached.

State 2 should be a final state then and exit the FSM, as there is nothing left to do.

Difference Between Scripted and Native Type?

I find the description in the article very unclear. The information as it is now is pretty useless for me because I can't connect it to anything. I have been working with the .fsm files from the characters.pbo so far. I assume those are the scripted types. Where do I find the "native" types? -- Donnervogel 03:33, 5 March 2007 (CET)

afaik you can find them in configs. For example I remember a FSM for the dragonflies in the config. --T_D 11:34, 5 March 2007 (CET)
ah ok thank you. Well I saw them before but I though they were somehow a part of the .fsm files because most states and links are identically named. But now I had a look at the animal FSM class and I don't find any .fsm files for them. SO it looks that they are different things. Plus there are some differences in the FSM class for units and the .fsm Files. --Donnervogel 12:01, 5 March 2007 (CET)

Some (most verified) News about FSM

More than 2 Years are passed since CrashDome released the first information about FSM. The knowledge about FSM was and is low... but I'm happy to provide you with new infos I figured out.

A very good start about FSM is provided by rune from sinesofWar. I hardly recommend to read this Tutorial! You can get [FSM Introduction Tutorial here]. Not all is truth, but the most!

Let's start with the different types of FSM's (community given Names, no one knows, how they are called by BI):

  • scripted FSM
  • native FSM

Scripted FSM

scriptedFSM are devided in two styles by me:

Files can be in mission directory, and are used by the doFSM script command.

The MissionFSM are NOT running alone (unlike the tutorial of rune explains). They are call parallel to the character FSM! (and that's verified by me!) ;-)

Files must be placed in a Addon.

Then you must create new character classes and link the FSM Files. More about how to set them up later.

In Scripted FSMs you must use Script Commands.

Native FSM

Native FSM are stored in the GameConfig in the Class CfgFSMs. They use little other format than the scripted FSMs and you can't use script Commands. There are some different functions (a list of some(all?) later). The picture provided by SoldierIsNotHistory is the default formation FSM from BI. That IS the FSM used in Game! And its simple if you studie it for a while.

The Syntax of FSM

Scripted FSM

Scripted FSM is very good explained by rune's tutorial. So, I only list here a other sample: class FSM { fsmName = "FSM_Document"; initState = "Init"; finalStates[] = {"End"}; class States { class Init { name = "Init"; init = "private[""_debug""];_debug = false; if (not isNil(""debug"")) then {_debug = true;}; if (_debug) then {debug globalChat format[""%1:Init Formation! # _this:%2 # _units:%3 # _queue%4"",time,_this,_units,_queue];};"; class Links { class default { to = "Start"; priority = "0,000000"; condition = "true"; action = ""; }; }; }; class Start { name = "Start"; init = "if (_debug) then {debug globalChat format[""%1:Start.."",time];};"; class Links { class default { to = "Start"; priority = "1,000000"; condition = "true"; action = ""; }; class goEnd { to = "End"; priority = "0,000000"; condition = "true"; action = ""; }; }; }; class End { name = "End"; init = "if (_debug) then {debug globalChat format[""%1:End.."",time];};"; }; }; }; To get the chat messages, you have to place a scriptLogic with the Name 'debug' on your map.

Native FSM

Native FSM have a slightly different format and they must be placed in the CfgFSMs class. class CfgFSMs { class HJ_Debug { initState = "Init"; finalStates[] = {"End"}; class States { class Init { name = "Init"; class Init { function = "formationInit"; parameters[] = {}; thresholds[] = {}; }; class Links { class Member { to = "Member"; priority = "0,000000"; class condition { function = "formationIsMember"; parameters[] = {}; threshold = 0; }; class action { function = "nothing"; parameters[] = {}; thresholds[] = {}; }; }; class Leader { to = "Leader"; priority = "0,000000"; class condition { function = "formationIsLeader"; parameters[] = {}; threshold = 0; }; class action { function = ""; parameters[] = {}; thresholds[] = {}; }; }; }; }; // End States/Init class Member { name = "Member"; class Init { function = "setUnitPosToDown"; parameters[] = {}; thresholds[] = {}; }; class Links { class default { to = "Init"; priority = "1,000000"; class condition { function = "true"; parameters[] = {}; threshold = 0; }; class action { function = "nothing"; parameters[] = {}; thresholds[] = {}; }; }; class goEnd { to = "End"; priority = "0,000000"; class condition { function = "true"; parameters[] = {}; threshold = 0; }; class action { function = "nothing"; parameters[] = {}; thresholds[] = {}; }; }; }; }; class Leader { name = "Leader"; class Init { function = "nothing"; parameters[] = {}; thresholds[] = {}; }; class Links { class default { to = "Member"; priority = "1,000000"; class condition { function = "randomDelay"; parameters[] = {100000}; threshold = 0; }; class action { function = "nothing"; parameters[] = {}; thresholds[] = {}; }; }; class goEnd { to = "End"; priority = "0,000000"; class condition { function = "false"; parameters[] = {}; threshold = 0; }; class action { function = "nothing"; parameters[] = {}; thresholds[] = {}; }; }; }; }; class End { name = "End"; class Init { function = "nothing"; parameters[] = {}; thresholds[] = {}; }; }; }; }; }; This is a working native FSM! (yeah.. i did it!!! ;-)). Its very simple...
This native FSM does only make a difference between SquadLeader and SquadMember. SquadMembers go down to prone position directly after mission start. The SquadLeader with a little, random delay later. That's all... but it works!

Character with own FSM

Each CharacterType can have up to 2 FSMs.

  • fsmFormation
  • fsmDanger

The fsmFormation is the default FSM, wich is automatically run at mission start. You can leave it blank, but then the game engine falls back to the native "Formation" FSM, wich is declared in "CfgFSM/Formation". The value should be the name of a nativeFSM or the name of a FSM file(see example below).

The fsmDanger is the second FSM you can define. This FSM is optional. It's automatically run by the game engine, if your character 'thinks' he is in danger (for example i could start it by firing some bullets into the ground close to the character). The fsmFormation is then immediatly aborted (it will not run an "End State"). If the fsmDanger comes to a "End State", the engine will restart the fsmDanger again (if the fsmFormation was running while firing the fsmDanger). If you don't use it, set the value to "" and the game engine will continue to execute fsmFormation if character is in danger.

For my tests I used following config entrys: class CfgVehicles { //************************************************* //*** West Soldiers //************************************************* class SoldierWMedic; // External class reference // A Character wirh a Scripted FSM class FSM1SoldierWMedic : SoldierWMedic { displayName = "FSMDebug Scripted"; fsmFormation = "HeliJunkie\DebugDirectEnd.fsm"; fsmDanger = "HeliJunkie\DebugDirectEndDanger.fsm"; }; // A Character with a native FSM class FSM4SoldierWMedic : FSM1SoldierWMedic { displayName = "FSMDebug CfgFSMs"; fsmFormation = "HJ_Debug"; fsmDanger = "HJ_DebugDanger"; }; };

Special variables for scripted FSM

There are some special variables (you know it, if you read the FSM Tutorial from rune). But you cant use all variables in all FSMs!

  • _this

It's the only variable wich is provided in every FSM. It contains the Unit, wich is executing the FSM.

  • _units, _destination and _target

This variables are the parameters provided to the doFSM script command. So you can use them only in FSM Files, wich are startet by that command. For more see doFSM.

  • _queue

This variable is only available in scripts, wich are defined in fsmDanger. It contains an Array of Arrays. Each Arry contains:

  • the danger cause
  • the position of the threat
  • the time, until this threat is valid

It can look like this:


This array will only be extended! Even reasons, wich "until time" has elapsed stay in this array! So be shure that you leave the fsmDanger from time to time over the "End state". Otherwise this array will be very large!!!

The time can be compared with the time value. So you can see, if a threat is new or old.

The reason is a integer from 0 to 6. I don't know, wich reason causes wich number. But from the "formationCDanger.fsm" (you find it in "character.pbo/scripts") I extracted that BI gives them following prioritys:

cause     0 1 2 3 4 5 6
priority  3 3 4 5 2 1 1

nativeFSM Functions

I figured out some(all?) of the functions you can use in nativeFSM.

nativeFSM Functions/Commands
Name Parameters Remark Verified
formationDeadlock  ? -
formationTooFarAreCovered  ? -
randomDelay  ? Returns true after a random delay. X
coverReached  ? -
checkCover  ? -
formationTooFar  ? -
formationEnemy  ? ( Saw a parameter {100 , 0}. But have no idea, what this means) -
reloadNeeded  ? -
formationNotEnoughCover  ? -
formationIsLeader  ? Returns true if Unit is Leader of Group X
formationIsMember  ? Returns true if Unit is a Member of Group X
vehicleAir  ? -
behaviourCombat  ? -
formationCleanUp  ? -
setUnitPosToDown  ? Unit goes to prone position. X
formationSetHideBehind  ? -
formationNextTarget  ? -
formationLeader  ? -
formationProvideCover  ? -
goToCover  ? -
formationMember  ? -
formationInit  ? -
formationExcluded  ? -
formationReturn  ? -
formationNoCombat  ? -
vehicle  ? -
reload  ? -

Some Helpful Links

To watch the game config, it is not nessesary to extract and unrap all config.bin files.
Use my ConfigExplorer to watch the gameconfig easily.
You can download it (for example) from [here].
It helps me really a lot, and not because i wrote it.

To edit FSM-Files you can use "FSM-Edit" by CrashDome.
You can download it from [here]. One Tip: Write all your code in one line! Otherwise you will get errors, if you use the FSM without the doFSM command!

We all need YOUR help

Because the informations about FSM is very spare, share all new information with us over this great Wiki!

So I hope that are good news for all of you, wich are interested in FSM. And don't watch only to the spelling errors... go and correct them ;-)
I read a lot in english, but I'm writing it rarely... sorry --HeliJunkie 21:27, 6 December 2008 (CET)

Parlez-vous FTM?!

Back in the day I used "Libero", produced by the same crew who pushed out the Xitami server. (Big deal at the time; small, fast, multi-threading. Typical of Pieter Heintjens'!)

FSM is tediously detail-oriented. I'm like that; is why I get along with it. Anolog: editing some elaborate XML by hand. Not for the fain-hearted, and there by rights should be a better way.

So glad I now how some sense of where you're coming from! -- aka Dawks Bentrem 07:29, 8 September 2011 (CEST)



well, according to coder FSM has no better VM than SQF, but it gets bit more % in simulation space (cycles)
that's why it's probably faster (also prio is higher due being closer to low level AI layer)

FSM is not possible terminate from outside while script is possible via external terminate
sequenced scripts are better to do in FSM
.fsm is always called as execVM thus it has different effect as code call(ed) via call (no continue until code done)


You can terminate FSM from outside and check for that condition in fsm:
 _fsmHandle setFSMVariable ["someVariable",true];