playMaker

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - FrozenTarzan

Pages: [1]
1
PlayMaker Help / Re: Return behavior of "Send Event" [SOLVED PARTIALLY]
« on: September 17, 2013, 06:24:34 AM »
Quote
I see the distinction you make between stack and queue
That's not my distinction, that's the definition ;-)
Stack behaves as Last In First Out, LIFO (for example Callstack of methods)
Queue behaves as First In First Out, FIFO (for example a printer-queue, or people waiting in a row)

Quote
I'lls see if I have time this week to come up with a queueing system to have a working example.
Would be amazing! :-)

2
PlayMaker Help / Re: Return behavior of "Send Event" [SOLVED PARTIALLY]
« on: September 17, 2013, 02:42:15 AM »
Quote
I don't think Stacking events is a good thing in an FSM environment, but having this kind of power is however welcome indeed.
I don't want to be too picky, but "stacking" events is what actually happens in Playmaker right now. When an event happens (goes on the stack) another event can be processes before the first one. In a decoupled system the events have to use a queue, where it is not possible that an event is being processed before another one. The relative timing of events is important and preserved that way.

By the way, the concept of the event stack is the reason why "Magic: The Gathering" is such a fun card game, because you CAN react onto every action of you opponent :-)

I think I get the idea of your "forwarding" additional fsm. I tried to create them to visualize your idea:



So the SoundManager listens for the different events. Now the processing of the events has a few things in common: taking the event data and storing it into the queue of our PlaySoundObject. But there are parts of the events that have to be handled separately, like the name of the soundfile that should be played. This is a general problem that I have experienced a few times now. When multiple events needs to be processed in the same way, but afterwards I need to know what event was responsible. This would require some sort of branching? So do I have to have a single state for each one of the program flows?



Of course this is not possible. Without Playmaker, I would have all my States that need the same processing of the data before call a method of a base class. In Playmaker I would have to write a custom action, and have multiple state-blocks where each of them uses my custom action in the first place?



And the PlaySoundObject would not listen to events, right? Because it basically works on its data-packages/messages?

3
PlayMaker Help / Re: Return behavior of "Send Event" [SOLVED PARTIALLY]
« on: September 16, 2013, 03:13:37 PM »
Hey jeanfabre your comments and forum activity are amazing, thanks! :-)

Quote
And that's fine that data gets overwriten because if your FSM responds to both, it means it would switch states and therefore context, so it's a very important rule that event data is processes as early as possible in the state stack, preferably in the very same state that implemented the global event. in that regards, event data from a previous events would be very confusing actually because the FSM moved on to a completly different state and flow.

I think you have misunderstood my concept: Each event is packed with its relevant data to one message/object/event/packet. So when an event happens the waiting/listening FSMs do not get informed right away. Instead the message/event (including the data!) is pushed into a messaging-queue. The call to the queue returns immediately and the sender can switch state or do what ever it wants. The events are then processed in another iteration. This concept is described in "Games Coding Complete" (by Mike McShaffry). I try to give a picture:

Involved Objects:
* Global Messaging System handling the event (+data) and the queue
* Player (holding a gun, what else?!)
* Enemy (running in circles)
* SoundManager (wondering why the world is so cruel)

Now the Player shoots. The Player object creates an instance of an event called "PlayerShot". This event is a class and has its own clear and type-safe definition. It includes the Player ID, the position of the player and the weapon type used for the shot. This event is handed to the Messaging System (MS), which pushes the event (+data!) into a queue. After the call to the MS the call returns and no other code has been processed yet. The Player reacts to the shot himself and plays some animation and checks for current ammunition etc. Then the rest of the Player's code is completed and other objects do their stuff in their Update() method, eventually pushing new events with their own data into the queue of the MS. After all those objects have been updated the method "ProcessEvents()" from the MS is called. The events are taken from the queue, one by one, being in the correct order of their appearance, and the listeners (we could call them observers, because its a similar pattern here) are notified by calling the method "HandleEvent(IEvent event)". The Enemy is such a listener and determines the type of the event (this can be tricky in C++ so that it is sort of type-safe, but with little dependencies to lower compilation times) and reacts accordingly by checking data like the position of the event, he might be hearing the shot and wants to take cover or uses the information about the weapon type to switch to an other, more efficient tactic. In the methods handling the event new events can be pushed into the messaging queue, but this time in a new one, because the MS uses a DOUBLE BUFFER queue. After the Enemy, the SoundManager (another listener for this event) is notified and takes the position from the event for some 3D sound effects, also taking the weapon type into account.

