Ashley's Forum Posts

  • I think this feature is simply currently missing in the 0.13 branch (they're still alphas). Closing, this should be fixed by future NW.js updates.

  • Can't reproduce in alpha 7. Closing, please file a new report with a .capx if you still have trouble.

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • Closing, please follow the bug report guidelines.

  • This should be fixed in alpha 7, I think it's just the 0.13 branch catching up with 0.12 features.

  • > - fail the expression evaluation, cancel the action/condition, cancel the event, and log some kind of diagnostic error somewhere. However this can leave events in a half-run state which can leave the game in an unexpected state. This is also different to how the vast majority of events work: you never need to look up diagnostics to see why something isn't working.

    >

    This is already what happens if you do it the current way, by picking objects sequentially using the "object UID exists" and "pick by unique ID" conditions.

    I don't think it's the same: it's obvious looking at a condition that it might not run if the condition is not met. It's a lot less obvious that an event could bail out half-way through evaluation of an expression, which is more of a "gotcha" type surprise. It's also easy to add an "else" to the "pick by UID" condition to handle the error case.

    [quote:4doavahe]Make the "pointer" static-typed: you have to specify what type of object the pointer can point to. Issue solved.

    It's not quite that simple. People often want to refactor projects later on, and as soon as there is a single expression reference depending on some aspect of the pointed-to type, it now can't easily be changed to anything else. It's the same reason you can't take a number instance variable and change it to be a string when there are already events referencing it. Once you have "object.pointer.turret.fireRate", the "pointer" variable of "object" can no longer be changed to anything apart from other objects with a "turret" behavior, otherwise the expression would become invalid. Various extra tools can help with this, but it could end up a bit of a straitjacket for event refactoring, and the extra tools to help replace things become very complicated in order to ensure the integrity of the project is maintained regardless of which changes are made. For example it's not enough that "otherobject.turret" is a valid expression, since "turret" could be the name of an instance variable, so even though the "turret" name exists on "otherobject" the expression "otherobject.turret.fireRate" is a syntax error.

    I'm not saying it's a bad idea - it's probably actually quite a good idea. My main point is it's easy to throw out a suggestion like "let me type object.variable.turret.fireRate", but if you follow all the implications of that, it also ends up with non-obvious complicated consequences like writing special refactoring tools which can inspect the existing set of expression references to a pointer-variable across a project and only let you choose compatible choices when swapping the type of pointer, which maintains the validity of events but is itself restricting of the flexibility in the ability to easily refactor a project. That kind of thing turns otherwise simple suggestions in to a major project which will consume considerable development time and probably have a range of nasty bugs involved (I dread to think of the cases that come up when you start to copy-paste pointer-variable references to a different project). UIDs on the other hand are pretty straightforward, and although they may not be as concise, they work nicely within the existing event system. So I think it's worth trying to think of alternative suggestions still based around UIDs, so we can try and get basically the same usability result, but without having such major consequences.

    That's also a microcosm of all feature suggestions in general. This is another factor in having users vote on suggestions: it's easy to vote up cool and easy sounding suggestions, but few users appreciate the true scope of the consequences for the code base, development time, future maintainability etc. If I sound like I'm fighting back, I'm only trying to find the path of least resistance to get the end result you want, which can sometimes look quite different to the original suggestion.

  • Not yet, but I believe both Apple and Microsoft are working on WebRTC support for future releases.

  • 3)Last but not least Ive reverted back to AERO theme instread of classic, because from what I read only AERO supports vsync for tearing.

    I think that was the real problem. I think on modern versions of Windows the desktop window manager (DWM) doesn't run in "Classic" mode, and modern browsers need DWM for hardware acceleration and v-sync.

  • For game performance: Performance tips

    For memory usage: Memory usage

  • I guess it's a missing feature. But because you can use any dynamic expression, it can't guarantee that 100% of references will be updated. For example if you reference

    "Layer" & Sprite.LayerNumber

    then rename "Layer0" to "Main0", it can't update the reference to "Layer" there.

    • Post link icon

    Closing this thread. Posting to just get rep will get you banned, and you'll lose any rep you gained.

  • It's up to the OS and browser engine to support gamepads. Last I checked a wired Xbox 360 controller worked fine with an Android 4.4 phone. If a particular gamepad doesn't work, it's probably because the OS needs a driver for it.

  • So you just implement up to 3 retries for loading the image?

    Even if that works, it's a classic band-aid solution: the root problem is still there, and there's no reason to think there won't be three or more failures for image loading which will have the same consequence, so it seems dubious...

  • How about a "Digg" style page somewhere on Scirra.com that we can use to post these feature suggestions and "sales pitches" and then let others vote them up/down to build a C3 feature list?

    Yeah, that worked out pretty badly for multiplayer. If the vote counts had been representative, most users would be using multiplayer. From what I can tell, it's just a small minority. So I think that shows that large numbers of users - even a majority of those participating in the vote - will vote up features that sound cool even without actually ever using it.

    I already know if we did that, even with rep limits/controls/weighting, the top requests will probably be "make Construct 3D" (probably with people saying things like "it's only one extra dimension, how hard can it be?!?!"), "make native exporters", and maybe something else like "add support for scripting". These all have serious technical, business, marketing and user experience implications. For example "Construct 3D" is basically an entirely different product which few people will be able to take full advantage of and IMO is kind of a crazy idea, but predictably will be super popular in any kind of vote. Then if that's the highest voted feature and we quite reasonably decide not to act on it, now it's fodder for the trolls: "look, Scirra ignore their users, they don't care what we think".

    Call the expression players[0].character.turret.fireRate directly

    It's a nice idea and it does look useful. But if you think it through it becomes a lot more complicated with further-reaching implications than you appear to have considered. This makes it far from a straightforward suggestion.

    Take the "players[0].character" part of the expression, which appears to refer to a "character" instance variable designed to store an object reference. Suppose the object reference is empty, or was destroyed or is otherwise no longer valid. Now the "players[0].character.turret" part cannot be evaluated. Now there are two reasonable ways to handle this:

    • fail the expression evaluation, cancel the action/condition, cancel the event, and log some kind of diagnostic error somewhere. However this can leave events in a half-run state which can leave the game in an unexpected state. This is also different to how the vast majority of events work: you never need to look up diagnostics to see why something isn't working.
    • return a dummy value like 0. Even this is surprisingly complicated. The event system doesn't necessarily know what the return value of "players[0].character.turret.fireRate" was meant to be, especially since no object exists at the time of the error. E.g. was it meant to be a string or a number? It could always return 0, but then if it was meant to be a string now you can end up with unexpected results since something which is normally a string is suddenly returning a number. If you then later extend this with array types and try to chain expressions like "players[0].character.someArrayValue[0].turret.fireRate", now you might end up returning 0 and then trying to access it as an array (i.e. equivalent to 0[0]), which starts to get even more gnarly a problem.

    There's also the problem of validating expressions. Right now a strong point of the event system is it is near enough impossible to enter invalid events. However if you type in "players[0].character.", what should autocomplete show and what should the expression validator consider valid tokens to follow it? At edit-time, the editor does not necessarily know what type of object the reference could be pointing to. So should it just dump a list of every behavior and instance variable name in the entire project after it? Is that useful to the user? What if you pick a behavior that does exist in the project, but at runtime the object instance you get does not have that particular behavior? Even if a bunch of clever workarounds were deployed to dodge all these difficult questions, would the end result be something that is still easy, intuitive and useful, or would it just be a minefield of nasty gotchas for large projects?

    This is a good example of how as a user it can be difficult to grasp the full extent of what is an apparently straightforward suggestion. It can lead down a rabbit hole of awkward bugs, difficult-to-explain features, gotchas, and make it more difficult to add more features later on.

    A little-used feature of the expression system is you can refer to currently picked object instances by index with:

    Sprite(1).X

    This already works, and reads the X value of the *second* picked Sprite instead of the default first. However this is not always useful since you don't necessarily know which instances are picked or in which order. Perhaps a similar feature that picks by UID and *ignores picking* (so you can always get any instance) would be better, e.g.:

    Sprite[1].X

    would pick the Sprite instance with UID 1 and then get its X position. This is a lot easier to implement and avoids many difficult cases above, but still has some gotchas.

  • zenox98 - can you file a new report to remind me to look at that case? This report is already closed.

  • Yeah, I'd be curious to know what you changed and if we can incorporate it in to an official solution.