Ruskul's Forum Posts

  • 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.

  • I don't think those are good analogies - software is pretty abstract and personally I don't think maintaining a reliable software platform that other third-party developers build on top of has much relation to a restaurant. Tweaking random bits of internal code is fundamentally unmaintainable. This is widely understood among professional software developers. There is no way to make that work. The solution is a public documented API which you promise to support. That is what we have done.

    I think a better analogy is: imagine a block of flats where any resident is allowed to make any structural, electrical, plumbing, gas, or water alterations, to any part of the building, at any time, without permission from anyone. Chaos would ensue and the result would probably be extremely dangerous. This is not a reasonable way to run a shared building. There are rules about what you can and can't do, and who is allowed to make which changes, specifically to prevent that end result. Residents who complain that they can't just break open a few walls and run another gas pipe through several neighbor's flats are not being unfairly restricted in their freedom to do what they want with their flat - the rules are there to make sure the building can continue to function and be properly maintained in the long term.

    Fair points, but the public documented api sometimes doesn't let us put up our christmas tree the way WE want to (the point maybe actually IS to light the tree on fire, not put lights on it). And when I break my project, I am not harming my neighbor. In this case, you are requiring us to build our house to code- not for the sake of any neighbors (because we have none), but for the sake of the county inspector who like easy paperwork. I agree on the point about maintainability... but also, from our side, sometimes a project needs to be done today, not maintained 10 years from now. From your perspective, I get it, but you also have to see it from the side of the developer that is in a huge pickle, that a small tweak could save huge ammounts of time, and that future maintainability of the engine isn't a concern when you can't finish the project... Its back to that, you lose users to other engines that don't even want to leave but have to. Once they get invested in those other systems, they have an even easier time porting every project there.

    I have, in many respects, tried to make unity more like construct, because I prefer construct. I have scripts over there that essentially mimic the behaviors I commonly use that come stock with c2/c3... But the more I invest in unity to get around a small problem in construct, the smaller that problem has to be before I dive towards unity.

    Like I said, I like working in construct better than unity - and start pretty much any idea in construct, but I have only finished 1 project in construct (and that one involved making external tools in c# to manipulate c3 save files in order to inject data and assets more efficiently and not deal with it in construct... for important reasons :p.

    I'm rambling now.

  • Whenever I see negative comments about C3 (mostly from users of it), it dumbfounds me.

    I am no sycophant, but I think that C3 is a brilliant piece of software that is extremely underrated both in the community, and out of it, too.

    C3 is vastly overrated by most users inside the community (making small games typically) and vastly underrated by outsiders. c3 is best in class. It knocks gamemaker out of the water in specific circumstances. But in others, it comes up short. Same thing for Unity or Unreal. It depends on what your needs are (talking about 2d only). If you need shaders, custom rendering, lights, onstruct probably isn't for you and that makes sense. But there are still ways in which construct could possibly better support some areas.

    I think from Ashley's participation in the forum, and the ability for us to create small-medium games pretty rapidly, that you would "miss it when it's gone"...

    Don't get the negativity wrong. The vast majority of salt on these forums comes only because people know this is a great product, they just have run into problems - I spend no time on Unity's forums because it is basically pointless. Ashley spends alot of time here, and I think that is worth volumes, even if he is just saying no. But sometimes he says yes, and sometimes he fixes the "bug" you want fixed. Unity can go for years with breaking problems in some systems and ignore it. It's pretty rare to be able to speak directly to the developer like this.

  • It's not that I don't understand the issue with giving people power. I simply disagree with Scirra's philosophy. Obviously a small tweak can introduce bugs, but that is precisely why I want to be able to do my own tweaks, so Scirra doesn't have to.

    I believe every patron at every Thai restaurant deserves to be able to add additional hot peppers to their dish at their own discretion, regardless that some irresponsible Patrons have thrown a tantrum when their curry is too hot. Any idiot who breaks their own project, ignoring all warnings, and then quits construct blaming it on Scirra, isn't a customer you philosophically want anyway - they are fundamentally unreasonable, and won't last in development anyway.

    It is about agency, responsibility, and the fact that all users are treated like children. You can either hand a knife to a chef in the kitchen or you can give them a fork and tell them they might hurt themselves with the former.

    It would be the same if your OS provider said you can't install anything not on their list, lest you have a bad user experience.

  • Zizaco

    I'm curious what you ported your project form. Totally curious to check it out.

    TS was brought to my attention by Skymen and Ashely as well. Unless I am not setting up correctly though, when working with builtins I still see anything in the c3 runtime (ex: SomeSpriteObjectInstance.AnythingAndEverything.AnthingAndEverything.Etc). Which makes it good, but only half the time.

    TS only works while in VS right? not within c3?

    I mentioned in response to skymen about scalability, that while there isn't a hard reason you can't make a complex project, how can you deal with object and function bloat besides just "dealing with it". In unity, for example, I can package up alot of code and forget it exists. I can't do that with events. Its super distracting to have to keep picking the same object type nested down 3 folders amongst 1000's of other objects. Unity doesn't care how many prefabs you have made, none of them are available to you code side unless you specifically add it, and even then, its whatever you named it in that script. Autocomplete works fine in construct, but there is no enforcement of scope across objects, functions, customactions, etc...and auto complete includes them all. and part of wanting to work with events is that they feel cleaner, more visual, to me, and the moment I can't, it just feels like the core advantage of c3 is no longer present and other environments offer cleaner code spaces. I'm not a fan of gamemaker language for a similar reason.

  • ...I guess some people want to tinker with the engine internals, but that type of thing has historically caused awful, horrible, nightmarish compatibility problems, so it's something I would specifically discourage. (And often I think the things people want to do are already possible, just if designed in a different and more maintainable way.)...

    "Often" is the keyword. Often, but not always. I think the users who end up using monogame, for example, are the class of users that would have stayed if they could, but they can't.

    One of the biggest things I needed to do in c2 was add collision layers to the platformer (so some objects could go through some things, some of the time), handle slopes (built in platformer is slope agnostic - The object gets pushed correctly from collision but is ignorant of y velocity as it travels up or down), get collision point, collision normal, etc, as well as a few other things. The built in platformer didn't cut my needs at all so I had already rolled one, but adding additional features to the collision system was... unfeasible. Recreated the whole project in Unity in 2 weeks.

    Now, some of this is possible in c3 now, because features have been added. But this is years after I needed them. But the problem is the same now as it was then, in principle. If Scirra don't agree that a suggestion will benefit enough people, it's basically shot down. In other cases it takes YEARS before it is added (prismatic joints in box2d, as an example). Adding such a joint was only like 10 lines of code, but it was never added to c2 despite a fair number of people asking for it. But I added it to my project and dealt with it. Regardless, I still can't get the surface normal of the collider an object is overlapping without adding more. Box2d provides raycasts, boxcasts, etc... so if you are already using physics, there are solutions already baked into the box2d behavior... but... not exposed. So I added workaround and hacks. If you aren't using physics, you quickly realize that the construct runtime does some shady black magic behind the scenes just to make behaviors like SOLID and Platformer interact.

    Enter the desire to want to tweak the engine. Because you need it, even though Scirra doesn't see the need. Even though Scirra does see the need in their specific uses.

    Basically, its seems like Scirra recognizes the need for engine tweaking to support behavior interaction, but is adamant that isn't how you should develop (do as we say, not as we do). So instead you end up with behaviors that, in order to function correctly, need some back and forth boiler plate added either to the event side, or through scripting.

    TLDR, its hard to take such advice seriously when the Scrirra team authors behaviors that need engine tweaks in order to function (shadow caster, platformer, solid, dropthrough, etc... all have some internal engine stuff if I recall). Its frustrating in many cases and makes the itch to switch pretty strong.

    I think there are good arguments for steering most users away from doing this. But in my case, c3 clamping down on this literally steered me right towards another game engine. I cannot (quickly/easily) make some of things I did in c2, in c3, without modifying behaviors. If I have to rewrite behaviors from scratch, I'm going to do that in an engine where my power gains will be substantially higher. I really like working in construct, it is relaxing and less stressful ide (hard to explain, but opeing construct is fun. Opening unity is work), But, when a simple tweak to the engine would fix your problem but Scirra advocates essentially rewriting core components entirely on your own... If I sink my time in that, I want AAA rendering and postprocessing and access to 1000s of premade tools, etc...

    Simply not being able to tweak pathfinding in c3, lead me to unity where I bought a* pathfinding project for $30. It solved my needs and now the prototype is sitting in a development environment where the clients can more easily take it further if they wish.

    I still do alot of stuff in c2, and I do some stuff in c3. But every time I'm just about to buy c3, I remember its leased, yet doesn't offer the ability to adjust it to fit my needs without reinventing the wheel. So... basically... don't use inheritance, even if objectB is functionally the same as ObjectA but with one additional feature.

  • Ashley

    One of my main use cases for the Addon SDK, is portability and reuse of code. everything is packaged together nicely. a lot of things that can be done with JS is much more convenient to move to addon.

    And I think that stems from JS and event not having good interoperability.

    I totally agree with this.

  • I understand where you're coming from Ruskul but I don't necessarily agree. I don't think it's fair to try to strictly apply code architecture principles to Construct's Event sheet system as they have been written with typical coding languages in mind, and not event sheets.

    Instead I think it's far more sensible to apply a set of new coding principles that are designed around the event sheet and Construct's addon architecture instead.

    That's a totally fair assessment. But I also think common code designs are created to solve particular problems. In some cases, construct has no good way of solving those problems in a handy way as it is. Take object pooling as an example. Construct handles it behind the scenes. That is spectacularly amazing. In pretty much any other major engine, you have to create the pooling system yourself afaik. But, for something where you need decorator or protected factories? That's where you can make those in construct, but there is no way to force other contributors to use those systems. right? So like, I can make a factory with events, but another programmer can still just spawn the object the factory is supposed to, without going through the factory. It's those types of problems that construct doesn't handle well imo, and if it had them baked in (like with object pooling), I think that would be great. Just a few architecture tweaks (such as creating protected, private object/family functions events would be great. But to do that, I think you would need per object event sheets, which would also cut down on some common boiler plate events that iterate through objects to apply instance specific logic anyway.

    The idea that because you might outgrow an addon then you should absolutely avoid it doesn't make sense to me. If you truly have a good reason not to use built in features, I think writing a new behavior is a far better idea than trying to handle everything using events.

    I should be clear - I do use them. But I am really careful about using them for more than a prototype. Being midway through a project and realizing you have to substitute several vanilla behaviors with custom ones is kinda pita. At this point, I have alot of the behaviors recreated, but then I don't benefit from any feature improvements. For a long time in c2, it was physics. I would have to keep adding my changes to the newest release when a simple inheritance scheme would allow users to specify additional ACES without having to recreate the whole thing.

    I have seen projects scale just fine within Construct's features...

    How can you deal with global space bloat in a large project without simply having to "get over it". For someone with pretty bad adhd, I have a aneurysm when autocomplete lists literally every function or object in the the game. The real big appeal to construct is how sleek it can be, at a smaller scale. It isn't that you can't scale in construct, its just that it you do have to just "deal with things" that you don't in other environments.

    Also, with the recent addition of TS, and with the VS Code extension, I think Unity C# with Visual Studio isn't that much of a better coding environment compared to C3. The only thing maybe is that it doesn't integrate into the editor, and C3 scripts aren't treated the same way as Unity scripts.

    That is pretty big, but still not quite as seamless. Also, the construct runtime still functions JS style, not TS. Unless I did something wrong.

    TLDR, I think your disagreements are pretty fair.

  • And since Ashley ninjad me... yeah I know you're basically a 1 man army with a sidekick. I always wondered, is it not reasonable to add another person to your team? Just one extra person that dedicates time to a plugin here and a behavior there? I don't know all the logistics and finances involved, but I'm really curious. I know more people doesn't necessarily always help, but I feel like in your case it would.

    I think that wouldnʻt be the right thing. I basically already use 0 of the included behaviors, because Iʻm not allowed to touch their code. Adding more, doesnʻt make c3 better. Effort should be spent making c3 have better event system features that enable us to do more in a scalable environment... People have been talking about abstract "template" events since c2, and rumors back in the day was that c3 would allow better cross project object/events sharing. Behaviors and plugins are currently black-boxed systems and as soon as you outgrow them they are useless. But... custom expressions? Better functions? object and event scoping and encapsulation? now that would be useful.

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • >

    > If you already know Javascript chances are you aren't going to use C3, and if you use C3 to learn JS then you'll probably outgrow the engines limits and move on.

    >

    As some one who knows javascript and work professionally as a software developer (not in game) I disagree with this take. I have used all the engines and keep coming back to construct. And those advanced scripting makes me want to invest more time In The engines.

    I agree and disagree. I used c2 to launch into other engines, mostly due to c2 shortcomings. It was easier to learn unity than grapple with c2 sdk (especially considering the performance tradeoffs). I keep coming back to construct because I think it has alot of promise. Recent additions in the form of custom actions/ hierarchies, templates, etc... all make the engine more viable, but the addition of scripting is pointless as has been mentioned. C# with VS and unity, is objectively a better featured environment for coding. and the returns on effort spent there is greater. Its also cheaper, unless you are a millionaire.

    EDIT: I shouldnʻt say scripting is pointless. Its quite nice. But there is a bit of boiler plate required to talk back and forth and the moment you need to use scripting to solve a problem, it undermines the "no code" benefits of construct. I hate typing code, which is why I like construct, but since I hate typing code, I sure am going to do it in the most efficient manner, which... imo, is not in construct.

  • I have been using C2 and C3 for a total of 10 years now. Yes, I haven't developed great games, but I still don't get the point where some users says that C3 is not scalable. Since "scalable" is a term that can be used in many situations, could you provide me some examples so it's easier to understand what's wrong?

    Scaleability, in software at large, refers to difficulty/cost/time in adding additional features, allowing more users, and so on.

    In games, scalability is the ability of developers to continue adding features/complexity to a game without breaking old code and taking forever to do it. In traditional coding environments, Poor architecture and poorly written code can mean that each additional feature added to the game requires exponentially more time, and risks breaking other features.

    In construct, starting a new project is fast. Creating new objects is fast. Prototyping features is a breeze, But refactoring is SLOW and gets even more tedious the larger the game gets. Construct, by its very nature, encourages poor architecture (with nearly EVERYTHING in global scope, simply adding more objects to the project increases the time it takes to add new events). The event system itself, while easy to grasp and use initially, is nearly impossible to follow and implement industry standards for clean code. This is never a problem in small projects, but it is a massively huge problem in large projects. The awful part is that creating clean, SOLID style events, creates a rather large performance burden and overhead and require a ton of boiler plate events just to run. Not only that, you still canʻt create safe ways to interact with previously authored event sheets. Dang if you do, dang if you donʻt.

    If you were to make a custom platformer handler, the fastest and most naive way to do so would be simply to make an if/else tree. For simple platformers with only running and jumping, this may be fine. No need to complicate things. But then what if you want add duck, duck rolling, ground pounds, jump forgivness, double jumps, wall runs, wall slides, phaseshifting, object lifting, rewind and timeshift, shooting and reloading, but only in some cases. No that original choice to use if/else trees looks pretty bad. You probably should be using some sort of state machine. But then what if you want the character abilities to be added and subtracted at runtime. There are flaws with using a state machine for complex character behaviors, so now we need a different system where components talk to each other, but remain implementation agnostic.

    In order to build such a component system, you really need to the full power of OOP and (very importantly) encapsulation. I can tell you right now, that that construct wonʻt make this easy to make. It also will be difficult to use and not accidentally break. You will spend alot of time repeatedly picking objects, so you can get their array or dictionary, so you can get another array or dictionary so you can pick another object so you can run a custom action on, that should return a value, but canʻt, because reasons. And every function you create has to exist in the global space, even though 90% of them should absolutely be private to only a few objects.

    Given the way behaviors and plugins work with each other (not well, unless you can customize the runtime like SOLID does), they arenʻt good solutions either, especially since you canʻt use OOP with them.

    For these reasons, construct is "unscalable". Making mario isnʻt too bad, and Iʻve seen alot of people make some pretty cool stuff with construct, but alot of times, the ease of using "construct" becomes more of a burden in those cases.

  • So - as I make a game... I reach a point where events can't keep up, either because they don't scale, or they lack key functionality. I now have the option to use sdk, or JS directly in construct.

    So NOW, it isn't even a competition between construct and unity(or whatever else). Its a competition between the best coding environments... in my case, c# with visual studio support, or javascript without good intelesense/scope with construct. This isn't even a competition. Construct cannot compete in performance or features in this arena. As construct already can't compete feature wise with the big engines, it makes a space for itself by being clean and fast without touching code. WITHOUT TOUCHING CODE.

    If construct is to ever be a widely accepted tool for creating anything more than little games, The focus has to be to improve construct's ability to create scalable events, across multiple projects, and include more OOP/features that enable more complex/abstract designs. It needs to implement common design patterns (like observer, decorator, etc) behind the scenes to allow users to use events without performance degradation (as creating these patterns with events impose heavy overheads). The functions need to be rebuilt - no matter how much Scrirra likes them, the user base pretty much is clear on this - they suck. Construct also needs scope. It is monumentally annoying to be working on a behavior for a single object type, but every condition/event have to keep clicking that single type out of a list of 1000 types (folders always default to top, so if you have lots of folders, you get to enjoy drilling down every event you create).

    So much of what construct does is great... in small projects. But projects with 1000s of assets get unwieldy in every aspect. You can't even write safe systems to prevent yourself from breaking things. In unity, I mark classes sealed, private, protected, and so on. I can force objects are used in only the ways I intend, but in construct, I can do anything to anything from anywhere. I can call any function from anywhere. Now bring in a collaborator and cry. Static Singletons are okay patterns for a few things, but not for EVERYTHING.

    IMO, construct is sitting in a niche, and that is okay. But to really compete, and why it hasn't become a popular tool for console/PC games, is because despite its ease and ALL the THINGS construct does RIGHT - it just doesn't scale.

    The moment I hit the code, construct isn't easier than unity - its harder. and I started coded for construct before I ever touched unity.

  • The Addon SDK isn't meant to be the primary way of writing code for your project. Just use script files (or scripts in event sheets) instead. The Addon SDK is there if you want to do something like integrate a third-party service in a way you can use from event sheets and re-use between a wide audience. If you want to do something project-specific I'd definitely recommend to just write code directly in your project instead. JavaScript Modules are also a really good way to share chunks of code between projects too, if you have bits of code you want to re-use across projects.

    Ah, that would make more sense. I might be extra dumb here though... How would you use the script files to extend an object's functionality?

    Like, if I want each instance of type T to have a list on it, I'd still have to create some sort of manager to link those lists to each unique instance. With a behavior, I can just drop it on the object type/family, and roll without much care for how its implemented behind the scenes.