Ruskul's Forum Posts

  • Hey everyone,

    For those of you who make would like to make shader effects but don't like coding them, as it happens, you can use Unity's shader graph to author construct 3 effects.

    If you are already familiar with Unity, I'd say its worth it.

    I realized this when I started the process porting a game from Unity to Construct.

    I thought it might be helpful for any interested. There is still a bit of work, and you will have to ignore "superlongwierdvariablenamesusedbyshadergraph" or replace them. But the TLDR, for complicated effects, I am finding that authoring them in a shader graph involves faster iteration and experimenting , and porting them over is as simple as changing a few things.

    Does anyone know of any other shader graph programs that can export glsl 1.0/2.0 ?

    I'd love to know about them.

  • Hey all,

    There are a number of ways in scripting to end up with an instance, without knowing much about it,

    Such as runtime.objects.SomeFamily.getFirstInstance().children();

    In this case, I am looking for all children that belong to a specific family.

    for (const character in runtime.objects.characters.instances()) {
    	
    	//how to easily get this:
    	const effects = character.children //where children belong to family "effects
    	//obviously that wont work, but I also dont see a way to to check...
    	//...if an instance belongs to a family.
    	//I can see a property "ObjectType" for checking instance types, but not family
    
    	//this is what I am doing instead:
    	for(const effect in character.children()) {
    		if (effect.instVars.aVariableExistingOnFamilyEffects !== undefined) {
    			//this specific variable exists only on the family "effects"
    			//since this child inst has that variable...
    			//...we can treat it as the family now.
    		}
    	}
    }
    
    

    Checking for a variable on the object that belongs to the family I want seems like a hacky way to go about going from a parent to checking for children of a specific family type.

    I can't see that this is an uncommon operation, is there a better way of going about it?

  • WackyToaster

    half a year later... Yes, I think so.

    Though that still means you have to subclass every object type you have needs to add the functionality to... which is repetition I hate, especially when it also means you have to remember to do that when making changes to the project...

    I am currently solving in another way. During an objects initialization, I have a "onCreate" event for the family I need my behavior on. In that event, I call a javascript function that stores a reference to the created object, and creates a new instance of a custom javascript class (I'll call it a component now).

    The components I add to objects do various things, such as manage buffs/debuffs and character behavior states (like walking, running, rolling, climbing, etc)...

    In this way, I have wrapped up it up in JS for performance sake, but now when I create a new objectType and add it to the family of consequence, I don't have to do anything else, or remember to subclass it. It's a little more fool proof and less prone to programer error in the future... I also made it so the system interacts with editor side instance variables, and linked dictionaries for dynamic data, so I also don't need to worry about interfacing with it via JS if I don't want to.

  • I use finite state machines a fair bit (for things like triggering character abilities, behaviors. etc..), but I noticed they took as much work in flowcharts to set up as in events -which I could be using them wrong.

    So the benefit here then, is the visualization? I'll have to mess around with them some more I think.

  • Yeah, I was starting to switch to the convenience of hierarchies when I noticed this. I very much prefer being able to build templates and attach children objects for additional functionality. It makes for much cleaner events than picking by uid.

    On picking though, it is very, VERY, fast. Picking an object by uid is blazing fast as far as I can tell, and negligible on performance unless it forces you to use a for loop you didn't need to use.

    It would be really cool if you could have children automatically associated in terms of picking. Like, if we could have another "self" type keyword that allows you to reference a child or parent in batch without a foreach loop/

    On a side note, if you use functions for nearly everything, and have performance pains, It is good to understand a raw function call can cost 8x the price as an empty event. That may be insubstantial if the processing for logic implemented is high, but sometimes, the event itself (empty) can have a higher cost than the ACES it calls. I had a project using a lot of vector rotations and such, and the most costly part of the math was the overhead of the events and function calls. I created a bunch of math functions through events. And it was bad, especially when you have function calls in function calls. I wrapped that functionality into a plugin and then just call the ACES I created. If I need to run rotations on a bunch of projectiles, for example, the savings was well worth it.

  • Ah, thanks a bunch!

    When the manual calls *Instances() a method to return an iterable, is that the same thing as a generator function? In this case *children()?

  • On further investigation, I tried to see if there was an exponential relationship between the number of children and the time it takes to iterate through them. I need to dig deeper, but it seems to be true.

    1 child runs runs at 30 fps, 2 children at 14fps, and so on. Whatever is happening internally to fetch children or mess with the sol is extremely slow.

  • Edit: Bug report at github.com/Scirra/Construct-bugs/issues/8230

    Project file : drive.google.com/file/d/1Aq1BkpicNGKQhw9GnLaNRa-KhgsLy94Z/view

    In a test, Looping through and picking children in a scene graph is insanely slow compared to manually tracking and looping though array lists of uid attached to a parent and then picking those children objects by uid. Via constructs child picking I get 2 fps and 100% cpu. Via manual uid tracking and picking, I get 60fps without only 25% cpu.

    This doesn't seen right.

    I once happened upon a bug that caused a dictionary and array forloops to run extremely slow. But that bug increased the lag exponentially with every item added to the loop.

    Why is picking an object's children so slow compared to manually tracking and picking those same children from UID?

    For example, if I create 1000 parents and attach 10 children to each parent, and the loop through each parent, picking children, and then looping through the children, I get 2 frames a second.

    But, If I do the same, but instead add an array for each parent to store child UIDs and add 10 children to each array. Then when I loop through each parent, picking each parents array by uid, then loop through each element in the array, picking a child by uid, I get much better results.

    The uid method runs 120 faster than the scene graph method.

  • I have a companion post about *Instances(), and iterators, but now I am having trouble understanding how to best use *generators

    Specifically, I am looking at *children() , used to be able to iterate all children attached to an instance.

    But how? Needing to relate this back to event sheets, how would I recreate this:

    Pick children of type "A" -> Dothing

    If I simply do this:

    For (const child of someinstance.children()) {
    	If(child.type === Desiredtype) child.DoaThing();
    }
    

    ...Then why is this a generator. What power does that give me, etc... I tried reading the docs for JS, but I need to see it in use here. Code samples would be fabulous in the manual.

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • I don't have a deep desire to see event behaviours, mainly because it feels doable right now, and I envision the downsides of what we have right now would also affect event behaviours.

    Say you made a custom platformer movement in events for a "Player" object, all in 1 group,and then you want to copy this to a new project? Well then you better have any objects/families with same name and same variables in other project before you can copy/paste this group. Once everything exists then you can indeed copy and paste.

    You are correct if behaviors are literally just snippets of event sheets, but that is ignoring a key concept of abstraction that behaviors have. Behaviors are abstract, they dont care what object you put on them, or what values they have, because they are adding all that. To create a behavior through events, you need a set of specific, abstract ACES that allow you to define an object's properties, actions, and conditions, and expressions. When you create a behavior through the sdk, you ARE defining all these things - that gets added to an object without the user needing to. You don't need to add "acceleration" variables to an object before adding the platformer behavior to it, because the behavior already defines it.

    Defining a behavior through events, that you can simply add to any object, just as you do a behavior defined through the sdk, wouldn't be at the same as copying event sheets and objects.

    It is important to note that everything you can do with an event sheet may not translate directly to what you do with an event sheet composed behavior. You could define specific functionality, but that isn't the purpose. Its abstraction and the ability to be able to reuse as much code as possible.

    I have custom behaviors and plugins, for example, that define only variables I constantly use across all projects. I made these purely so I can simply add them to a project, without the need for templates. In the end, All I have to do is create an object, rename it "world", and slap my globalVariables behavior on it, and it now has all the variables I normally need, and helper actions, and I can easily access it via events by the expressions: world.gravity , or world.GetVectorTransformation , etc...

    The issue is that authoring a plugin is tedious so I need to be careful about what I author, but it shoudln't be, as tools like c3ide prove. If you could seemlessly author behaviors within construct, using a gui, it would speed up things considerably.

    Let's assume we have behaviour event sheets... Same issue, any "on sprite collide with ground", the new project will need that ground sprite, any vars from the ground sprite need to be added, etc, before you can copy that behaviour to a new project.

    Again, this isn't true. You are thinking in concrete space rather than abstract. Instead of defining specific behaviors, you define open ACES. For example, condition: "OnThisObjectCollide with <UserDefinedObjectType>" . If you want to pass info to the behavior (say you need a friction variable), you can easily include this. Basically, you have to think about what a behavior adds conceptually, not what you do with the behavior specifically in a project. A good example is if you make a custom set of physics. You don't care what objects are colliding, and you let the user decide, but you do give them actions for resolving those collisions, tracking velocity, and integration methods.

    Maybe the more reasonable solution would be a better copy/paste system, like a special paste or import/export functionality that, instead of attempting to paste and having C3 say "cannot find sprite, cannot find var", it would automatically know to copy the relevant objects/families across. Maybe being able to export a group of events as JSON which captures all relevant objects along with instance vars, effects, and their defaults, so that they can be imported into a new project.

    I agree, this would be a welcome feature. I would also welcome a way to define an object/template and export/import. That would be very nice and allow easy cross project collaboration.

    I sorta see the idea of "applying an event behaviour to any object" but then this is also achievable with families, throw a new object into the family and boom, the group of events applies to them.

    Yes... but without family nesting, you have now burned your one layer of abstraction without resorting to performance killing workarounds, and if you want to compose additional behavior on the object, you have to bloat the family/project template you use, or add it manually on a per project basis.

  • Hey, Last I was engaged and exploring flowcharts was back in January, and they seemed to lack significant features and didn't solve any problem I had. My takeaway is that they took more work to use to solve the problems they were meant to solve than other methods.

    fastforward to September:

    I was curious if anyone is using them in projects now, and what they are finding useful about them. I notice they have more features, but I still don't understand what power, if any, they bring to the table.

    Any illumination for what things I should consider them for?

  • piranha305 - I definitely thought back when c3 was first being discussed that there was a plan to be able to define behaviors in the editor, and even use events to do so. I'm not sure where the disconnect was, but my entire perception was that c3 was js based so could be used anywhere, and more modular with better customization. Also, allowing compartmentalization would be nice too (I should be able to define a function available to only a particular event sheet, for example)

    Imo, that would be absolutely huge to be able to define abstract functionality that you can easily share between other projects and users. Bolt for unity was built by one guy, (it is a visual scripting tool) and it exports semantic c# scripts.

    Thanks for c3ide, btw. I dig the gui and adding aces to code where I simply plug the info once and it takes care of all the tedium.

  • Hey Overboy

    I was curious if you have a timeline for migrating to sdk2 on these tools and if you know offhand if any will have trouble due to internal api use?

    I use modified versions of mostly array and dictionary as behaviors but I am trying to ensure I don't face troubles in the next year or so on this current project.

    Mahalo!

  • This is in response to the last page located at : construct.net/en/forum/construct-3/plugin-sdk-10/addon-sdk-v2-182122/page-12

    On the topic of coding limitations and design patterns in c3.

    I'm looping in Jase00 and skymen as I had remarks for both their responses.

    First for skymen , I'm a little confused, because in regards to family nesting, inheritance, etc... I thought I was making the points about construct 3 that you made. So we might be on the same page? I didn't touch data flow, but I was meaning to use patterns as an example as to show some of the deficits that construct has in regards to addressing certain types of games. Those deficits would sometimes cause me to try to solve the probelm via the sdk, where I would be met with shortcomings within the api. For me personally, many of those short commings have been alleviated with the addition of a few news calls (like being able to use collision cells, etc).

    For Jase00 - I'll write a second post concerning some of your solutions. I agree with some, though I think others are not feasible/ need clarification, but as a summary, I'll point out a few things.

    1st, I should clarify that "not possible" and not "reasonably possible" are two different things and I think I am arguing the second. Values and expectations will come into play when we try to define reasonable. I think you are right to point out that in particular instances, I am arguing a problem is impossible to solve when it is in fact possible, so I think I need to clarify them.