0 Favourites

C2 games and 120hz monitors (*dt problem?)

  • Do you guys tried your games on 120Hz monitors?

    Some people are reporting how my game goes bananas on it, it's like "every tick" events are executed twice, even with *dt on it.

    If they switch the monitor back to 60hz, everything's fine.

    Thanks : )

    EDIT: as written below, the point of this thread is to know if I'm making something wrong or if 120hz monitors are incompatible with C2 games.

    SPOILER: As mentioned later in this thread, C2 games should work ok with 120hz, if you handle your delta time operations correctly.

    As very useful post for beginners can be found here:

  • Even if dt is used properly in all aspects?

    I once thought I was doing everything right but my game would still act different on 40fps compared to 60fps. It turned out, here and there there was somethings that should have been scripted different.

    I wish fps wasn't tied to monitor hz

  • This is my very first game with C2, so me making something wrong with DT is ***HIGHLY*** possible!

    That's why I'm asking, to know if every C2 games behave this way, or if have to work harder on some of my *dt events : )

    Streaming is causing problems on the game if perfs are too low (the usual frameskip visual issues with janks if you get <40fps), but also when the perfs are too high.

    I'm sure I can do something for case 2!

    There's this event where I never could figure how to put *dt correctly in it:

    " lerp(layoutscale,0.65,4*dt) "

    Any professor to teach me? : )

    I read the *dt guide many, many times, but I'm never sure how tu use *dt when it's not only related to X and Y. It's like the rules change for every case.

  • I've just tested CoinOp Story on a 120hz screen -> broken!

    Every timed stuff are divided by 2 : wait time, time between 2 actions...Etc

    Some events don't even launch.

    And everything is set up with DT.

    So I tried a little test with a simple object that jump every 1 second.

    On 120hz : it jumps every 1 second.

    If I set it to 60*dt, it jumps every 0.5s.

    So using DT is useful for a game under 60 fps but is an issue upper 60 fps. Am I correct ?

    We probably need a way to block the fps to 60.

  • I don't see anything wrong with the event above; you have dt in the correct place.

    I've wondered before about what would happen with C2 games on a 120hz monitor. What do you mean the game is 'going bandanas'? Is it running too fast, too slow, dropping frames?

    My understanding is that it's problematic to 'sync' frames in browser engines when the monitors refresh rate differs from the refresh rate of the game. So, TLP is probably 'ticking' 120 times per second on the 120hz screen.

    It's possible that you have some logic that should be "*dt", but isn't, and you've never noticed before since C2 goes apesh!t under ~40fps anyway, especially when GPU limted.

    Unfortunately, we just don't have a good way of doing framerate-dependant or framerate-locked games in C2; to do so you have to eschew most of the built in behaviors entirely.

    For example: CC had a setting called 'Override Delta Time' which would slow down/speed up the game when running at less/more than the intended framerate.

    This is basically what you get in C2 if you do event based movement and don't use dt; the game speed is variable, but collisions will always happen the same given identical settings.

    However, none of that applies to the built in behaviors in C2, whereas in CC it did.

  • Browsers arent designed for professional games, there no solution.

  • If you're using Chrome, it's entirely possible that this could be an artifact of the vsync non-adherence problem. Does the same happen when running on the 120 Hz monitor but in NW 10.5?

  • Construct 3

    Buy Construct 3

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

    Buy Now Construct 3 users don't see these ads
  • Ok, I've made a little trick to avoid the issue. Here is a CAPX :

    https://dl.dropboxusercontent.com/u/13847313/Scirra/DeltaTime120fps.capx

    I DON'T KNOW IF IT'S A WORKING TEMPORARY SOLUTION as I'm a completly noob about that kind of technical stuff.

    The idea is to change a simple

    'EVERY 1 SECOND' or 'EVERY 60*dt SECOND'

    by

    'EVERY (1*variable)*dt SECOND'

    We change the variable depending on the fps.

    On my example, the sprite jumps every 1 second with 60hz or 120hz.

    But perhaps my trick has downsides. I don't know.

  • Kamizoto is explaining things way better than me : )

    But yeah, basically that's it: all +60*dt events don't make any sense on 120hz. And then... game broken : /

  • Aurel

    KaMiZoTo

    Woah, you should definitely never have an event which runs as a factor of dt. The underlying Construct 2 engine uses something called "requestAnimationFrame" to attempt to peg the game tick at approximately 60 times per second, but it usually matches the display refresh rate of the browser/computer(nearly always 60hz except in the case of these new 120hz monitors).

    This means that in most cases, dt ~= 0.0167 of a second (remember that dt is the elapsed time in seconds since the previous game tick). Obviously though, cpu intensive games and other things can cause the frame-rate to fluctuate. However, on a 120hz display, dt will average ~= 0.008, since the engine will attempt to run the game tick 120 times per second. So then, setting up an event which runs every 60*dt is going to run approximately once a second on a 60hz vsync, and once every 0.5 seconds on a 120hz vsync. Obviously not good, since the game behavior will be inconsistent depending on the hardware.

    For setting up events that should run at specific times or intervals, either use the system expression "time" or events such as "Every X seconds". In this case, this event should just be "Every 1 second". For example, if you wanted to schedule a one-time event to run 5 seconds in the future, you could record a instance variable NextActionTime = time + 5. Then in the event:

    If time >= NextActionTime & Trigger Once ---> Do something here.

    You should use dt as a means of scaling movement/velocity/vectors/etc. So for example, let's say you have some Sprite1 with CustomMovement, and you want it to move approximately 100 pixels every second. Under an event:

    Every Tick (aka every game cycle): Move Sprite1 by dt*100.

    This way even if dt fluctuates because of slowdown or because of computers with different refresh rates, you are guaranteed a constant rate of movement.

  • Oh, man, yeah, 'every X seconds' should never be used with dt. It uses it internally. So you're actually checking the timer for 60 * dt * dt !

    So... The consensus is that the code should be working, assuming that dt has been used correctly everywhere?

  • You should use dt as a means of scaling movement/velocity/vectors/etc. So for example, let's say you have some Sprite1 with CustomMovement, and you want it to move approximately 100 pixels every second. Under an event:

    Every Tick (aka every game cycle): Move Sprite1 by dt*100.

    This way even if dt fluctuates because of slowdown or because of computers with different refresh rates, you are guaranteed a constant rate of movement.

    so in what situations would the "dt*100" provide inconsistencies across different framerates? I use it a lot for adding/subtracting from a variable, for things like cooldowns, is that ok?

  • alspal

    Yeah, using dt to adjust the speed at which variables are modified is great. DT is there so that by saying Add (DT*X) to SomeVar, you can make sure that it is added at a total rate of X per second.

    DT returns the elapsed time since the last game tick (basically the last time the event sheet was processed), and it usually hovers around 0.01667 on most 60hz systems (aka 1/60) because Construct 2 uses underlying v-sync related browser timing.

    So for example, if you wanted a variable Life to gradually regenerate at 20 points a second. You would say: Add DT*20 to Life. If you test your game on a 60hz refresh rate display: Every game tick, you are adding dt (~0.01667) * 20, or approximately 0.334 life points every tick, after 60 ticks or approximately 1 second, it will have added 20 points to life.

    When running same game on 120hz display rate, every game tick, you are adding dt (~0.0083) * 20, or approximately 0.166 life points every tick, and after 120 ticks or approximately 1 second, again it will consistently have added 20 points to life.

    So no matter what your frame rate is, dt allows you to maintain consistent value ratios.

    Just avoid using dt as a part of a time-dependent condition in an event, so for example, you wouldn't want to have:

    Every DT*60 seconds: Add 20 points to Life.

    On a 60hz system, dt is 0.01667, so in this case, the statement is roughly equal to: Every 1 second: Add 20 points to life.

    But testing on a 120hz system, dt is ~0.0083, so the statement is roughly equal to: Every 0.5 second: Add 20 points to life. Completely different behavior.

  • Ok, that DT stuff drive me crazy.

    I really though we should use DT each time we use a time value to secure the game behavior depending on the fps variation. But now I read that's not the case.

    Sorry to say that (and I blame nobody) but it's unclear and unintuitive. I just want to make games, not formulas for waiting 1 second depending on the fps, the frequency, the size of the sun and the weather outside.

    I have the bad feeling I will have to spend a day, changing all the time events of my game. But right now, I don't even know what to change exactly. Ho bother....I'm lost.

    What about every tick event ? Wait action ? We should not use DT too in these cases?

  • I tried changes on my boss fight. I use DT ONLY for value variations (lerp(x,y,z*dt) or every tick-> value*dt)

    It's working the same in 60hz and 120hz.

    So is it the right way to do it? Will it work the same when the game slows down too ?

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)