playMaker

Author Topic: FSM Execution Order Priority  (Read 9660 times)

dasbin

  • Junior Playmaker
  • **
  • Posts: 92
FSM Execution Order Priority
« on: May 09, 2013, 12:44:03 PM »
Hi,

I know FSM's logic execute in a loop. Been thinking about all the ways to make sure things get done in setup FSM's before another FSM accesses the needed data from it. The two main ones are using Wait (can really slow things down, not always reliable if game is running slowly), and (more reliable and faster) sending events to and from FSM's or checking a "done" boolean.

However, this can be really time-consuming and confusing when you're dealing with hundreds of things being setup by hundreds of FSM's in a larger project.

Easiest possible solution: set the execution order priority of a particular FSM, like script execution order in Unity. So if the default is 1000, an FSM with priority of 999 will always execute before the others. It would iterate all the way through whatever it can do in a single frame (or until it has to wait for something) before other FSM's get executed.

Possible to implement?
This would be unbelievably helpful!

Lane

  • Administrator
  • Hero Member
  • *****
  • Posts: 2511
  • Mender of the past
    • Cleverous
Re: FSM Execution Order Priority
« Reply #1 on: May 09, 2013, 01:22:02 PM »
Is all of this happening at runtime?

Generally your FSM structure is such that you don't have this problem, I would use send events, broadcasts or other methods to systematically link things together so that they execute in an orderly fashion rather than having to rely on the processing order and risk having an FSM with dependencies that you know don't work like this. You can use Idle/Listener states that are exited by event triggers from its dependency parent to control the flow.

States don't really have this issue, they run top to bottom and Next Frame Event's can help keep things smooth if you're bouncing actions between separate FSMs.
Products by Cleverous
|| Vault Core : Database
|| Vault Inventory : Multiplayer Inventory
|| Vault Attributes : Character Stats
|| That Hurt! : Dmg Floaties
|| Quinn : 3D

dasbin

  • Junior Playmaker
  • **
  • Posts: 92
Re: FSM Execution Order Priority
« Reply #2 on: May 09, 2013, 01:37:49 PM »
The problem is when you have more than just one "dependency parent." If a state is waiting for multiple other FSM's to get setup, you don't know in which order they will finish setting up, so you can't necessarily listen for a particular order of broadcast events.
Where it gets really confounding is trying to setup a chain reaction of these (ie one setup waits for another before starting its own setup) and trying to listen for the last one in line. What if you suddenly add a new setup dependency to your project that you want to be the last one in line? Then you have to redo every single FSM which relies on it.

Right now I am using the "Bool All True" action to test multiple setups, but again, it is very time-consuming to add new dependencies. And I don't like the performance implications of having thousands of bool checks running every single frame, even if it is only for the first few seconds after loading.
« Last Edit: May 09, 2013, 01:41:48 PM by dasbin »

Lane

  • Administrator
  • Hero Member
  • *****
  • Posts: 2511
  • Mender of the past
    • Cleverous
Re: FSM Execution Order Priority
« Reply #3 on: May 09, 2013, 01:44:17 PM »
Can you post an example of this? I can't wrap my head so many different FSM's having communicate between each other on this level and there not being a better solution.
Products by Cleverous
|| Vault Core : Database
|| Vault Inventory : Multiplayer Inventory
|| Vault Attributes : Character Stats
|| That Hurt! : Dmg Floaties
|| Quinn : 3D

dasbin

  • Junior Playmaker
  • **
  • Posts: 92
Re: FSM Execution Order Priority
« Reply #4 on: May 09, 2013, 01:51:57 PM »
My gameplay mechanic relies on a magnetic charge function whereby the player can assume one of three different charges (positive, negative, neutral) at any given time. Every single object in the game changes its state and behaviour based on what charge the player has assumed.  The level can start with the player in any particular charge state, set by the level designer.
However, each of these charges also has a particular colour associated to it, and the game objects derive their own material colour from the Colour Manager based on whatever particular charge they represent (colours are per-level).
Add to this a per-level musical mechanic (sounds in the game change their pitch based on the musical key of the level corresponding to their charge) and a gravity mechanic (gravity can switch colour charges and pull objects in the game in any particular direction).
There are also mirrors which reflect beams of a particular colour charge, but they must wait for the beam to be initialized and set to a charge. And there are switches which slave to one another - they must wait for their "Master" switch to complete setup before they themselves attempt it.
There are more examples. All of these elements rely on a chain of initializations, and then every object in the game relies on all of these particular level variables to be set up before they set themselves up and appear in the world.
My global vars and global events are already out of control and impossible to navigate. Add initialization to the mix and it just gets unwieldy.
« Last Edit: May 09, 2013, 01:58:59 PM by dasbin »

Lane

  • Administrator
  • Hero Member
  • *****
  • Posts: 2511
  • Mender of the past
    • Cleverous
Re: FSM Execution Order Priority
« Reply #5 on: May 09, 2013, 02:07:14 PM »
Well, that is definitely complex but it doesn't seem to need to rely on process order.

It seems to me that you could setup the objects with Listener FSM's that get orders from a Manager.

