Ashley's Forum Posts

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

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

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • 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.

  • I can't reproduce either problem. It works correctly here with the latest NW.js (0.12.0).

    Please only report one issue per post BTW, otherwise it can get very confusing what the status of the report is.

  • Thanks, should be fixed in the next build.

  • Thanks, should be fixed in the next beta.

  • Original .capx link is 404 now, so I can't investigate this bug report any further. Closing, will reopen if new link provided.

  • "Trigger once" is a short name for "run if the event is true this tick but was false last tick". That only applies to normal evaluated events which are tested every tick. Triggers and events like 'On collision' aren't evaluated every tick, they just fire whenever something happens, so "trigger once" does not apply to them.