Ashley's Forum Posts

  • Well, in the case of "has tags", in one case you just compare a string which is a very simple and quick operation for a CPU. On the other hand "has tags" has to split the given string by spaces to extract individual tags, and then verify that all the provided individual tags are in the set of tags for the given instance. It's probably at least 10x as much work as just comparing a string. It's not that it's slow - JavaScript is still exceptionally fast with such tasks. It's just that you've used a feature which necessarily includes more complex steps. So if you make a benchmark that absolutely hammers that specific feature, you will probably see something like a 10x difference.

    But does it matter? I find it hard to imagine it matters at all in the vast majority of projects. Even 'Has tags' should be so extremely fast that you'd have to do it something like 10000+ times per frame for there to be any significant performance difference. And if your only evidence involves low CPU usage numbers like 5.8% then I'd say you're probably just looking at results in low CPU power mode and your numbers are misleading. Perhaps it's the case that if the CPU was running in full power mode, your numbers would look more like 1% vs. 1.1%, which would be a better reflection of the performance difference.

    This kind of thing comes up so much and seems to mislead people so consistently, even after explaining the pitfalls, that I do wonder if it would be better just to get rid of Construct's timer-based CPU/GPU readings. However they are still useful for general "is it low or high" type readings, for example knowing whether you've maxed it out or not, so I don't think we should get rid of them. It's just something you need to know basically can't be trusted at all. Hence the trap: the CPU/GPU usage numbers look misleading for real-world projects, and a benchmark running flat-out is probably also misleading as it doesn't represent real-world projects. So when do you know if something needs optimizing? The framerate is the ultimate measurement. If your real-world project can't hit the display refresh rate (typically 60 FPS), and changing your events allows it to hit the display refresh rate, then it was significant to performance. Basically in all other cases, there is not really any way to say for sure it actually mattered.

  • I just want to caution everyone about the same old issues when people talk about performance. It's a way more subtle and complex topic than most people really understand.

    Issue 1 is Construct's CPU/GPU measurements are only timer based, and all modern processors have advanced power management. This means it's possible to make a benchmark and slowly increase the amount of work, and then at some point the CPU/GPU measurement suddenly drops a lot. You might think "OMG! Adding more work made it faster, WTF?" but all that happened is you created enough work for the processor to step up from slow, low-power mode to fast, high-power mode. We warn about this:

    CPU measurements can be unreliable, especially when the system is largely idle. Most modern devices deliberately slow down the CPU if not fully loaded in order to save power. This means work takes longer to get done, and these measurements will misleadingly return a higher measurement, since it's based on timing how long the work takes. It will generally only be reliable in the device's maximum performance mode, i.e. under full load.

    But most people still seem to ignore this and design benchmarks that run at less than full load, which means the results might be nonsense. So most of the results in this thread may well be nonsense on that basis alone.

    Issue 2 is that both Construct and JavaScript are so exceptionally well-optimised that, counter-intuitively, it can make changes to the workload seem much worse than they really are. Even Construct's event blocks, with the overhead of the event system, is so fast that one benchmark we did a few years ago showed Construct events being 5x faster than GameMaker Language in VM mode, and still nearly as fast as GML when compiled to C++!

    To illustrate how a faster engine produces counter-intuitive seeming results, consider workload A which takes 1 CPU cycle, and workload B which takes 2 CPU cycles. If you make a benchmark, workload B is half the speed! Some people then start giving advice like "never do B, it is slow". However imagine working in a slower engine where workload A takes 10 CPU cycles, and workload B takes 11 CPU cycles. It's the same difference, but now it's only 10% slower. People might give advice like "both A and B are fine, there's not much difference". But the absolute difference is the same.

    In other words, if an engine is already insanely fast, very small changes to the workload show up as disproportionately large changes in performance. However in most cases it just doesn't matter. In the example I gave earlier, the slowest workload B is still 5x faster than the fastest workload A in the slower engine. Something taking 2 CPU cycles instead of 1 is unlikely to ever affect real-world performance of an actual project, even though you can make a benchmark showing a large percentage difference. Making that benchmark and then saying "never do B" is may well actually be giving bad advice, causing people to do contrived, inconvenient things to their projects that are entirely unnecessary. This is really just another way to re-state that optimisation is usually a waste of time.

    Lastly the event system has been fine-tuned for maximum performance for over 10 years, and it's got a lot of sophisticated optimizations. Whether or not these matter and how they apply depends on what your project does. For example the 'Is overlapping' condition can use the collision cells optimization, which means if you have something like 10,000 sprites spread across a large layout and test overlap with a single sprite, it only checks nearby instances - let's say just 100 instances (which might sound a lot but is just 1% of the total). However if you put a different condition first, it has to disable that optimization. So putting some other condition first that only picks a small number of instances may in fact, perhaps counter-intuitively, be much slower, as that condition will check all 10,000 sprites. It may also have the opposite result, and be faster that way, depending on how much work the condition is versus the very small amount of work of identifying just the nearby instances, as well as how many instances are involved, and where those instances are. So you may in fact be able to measure that collision cells are slower in some contrived benchmark. That does not mean you should change the best advice of "put collision checks first" because usually collision cells is an important and highly effective optimization.

    I'd also note running events once with N instances picked is almost always more efficient than running events N times with one instance picked, because the latter repeats the overhead of the event engine. So for maximum performance, avoid "for each" unless you really need it. Again, a contrived benchmark may be able to measure the opposite. That should not change the general advice.

    So really as usual my performance advice is:

    • Ignore performance results unless you have a real-world performance problem in your project
    • If you have a performance issue, rely on performance measurements in your actual real-world project, and avoid making contrived benchmarks
    • Follow our official performance advice
    • I'd say 95% of the benchmarks users make do not correctly take in to account processor power management, so my general advice would be to ignore user-made benchmarks. If you really want to use benchmarks, only pay attention to properly designed ones that max out the processor, and ignore all others as probably misleading.
    • Remember that even a properly-made benchmark that appears to show a significant result may still be entirely irrelevant to any real-world projects.
  • We're always adding loads of new things to Construct. See the new features and new additions lists - since launch there have been over 100 major new features and over 1000 additions. If you're interested in using AI-assisted coding, you can use an external editor, e.g. to use Copilot in VS Code.

  • It looks like this does the trick:

    declare global {
     var foo: number;
    }
    
    // no longer an error
    globalThis.foo = 1;
    
  • I don't know what to say - the plugin returns SteamUser()->GetSteamID().GetStaticAccountKey() (as a string to ensure a 64-bit number is preserved). If that is not right, I'm not sure what else it should be accessing, and you'd need to ask Valve what it should be doing instead.

  • alastair - that does not refer to the Steam fallback, and it's also out of date information: consistently rendering full frames is easy to do even with a browser engine, but it still doesn't work even when you do that.

  • The Steamworks plugin documentation should explain everything you need to know.

  • Please, please contact Valve as your first port of call. There is very little we can do about it. It's all their software and we comply with all their documented requirements, which pretty much just say "it should work".

    NW.js support for the overlay currently depends on hacky settings that are not officially supported, and in fact is currently broken in the latest NW.js releases. As it's not an officially supported feature, they are within their rights to say "sorry, that's not supported" and close the issue as 'won't fix'. So I really would not say that's working particularly well either and is not a reliable basis for a feature anyone cares about. If they fix it, it will basically be luck; if they don't, we're back to square one. To have robust support for the Steam overlay that consistently works, we need Valve's co-operation.

    Having said that, try WebView2 in the latest beta if you haven't already - it contains a change that may help.

    • Post link icon

    As far as we're aware it's working for everyone else. Try disabling any browser extensions you have - those can sometimes interfere with Construct.

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • Possibly, it depends on what you did. For example extracting the files on Windows and then transferring the files to macOS is known not to work, and so that might show that message.

  • But...if you have a TS block in the event sheet and make a change there, it doesn't trigger a tsc event reliably. In order for a change in a TS block in an event sheet to recompile, I had to reload the project entirely.

    Again, this seems to be working fine for me. If I change the console.log message in the provided project to "foo", preview, then change to "bar", preview, then change to "baz", and preview, every time it updates correctly. Currently Construct just compiles everything in the project on every preview, so nothing should ever be out of date. If you still think Construct has some bug with this then please file an issue following all the guidelines and in particular providing precise steps to follow that reliably demonstrate the problem.

  • It works fine for me - here's a sample project showing it working as described. As ever if you share a project we can see what you actually did which makes it much easier to help.

  • It is difficult to help when you send a full project. There could be a mistake in your events, but it's difficult to rule that out from a project with thousands of events.

    A much easier way to diagnose this is just make a new empty project, display the available status in a Text object, and export and test with that. If I do that using the app ID 480 (the "Space war" sample, just for testing) then it works fine for me. If you're using a different app ID and it doesn't work, perhaps Steam thinks your app ID is not valid - in which case you probably need to do some configuring on your end, or you need to contact Valve for support.

  • NW.js and Greenworks are both deprecated and have been removed from the latest releases. Our official advice is to use Windows WebView2 and the Steamworks addon which have continued support.

    The Steamworks addon should work out-of-the-box and I fairly regularly test it and it generally looks fine. I would guess you've done something wrong, but it's hard to tell unless you share a project. My best guess is that you should test with development mode enabled. It sounds like you had that turned off, and if you turn it off, I believe the game must have actually been published to Steam for it to work, and so if you haven't yet done that, it won't work. So use development mode until then.

  • macOS now has very specific requirements about permissions (you must extract the exported zip on macOS) and security (you must now always at least ad-hoc sign an app for it to be allowed to run). The most up-to-date advice is in our guide on the macOS WKWebView exporter, which although is for a different export option, the requirements regarding macOS running apps is the same. Construct's macOS WKWebView export option also exports some helper scripts to make this easier - if you use NW.js you'll need to do the same things manually.