Behavior Communication Question?

  • Ashley

    Is there currently a way to invoke Actions/Triggers on a separate behavior? for example Lets say i have 2 instances A, and B, and they both have my same custom behavior.

    in the event sheet i call A.Execute Action

    I want that action to execute a trigger on all Object Types/Instance that have the behavior?

    var bInstances = this._inst.GetBehaviorInstances();
     for (let behavior of bInstances)
     var behaviorType = behavior.GetBehaviorType();
     if (behaviorType.GetName() == "PubSub")
     var sdkInstance = behavior.GetSdkInstance();
     sdkInstance.CallAction(C3.Behaviors.Piranha305_PubSub.Acts.SimulateMessage, channel, msg);

    So the intention of the code above is, when this action is called, it's going to iterate over all instance(of any object type) that has this behavior attached and invoke an action on that behavior, which fires off a trigger

    What i am noticing is this._inst.GetBehaviorInstances(); only returns the instances of the same type? is there a better "documented way" to get all instances which share the same behavior?

  • okay i figure it out, the instance i was getting was not the type i was expecting. so this code achieves what i was trying to do

     	var behavior = this._inst.GetBehaviorInstanceFromCtor(C3.Behaviors.Piranha305_PubSub);
    	var instances = behavior.GetBehavior().GetInstances();
    	for(let instance of instances){
    		var behav = instance.GetBehaviorInstanceFromCtor(C3.Behaviors.Piranha305_PubSub);
    		var sdkInstance = behav.GetSdkInstance();
    		sdkInstance.CallAction(C3.Behaviors.Piranha305_PubSub.Acts.SimulateMessage, channel, msg);

    this works good if the instance only has only one instance of the behavior attached.

    would it be possible to add instance.GetBehaviorInstanceFromCtor(C3.Behaviors.Piranha305_PubSub);

    but have it return an array of behavior instances instead of just the first instance?

  • This is specifically not supported because it's generally a terrible idea:

    • Nothing else in Construct works this way, so it's confusing to users
    • It hides logic behind "magic" behavior when it could be clear and straightforward events
    • It's brittle and inflexible because it has a hard-coded kind of action/condition to trigger - the user can't choose to do something else, or use a different kind of plugin
    • When using other addons, you end up taking an unnecessary dependency on an external addon - now you're subject to any backwards-incompatible changes or deprecation that may happen to that addon in the long term

    In particular, the last point is problematic - sometimes developers hack in poorly-thought-out features involving official addons, then we change them over time (e.g. deprecating them as we replace them with better features), and now the addon developer has a real headache as they need to figure out how to change their addon, which may in turn cause a backwards-compatibility problem for users of their addon.

    Just fire a trigger in your addon. Users can put whatever events they want in that. It's simpler, and avoids all these problems.

  • Well i was never planning on releasing this addon, i am using it internal in my project, but i see your point in trying to hack that in the framework.

    but now as a counterpoint for more extensible addon. there should be a clean way of publishing a message, and having a set of instance be able to subscribe to that message type, and trigger some type of functionality. without having to couple the instances to the messaging system. it would also improve event sheet maintenance if your are designing your event sheets in a modular way, you might not want to mix concerns.

    a common example is pausing your game? that is a cross cutting concern across all your event sheets? you have to disable some button collision, reduce the time scale, hide/show new elements, these things might be implemented in different events and you might not want to mix that logic. can we just emit a message (in this case a string) "pause" / "unpause" and fire off a trigger to all the instances/system that are subscribed to those events?

    i guess there are multiple ways to handle the situation, i am just trying to apply different concepts to implementation, which might not fit so well, writing this you could solve that issue by having a separate event sheet dedicated to your cross cutting concern, and that event sheet will be aware of all the instances

    i was just dreaming of a more flexible approach, where i can just attach a behavior to the object and set the message to listen and have it all happen auto-magically so i would not have to duplicate those events.

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • In that case I would assume the user will call a "Pause" function where they implement their pause system in events. If your addon needs to do something to respond to a pause, this can then just be a "set paused" action in that function.

    I think if you try to pre-empt it with different built-in mechanisms, you actually end up with a less flexible approach. Events are the way to customise your game's logic, addons shouldn't try to short-circuit that.

    If you're integrating with your own addons, I'd recommend simply calling internal class methods instead. There's no need to drag the event actions logic in to it. A nice architecture (which many built-in addons use) is actions actually just call methods on the instance class, and then any other logic that needs to re-use that function can just call a normal instance method, rather than trying to bodge in a call to an action. Basically for internal stuff you can easily bypass the entire event system, and it makes your code nicer.

    Lots of addon developers seem to want to hack around with the event system - generally I think that causes more problems than it solves...

  • you are 100% correct, it was much easier to handle this logic outside the event sheet. by adding the instances to data structure outside the runtime, and assigning the trigger as a callback when a new event it emitted, i can skip using call action, and just get to the trigger directly for the specific instance.

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)