Jump to content
Sign in to follow this  
fabrizio_t

FSM editing

Recommended Posts

Hello,

i've tried to do some FSM editing through Flea's nice editor.

I was able to correctly load my FSM (a modified version of formation.fsm) through DoFSM / CommandFSM, but i noticed that the unit i've bound was ignoring the FSM logic.

After some investigation i discovered the variable "_this" - the one i think should identify the unit object appears to be undefined in the FSM (tried to dump it by Hint / sidechat).

Also it seems that a "default" FSM is still overriding my own ...

Any clue ?

Share this post


Link to post
Share on other sites

sorry for "stealing" this topic, but i think it would be counterproductive to create another topic about FSM.

I want to ask for anybodys opinion on using and running one big FSM file, or splitting it into more files which will switch between themselves.

What do you think works better (performance-wise)?

EDIT: ...it probably depends on how often are the FSM switched, so let's assume that it will be switching between 3-4 different FSM files, while each FSM file should be running for at least about 5 seconds (which is the shortest possible time, in reality it should last few minutes),

with 50-70 units each running its own FSM.

Share this post


Link to post
Share on other sites
Have you read the tutorial?

Tutorial

You may find some of your answers there.

yes, i read it, but that didn't answered my question.

Maybe i missed it, but i really haven't found anything concerning the overhead of switching FSMs.

btw. it would be nice to have some HTML version of the tutorial (i prefer html or plaintext, except when you really need to preserve correct layout of the document)

Share this post


Link to post
Share on other sites

I decided to use the switching of different FSM files - primarily because it makes the sources more lucid, and truth is that i can simly join them back into one FSM whenever i want.

I'll try the difference later, but if there is anybody who's got some insight, it would be nice to share :)

Share this post


Link to post
Share on other sites

Did I miss it? The originally question hasn't really been answered here, has it?!

Someone sometime said that only one FSM can run at time and former FSM will terminate as soon as a doFSM is executed.

But from what latinman says it doesnt apply here.

Share this post


Link to post
Share on other sites
Did I miss it? The originally question hasn't really been answered here, has it?!

Someone sometime said that only one FSM can run at time and former FSM will terminate as soon as a doFSM is executed.

But from what latinman says it doesnt apply here.

No, you cannot run more than one scripted FSM.

You can test it yourself - create this FSM file:

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">class FSM {

fsmName="Test";

initState="Init";

finalStates[]={};

class States {

class Init {

name="Init";

init="_tout=0; _unit=_units select 0; _n=_destination select 0";

class Links {

class RunTest {

priority=1.000000;

to="Testing";

condition="true";

action="";

};

};

};

class Testing {

name="Testing";

init="";

class Links {

class Repeat {

priority=0.500000;

to="Testing";

condition="true";

action="if(_tout<time)then{_tout = time + 1.5; _unit globalChat format[""test%1"",_n]}";

};

};

};

};

};

Then you can try to run multiple FSM files like this:<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">unit doFSM ["test.fsm", [1,0,0], nil];

Sleep 5;

unit doFSM ["test.fsm", [2,0,0], nil];

Sleep 5;

unit doFSM ["test.fsm", [3,0,0], nil];

You will see that "test1" is printed continualy, then after 5 seconds the "test2" is printed continualy,etc. - no mixed output of "test1" and "test2" and "test3".

There is only "test1" in the output, then the fsm is ended by the other run fsm and then only "test2" will be print to the output, and then only "test3".

Or you can remove the Sleep commands, and then you will see ONLY "test3" - all previous FSMs were stopped by the next doFSM.

Share this post


Link to post
Share on other sites

It is always an assumption that one versus many is going to be better when you cannot compile before hand. This is assuming it needs to compile or read the file each call. What type of difference this makes is not known.

Quote[/b] ]CrashDome

great job on the tute

Don't thank me! I didn't write it wink_o.gif

Share this post


Link to post
Share on other sites

i just realized, that my logic regarding proof, that you can't run multiple FSM files, is seriously flawed :-)

In the example i gave, the termination of previous FSMs can be happening because we are trying to run agan same FSM file for same unit.

...however, i think that its impossible to run multiplne FSM files - why would you do that anyway?

Running multiple FSMs for the same object is ...contraproductive? contradictory to the purpose of FSM, in one word - a nonsense.

Or maybe i am too blind to see why would anyone wanted to do such thing.

Question: Is there any way of passing more parameters/variables to the FSM?

Anything other than what is available through _units, _unit, _destination, and _target?

