Ashley's Recent Forum Activity

  • It's difficult to comment on suggestions. They can seem simple but turn out really hard. Sometimes they can seem difficult but turn out not too hard. You don't really know for sure until you actually implement it. Having said that, the effects system is one of the most complicated parts of Construct and very difficult to work with, and on top of that at the moment we are maintaining two renderers - WebGL and WebGPU - which means any graphics features have to be implemented twice with considerably different technologies. So overall I would say this would be a complicated change, regardless of what anyone claims about it. I'd add that we do not really want to end up making a full 3D engine - that would involve years of work and potentially amount to an entirely new kind of product, and I think we're already seeing a stream of "just one more 3D thing... just one more 3D thing..." that is trying to push us all the way down that road, and I'd rather not go very far down that road. Finally I must point out that for this and other reasons, the feature request guidelines state that we do not guarantee implementation of features, even for the top voted ones.

  • Changing the contents of just part of the text is not currently supported, but you can achieve a similar result another way, by building up the string with variables. For example "xxxxx [tag=mytag]" & SomeVariable & "[/mytag] xxxxx", and then changing SomeVariable and updating the text to that expression again will have the same result as if the contents of the tag were changed.

  • There is a fundamental tradeoff between a small well-supported API which is reliable in the long term, and a large API which keeps breaking in the long term. The worst case scenario is to refer to undocumented engine internals. This can break at any time and we will not provide support if this happens due to use of undocumented internals.

    Long, painful experience has shown the downside to just letting developers loose on the codebase results in unmaintainable software. This point is obvious to experienced software developers who have maintained a platform other developers use for the long term, and is the reason why decades ago the industry came up with concepts like encapsulation. It's not always obvious to people who run in to the limitations of the public API. The risk is that you end up in a situation where every single release of Construct breaks hundreds of projects and causes constant chaos with rolling waves of breakages on every release. Normal users do not care whose fault it is when things break. They blame us, blame the product, leave negative reviews, and tell other people not to use it because it sucks and keeps breaking all the time. Sometimes addon developers even blame us because they do not understand the tradeoff. Avoiding that means stopping improving the product: no more bug fixes and no more features, so eventually the product ossifies and becomes uncompetitive. This has happened to us to some degree in the past, and we've seen it appear to happen to a couple of competitors over the years, sometimes with catastrophic consequences. Once you fall in to development hell it's already too late. The best approach is to avoid that outcome happening in the first place, at all costs.

    Calling a set of APIs "experimental" does not mitigate this risk. Someone might use those APIs, leave the community, then years later we change them, lots of people's projects break, and then we are forced to reverse the change, and accept we are no longer able to improve the product in the way we want to.

    The cost is a small and documented public API that we promise to support indefinitely. Relative to the risk of the failure of the entire product, that is not such a high cost to pay.

    We can and do increase the public API over time at the request of addon developers, but we have to think carefully about every addition - we know we are committing to still support that in 10 years time, possibly long after any developers who wrote code using it have left the community. We already do this kind of thing, as Construct 2 first came out in 2011, and we are still maintaining backwards compatibility with projects and from back then (this blog post includes a section on how adding a single seemingly obvious action led to significant work to maintain backwards compatibility, which illustrates the kind of complex work we occasionally do with the engine to avoid mass breakage). Even the C3 runtime alone is about 6 years old now, and we are still committed to supporting addons using the public API from ~2018 and will still be doing so in 2030 and beyond. When you've felt the pain of decisions made a decade ago, it gives you a new and deeper perspective on how to best manage an SDK.

  • Do not do this. See the warning in the addon SDK documentation. If you refer to undocumented engine internals, your project will be unsupported and could permanently break at any time.

  • You're wasting your time. Just use a HTTPS connection and everything is automatically encrypted on transmission and decrypted when received by the server. The Cryptography manual entry has a section on that ("HTTPS is already encrypted").

  • The SDK doesn't really support modules yet. It would probably be a lot of complicated work to make sure they are compiled/bundled properly on export (especially with no-minify mode) and have difficult compatibility implications (e.g. legacy file: protocol Cordova apps). However using dynamic import should work, or use the file dependency system to bundle a script (using the old-style browser script approach of adding to global variables instead).

  • Export as an Android Studio project, and then you can edit AndroidManifest.xml like you can with any other Android app.

  • I didn't mean to suggest object pooling via events isn't worth it - if you do want object recycling then that is the most efficient way to do it. However you'd probably be surprised how rarely you need to do such things. As Performance Tips says, the best thing to do is the most easy and obvious approach, and only optimize if necessary.

    Modern JavaScript GCs are very sophisticated. Generational collectors do make it especially cheap to handle short-lived objects (minor GC). However modern JS engine's major GCs are still parallel (using multiple CPU cores), incremental (running small jobs intermittently instead of one big stop-the-world pause to avoid jank), concurrent (running simultaneously with JS execution, preventing risk of jank), and also where possible schedule work in idle time to avoid interrupting smooth framerates. The V8 blog has some good entries talking about this, such as this 2019 blog post, and bear in mind there's been ~5 years more improvements since then. Overall the state of modern JS GCs is so good that I don't think I've seen any meaningful performance impact from GC in Construct games for a few years now. I just write modern engine code ignoring GC, and everyone's games are running perfectly smoothly, and where any problems come up, they are not because of GC. So, it feels pretty close to a solved problem really. I don't know if C#'s GC is as good - I would not be surprised if it was not as sophisticated, and so some people do have to code around it to some degree, but in my opinion that is not necessary with JS.

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • If you right-click the project name in the Project Bar and select Tools - View spritesheets, you can see the images that Construct is really loading. Since everything is placed on spritesheets, it may be that a new image is added and it increases the spritesheet size by more than the image size. Usually Construct will pack a range of images on to spritesheets to reduce any waste, but you can also tweak the memory impact of it by adjusting the max spritesheet size in Project Properties.

  • Safari doesn't support prompting to install a web app. You can do it manually though with the "add to homescreen" feature in Safari.

  • Well, C3 doesn't pool objects, and it still significantly outperforms C2 on many benchmarks, including intensive destroy/create benchmarks, so it's not like it's made C3 slow.

    In Construct, there are two different things that happen when creating an object: firstly allocating the necessary memory, and secondly running a bunch of engine code to initialize the object. It's important not to conflate these things. Object pooling only helps with allocating the necessary memory. Even if you get an object from a pool instead of allocating a new one, the second task of running a bunch of engine code to initialize the object still has to be run. And that is much more work than allocating a bit of memory, and so object pooling has little benefit to improving performance there. If you make a Construct project that recycles objects, note that is not running the engine initialization code as it is keeping the object alive, so that will measure much faster, but mainly because it's not running the engine initialization code when creating objects. So if you want maximum create/destroy performance, you'd still be best off doing it in the project, as you can design the project to work with objects that continue to exist, whereas the engine cannot do that. Pooling also has downsides: it adds complexity right the way through the engine, as it means class constructors run at allocation rather than initialization, so all the initialization stuff needs to be moved to a separate method; it opens up a whole class of bugs where a created thing has the wrong state because it was recycled and something wasn't reset correctly, plus memory leaks from pooled objects holding on to things that weren't reset; it opens up memory management questions about just how many objects can be held in the pool and for how long; probably some other stuff I've not thought of.

    So C3 doesn't do any in-engine pooling for entire objects, and I think time has shown that to be the correct decision - it just doesn't matter, and even if it does, doing it within the project is the best approach anyway. I think the engine does pool things in a couple of specific cases like for individual particles. I still doubt it makes much of a difference. The main problem with JavaScript performance these days is that everyone continues to underestimate it, when you can usually write basic obvious code and it'll be competitive with C++/C#.

  • It depends on the type of the thing that you call GetSdkInstance() on... and whether it's editor or runtime code. It's hard to tell from your post.

Ashley's avatar

Ashley

Early Adopter

Member since 21 May, 2007

Twitter
Ashley has 1,383,201 followers

Connect with Ashley

Trophy Case

  • Jupiter Mission Supports Gordon's mission to Jupiter
  • Forum Contributor Made 100 posts in the forums
  • Forum Patron Made 500 posts in the forums
  • Forum Hero Made 1,000 posts in the forums
  • Forum Wizard Made 5,000 posts in the forums
  • Forum Unicorn Made 10,000 posts in the forums
  • Forum Mega Brain Made 20,000 posts in the forums
  • x107
    Coach One of your tutorials has over 1,000 readers
  • x61
    Educator One of your tutorials has over 10,000 readers
  • x2
    Teacher One of your tutorials has over 100,000 readers
  • Sensei One of your tutorials has over 1,000,000 readers
  • Regular Visitor Visited Construct.net 7 days in a row
  • Steady Visitor Visited Construct.net 30 days in a row
  • RTFM Read the fabulous manual
  • x35
    Great Comment One of your comments gets 3 upvotes
  • Email Verified

Progress

32/44
How to earn trophies

Blogs