Ruskul's Recent Forum Activity

  • As often as not, I find my use of arrays and dictionary to be tied to objects. Dropping them in a container is great... but I always use families.

    Thus... object picking is required for every object pair... which can reduce performance and adds alot of boiler plate to families for no reason.

    Are others interested in being able to add lists, arrays, dictionaries, etc. directly to an object?

    Has this been suggested before? Are there cons to this? I know I have seen 3rd party behaviors that do this and wondered why it wasn't default in construct since the beginning?

  • Haha, Iʻve been trying to deal with that in my own project right now. Figuring out ways to git rid of foreach when you need to pick objects by uid associated with the current instance.

  • If you have an extreme performance requirement and the event system just isn't cutting it, there is also the scripting feature - I know writing JS isn't for everyone but at least the option is there for raw code to make things as fast as possible if necessary.

    Iʻve been running some comparisons and I noticed many times the events are already so well optimized that rewriting it in JS seemed to do nothing to speed it up. I actually managed to slow it down using JS in some cases - which is always nice. I know that many pretty sweet optimizations have been added to c3 over the years and it really shines through sometimes. Iʻve had several occasions where c3 is able to be beating both construct and construct 2 by quite a large margin doing the same exact thing.

    Iʻd be curious to know if anyone has tried creating an ECS like system in construct. I donʻt even know if JS can go low enough in memory allocations to enable that type of design, but that would be a neat project.

  • I would love to put things in containers, but they donʻt work with families, and I usually end up with everything in families, because I usually always end up with multiple types.

    Iʻve tried using instance variables on objects to hold dynamic function names and using those functions to differentiate behavior and that works, but I havenʻt fully investigated the other issues this might cause.

    One thing, I think... it would be nice if dictionaries and arrays could be able to be added as behaviors or instance variable types, rather than being their own object. I always wondered why that was. Basically have them more baked in. Any object that needs a bunch of data for each instance, always ends up needing to be in a container with them, or worse, as a family, needing to run a bunch of picks.

    As far as optimizations go, I generally try to cache data that is costly to compute, and filter conditions with by order of least common first. Usually I have isDirty flags on set and check. Alot of effects that needed updates every tick, I just set a tween on them. Iʻm assuming that is better, but even if it isnʻt, the tween is a pretty awesome tool for simplifying timers, delays, and other varibles that need to update every tick.

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • I structured a project like this:

    Characters hold a UID to a unique dictionary (one for abilities, another for effects). The dictionaries hold the UIDs for whatever abilities / effects are affecting that character. Basically, you will have a lot of picking objects from a UID reference.

    I actually create objects for the effects and abilities, even though they arenʻt rendered, add them to a family, and add custom actions on those families. In this way you can abstract away alot of the common behavior like adding and removing abilities from the player. Once you have the boiler plate done, adding a new effect/ability is as simple as creating a new sprite, dropping it in the correct families, and then overriding the base custom action with whatever you need the new ability to do when it ticks.

    Those abilities can simply be spawning bullets, explosions, particle effects or whatever you like. Just make sure you properly you have actions for removing an ability that ensures the ability also removes anything it adds to the game.

    Since vampire survivor largely operate on automatic abilities, you donʻt have to worry too much about hooking input through this system, but if you needed to do that, you would probably need a number of "input actions" that abilities would check when being iterated through. Either that, or they would add themselves to another list that on succesful completion of the input action, and you would simply call them via callback. I typically use an input object that can be changed by either player or ai, and then a movement handler reads that input and responds accordingly. Hooking a system like that into the player abilities will be easy because each aspect is already isolated and doing its own thing.

    If you have an extreme number of these objects linked like this, you will have performance issues. I make sure I only run foreach loops after filtering objects by other conditions. Also, iterating through arrays is faster than dictionaries, but the dictionary is faster to add and remove items arbitrarily, while the array handles pop/push more efficiently. I havenʻt tested queue, because I have had no need, but no optimization is needed until you have a problem anyway. In my case, I needed to be aware of this from the start because I knew I would have up to a 1000 lists to iterate through (each list having up to around 12 items)... basically, so long as you donʻt have to run picking events for 10k objects, you are fine.

    Also, most games wouldnʻt need to actually create those objects but simply refference data stored somewhere in one place. I just.... happened to have specific reasons why I needed to go overboard on it.

  • The gpu is used for rendering... event logic, scripts, etc... is handled by the cpu. Depending on your project, you could get really creative and shove some work towards the gpu, but you need to know how to both program and write shaders.

    Iʻm assuming your project is heavy on logic and light on graphics?

    Without knowing anything about the project, there isnʻt much I can suggest.

  • So yeah, don't use 'For each' unnecessarily.

    In the event where you are using foreach to pick associated objects by uid, do you know of more elegant solutions than the typical:

    Foreach Character

    Pick dictionary by UID (character.myDictionaryUID)

    Pick collider by UID (character.myColliderUID)

    etc...

    Foreach element in myArray

    pick Effect by uid (myArray.currentvalue)

    For each effect, pick refferences objects by uid

    In the past, I never had a need to think about the efficiency of all this foreach and picking stuff because it was only for dynamic characters (like npc and main player for example). Maybe you have 30 characters active in a scene. But now Iʻm trying to do a bullet hell and every bullet carries a dynamic list of effects (easily dozens) and those effects may further reference other objects, custom actions, etc.... So I find myself needing to do a foreach over a 1000 bullets (to pick ascociated objects) and then a foreach over an array of elements containing a reference to the list of effects that bullet is affected by. If the effect is a general effect, I can just do that without picking, but sometimes the effect also needs to pick other objects as well such as the object that fire the bullet.

    All this picking seems to be required in order to maintain a system where projectiles and characters can be decorated by numerous effects and have many links to one another or characters in the scene.

    Many times the effect list can be 0, so I can filter those out and not bother iterating and picking them. But other times, it can be every single bullet has a dozen effects that all need updated.

    For every object that needs to pick another object by uid, I have to run a foreach on using this architecture.

    This seemed to be the standard approach, but is there an updated way these days?

  • Ah, that is code snippet makes total sense. Thanks ASHLEY.

  • Hey, I'm curious if I have done something wrong, but when I change the height of a sprite smoothly over time, if the sprite is small (in screen space), the change to height appears as though it is happening at a low frame rate. The smaller the object, the lower the framerate.

    Given a different way, if an object is 32 pixels on screen, a tween from full height to 0 height, will appear to take place in obvious "discrete steps" at like 2fps. If the tween(linear) only lasts a second, you get a height change that more or less looks like full height, half height, done. The same object taking up 300 pixels on screen, will appear to have a more "steps" (basically 60 fps) to acomplish the same effect.

    Obviously a retro project will have pixel snapping and all that, but this issue affects any combo of those settings.

    Does anyone know what might be happening here to cause this? I can share a file, I just wasn't sure what the standard method of sharing was for c3.

  • Hey all,

    In a project where I spawn 40k sprites with a single instance variable: In a single event:

    (Foreach Sprite, Sprite.value < 0 ) do nothing

    vs

    (sprite.value < 0) do nothing

    Why is it that the first condition will drop the fps to 30 with 100% cpu usage, while the second will still cruise at 60fps and only 40% cpu? Even if I eliminate the value check and just have a foreach Sprite, That will still be 80% cpu at 60fps.

    I know foreach events are vastly less performant than some condition checks, but why? Isn't the engine internally doing the same thing (getting a list of objects, and iterating over it to check some condition and then returning the final list)

    In some cases, its useful to maintain a custom SOL and use a foreach to iterate over those objects and do something, check something, etc... Usually its more efficient if the alternative condition is checking overlaps, for example, but in any case, is foreach simply duplicating the overhead of a single event, in this case 40k times, while the former is only the overhead of 1 event and the resulting cpu usage is the internal time to generate the sol based on the condition?

  • Sorry, totally dumb question:

    I don't see any documentation on writing your own effects for c3. I have a lot of effects I made for c2 but I can't figure out where to begin in c3.

    I was looking to open up some built in effects to look at difference , but have they gone the same way as behaviors and plugins and no public access is given?

  • If we were able to fully block all engine hacks like other engines, then it's unlikely anything would have gone wrong in the first place, and everyone could trust that third-party addons will work reliably. I think that would be a much better situation.

    Yeah, it also would have not "gone at all", let alone right or wrong - in a few cases. Though I admit you are right in the majority of cases, you do use words like "most" and "usually", and I agree, most users didn't need the hack, just like most users don't need to worry about function call overhead - but there are some who do.

    Also, gamemaker and unity have a much more robust api. locking down construct to be like the other engines ignores the fact that the other engines manage to get away with it by have a much larger feature set exposed. Construct has alot of those features, it just doesn't expose them.

    The example with no collision information I think is perfect. On overlap, where is the contact point, what is the surface normal of that contact...? That isn't something alot of small games need, it isn't something most beginner or intermediates will ever touch... and obviously, 8 years after suggesting it, it isn't something most people care about... as it still doesn't exist afaik but... when a behavior like bullet makes some obscure call to the engine to handle "reflections"... you know it is in there.

Ruskul's avatar

Ruskul

Member since 23 Nov, 2013

Twitter
Ruskul has 2 followers

Trophy Case

  • 10-Year Club
  • Forum Contributor Made 100 posts in the forums
  • Forum Patron Made 500 posts in the forums
  • x6
    Coach One of your tutorials has over 1,000 readers
  • Educator One of your tutorials has over 10,000 readers
  • Regular Visitor Visited Construct.net 7 days in a row
  • RTFM Read the fabulous manual
  • Email Verified

Progress

17/44
How to earn trophies