playMaker

Author Topic: Blocking/ignoring events, rendering a FSM deaf[SOLVED]  (Read 5044 times)

Broken Stylus

  • Beta Group
  • Hero Member
  • *
  • Posts: 772
Blocking/ignoring events, rendering a FSM deaf[SOLVED]
« on: December 12, 2018, 12:27:56 PM »
Events are brutal.
They short-circuit everything and it's really a pain in the **** to manage them when one wants to prevent a FSM from being attentive to new events or receiving the same event twice.

I haven't found an option that renders the FSM deaf to all or certain events.
This means I need to circumvent that by creating a monitoring central FSM that dispatches orders (like activate FSM) or events (forwarding) to other FSMs based on the events received, using alongside bools to check if event #n was already received or not.
This creates an unnecessary extra step, preventing the other FSMs from directly receiving the events.
It also creates a potential bottleneck if there are many FSMs are tons of events sent at once.

I just wish there were actions (in StateMachine) that would allow me to have a FSM ignore all or specific events until I lift the ban or the game object or until the FSM is reset or disabled and reactivated later on.

PS: what's the "eat event" option in Forward FSM btw?
« Last Edit: December 21, 2018, 01:42:14 AM by jeanfabre »

djaydino

  • Administrator
  • Hero Member
  • *****
  • Posts: 7616
    • jinxtergames
Re: Blocking/ignoring events, rendering a FSM deaf
« Reply #1 on: December 12, 2018, 07:38:29 PM »
Hi,
Can you show some fsm with your setup?

Maybe you can set some of the transitions to local so that they can't get triggered twice?

Thore

  • Sr. Member
  • ****
  • Posts: 480
Re: Blocking/ignoring events, rendering a FSM deaf
« Reply #2 on: December 13, 2018, 06:12:49 AM »
Events are brutal.
They short-circuit everything and it's really a pain in the **** to manage them when one wants to prevent a FSM from being attentive to new events or receiving the same event twice.

For that problem use a simple design pattern: when the event is received, place a bool check that asks “did we do this already” with a bool, and if true, go out to a different state (a dead end, for example). Underneath that very action, put the routine you want done, and after the crucial bits, place a set bool that turns the “did we do this already” variable to true. Next time, it runs through, the bool check on top sees it was done already, and goes off a different track. Don’t forget to set the variable to false later on again, when you want to permit retriggering the event again.

If that still isn’t good enough, you can broadcast the event, trigger the receiver and at once tell all senders to cease sending that event. I’d go with the above method, though and rethink the design.
« Last Edit: December 13, 2018, 06:15:53 AM by Thore »

Broken Stylus

  • Beta Group
  • Hero Member
  • *
  • Posts: 772
Re: Blocking/ignoring events, rendering a FSM deaf
« Reply #3 on: December 13, 2018, 06:13:43 AM »
Hi,
Can you show some fsm with your setup?

Maybe you can set some of the transitions to local so that they can't get triggered twice?

What do you mean?

Also, the problem exists because I have a major FSM regulating reward, victory and defeat conditions that are sending global events on broadcast to a large quantity of objects with different purposes.

It is logical to have the objects manage how they react to these global events by deciding locally if they'll "listen" or even "react" to a received event.

Thus far I haven't found any other solution than using a monitoring FSM that acts as a gatekeeper on each game object that could be receiving the global events multiple times but actually must not do anything beyond the first reception.

That's related to the way Playmaker's FSM handle events, more precisely global transitions, whether the event itself is global (sent by another FSM) or sent internally within a FSM: regardless of what a FSM was doing, the flow is rerouted to the state where the event is meant to be received.
I haven't found a way to control that, to switch the "listeners" off, whether to be totally deaf or to only ignore events that belong to a list—typically the action would allow the user to add any given amount of FsmStrings, each string being the name of the event to ignore.

My effective solution consists of having a FSM-0, acting as a filter, that receives events and uses bools to decide whether to activate FSM-1, FSM-2, etc.. Those other FSMs actually hold the real functions fir the object(s).

The activated (monitored) FSMs are either meant to be active once or remain active as long as the game object is active.

This works, but it would be straighter and faster to initialize FSMs by putting them in a given mode where I decided how they'll react to events. This initialization would simply be done through a primary state with START and actions that define the kind of behavior to follow for incoming events, whether external or internal.

Broken Stylus

  • Beta Group
  • Hero Member
  • *
  • Posts: 772
