Ashley's Recent Forum Activity

  • No, I don't think a cache is a good idea. I previously considered it to keep it compatible with WebStorage, but decided not to for two reasons:

    • performance: the speed at which you can read and write values to the actual storage is proportional to the total amount of data in storage. So suppose you had 300mb of data in storage, and your app wants to read a single number, change it, then write the number back (e.g. a simple play count). That involves reading 300mb of data, plucking out a single value, then writing 300mb of data again.
    • it's always going to be unreliable: you can't really solve the problem of how to write the cache to the actual storage. At any time the user could just close the browser, and then there is no opportunity to do an asynchronous write to storage, and the changes in the cache are lost. There aren't any good options to mitigate that. Writing storage every time it changes will completely hammer performance (imagine writing 300mb every time any key changes), and throttling it to a timer means you can still lose data (e.g. if you write every minute, you can still lose up to a minute's worth of data).

    Besides you can do this yourself already if you really want to: just store the JSON data of a dictionary object in storage - but you'll probably have subtle and frustrating issues with data being lost randomly.

    I agree "Then" is a poor name... I think I'll go with "Next" for the time being.

    Reading Animmaniac's post, I think actually it could be a good idea to make "Next" act like "All completed", so it doesn't have the one-async-action limitation. The problem is then how to access multiple storage keys, but I think it could load multiple keys at once by a comma-separated list, e.g.:

    • Get item "level1score,level2score,level3score"

    Next

    • Set level1score to LocalStorage.ItemValue("level1score")
    • Set level2score to LocalStorage.ItemValue("level2score")
    • Set level3score to LocalStorage.ItemValue("level3score")

    This could of course use three separate "Get item" actions, but I think it's clearer with a comma-separated list: there's only one trigger that fires for the one action, instead of three triggers firing and "Next" only really triggering on the third, which could make it tricky to identify which values should be available to the ItemValue expression (since it should only make available values that the trigger is firing for).

  • If you want me to take a look send your .capx over to with an overview of the problem areas/what to do and I'll take a look. I may not be able to do this for everyone since we have thousands of users, but hopefully a few real-world examples will allow me to make some engine improvements if necessary.

  • Nesteris - please only report bugs to the Bugs forum following all the guidelines and one thread per bug. If you don't want to run in to beta-related issues, stick to stable releases. By using beta releases you are opting in to this testing process.

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • An additional idea raised by talking to Kyatric:

    Have another kind of "All completed" trigger for events which start multiple async actions in one event. So if you start 5 async actions in "On start of layout", and follow it with "All completed", the next event runs when the 5 async actions in "On start of layout" have all finished.

  • I had to quit just one game because of the performance, but because I was using a lot of graphics in HD

    Lots of HD graphics is a classic case of hitting the GPU fillrate limit, which is a hardware limitation. This is exactly what I was talking about: you seem to think it's HTML5's fault and that a native engine would be faster, but it would still have the same hardware limitations. It's entirely possible this type of game would perform exactly the same in a native engine - no faster at all. This adds to my skepticism when people ask that we develop a native engine. It is not a magic bullet that makes existing hardware any better than it is.

  • I was thinking about the new Local Storage plugin and how it's a little tricker to use with the new asynchronous style of access. Previously with WebStorage you could just directly retrieve a value in an expression:

    This is really easy to use, but has the disadvantage of being synchronous, i.e. it pauses and waits for "MyValue" to be read from storage. If the system is busy or it's a large value, this could take say 100ms, and the game freezes for this time (jank).

    Local Storage solves this with asynchronous storage. You use the 'Get item' action, which then triggers 'On item get':

    Now if it takes 100ms to read, it continues running the game while reading from storage in parallel, and when finished it triggers 'On item get'. The new problem is now the reading logic is in a trigger event. This event could be far away from the action that started it (e.g. in a different sheet). It could also be inconvenient if there are multiple 'On item "MyValue" get' triggers for different purposes, and they all trigger at the same time based on this one action. This gets more complicated if you want to do something else async afterwards, e.g. set a value, which involves more triggers.

    This can be solved with good organisation, but it would be nice if we could have events that are both async and as easy as the sync version. In Javascript "Promises" go a long way to help making this easy, so I was thinking of a similar type of feature for the event system - a "Then" condition, which triggers whenever the previous event's asynchronous action finishes (mockup):

    The "Then" trigger is tightly coupled with the previous event, in the same way the "Else" event is based on the event directly preceding it rather than working by itself (and that also means there are valid and invalid places to put it). It works the same as the previous async example, but:

    • you didn't have to find the right trigger to use
    • you didn't have to type in "MyValue" again for the trigger, it knows it's triggering for that value from the previous event
    • it guarantees the thing to be done afterwards is in the next event, not somewhere far away, keeping events tidy
    • it only fires the one "Then" trigger, not every trigger of that kind in the event sheet, making it easier to use if the value is loaded for different reasons in different places
    • this might end up being a C3 feature, not sure it would make C2

    I think to make it clear the asynchronous action needs to be clearly marked - I just scrawled in a red asterisk as a placeholder representation.

    This kind of asynchronous "Then" event could be applied to all sorts of objects which already implement asynchronous features:

    • AJAX "Request URL" could be followed by "then" which is fired when the response is received, and would mean you don't need to worry about getting tags right
    • "Request user media", "Request fullscreen", "Request location" or other user-prompting actions can fire "then" after they are approved/get data
    • Pathfinding could fire "then" after the path is found
    • third party plugins could integrate with the "then" trigger
    • anything we add in future could more easily use asynchronous actions, making it easier to add parallel features that make use of multiple cores

    A few other thoughts:

    • the "Then" condition would have the caveat that you can only have a single async action in the previous event. If there were two, it wouldn't know which to fire "then" for. So in that case you'd probably have to go back to using the existing trigger system.
    • "Then" triggers could be chained. So the "Then" event could contain another async action, and be followed by another "Then" trigger, making a clear sequence of actions which run in parallel.
    • Async actions can fail, e.g. AJAX "On error", Pathfinding "Path not found" etc. I guess there would need to be a kind of error version of "Then", which could also come after the "Then" event. Javascript calls this "catch".
    • I'm not sure the name "Then" is the best name - it's the term Javascript uses, but it could confuse beginners who often want to figure out how to make an "If - then" type logic (which is basically just a normal event - "if conditions true, then run actions"). It would be especially confusing that "Then" is a trigger. Other trigger names could be "Next", "After", "On done"...

    A different idea I had was to make asynchronous actions like the "Wait" system action, except instead of just waiting, it would be processing some async action. I think this is limited though, since it makes it difficult to run asynchronous actions in parallel - if an event had 3 async actions, this method would force them to run one after the other in sequence, rather than starting them all at once and firing triggers as each completes (important for best performance and multi-core usage). So I think the "Then" event is a better idea.

    Does anyone have any thoughts about this? Good idea or bad idea? Perhaps there's an even better way it could be approached?

  • Ashley If I had the time to put 1.5 years into a game made just to demonstrate areas of slowness in C2 so you can be able to check it out then I'd really love to, but right now I don't, and I can't recreate the issues on smaller scale.

    Minimal .capxs is just for bug reports. For performance testing I will happily profile an entire project. If you can't send it over then there are a couple of options:

    • signing an NDA (this is a pain in the ass, but I will do it for special cases if say the publisher requires it)
    • just run the Chrome Javascript profiler yourself, which is what I would do with your project to examine its performance. This should show up any bottlenecks in the C2 engine. I think it also lets you export results so they can be shared, or failing that, just print screen the top results and send them over.
    • For a high-level view of event usage the C2 profiler gives a good indication of any performance bottlenecks in the events, but remember events are yours and up to you to optimise. A super fast engine will only help so much with inefficient events. I'd only use this to give some general advice on which of your events are the slowest.
  • Closing as not a bug: the Browser object 'Download' action exists to invoke the browser's 'download file' UI instead of opening the file in the window. In Crosswalk there is no browser UI (e.g. the address bar is gone, there's no downloads page, etc.) therefore this feature is not supported. You'll need to use some other feature to save the file. Perhaps we need to add a feature, but then that would be a feature request, not a bug report.

  • Closing as not a bug: IE11 does not support the Web Audio API which is necessary for positioned sounds, only basic HTML5 audio. You can test for availability of this feature using the "Advanced audio supported" condition of the Audio object.

    The good news is Project Spartan (aka IE12) already supports Web Audio, so it should be available in Microsoft's next browser.

  • I think this is because the Sprite object ignores loading the same image URL twice. If you load C:\image.png twice in a row, the second time it ignores it because it's the same path and is assumed to be the same image. This is important especially when loading images in to multiple objects, e.g. your other example with 5 sprites all loading the same image: it recognises they're all the same and only loads one texture. If it loaded it every time, it would load the image five times and use five times as much memory. So I think this "ignore the same URL" behavior needs to remain. However it means if you load C:\image.png, then copy over that file, then load it again, it still ignores it - it doesn't know it's changed. (This is the kind of thing that can happen locally but is rare on the web, images at URLs rarely change that easily.)

    There is a workaround though: load a different image in between. If you load "image.png", then load "dummyimage.png", then load "image.png", it will really load it again since the URL has changed every time.

  • Please contact for help with licenses. Closing as not a bug.

  • Thanks, should be fixed in the next beta.

Ashley's avatar

Ashley

Online Now
Early Adopter

Member since 21 May, 2007
Last online 27 Oct, 2026

Twitter
Ashley has 1,834,249 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
  • x126
    Coach One of your tutorials has over 1,000 readers
  • x74
    Educator One of your tutorials has over 10,000 readers
  • x6
    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
  • x44
    Great Comment One of your comments gets 3 upvotes
  • Email Verified

Progress

32/44
How to earn trophies

Blogs