Overboy's Forum Posts

  • Wow amazing ! Thank you 🙏

    1. Does it also includes Object Property support for Behavior ? I found out that anytime an Addon could be a Behavior, it's better to make it a behavior rather than a Plugin as it allows for better Modularity and ends with easier events (no need to act on a bunch of seperate objects and to do picking). I think it's especially true for 3rd party addons that are meant to extend the functionnalities of Vanilla feature, they must work on top of any Vanilla World Plugin. construct23.ideas.aha.io/ideas/C23-I-464

    2. Thanks ! that's good to know, i'll keep that in mind if i ever face a similar issue and will report it as a bug.

    I suppose if LoadWebGLTexture() for AnimationFrames was wrong then maybe GetCachedWebGLTexture() also requires some fix ?

    3. I thought about it again and realized it was more complex than i thought, updated the suggestion to reflect those extra thoughts : construct23.ideas.aha.io/ideas/C23-I-469

    Some methods might be difficult to implement but other are probably a matter of exposing existing stuff and would help for a lot of usecases not even related to UI (Getting Parent/Children, Destroying Instance etc.)

    Other issues i faced (workarounds kinda exist for them - in some sitations only - but it feels like they're unnecesseraly tedious)

    5. It would be probably good to add a project.GetInstanceByUID(uid) or a layout.GetInstanceByUID(uid) depending on where it makes sense

    6. There is no way to get the Layouts of the Project, as explained in Skymen's article, a project.GetAllLayouts() would be useful to have.

    Above all, a project.GetCurrentLayout() would be useful to then get a specific layer then create a world instance on it, as Layout allows to access all Layers. (layout.GetLayerByName() would be a nice QOL but very easy to workaround with a loop) There is already a CreateWorldInstance(layer) method but it's sometimes tedious to use without handy ways to pick a specific layer.

  • Hi ! this topic aims to be a constructive discussion between Addondevs and Scirra about how the exposed Editor SDK could be improved to allow us to create simple tools working in editor.

    As Scirra is using the "secret obfuscated Editor SDK" under the hood for all Vanilla Plugins and Behaviors, the "exposed Editor SDK" was never dogfooded in any way and there are many many holes that makes it almost impossible to use for anything relevant. This is why most addondev just abandon the Editor part of their addon and everthing can only happen at runtime. But it is an issue as many cool Plugins/Behaviors that could be made would only be useable if the user was able to set them up and preview some stuff happening at edit-time.

    Example usecases :

    • UI System
    • Addons displaying textures from other Plugins (as Particles and 3DShapes are doing)
    • Utility Plugins to create/place instances in bulk in the Editor

    Tagging skymen and Mikal as they're the 2 other devs I know that tried a lot to deal with the Editor SDK before. Skymen wrote an amazing article about this topic about this btw : construct.net/en/blogs/skymen-13/flexbox-weird-characters-1590

    Even if the best would be to have access to a much bigger part of the actual Editor SDK API, the goal of this thread is to discuss about the main holes in the exposed SDK and try to find reasonnable and clever ways to makes things much better with the smaller amount of changes and new methods, as I understand Scirra wants to keep most of the Editor SDK obfuscated.

    I spent an entire week trying everything I could thanks to skymen's help to make simple stuff happening in Editor with custom behaviors/plugins and just faced walls after walls preventing me to do anything relevant, no matter the tricks I used, even after trying every possible way of doing stuff. Here is a few issues I faced.

    • 1. Object property : Plugins can select other ObjectTypes as one of their property. It's very useful and used by Particles and 3DShape to be able to do stuff based on other objects. However at editime, those properties returns the SID of the ObjectClass but there is not a single way to get an ObjectClass by its SID using the Editor SDK.

    Solution : Add a GetObjectClassBySID(SID) method to the IProjectClass

    (could be cool to also add Object property support for Behavior btw)

    • 2. IRenderer.SetTexture() only works with IWebGLTexture class but "not secret WebGLTexture class" which is a big issue because it means there is no way to make anything work both with official Plugins/Behaviors and 3rd party addons. Indeed LoadWebGLTexture() method of AnimationFrames returns a secret SDK instance (WebGLTexture) that can't be used using the exposed SetTexture() method. It's as if the Vanilla Addons and the Custom Addons were their own island that can't interact with each other, making it pointless

    Solution : Different possiblities : make LoadWebGLTexture() returns an IWebGLTexture instance instead, also make functions like SetTexture() work both with exposed IWebGLTexture and WebGLTexture

    General Thought : Make sure any method that exists in the exposed SDK work both for Vanilla addons and Custom addons

    • 3. No way to do anything related to Hierarchy feature, while it would allow us to create AutoLayouting behaviors, utility tools and full UI system : I describe every missing stuff extensively in this suggestion : construct23.ideas.aha.io/ideas/C23-I-469

    • 4. Missing GetName() : It is possible to GetAnimations() from an ObjectType, but not a single way to get their animation name, so it means it's impossible to know for sure we access the animation we wanted to access.Ideally everything that has a name should have a GetName() property

    Solution : Add a GetName() method to the IAnimation Class (and any other class that should have one one but has not, same for all the basic stuff that would be useful and that isn't subject to change)

    Those are just a few roadblocks I faced while trying to do simple things using the Editor SDK. As there was never detailed dogfooding or detailed feedbacks from addondev on this, I hope a discussion could be a start to solve those annoying roadblocks in reasonable ways to improve the Editor Addon SDK so we can use it to make cool stuff.

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • Looping back to the original point of the post, I'm still confused why "OnTween" finished seemingly causes no reduction in fps, while "onTimer" does. Seems like timers are.... outdated? Tweens are nice and fast for all they do.

    It's because Fake Triggers which is used by the "On Timer" in the Timer Behavior actually check if they're true everytick as opposed to True Triggers So if you have a bunch of objects checking a bunch of On Timers it can be heavy.

    True Trigger on the other hand don't do anything every tick, they're just triggered when they're called (with a little overhead)

    Both approach have their own trade-offs as often in programming. Even if I admit I did tricks to avoid many "On Timer" Fake Triggers in my project

    (Ruskul, I think the comment of tunderrunz was about official behaviors not the Advanced Signals pack I made)

  • Overboy

    Sorry If I missed the answer elsewhere, but I wanted to ask about performance of your tools.

    For the custom signals and the like, do they perform better than c3 built in functions?

    I have a project where I need to call alot of functions, those functions call other functions, etc... Its in loops in order to achieve object picking,.

    I have alot of object that have large lists of buffs, effects, etc, that are all being passed around. And alot of those effects do something every tick. How is the comparable performance of your plugin compared to built in custom actions and functions?

    They don't perform better than built-in Function.

    Please check my posts in your thread about Timers and True Triggers for all the details ! In my post where I link my Addon Pack, I explain the only example in my big project where the performance did matter and the tricks you can do to solve it (using multiple Advanced Signals behavior to split the workload or using the Simple Trigger behavior also included in the pack for the most commonly used Signals). As ever with optimization, only do it when it matters.

  • There is not a single way to get the IObjectInstance from IBehaviorInstanceBase or a IBehaviorInstance in the Editor API of Addon SDK

    Please could you add a GetObjectInstanceBase()

    Because we can't do anything thanks to behavior in Editor as behavior don't let us do anything - only ObjectInstances have useful methods

    I'm currently stuck on an urgent work because of this.

    Edit : I also posted a dedicated request : construct23.ideas.aha.io/ideas/C23-I-468

    If you find some time to add it for this week beta it would save me ! 😅

  • I just pushed Updates to 3 of my addon packs !

    There is currently a sale/bundle to grab all of them with a discount on itch.io

    overboy.itch.io/construct-3-object-signals-custom-expressions

    ADVANCED SIGNALS & CUSTOM EXPRESSIONS : V1.2 Released

    • Added AllParams() expressions to Signals and Custom Expressions
    • It allows you to return all the parameters of the current Signal/Expression as a string (seperated by '|')
    • It can be useful for different purpose, for example, it provides an easy way to pass the parameters of the Current Signal to additional Signals you'd like to call

    UIDToAnything : V1.3 Released

    • Added UIDTo.LayerName(UID) and UIDTo.LayerNumber(UID) expressions
    • Fixed a few typos
    • Improved the naming of some ACEs to be more consistent

    DATA+ : Minor Update

    • Pushed a minor update to move JSON+ Behavior to the "General" category (instead of "Other") to improve consistency with Array and Dictionary behaviors of the addon pack !

    Thanks to TackerTacker and fedca for their feedbacks and suggestions!

  • It's seams quite powerful. Some of these use cases you mentioned can still be done with vanilla c3 features but others are quite difficult or impossible to achieve.

    Hey Rafael thanks a lot !

    How is it integrated with the engine? Relying on this just to be broken after some construct's update is always a concern about plugins/behaviors in general

    I don't see how any of those 3 new behaviors could break besides of a huge change where Construct Team would require everyone to rewrite all their addons from scratch

  • ADVANCED OBJECT SIGNALS & CUSTOM EXPRESSIONS

    [Addon Pack]

    I just released a new Addon Pack 🎉 GRAB IT HERE

    A powerful ADDON PACK containing 3 new behaviors for Construct 3 :

    • ADVANCED SIGNALS Behavior (Per-Instance Functions on steroid)
    • CUSTOM EXPRESSIONS Behavior
    • SIMPLE TRIGGER Behavior
    • (all those behaviors also support polymorphism, making the Family feature way more powerful)
    • Example/Documentation .c3p project

    Those are the 3 addons I used in all my systems to create a highly modular and maintainable Roguelike. Thanks to this pack : you can create scalable systems easily, decouple your logic to avoid spaghetti code. It also makes the Family feature way more powerful thanks to the polymorphism support.

    Above all, it allows you to "CREATE YOUR OWN BEHAVIORS" only using the eventsheet.

    (In fact it's even more powerful than Behavior on some aspects, thanks to the polymorphism feature allowing each member of a Family to act differently)

    There is so much use-case and advantages of being able to create Custom Signals, Triggers and Expressions (supporting polymorphism and multiple parameters) I wouldn't know where to start,

    take a look at the addon pack page for more info !

    ADVANCED SIGNALS & CUSTOM EXPRESSIONS

    (I'm currently running a sale/bundle to grab my addon packs with a discount)

  • Yeah i agree we shouldn't waste time optimizing stuff that don't matter, I just had performance issues on a specific heavy task in my game but I managed to solve it by making my own Addons.

    Anyway i went ahead and released a new Addon Pack that fix all the issues i've been mentionning for months and that i've been using extensively using in my project for about a year, it basically implements all the things i've been advocating for. I couldn't imagine making any project without those now :

    ADVANCED SIGNALS & CUSTOM EXPRESSIONS

    GRAB IT HERE

    A powerful ADDON PACK containing 3 new behaviors for Construct 3

    It contains :

    • ADVANCED SIGNALS Behavior (Per-Instance Functions on steroid)
    • CUSTOM EXPRESSIONS Behavior
    • SIMPLE TRIGGER Behavior
    • (all those behaviors also support polymorphism, making the Family feature way more powerful)
    • Example/Documentation .c3p project

    Those are the 3 addons I used in all my systems to create a highly modular and maintainable Roguelike. Thanks to this pack : you can create scalable systems easily, decouple your logic to avoid spaghetti code. It also makes the Family feature way more powerful thanks to the polymorphism support.

    Above all, it allows you to "CREATE YOUR OWN BEHAVIORS" only using the eventsheet.

    (In fact it's even more powerful than Behavior on some aspects, thanks to the polymorphism feature allowing each member of a Family to act differently)

    There is so much use-case and advantages of being able to create Custom Signals, Triggers and Expressions (supporting polymorphism and multiple parameters)

    it's hard to explain all use-cases and advantages, take a look at the addon pack page for more info !

    ADVANCED SIGNALS & CUSTOM EXPRESSIONS

    (currently running a sale/bundle to grab all my packs with a discount)

    Regarding the performance issue I faced at some point calling a bunch of Advanced Signals, a good thing with this improved solution is that Custom Expressions and Custom Signals are 2 different behaviors, this way you just add the functionality you need on the relevant object and the "workload" is split, on top of being better UX-wise. (Calling an expression will only check the expressions triggers of the same behavior, same for signals, they are separated). There are also a few optimization tricks we can do that i explain in the last part of this post.

    In most situations performance doesn't matter at all, I agree, we should only worry about them when we need to optimize very heavy stuff

    In my project I wanted to optimize further because it happenned very often that many many entities were hit at the same times calling a bunch of signals (on hit received, on critical hit received, on death, on damage dealt, on critical damage dealt etc...), and I had many many different signals handled by a single behavior with many Triggers blocks so it was like :

    (a bunch of entities + their damage dealer)

    * (a lot of signal that are triggered at the same time)

    * (a lot of existing signal handled by the same behavior)

    * (a lot of listeners blocks for each Signal

    = the exponential overhead i was talking about, and fixed

    I think it's pretty rare to have that and i reckon Trigger Overhead wasn't the main bottleneck (it's just that I wanted to make sure that scenario was as optimized as possible, even if it would just save a few CPU% on those especially heavy frames), I mainly solved those heavy frames thanks to some other addons i'll probably release soon that weren't related to Trigger overhead I had.

    My goal was being able to hit 100 entities at the same frame yet being able to launch a bunch of signals doing a bunch of extra checks and logic on many eventsheets for all of them without any noticeable perf drop and I managed to do it.

    (Those behaviors are all as optimized as they can be, nothing is happening on tick - as opposed to Timers Behaviors - and they don't require to init anything fancy etc)

    Here are a few tricks on how to enhance the performance if someone also has specific events in their game with very very intensive use of the Advanced Signal behavior on a single Object and needs to save every CPU% they can :

    • Create several Advanced Signal on your object : "HitSignals", "MiscSignals" each handling just a subset of all your signals

    • Use the SimpleTrigger variant for the most commonly used "Signals" or requiring the biggest number of eventblocks.

    As ever with optimization, and i join Ashley on this : only do it after you actually runned into perf issue

  • As I said I never used or suggested anything related to the too limited On Signal feature because they have no parameters + no way to pass instance or SOL (+ perf can get exponentially worse and the UX is pretty bad). Same for all the other convos we had about this during the past 10 months 🤷‍♂️

    That feature doesn't help at all with the issue I'm describing and the performance gets exponentially worse the more you use it.

    You always told us how much cooler and performant Builtin Functions were versus True Triggers (x3.5 perf i think ?), so the perf diff is even bigger if you compare builtin Functions versus tag-based true Triggers with increasingly bigger number of triggers and signals, because it will trigger every single Signal block even if it's not the same Signal string you just called.

    There are your own blog posts explaining this :

    - construct.net/en/blogs/construct-official-blog-1/construct-3s-new-redesigned-1059

    - construct.net/en/blogs/construct-official-blog-1/constructs-new-functions-1060

    Here is your own graphic showing the difference between a between function and a old tag-based functions.

    (+ note that the difference would be even bigger with tag-based True Triggers as old functions were already optimized via the deprecated Fast Trigger feature AFAIK !)

    I still don't understand why asking for perf benchmark as you're well aware of this and you already did it yourself

    The suggestion I made for "Better Signals" via a Emit Signal option for Functions/Custom Actions, allowing to add extra Listeners Blocks would solve all the issues mentionned (and even more as it could also feature an execution order option) :

    construct.net/en/forum/construct-3/general-discussion-7/custom-actionsfunctions-175063

    By default you would create a Function or a Custom Actions (nice UX and optimal perf for the "First Listener Block" at least), and if latter you realize that you'd like an additional listener blocks for it (for decoupling/organisation or because you want to apply different logic depending on the Layout or because you want to apply different logic depending on active groups/eventsheets as explained by me and other in different examples in this thread), you would just tick the "Emit Signal" boolean, and you could now create as many extra Listeners Blocks via the usual Object Conditions creation worklow. (that could probably be a bit more efficient than existing True Triggers for reasons mentionned on my first posts)

    Some advantages of building Better Signals on top of Functions/Custom Actions instead of current On Signal Event :

    Perf advantages : Built-in function perf + no need to trigger every signal every time + no need to do shenanigans to pass parameters + no need to do picking for each listeners

    UX advantage : no typo due to strings, automatic bulk rename, parameters are automatically accessible as local variables in each listener block, Find all references support

    + if JS Events and scripting interfaces for calling Custom Actions are added, it would also work for this feature.

    Other potential advantages from this suggestion : listeners blocks could be added via the same workflow as regular Conditions (the same way custom actions calls are added via regular Action workflow), execution order feature

  • The thing is that very few people are facing this performance issue because again : the feature just doesn't exist at all in Vanilla Construct : this is the main issue. We just can't create Per Instance Signals supporting multiple listener blocks (and multiple parameters) to be able to decouple stuff for example (but it's not just an organization issue, it's just impossible to develop a modular Roguelike without those for example). This is the problem number 1.

    I think a lot of users are happy that they can have several different places in their eventsheet to apply logic using vanilla Triggers. For example, i think it's common that people have multiple "On Main Player Created" blocks in their big project to initialize stuff on their Player (one for UI, one for Visual, one for Gameplay stuff, or even one for "Arena Layout" that differs for the one of "Dungeon Layout"). But we just can't create our own Triggers like that for stuff like "On Main Player Hit".

    The same way people are happy to have a bunch of "On Start Layout" events in the same project, could you imagine making a big project were you would need to put everything you want to happen On start of Layout but in a single place in the eventsheets, no matter what is the current Layout (so we would need to make a huge else if statement in a single place), no matter what object you want to act on, the game feature that is relevant ?

    I created various solutions myself by writing Addons to be able to do this. Including a Tag-based versatile Self Function behavior solution and later a "Create a new Real Trigger each time i need a new Signal".

    So I don't get the point to prove the performance issue for a feature that just doesn't exist at all in C3 to prove it is worth developping it ? Again we just can't do that in Vanilla C3.

    I totally understand the priority stuff, and i don't care if the feature isn't developped any time soon or even isn't developped at all, I think a lot of other stuff are 10X more important and urgent to have in the engine such as some stuff i listed in this post from an other thread : construct.net/en/forum/construct-3/general-discussion-7/good-time-construct-great-178657/page-6

    The issue is that it happens very often that the answers I get from reports totally ignore the main points I'm raising. There is zero acknowledgment about the missing spot, just oversimplification of the issue and potential solutions i report and some suspicions i'm doing stupid stuff on my project that makes it slow or i'm trying to achieve things that are useless to do. I get why it could be the first answer that is provided to challenge the idea/the issue : it's totally fine, but i just don't understand why after maybe 25 detailed messages over 10 months we're still stuck on the comprehension/acknowledgement of the important thing ?

    And i'm still feeling this about that issue C3 has that :

    1. We can't create our own Triggers in C3. (Working per instance/SOL and supporting multiple listeners blocks).

    2. Even after spending weeks developing my own solutions for this there are either performance issue (tag-based Self Function) or the process is just too hacky and cumbersome (need to create Behaviors and Real Triggers via SDK for every single Signals I want for every project i make)

  • > Yes the performance does matter a lot.

    Do you have performance benchmarks that demonstrate the performance overhead of "On signal" is too much for reasonable use cases? I think it would be surprising - why would you need something like thousands of signals per frame? If you are doing something like that wouldn't another feature like functions be a better approach anyway?

    This is exactly what i'm suggesting here and what i've been suggesting for several months with the "Listener Blocks" feature built on top of Custom Actions and Functions, i never used or even suggested to enhance the current "on signal" feature for many reasons i explained. (no parameters, no way to pass an instance or SOL, bad perf, bad UX)

    I never needed thousands of signals per frame, I had actual performance issue on my real world project using the various methods i mentionned until I opted for my hacky "create a Real Trigger via Addon SDK" anytime I want a new instance Signal. It wasn't even triggering thousands of signal, just some specific events of my game like when 10ish entities were hit at the same frame was freezing my game. (Because of the exponential performance overhead of tag-based Real Triggers I explained in my first posts of this thread) I didn't have stable 60 FPS until many many optimization tricks I did.

    I find my own solutions for this after weeks if not months of work extanding the engine in multiple ways using both JS scripting and Addon SDK.

    I already spend several days explaining this issue, a bunch of example usecases and different suggestion that could fix it on various occasions.

    From your answers, i have the feeling you still didn't understand what is the issue (the performance is only a part of the problem - a big one - but also we just can't create at all Signals per instance supporting multiple listener blocks with the current features of the engine, i think i already reported that 15 times), and what are the solutions i'm suggesting (nothing related to current limited and not perfromant signal feature)

    I have the feeling any benchmark i could provide won't change anything, as there here is no recognition of the problem in the first place, so i'll probably just avoid overworking even more on this.

  • I added a suggestion for Functions and Custom Actions JS events support ! construct23.ideas.aha.io/ideas/C23-I-456

  • Also to add to some of the points made, the current "Signal" system action and "On signal" trigger are event sheet only...

    Adding them to the addon SDK or the Javascript API, greatly improves the flexibility of the system.

    Yes ! A good start for this would be to add Custom Action scripting interfaces : construct23.ideas.aha.io/ideas/C23-I-272

    But yes it would be awesome if we could also have JS event for Signals, Functions AND Custom Actions ! (We need per-instance Signals)

  • I detailed the suggestion extensively in this post :

    construct.net/en/forum/construct-3/general-discussion-7/custom-actionsfunctions-175063

    The idea behind this is that C3 would be able to optimize those "Signal Triggers" almost as good as the built-in Function/Custom Actions.

    No need to check every single Signal Trigger that exists in the project to check if the "tag" is the same, just the ones mapped to the right Custom Action or Functions. (It would still need to check if the Trigger Eventsheet and Group is active though which is why I said "almost as performant")

    There is probably even better way to achieve this UX wise, but I tried to suggest something that could be built on top of existing stuff instead of creating a brand new customAction-style Signal feature. (Which should work per instance). Creating a brand new feature for this could be cool though