Suggestion: Add a new empty object type

0 favourites
  • 13 posts
From the Asset Store
This is a single chapter from the "Construct Starter Kit Collection". It is the Student Workbook for its Workshop.
  • Everyone puts sprites right outside of the viewport that holds instance variables to reference later with events or that holds important variables you don'T want to pollute the global variable scope with.

    I suggest adding an empty object type that contains all of the usual instance variables and families and containers of other type of objects, but none of the internal engine stuff that has to be updated like a sprite's X and Y and Quad or the array object'S methods,

    I suggest to have a lightweight object type to use for instance variables that is cheaper to instantiate and destroy, and has no risk of showing up on the screen or causing bugs

    https://construct3.ideas.aha.io/ideas/C3-I-1463

    Tagged:

  • Dictionaries or the Json object if you're feeling masochistic.

    Unless you need an object to host a behavior like Timer, Tween, Sin, or LOS.

  • Sounds more or less like a classic Null-Object. I´d take that.

  • From a simple performance point of view, if you modify the quad issue performance test to spawn empty arrays instead of invisible sprites, you can spawn around 300k sprites, but millions of arrays(until out of memory) with basically no CPU bottleneck because they do not tick system properties like their quad, their X or their Y, etc...

    But using arrays like this is not very intuitive for users and array are not perfect either because they have useless actions and conditions so I'm going to assume that empty game objects would use less memory and be easier for the engine to create and destroy with less garbage collection.

    I want to add that for my use case, my game objects are empty arrays that only spawn a sprite once they enter the screen, making picking and sorting much faster and removing overhead, and they're updated and controlled with instance variables. By making my game this way, I've about doubled the amount of objects I can put in the game which is very significant.

    Another use I have for these is for rare conditions, for example, playing a sound while a character is sliding down a wall. Instead of adding a condition for every single game object to check if they're sliding down a wall or not and keep playing the audio for it or stop it, once a player touches a wall, an empty object is created with the player UID saved as an instance variable, and I have a condition that makes these objects check if their corresponding player is still sliding down a wall or not, and this kind of code greatly reduces the CPU usage because these kind of conditions don't need to be checked on every single object on every tick anymore, instead of creating a condition for every object, it loops though this seperate object type and runs the condition on the related player object, and that new object type isn't created for game objects that can't slide on walls, so that property doesn't need to be checked on every tick either.

    I think this use case for construct 3 is very important because it lets users make their own unique game and physics and player movement instead of relying on the behaviors, and reduces bugs and feature requests for those behaviors because while behaviors are good for all around game mechanics, they're usually not suitable for specific mechanics users have in mind to make their games unique and there'S very little they can do to change the mechanics since they rely on built-in physics they have no control over and since they haven't practiced creating their own, they end up using band-aid fixes to keep their game together and become pretty unsatisfied with their game's stability and performance and start thinking and saying that the engine is limited for small games and hobbyists and switch over to a different engine.

    I'm currently writing a series of tutorials that teaches all of this.

  • The performance impact of using a sprite should be almost zero. The quad issue performance test measures performance for rendering sprites; if you make the sprite invisible, it doesn't even do that work. Even if it does, it's 1/300000 of the work, which is negligible. So I don't see any performance argument for this at all. Maybe there are other reasons for it, but performance is not one of them.

  • Performance is important to me because I want it to run on old mobile devices so every little bit counts.

    I'm trying to convince you with big words and advocate for both user friendliness and growth of the community.

    I hope that once my game releases people take construct 3 seriously for big projects and you get more money

    I'm sorry if it makes you cringe, but I do my best.

    I think that my results and the performance of my game with a thousand AI doing 3D collision detection and moving and doing physics and sorting counts for something and gives some weight to my opinion, even if it doesn't always make sense to you, that you will consider it.

    also Ashley, how difficult would it be, engine wise, to dynamically add and remove objects from families/containers at runtime and at an instance-level, rather than object type.

    I'm asking because picking is pretty much the main thing in the engine, and accessing properties from a container object is great, it lets me use self and reference a containered object and it will automatically get picked instead of having to do a "foreach" or function call with UID to pick to do the action.

    what I'm ACTUALLY trying to do and why i made this suggestion, is to dynamically create objects and give them properties at runtime so that the game loops through every object with an animation property and steps animation, same thing for collision and physics and gravity, etc, without creating a giant object that has every single property and looping through that massive object and picking by boolean "animation", "collision", "physics", "Gravity" and so on, because creating that massive object is a logical and debugging nightmare.

    what I've started doing is creating a "gravity" empty object for example, giving it the UID of the game object that needs gravity applied to it, and do pick by UID gravity.gameobjectUID, and then run the action on game object, to not have to bloat the code with conditions and seperate things.

    Another way would be to make like, 20 copies of the gravity object and put them in a family and then container with their specific immutable game object and do familygravity

  • I don't have the skills to really give any input on this, I'm essentially an UI developer, but what eleanor said about dynamically creating shell objects with the exact amount of information you need them to have sounds amazing, mainly through the argument of demanding less instance checking, like the wall slide she mentioned.

    I'm still reading through the posts again and trying to understand everything, but just wanted to show some support.

  • I'm not really clear on what you're trying to do - instance variables are the usual way to add extra data per-instance. If you need more sophisticated data per-instance, you can put a dictionary or array in a container with a sprite, and then you get a whole dictionary or a whole array per-instance. I'm afraid it's still not clear to me what a new empty object type would add to this?

  • Give me some time I'll work on a prototype to show what I mean exactly.

  • This is taking longer than expected, thank you for your patience, meanwhile:

    When i try to code a game without using behaviors in construct so that the mechanics better suit my needs and I don'T need band aid fixes, my options are:

    • make every state a condition of every object. every single object has to go down a if { }elseif{ }elseif{ }else if{ } kind of thing. States sorted by how often they are in that state from top to bottom for efficiency this only works if objects cannot have multiple states. Code is pretty annoying to write this way because if you change something in one state, you may have to edit other similar states too (not using functions because they lower performance, so they put a ceiling on complexity of the game). To make this method more flexible, instead of using elseifs, every object has to check every state on every tick, that's not very good.
    • Don't use conditions (except for exceptions) and instead jam pack all of your code into actions like this
      with a megaobject that contains all possible states. this code is more flexible and faster than the previous method, in the example, the velocity of the object on the x axis is set correctly, regardless of state, all at once for each object, and like previously, the action is optimised to exit early and not check for states if the correct one is already found. All velocities are set in one fell swoop without having to return to this variable later down the line, removing overhead for calling multiple engine functions that basically do the same thing, but at different times.
    • what i want to do is to not have to loop through objects to check for states altogether, when the state changes, a new object is created, variables are passed, and the old object is deleted. Then, this object's code executes unconditionally until it passes to another state. The problem with this is it creates a lot of garbage ( especially with containers) and isn'T as flexible as the previous model, and code isn't as reusable, since in the previous one, all objects passed through the same code so bugs were easy to fix, but now the bug may be in multiple places.
    • The solution I theorized is a combination of both previous models for my events, with a main game object that can be given components (the new empty object type) Components run the big code inside of action without conditions like before, but can be removed or added to main game objects at will. The roadblock with this method is that, within the construct 3 architecture, it'S actually slower than the good second method because while it does not have to do conditions and saves cpu there, it adds cpu by needing a main game object UID property saved to it and then it needs to be looped and pick main game object by UID to do its job,which ends up being slower because while picking by UID is fast, a loop to pick by UID has to be invoked, removing the CPU time benefits for this method unless the state is rare (like the wall sliding example from my previous post),

    So basically, I know that you keep saying that performance doesn't matter

    Ashley but that's not exactly the case.

    I Consider performance a complexity Ceiling, and I discovered all of these weird ways to use events to raise that complexity ceiling for my game, it being multiplayer and 3D/isometric with lots of sorting and collision detection

    Containers should in theory be able to do this because containers are great for avoiding picking, but one of the big problems I encounter is that containers are immutable, so if I would, say, create a "gravity" object and put it in a container, and then do an action on gravity, it picks everything in the same container so I can add gravity to my objects without any picking, and that'S great! BUT! Families and containers are incompatible.

    IF i try to do "gravity family" and "gameobject family", then nothing gets picked which means if I create a gravity object for every object type combination and try to put them all inside a family and do an action on that family, it will not pick objects in the same containers, so this method is a dead-end. Similarly, making an event for every possible gravity object for each object type without using families adds a lot of unnecessary code complexity and makes maintaining your code a nightmare, so, also a dead-end.

    So for my suggestion:

    I don'T actually know what you'Re willing to accept as a suggestion Ashley, and you're actually way smarter than me and got more experience, but it'S really hard to have a discussion together because you are so busy, and what I need is probably very niche within the community because most people are focused on ease of use and behaviors, which is great!!! it'S what got me into using this engine in the first place, but maybe niche very experienced users like me aren't really a focus.

    I'm still working on the example project, but making an example project that shows that complex games struggle is more difficult than anticipated, I can'T just use quadisperf for this one.

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • sorry i keep writing these super long posts

  • Seems like this is going into the scene graph territory.

    Better containers that efficiently express the parent child hierarchy in pairing, and un-pairing.

  • I'll be honest before this post i had no idea what scene graph meant and I still don'T really understand. Would this fit my needs or make things worse, I don't know.

    This whole engine is about picking, so I need a more flexible way to pick without impacting performance in a negative way.

    How? I don't know. All of this is just suggestion, but the suggestion itself isn't the goal. The goal is picking.

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