Re: Blocking/ignoring events, rendering a FSM deaf
« Reply #4 on: December 13, 2018, 06:20:26 AM »
Events are brutal.
They short-circuit everything and it's really a pain in the **** to manage them when one wants to prevent a FSM from being attentive to new events or receiving the same event twice.

For that problem use a simple design pattern: when the event is received, place a bool check that asks “did we do this already” with a bool, and if true, go out to a different state (a dead end, for example). Underneath that very action, put the routine you want done, and after the crucial bits, place a set bool that turns the “did we do this already” variable to true. Next time, it runs through, the top bool check sees it was done already, abd goes off a different track.

If that still isn’t good enough, you can to broadcast the event and, trigger the receiver and at once tell all senders to cease sending that event. I’d go with the above method.

The monitoring FSM does indeed uses bools, but it requires to be its own FSM that acts as a gatekeeper and filters events ahead of other FSMs that wait to be activated.

Otherwise, that wouldn't solve the problem because the events literally force the current FSM's flow to return to the state that is receiving events.

And even if I used "get last state" in the receiving state to know what state the flow was in just before the arrival of an event, returning to the former state with a goto action would retrigger this state instead of resuming operations as they were just before the event-hijack.

Essentially, I don't want to mute event senders. I want to deafen/blind receiving FSMs as I see fit.

Thore

  • Sr. Member
  • ****
  • Posts: 480
Re: Blocking/ignoring events, rendering a FSM deaf
« Reply #5 on: December 13, 2018, 08:18:56 AM »
You can make an FSM not receive further events by either putting a buffer FSM in front (on the same target object) that does what I wrote above, which triggers the destination FSM exactly once. Or maybe you can dynamically change the target FSM’s name or by whatever it is called.

djaydino

  • Administrator
  • Hero Member
  • *****
  • Posts: 7616
    • jinxtergames
Re: Blocking/ignoring events, rendering a FSM deaf
« Reply #6 on: December 13, 2018, 09:58:04 AM »
Hi.
Quote
This works, but it would be straighter and faster to initialize FSMs by putting them in a given mode where I decided how they'll react to events. This initialization would simply be done through a primary state with START and actions that define the kind of behavior to follow for incoming events, whether external or internal.

I don't think that will be possible to achieve.
As these event in c# would be static and you can not just set them to non static.

Broken Stylus

  • Beta Group
  • Hero Member
  • *
  • Posts: 772
Re: Blocking/ignoring events, rendering a FSM deaf
« Reply #7 on: December 16, 2018, 06:28:00 AM »
You can make an FSM not receive further events by either putting a buffer FSM in front (on the same target object) that does what I wrote above, which triggers the destination FSM exactly once. Or maybe you can dynamically change the target FSM’s name or by whatever it is called.

That's the method I already use too, but adding a supplementary FSM and more localized events for monitored FSMs just adds unnecessary weight and obfuscation to a project imho, and I even wonder if there wouldn't be a risk of losing a frame here and there down the road since all events are queued, so adding more of them may not be good.
One is pretty much stuck having to micromanage the events on the sending side of things or by introducing a mediating FSM between the sender and the potential receivers on each game object.
Shucks, never mind... :(

Fat Pug Studio

  • Beta Group
  • Hero Member
  • *
  • Posts: 1294
    • Fat Pug Studio
Re: Blocking/ignoring events, rendering a FSM deaf
« Reply #8 on: December 16, 2018, 09:03:28 AM »
Yeah, if you're having something so complex you'll have to using additional FSMs for event rerouting. Even in code, i doubt you ciuld make it simpler.
Available for Playmaker work

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 15500
  • Official Playmaker Support
Re: Blocking/ignoring events, rendering a FSM deaf
« Reply #9 on: December 17, 2018, 01:31:01 AM »
Hi,

 Events are not brutal :) they are extremly powerful, that's all :)

when I want to filter the reception a global event, I use two technics:

-- I have a dedicated FSM catching that event always, and the check if it needs to be processed or not, this is by far the best solution, your actual logic fsm implement your own global event that you fire yourself, so for ON TRIGGER ENTER, you would have ON MY TRIGGER ENTER or something.

-- the second option is to not have the global event as a global transition, but as a regular transition, which means it won't be processed if the active state is not the one implementation that transition. It's powerful as well.


So you can indeed do these kind of filtering, I do that all the time.

Your problem I think is that you don't implement the necessary level of indirection to allow your fsm to be flexible enough on that regards.

