Ashley's Forum Posts

  • For many use cases it's important to run even if the event is no longer true. For example:

    + On pressed spacebar

    -> Shoot a laser

    -> Wait 0.5 seconds

    -> Shoot a laser

    In this case the user wants a "double shot" every time the player presses space. Space may not be down for the second shot but it still definitely should run the action. In fact it doesn't make sense to ask if a trigger is still true after the event has fired, because triggers are one-off events.

    You could just wait then call a function which checks if the condition is still true, so you can have it both ways.

  • The first thing you should check is what Chrome says at chrome://gpu.

  • Check chrome://gpu in the Chrome browser on the device. The most common performance problem is buggy GPU drivers forcing the browser to use software rendering. The chrome://gpu page will tell you if it's actually using hardware acceleration.

  • If there's a problem please file a bug report following all the guidelines.

  • The SID should be unique for every action to guarantee the savegame feature works correctly. (I think it's used in a couple of other places too but can't remember right now)

    You should do everything from C2, since it's easy to corrupt your project by not updating the XML correctly! In theory event sheet includes are meant to prevent you ever having to copy-paste events repeatedly...

  • Take a look at one of the built-in webcam examples.

  • It's possible, yes - spritesheeting can in some cases change the scaling quality after export. It's worth testing both preview and export to compare the results, it might only be an issue in preview mode.

    FWIW, C3 will use spritesheets in preview mode as well so you won't have this problem of preview sometimes looking slightly different to export.

  • The idea is that the logic should run at a constant rate, while the rendering is a separate process that interpolates or extrapolates the logic steps to match any framerate the display uses.

    Extrapolation is off the cards, because the engine cannot predict the future. I think that only works for certain games which have very predictable movement and can make that assumption. It would result in objects doing things like going inside solids for one tick instead of bouncing off because it extrapolated incorrectly. Also fast, rapidly turning objects using extrapolation tend to get a weird floaty feel to them as they move around in a pattern which is not exactly on their true path (one of your graphs basically shows this). I don't think a technique like that can work in a general-purpose engine.

    The big problem with interpolation is the latency, which you tried to downplay but I think will be a significant problem. As you say the engine needs to know the next point along to do the interpolation math, so you need to deliberately delay rendering by the logic time step. Suppose logic is running at 30 Hz (33ms step). Unfortunately hardware timers and OS scheduling is not perfect, so there will be some jitter in that. So in practice the engine would need to increase that to say 40ms.

    There are two problems with this:

    1) 40ms is a lot of delay, close to the 50ms perception of "instantaneous". I don't know how this compares to the total system latency, but usually users can tell for every extra frame of latency added in. People already notice that there is 1-2 frames of latency on objects following the mouse, and I am pretty sure adding as much as 40ms artificial latency will be a significant, noticeable amount of extra input delay in games.

    2) how do you know the system *really* will both schedule and complete a logic step in 40ms? There are several sources of error in the hardware timers, OS thread scheduling, and variations in the actual amount of work that has to be done every tick. If one time it takes 41ms, you're missing a step so you can't interpolate anywhere, so without extrapolation you basically can't render a new frame. So this actually adds a new source of jank: occasional cases where a new step is not ready, forcing rendering to skip a frame. There is a nasty tradeoff here between reducing latency but making it risky you miss frames, vs. increasing the latency but making it more likely you always hit a frame.

    Alternatively you can run logic faster than the display rate, but again this comes at a very high CPU cost to gain any actual benefits from that.

    There is one more problem with interpolation. Object's positions can change multiple times within the same tick. So to remember where everything was the last frame, the engine will have to complete a tick, then go through every object and remember its finishing position for the next tick. This adds O(n) CPU work to track all moving objects. For games with a lot of moving objects this could be a significant overhead.

    So from this I think I can add a couple more benefits to the existing variable-step/v-sync approach:

    • does not add any extra input delay
    • guarantees a new logic step is ready in advance of every rendered frame
    • does not add any extra CPU overhead for tracking interpolation

    Just to clarify, I don't claim that the existing variable-step system is perfect, and there may well be some games that can or do use some of those techniques and have it work well. But I think being an actual engine developer gives me a unique perspective. Through some of the bug reports I've seen I know people routinely take the engine to the absolute limits and do completely crazy things. Ideas like extrapolation are interesting, but from this kind of experience, I *know* there are some cases that will just be totally broken by it. I feel the approach we have to take is to choose things which generally work OK everywhere over things that optimise for certain types of game but make others worse.

  • It's probably something to do with mipmapping. You could try setting the downscaling quality to low in project properties.

    • Post link icon

    We're not allowed to distribute any Steam SDK files.

  • Well, if you want unhackable software, it's not possible!

    We basically bundle the game data with NW.js and that's it. If you make actual suggestions of changes, I could perhaps evaluate them.

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • I think there's an interesting analogy with fan games. Some people (quite possibly a non-overlapping section of users to those posting here) like to make their own versions of Mario, Sonic, etc. and end up using ripped sprites. Firstly even these big companies can't stop people getting hold of artwork and such, even if they originate from cartridge-based systems. People find ways to rip it, or they just take them off screenshots, promotional imagery, or whatever they can find. Secondly they sometimes get upset when these big companies send them cease-and-desists, sometimes trying to frame it as "just trying to have some fun" (note these companies usually have a legal obligation to defend their work in order to keep their trademarks and such). Ultimately I think the same process will occur with your own games, you're just an indie dev instead of a megacorp.

  • calebbennetts - sure.

    Animmaniac - I really am not very persuaded by other time stepping algorithms. Sure, someone wrote a blog post saying "this is the best way to do it!" but that doesn't mean I agree. The way I see it is you either end up stepping more than the rendered framerate, which means you're burning CPU simulating stuff that isn't displayed, or you step less than the rendered framerate, which means there's nothing new to draw at the next rendered frame.

    Also people are very sensitive to jank/juddering/uneven movement. If the logic is running at a different rate to the rendering, the motion becomes uneven. For example logic at 45 Hz with rendering at 60 Hz means every rendered frame shows alternating step distances, e.g. 10px, 15px, 10px, 15px... given how sensitive people are to this (particularly when scrolling), I think the only solution would be to go for an integer multiple/divisor of the framerate to guarantee every rendered step moves the same distance. E.g. logic at 2x, 3x, or 1/2, 1/3.

    This means then that if you want faster logic than the display rate, it will have to go at least twice as fast, to 120Hz. This also means if your current CPU usage is 60%, you don't have enough overhead to do that, and your game will start lagging. It also will use more battery, make phones hotter, and significantly lower your headroom to do interesting stuff with the CPU.

    If you want slower logic than the display rate, it'd probably have to be 30 Hz. What I don't really get about this is if you only step the game at 30 Hz, there is nothing new to draw in between logic frames. I think some devs propose a "lite" step in between which just advances motion without doing anything else, but this worsens tunnelling problems (new scenario: object actually seen colliding, but no collision registered!), and could still use a bunch of CPU e.g. if it's a large physics game. Also, to reliably schedule at half-display-rate we need browser support.

    Finally the really obvious problem with fixed timesteps is systems which have different display rates. VR is making rates like 90 Hz more common, with plans to make it even higher. Gaming displays that run at 120Hz have already existed for a while. Variable-rate gaming displays like G-sync are now available too. Maybe Apple or Samsung will decide their next big differentiator is to run their next phone at 120Hz to make everything even smoother. It's naive to think everyone runs 60 Hz and will always do so, and then if you only run logic at an integer multiple/divisor, there is no solution - you can't choose a logic rate that covers all these display rates with smooth motion. And don't forget on weak systems fixed-step games go in to slo-mo instead of stepping further to compensate.

    So IMO the existing approach of variable steps has a lot of benefits:

    • with accurate v-sync, motion is perfectly smooth
    • all display rates are accommodated equally (which is also good future-proofing)
    • CPU usage is matched to the framerate and is no higher than necessary
    • slowdowns on weak systems are compensated for

    The downsides include tunnelling with large steps, but this can be mitigated in the main cases, e.g. the bullet behavior in Classic had a special stepping feature specifically to solve that problem, which I always intended to (but never quite got round to) port to C2, or there could be a stepping behavior to handle it. Then this CPU-intensive stepping only applies to things that really need it, rather than the whole game globally.

    The other downside is non-deterministic gameplay. To some extent we can improve this with better maths, as this thread shows. However I've always thought of this like floating point rounding errors: the calculations are never going to be exactly correct, so you always build in a tolerance instead of expecting exact answers. For example even with fixed steps, you can never assume your platform behavior will land at Y = 100, because floating point errors (literally occurring in the CPU circuitry) mean it will probably land at something more like Y = 99.9999999978. Given you need this kind of tolerant approach for that, I always thought this was wise to apply to motion as well, doubly so for the errors in time step. So instead of expecting the player to make a jump within 0.1px, make sure it works with say a 2px threshold (assuming we fix the math), and so on. There are ways to work around other problems as well, for example a record/replay feature could simply record the sequence of actual measured delta-times, and replay them for the purposes of making a deterministic replay.

    So my focus has always been on variable timestep, and then add features to help work around tunnelling and non-determinism if they pose a problem. So my approach for C3 is to add some of those mentioned features. The way I see it, changing the way the stepping works itself has worse downsides.

  • As pointed out, if someone wants to steal content from your game, removing devtools won't help stop them.

    TBH the most effective protection against people stealing your work is copyright law. Whatever technical measures you put in place can be circumvented: if your game can read it, so can anyone trying to steal it. Everything else is just security through obscurity, and anyone who knows anything at all about security knows that's not much security at all.

    Further, adding security can have serious side-effects for legitimate customers as well. Suppose you decide to encrypt all your game's assets. If your game is 500mb big, then on startup it has 500mb of content to decrypt, which could take a while on some systems. So now all your customers - including those who have paid - have a worse experience because you're paranoid someone's going to steal stuff. And they still can - there are tools which can pull the decrypted assets directly out of RAM. So the whole thing is kind of pointless.

  • If you try to sell other people's work on the Scirra Store, you can expect your seller account to be revoked.