When the queue is empty, the Messaging System swaps buffers and processes the other queue. There is no difference to the first queue! This double buffer queue simply offers the ability for the programmer to limit the processing iterations per update loop.

The advantages of such a systems are:
* The code is very clear and developers can follow the code easily and the debugging works like charm because there are no calls to completely different objects where the programmer doesn't know how the listener reacts. Instead, the programmer knows "ok, I've sent my message, everybody interested in it will do something, not my problem anymore"
* The events carry all important information with them, similar to a snapshot of the time when the event happened. The shot from the example above happened with a weapon type at a position from a player, and nothing will ever change this event.

Quote
Yes. It's good analogy, PlayMaker events are really methods actually. I guess this comes from the fact that PlayMaker events adhere to the "FSM" meaning of "event".
At first I thought that Playmaker uses events, but now I realize that they are no events in this sense. You are absolutely right, when you see Playmaker as a system for FSMs only. But in the last projects, I was involved in, I realized that FSMs are not enough for a stable and decoupled system. And a messaging system seems to fit perfectly into the system Playmaker offers right now.

Quote
I created a system where you can pass more data to events.
Thanks, I will take a look at your scripts. :-)

Quote
So if you have a use case, let me know and I'll do a unity scene trying to solve this elegantly.
Is this thread the right place? Should I open a new one, but what would be a useful title? Maybe "Playmaker FSM design discussion for a larger game project"?

4
PlayMaker Help / Re: Return behavior of "Send Event" [SOLVED PARTIALLY]
« on: September 16, 2013, 01:46:46 AM »
I think these are major design flaws, what I, and I guess a lot of others, would like:
* When sending event data, this data is defined per event, not a static/global limited structure that is overwritten by each other event.

* This would enable a redesign of Playmaker, so events are being processed like events and not (like it is now!) like method calls. Basically what playmaker does is not handling events in the original meaning, it just calls a method directly. And the data "sent" to an object is not sent at all, it simply sits in a global space and hopes that nobody overwrites it in the meantime. So the receiver HAS TO read back the data immediately so that the data is not lost.

* jeanfabre do you refer to "bubbling" as the mechanism and ability of processing events after each other as separate objects/commands with their own data like i have described it?

* Those major changes would break all existing code/fsms out there, but I think there is no architectural reason to not implement this in such a way, am I right?

* If it is not possible, I would at least suggest that the EventData structure can be extended in a useful way. Since the EventData is simply global memory, I can use my own memory, sure. But I think those type of things should be rethought in Playmaker itself. I use playmaker to overcome problems like global data, strings for eventnames, etc. and i see there is a lot of potential in Playmaker, but there is still a lot missing...

* The suggestion of the "EventHappendForward" and "EventHappendCallback" is a nice technique, though :-)

5
PlayMaker Help / Return behavior of "Send Event" [SOLVED PARTIALLY]
« on: September 13, 2013, 01:30:36 PM »
Hi,

I have a FSM, called A, that holds a reference to a gameobject. I want to change this gameobject from another FSM, called B. But I want FSM A to be able to react to the change, maybe because some exit/cleanup method has to be called. So I basically want to send an event from FSM B with the new gameobject to FSM A. Then FSM A could handle the event, call the exit/cleanup stuff and finally change its reference of the gameobject with the new one.
How could I realize this behavior?
[EDIT]: I have solved this by using the "Set Event Data" and "Get Event Info" actions. :-)