For instance if the player changes his state then it simply updates thisState manager which broadcasts a signal across all FSM's to do something, you could make it a unique FSM like changedPolarity and somewhere in the object FSM structure have a listener state waiting for that event, when it is triggered then the object changes. This will control your system fine, and you won't need to worry about process order because those objects are constantly waiting for an update to be handed to them by the Manager.

You can repeat this for each mechanic as necessary.

You can also have the manager enter a Negative state and have every other object just reading to see what state the Manager is in, if the state name is "Negative" then the object does xEvent to respond to that, this would be put in a listener state so it is listening for something to be done and send an event based on that, just get into another listener state to wait for further changes.

To illustrate it think of a light switch, the switch can do one action - up or down - and that action affects everything wired up to it - lights, phones, computers, whatever. Those items are waiting for a command and the switch triggers it. You can do the same with a Manager and put listener states on the objects that can be affected by that switch/manager.

If you need more events, more managers, whatever then just stack them up and create new FSM's if you're worried about simultaneous changes. That is the whole advantage of using FSMs and States.
« Last Edit: May 09, 2013, 02:10:33 PM by Lane »
Products by Cleverous
|| Vault Core : Database
|| Vault Inventory : Multiplayer Inventory
|| Vault Attributes : Character Stats
|| That Hurt! : Dmg Floaties
|| Quinn : 3D

dasbin

  • Junior Playmaker
  • **
  • Posts: 92
Re: FSM Execution Order Priority
« Reply #6 on: May 09, 2013, 02:16:34 PM »
Yes, this is exactly what I am doing, which works great - the issue is not in mechanic implementation but in initialization. No object in the game can set itself up until all the mechanics set themselves up, because the starting charge and colours and tones etc are all arbitrary per-level.

I should note that everything *works* as it is, but my complaint is that initialization is *needlessly complex* when a far simpler solution (execution order) appears to exist in theory. And the more elements I add to the game's initialization, the more frustrated I am with this, because I'm doing this time-consuming rote task (adding new initialization listeners to a great many objects) over and over again every time.

I'm not asking for this to make something work - I'm asking for this as a matter of convenience.
« Last Edit: May 09, 2013, 02:19:51 PM by dasbin »

Lane

  • Administrator
  • Hero Member
  • *****
  • Posts: 2511
  • Mender of the past
    • Cleverous
Re: FSM Execution Order Priority
« Reply #7 on: May 09, 2013, 02:20:37 PM »
The objects should stay in their default settings until their FSM is triggered to do something different, if they are initialized before the managers then you're looking at only a few frames of potential room for 'error' at initialization before the manager declares what actions or states the objects should be doing since they are always listening to the manager.
Products by Cleverous
|| Vault Core : Database
|| Vault Inventory : Multiplayer Inventory
|| Vault Attributes : Character Stats
|| That Hurt! : Dmg Floaties
|| Quinn : 3D

dasbin

  • Junior Playmaker
  • **
  • Posts: 92
Re: FSM Execution Order Priority
« Reply #8 on: May 09, 2013, 02:56:34 PM »
Then what if they are initialized *after* the managers?

In other words, the manager send out its initial trigger event, eg "Positive Charge", but the object isn't done setting itself up yet so it isn't listening in time.

For this reason I need to wait until the manager is done initializing, then check the states automatically. I can't risk having them sit in their default state waiting on an external event which may never come.

I know there are logical solutions to all this (I've found them!) but this entire conversation about how to handle the complexity would be moot with an execution order. Set the manager to a lower priority, and done. Adding a new manager or splitting a task? Assign its priority an intermediate number that is appropriate. Done. Don't have to add new checks upon checks.
« Last Edit: May 09, 2013, 03:02:52 PM by dasbin »

Alex Chouls

  • Administrator
  • Hero Member
  • *****
  • Posts: 3987
  • Official Playmaker Support
    • LinkedIn
Re: FSM Execution Order Priority
« Reply #9 on: May 09, 2013, 04:32:29 PM »
I'll look into this, but it might be tricky to implement.

PlayMakerFSMs are just MonoBehaviours, so they're updated in whatever order Unity chooses to update them. I haven't played with Unity's script order much, but my understanding is it's for a type of script, not a particular instance. Which wouldn't help in this case...

dasbin

  • Junior Playmaker
  • **
  • Posts: 92
Re: FSM Execution Order Priority
« Reply #10 on: May 09, 2013, 04:41:34 PM »
Thanks Alex, and you're right, a particular instance can't be managed that way. Hmm. I suspect then that each PlayMakerFSM would have to register itself in a manager's array, then the manager sorts them and sends an execute command to the first, waits for Done, then the second, etc.

So you're right, that might be more trouble than it's worth and there might be some performance penalty. But thanks for thinking about it.

Alex Chouls

  • Administrator
  • Hero Member
  • *****
  • Posts: 3987
  • Official Playmaker Support
    • LinkedIn
Re: FSM Execution Order Priority
« Reply #11 on: May 09, 2013, 04:54:37 PM »
I would focus on events to control the order (rather than wait or bool checks).

For example, avoid putting anything in the Start state when an FSM is dependent on another FSM, then send/broadcast an event to kick it off when you're ready.

You could also consider using Activate Game Object and the hierarchy to quickly turn lots of related FSMs on/off.

But I know you've talked this through above already... :)