If you have a concrete example, I can make a sample to show you how to achieve that.

Bye,

 Jean

Broken Stylus

  • Beta Group
  • Hero Member
  • *
  • Posts: 772
Re: Blocking/ignoring events, rendering a FSM deaf
« Reply #10 on: December 17, 2018, 09:25:57 AM »
Yeah, if you're having something so complex you'll have to using additional FSMs for event rerouting. Even in code, i doubt you ciuld make it simpler.

My project structure and logic are quite straightforward and simple, trust me, and I've already been using intermediary FSMs to filter global/parent->children events since ages, but I wanted to check out if I missed a simpler and much quicker option.
The point is about being able to turn off or fine tune the event-receiving abilities of a FSM; something that seemed to be logical and intuitive, without having to add another FSM and more (local) events or to activate FSMs.
Essentially the idea would be to put the subscription on halt either wholly or with minute detail, and also resume it if needed too.
Now, it's been more or less largely confirmed this wouldn't be possible. So be it really.  :(
« Last Edit: December 17, 2018, 09:30:37 AM by Broken Stylus »

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 15500
  • Official Playmaker Support
Re: Blocking/ignoring events, rendering a FSM deaf
« Reply #11 on: December 18, 2018, 03:32:15 AM »
Hi,

 yes, broadcasting a global event will reach any fsm actively listening to that global event.

 If you are part of the beta, maybe you could sugges this feature, I think it would create more issues than solve, but I do admit that it would make sense in some cases, during debugging.

for such feature to become available, events would need to get an overhaul rewrite, as a lot more would then be likely good to have next to that option, so you could opt in ad out of event visual as well, and a good editor overview so that when things go south, you are not left wondering where is the bug, when it is actually that you turned off listening to that event.

 so I would definitly picking one of the two or both solutions I explains earlier, they work well and are exploitable and efficient.

 I could do a little sample to demonstrate this if you want.

Bye,

 Jean

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 15500
  • Official Playmaker Support
Re: Blocking/ignoring events, rendering a FSM deaf
« Reply #12 on: December 20, 2018, 07:22:58 AM »
Hi,

 as I am wrapping up the KenPlane demo, I remembered about this post:

check out how I listen or not to Inputs, very simple, AND decoupled from Unity and system callbacks, these events are designed for this very game, and so now I have all the power to disable inputs with more events ( like pause menu, ads, etc)




I slightly modified the fsm for the sake of example. I have added a transition using a global event, this means that ONLY when "watch keys" is the active state that this fsm will listen to the global event KENPLANES / PROJECTILE / ON HIT




Bye,

 Jean

Broken Stylus

  • Beta Group
  • Hero Member
  • *
  • Posts: 772
Re: Blocking/ignoring events, rendering a FSM deaf
« Reply #13 on: December 20, 2018, 02:42:26 PM »
Hi,

 yes, broadcasting a global event will reach any fsm actively listening to that global event.

 If you are part of the beta, maybe you could sugges this feature, I think it would create more issues than solve, but I do admit that it would make sense in some cases, during debugging.

for such feature to become available, events would need to get an overhaul rewrite, as a lot more would then be likely good to have next to that option, so you could opt in ad out of event visual as well, and a good editor overview so that when things go south, you are not left wondering where is the bug, when it is actually that you turned off listening to that event.

 so I would definitly picking one of the two or both solutions I explains earlier, they work well and are exploitable and efficient.

 I could do a little sample to demonstrate this if you want.

Bye,

 Jean

If you add this feature for dev/debug and the plebe gets addicted to it, they'll wander why it's not available for builds and heads be rollin'.  ;D

PS : the KENPLANE example is interesting, would logically work, I didn't know it would work that way. I must say that from a UI/UX pov, it's not exactly intuitive. There's nothing indicating at first sight that this particular state is also receiving global events that way. It almost looks like a dirty hack.
...
Do you like dirty hacks?

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 15500
  • Official Playmaker Support
Re: Blocking/ignoring events, rendering a FSM deaf
« Reply #14 on: December 21, 2018, 01:42:01 AM »
Hi,

 Visually it works like this:

- any global transition ( black transition sitting on top of a state), will be caught regardless of the current active state in that fsm.

- any transition (grey transition sitting below the state), will ONLY be caught if the state is active.


so it's not a hack nor dirty, it's by design and in purpose, and I strongly encourage this kind of pattern.

Bye,

 Jean