So far i was able to devise only one primitive workaround, by creating a global array named 'somearray#'. Then i fill this array with desired values of desired types, and then i run the FSM while substituting one of the _destination array elements with the number #.

The FSM can then run some function which will take this # from the _destination array, and through "call compile" accesses the array 'somearray#'.

Any other ideas?

Share this post


Link to post
Share on other sites
i just realized, that my logic regarding proof, that you can't run multiple FSM files, is seriously flawed :-)

In the example i gave, the termination of previous FSMs can be happening because we are trying to run agan same FSM file for same unit.

...however, i think that its impossible to run multiplne FSM files - why would you do that anyway?

Running multiple FSMs for the same object is ...contraproductive? contradictory to the purpose of FSM, in one word - a nonsense.

Or maybe i am too blind to see why would anyone wanted to do such thing.

Question: Is there any way of passing more parameters/variables to the FSM?

Anything other than what is available through _units, _unit, _destination, and _target?

So far i was able to devise only one primitive workaround, by creating a global array named 'somearray#'. Then i fill this array with desired values of desired types, and then i run the FSM while substituting one of the _destination array elements with the number #.

The FSM can then run some function which will take this # from the _destination array, and through "call compile" accesses the array 'somearray#'.

Any other ideas?

I use created HeliHEmpty invisible helipads and setVariable on them, and I put these HeliHEmpty as "_target" of FSM. This for SP missions, for MP it could be tricky as variables attached to objects through setVariable are local only. OTOH FSM are not supposed to run on clients's PC wink_o.gif You don't want to replace human logic by FSM ones, as stupid a player can be wink_o.gifbiggrin_o.gif

My issue at the moment is that using <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">group move position on FSM _units's group doesn't work. I hear the leader ordering the "move to XXX", but no one moves

Share this post


Link to post
Share on other sites

@5133p39

You are absolutely correct. You wouldn't want the headache with trying to run multiple FSMs. Also, there is some behavior changes in regards to coding with FSMs and these are not scripts which can be run in parallel and loop consistantly. It is not the purpose.

@whisper

FSMs can be run on client PCs. Remember that your group of AI units are local to you.

Do NOT use doMove or move in an FSM. The reason they are not moving is because Move creates a waypoint and all waypoint following is suspended in an FSM while doMove will instantly terminate your FSM. Use moveTo or setDestination.

Share this post


Link to post
Share on other sites

Right, gonna dig into this setDestination, but its parameters are really strange. Any better description than Biki's one?

I ask cause once I'm @home able to edit a bit, I don't have access to Internet and I'm completely blind, no comref, no Biki, searching in the mist, so any bit of advice is welcome beforehand smile_o.gif

Share this post


Link to post
Share on other sites
Right, gonna dig into this setDestination, but its parameters are really strange. Any better description than Biki's one?

I ask cause once I'm @home able to edit a bit, I don't have access to Internet and I'm completely blind, no comref, no Biki, searching in the mist, so any bit of advice is welcome beforehand smile_o.gif

I answered your ? at OFPEC which might give you headway, but I'll reiterate here in a diff way:

Try using your FSM to create a waypoint structure rather than controlling all movement at all times. I found you can create a whole series of waypoints that the AI will promptly follow once you kill you FSM. Now, I believe that some waypoints you can even attach another FSM using setWaypointStatements command.

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">[grp,2] setWaypointStatements ["true", "grp doFSM ""MyFSM.fsm"";"]

i.e. when the above waypoint is reached (and set 'true' by waypoint condition) the FSM will engage. I have not tested this myself, but might provide you insight.

My whole point is to - instead of disregarding waypoints and trying to control everything yourself - use the FSMs as a tool to make the AI behave and create/use the waypoints properly.

Also, setDestination I think is more for formation behavior and things like flanking/combat maneuvars because you need to set it for each individual unit.

Share this post


Link to post
Share on other sites

notworthy.gif It works flawlessly now (well, 1% of the work is now done, I now can go on completing the other 99 tounge2.gif )

Thank you CrashDome

Share this post


Link to post
Share on other sites

It seems the orderGetIn command interrupts my scripted FSM.

I need the unit to get in a vehicle, while the FSM is running.

I hate the idea of spawning a script only to wait until the unit is inside the vehicle to run the FSM again.

Any usable workaround?

EDIT: now that i am thinking about this problem, it seems logical - the FSM was initialy run for a MAN, but when this man gets into a vehicle, he becomes "something else" - he becomes a VEHICLE, so it seems logical that the old FSM will end because vehicles often need to be treated differently.