And here is an extended problem problem:
I have to send more than one gameobject to FSM A, because it holds multiple references to all kind of gameobjects/variables. So I basically want to create a custom Event with custom parameters, that can be sent from FSM B to FSM A.
Is this possible?
[EDIT]: I found this post here from jeanfabre:
Quote
-- send a event to a Fsm, that fsm will then query the caller or what it needs when it receives that events, this is much easier, but introduce some dependancies, aka the receiver has to know where to get the informations. This is solved by creating what I call "META" Fsm, that acts as data repository, so if I have a player, all my enemies have a reference of "META PLAYER" fsm, and when the player wants to comnunicate with an enemy, it send an event, with no data, and the enemy simply pull from "META PLAYER" what it needs to react and act upon this event.

What I have done right now:
FSM A holds the reference/references. FSM B sends an event "Reset gameobjects". FSM A calls some exit/cleanup stuff for the objects. Then FSM B sets all the variables directly in FSM A. But here is the danger! Is it guaranteed that the "Send Event" for "Reset gameobjects" is processed BEFORE the direct setting happens? Is it possible that FSM A (holding the data) receives the "Reset gameobjects" event and FSM B sets the variables BEFORE FSM A was able to react to the event (calling cleanup stuff)?

I come from C++ and all my FSMs were designed like this:  All generated events were pushed directly into a queue and were processed in another iteration. This is really useful, because the program flow is easy to understand. Only one iteration of events is handled at a time. The programmer could then choose if he/she wants to process an other iteration... and another... but only one set of events at a time. In this case the solution above would fail completely!

I quess all my questions are a bit confusing, but being a programmer I need to know a lot of the technology underneath, so we don't run into problems later on.

Thanks!

6
PlayMaker Help / Re: Listen to / register for Playmaker events in C# script
« on: September 13, 2013, 02:41:19 AM »
Thanks for the clear answer! Will update the title to [ONLY WITH WORKAROUND]

7
Hi there,

I have searched a lot now and found a few posts that target the same problem, but there was no good answer yet. See here:
http://hutonggames.com/playmakerforum/index.php?topic=933.msg3844#msg3844

I want to receive events from a PlaymakerFSM. Ideally direct events and broadcasted events.

There is an action called "Send Event", where I can choose to send an event to a "GameObject". But how do I listen to this event in my script/gameobject? Especially to custom events created by myself?

But even if I could get the "Send Event" action working, how do I listen to broadcasted events?

The workaround would be to create a dummy FSM for my gameobject and forward all events with the "Send Message" action. But this seems to be hacky, right?!

8
Hi jeanfabre, hi Garth Smith,

thank you for the quick reply! I will set this to [SOLVED], even though these design questions might be interesting for a longer discussion :-)

Great community by the way!

9
Hi Playmaker community,

Let's say I have a component for a fighting-tower with a custom AI. The tower has a mesh that can "look at" a target position and has a component that handles the internal behaviors like "seek and destroy", "offline", "follow target peacefully", "turn around as fast as possible and shoot like there is no tomorrow".

Without Playmaker I would design a FSM with code. So When the Update() of the tower is called, I would call the FSM.Update() method, which would use polymorphism to call the correct Update() method of the current state.

Now how would I use Playmaker to represent such a FSM with the visual Playmaker window?

Possibility 1: Use the internal FSM for the tower as usual and just use the events from playmaker to handle the state-changes. The communication could happen by calling a method with the "Send Message" action. But this way I still have to use my own FSM implementation.

Possibility 2: Use the FSM from Playmaker and all the events and so forth. Then in the Update() of the tower, I have a lot of if/elseif/switches that check for different parameters and adapt the behavior. Like an enum with SeekAndDestroy, Offline,... This way I can set the parameters directly via actions from Playmaker (like Set Float Value,...) but the internal design is ugly.

Possibility 3: Use custom actions for each state I can be in. So I would pass the original GameObject (the tower) to the action and this action would encapsulate the behavior? It would be like passing the tower to a generic implementation of state design pattern. In this case I would have a custom action for each state the object can be in?

Possibility 4: ...insert your best solution here! ;-)

I'll try to reformulate my problem: When I have an object that behaves differently in different states and this object has to handle code (more complex than the predefined Playmaker actions) in an Update() routine, how do I design an appropriate FSM with playmaker?

Pages: [1]