Therefore i think it's not possible to prevent stopping of the previously run FSM - it seems to be on purpose. I need only some reliable way to start new/same FSM after the original one is stopped.

Maybe some special named state exists, which, when present in the FSM file, is being used when the FSM execution is interrupted?

Share this post


Link to post
Share on other sites
It seems the orderGetIn command interrupts my scripted FSM.

I need the unit to get in a vehicle, while the FSM is running.

I hate the idea of spawning a script only to wait until the unit is inside the vehicle to run the FSM again.

Any usable workaround?

I need help with this.

I made a workaround - i am stopping the FSM myself when a unit is about to get in or out of a vehicle, and before stopping the FSM i spawn a script which waits until the unit gets in or out of a vehicle, or until a 10 seconds timeout runs out (could be less, maybe, but i better be safe than sorry), and then it will start the FSM again.

The problem is, everytime this happens, the unit is just standing/sitting and doing nothing for 10 seconds, which is little awkward.

I tried the unitReady command, but it doesn't help - either it's functionality is disrupted because of the doFSM or other commands i used, or it won't help simply because the unit is in middle of something (a MoveTo which it hasn't completed yet).

I need some reliable way to determine when it is safe to run the FSM again - if i run it too early after the unit's get in/out action, it will be still stopped by something unknown (by native FSM?).

The 10 seconds delay works, but i don't want any unnecessary delay.

Please, give it some thoughts, i really really need help with this.

(It would be VERY nice if we could get at least a little comment from the developers, regarding this issue)

Share this post


Link to post
Share on other sites

My tests showed the same results. I could not for any known reason order a unit into a vehicle.

The *only* way I can see this changed is by doing what you did.

You might try adding an eventhandler onto the vehicle before you order him in. Upon entry, the eventhandler should execute the FSM again once the unit is "in" the vehicle and remove the handler.

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE"> if (unit in vehicle) then ...

Share this post


Link to post
Share on other sites
You might try adding an eventhandler onto the vehicle before you order him in. Upon entry, the eventhandler should execute the FSM again once the unit is "in" the vehicle and remove the handler.

Unfortunately, this won't help in this particular situation.

Here is what i am trying to achieve, so you better understand why i can't use simple eventHandler:

My goal is to make some very simple simulated life as a background for any mission (right now i am working on the new Psycho Slayer, and my Zombie mod, where in both scenarios i can use this).

The AI is simply wandering around a town, doing whatever, until there is a need to get into a vehicle and drive somewhere (an AI unit is sheduled to go to work, or they just "want" to go on a trip).

Imagine the AI is ordered to get into a vehicle 300m away.

In this case, anything can happen before the AI can even reach the vehicle. The vehicle can be destroyed or damaged and then the AI wont get in, so the EH will not be activated. Well, i could also attach other eventhandlers like "damaged", or "killed", but what if the vehicle is on some place where the AI cant reach it? ...there is no eventHandler which could catch this event.

Besides, i need to be able to react to various events until the AI reaches the desired vehicle, so i still need some FSM (or script sad_o.gif ) to be running.

Any combination of eventHandlers can't solve all possible problems, because various conditions may occur under which the EH may never be activated anymore, and then it will leave the AI brainless for the whole game.

Share this post


Link to post
Share on other sites

Can you run the FSM on the (vehicle _unit) as opposed to the (_unit)? That way it always refers to the units vehicle, or does it not make a difference?

--Ben

Share this post


Link to post
Share on other sites
Can you run the FSM on the (vehicle _unit) as opposed to the (_unit)? That way it always refers to the units vehicle, or does it not make a difference?

--Ben

No, you can't run FSM on a vehicle - only alive units can run FSMs.

MAYBE it would work if the _unit was already in the driver position of the vehicle (i didn't tested this), but until the unit gets in the driver position, the vehicle is just a vehicle - not alive and no FSMs can be run on it (i tried this).

And when the unit is already on the driver position of the vehicle, then there is no need for running FSM on the vehicle (whether it would work or not), because then i can run FSM on the unit.

Share this post


Link to post
Share on other sites

I just discovered that this automatic ending of FSMs is a really really BAD THING.

As i wrote earlier it happens when unit gets in or out of a vehicle - and the AI is doing this on their own, for example civilian units will get out of a vehicle when under fire, and you have absolutely no control over this behaviour!

This problem is starting to be really anoying one.

It forced me to start using "getIn" or "getOut" eventhandlers to make my way around it. I dont like this, its starting to be a little bulky :-(

I am thinking about throwing out the FSMs and use ordinary SQF script instead :-((

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×