Device screen refresh rate affects app runtime speed.

Welcome to our brand new Clickteam Community Hub! We hope you will enjoy using the new features, which we will be further expanding in the coming months.

A few features including Passport are unavailable initially whilst we monitor stability of the new platform, we hope to bring these online very soon. Small issues will crop up following the import from our old system, including some message formatting, translation accuracy and other things.

Thank you for your patience whilst we've worked on this and we look forward to more exciting community developments soon!

Clickteam.
  • I'm currently working on an online platform and rhythm game creation tool for mobile.

    A while ago a colleague and I noticed that the charts scrolling speeds were sightly faster when "Power saving" was disabled in the Android devices, which when enabled, makes the device screen run at 60 Hz (hence aligning properly with the app's 60 fps). When it's disabled, the screens run at higher Hz, somehow making the app run faster. The FPS remain unchanged (the app runs at 60 fps both in 60 hz and higher), but the charts somehow get faster (becoming out of sync) despite being the same FPS.

    I did look into DeltaTime, but from what I've seen it deals with the FrameRate, which is not the issue since FrameRate stays the same. Machine-Independent speed and vSync are enabled in the runtime, but they don't seem to fix this issue.

    I was thinking of correlating every chart element speed to that of the audio position with my time formula, but I'm not sure if that's going to work, since this seems to be a runtime-hardware issue.

    Any ideas of how we can get around this? Thanks

  • Machiene independent speed won't really fix it, you have to use deltatime for the game to run at the same speed on any frame rate
    I did make a guide on gamejolt for that you can check: Please login to see this link.

    Game/App developer, artist and a community contributor.
    You can support my work on: Please login to see this link.

  • Yeah, I was actually just checking out your guide! It's really well put together. Thank you for replying.

    The FrameWork I've built for the project to run the rhythm games creations is using DeltaTime. However my problem doesn't seem to be FrameRate-related. As I mentioned, the app is running at a solid 60 fps in both 60 hz refresh rate and higher refresh rates (when Power saving is disabled). The problem is that, when the screen refresh rate is higher than 60 Hz, the charts sightly speed up hence ruining the sync.

  • Yeah, I was actually just checking out your guide! It's really well put together. Thank you for replying.

    The FrameWork I've built for the project to run the rhythm games creations is using DeltaTime. However my problem doesn't seem to be FrameRate-related. As I mentioned, the app is running at a solid 60 fps in both 60 hz refresh rate and higher refresh rates (when Power saving is disabled). The problem is that, when the screen refresh rate is higher than 60 Hz, the charts sightly speed up hence ruining the sync.

    Hmm, seems like an incorrect delta time implementation because DeltaTime job is to fix this issue, note that stuff with increasing speed overtime will have problems, in the guide I explained how to fix the curve issue, same applies for things like interpolation "lerp", as it's something that changes speed overtime
    Check this video, it explains some of these stuff in detail:
    Please login to see this media element.

    Try testing on your PC and\or phone different frame rates, you can go up to 1000, I usually test 5, 10, 20, 30, 60, 90, 144, 240, 500 and 1000

    Game/App developer, artist and a community contributor.
    You can support my work on: Please login to see this link.

  • DeltaTime seems to be working fine.

    I recorded a video of it. It showcases two different runs: at 60 fps, and 20 fps.
    Please login to see this media element.
    They both run at the same speed.

    This is the code behind it:

    Code
    [ deltatime ]
    
    
    	* Always
    		Special : Set deltatime to ( ( deltaspeed / 1.0 ) / ( FrameRate / 1.0 ) ) * 60
    
    
    	* Repeat while "Right Arrow" is pressed
    		Active : Set X position to X( "Active" ) + ( 3 * Round(deltatime) )

    Again, the frameRate is always 60 fps regardless of the device's screen refresh rate. When the screen refresh rate is higher than 60 Hz, however, the chart becomes sightly faster than it is at 60 Hz. (Hz, NOT FPS. FPS IS ALWAYS 60.) Also speed is fixed, so it's always scrolling at the same speed.

  • Code
    [ deltatime ]
    
    
        * Always
            Special : Set deltatime to ( ( deltaspeed / 1.0 ) / ( FrameRate / 1.0 ) ) * 60
    
    
        * Repeat while "Right Arrow" is pressed
            Active : Set X position to X( "Active" ) + ( 3 * Round(deltatime) )

    Deltatime is not implemented correctly there, the caluclation is wrong, and you don't round deltatime in calculations, that will cause preciesion problems
    Also moving the active this way is not subpixel, so it will not move smoothly

    Do it more like this, here is a basic example:
    Please login to see this picture.

    Game/App developer, artist and a community contributor.
    You can support my work on: Please login to see this link.

    Edited once, last by Linky (July 15, 2023 at 11:16 PM).

  • DeltaTime is all about the difference between the current frame and last frame (the delta) Fusion already has a fully functional timer, and via the timer expression we can get the timer count in 1/1000 since start of frame
    So technically, Deltatime is only timer - OldTimer, then we set OldTimer to timer after we calcuate the Delta

    But we can maximize it's power by using a DtRatio value, this will act like a timescale of some sort, 16.66666 will act like a 60fps application (because 60fps is 16.66666 ms) we can change the value however we want at anytime, the best use would be for smooth slow motion effects or even pausing the game by setting it to 0
    the lower the value the faster and vice versa

    Game/App developer, artist and a community contributor.
    You can support my work on: Please login to see this link.

  • Alright I implemented your method and it seems to work fine now!

    There's a crucial detail though: "16.66666" as the deltatime ratio was too inaccurate (as dumb as it sounds), so there was always a speed difference between the deltatime'd object and a regular object running at the same speed. This might not be a big deal for most things, but since this is a framework for rhythm games, it meant that the charts would quickly lose sync.

    Setting the deltatime ratio to the maximum amount of decimals supported by the Fusion editor and ending with a 7 did the job for me. "16.66666666666667" works perfectly.

    Thank you for taking the time to answer my forum thread, It's really appreciated :)

  • Machiene independent speed won't really fix it, you have to use deltatime for the game to run at the same speed on any frame rate
    I did make a guide on gamejolt for that you can check: Please login to see this link.

    This is excellent! Thank you for the resource. I have a highly competitive game which I have been changing over to delta time as events are required to fire at the same time regardless of the frame rate. The guide and your added information really helped and I have my objects moving at the correct rate regardless of framerate.

    I have been trying to figure out the best way to replace the following events using delta_time and this is what I have come up with using the forum search as a major helpful resource! I figured I would drop this here in case it can help others out and I am also having some odd issues which I am hoping you, or others, may have some insight into. I have been trying to wrap my head around it, but for some reason it just isn't clicking for me. I just need to be pointed on the correct path.

    You can assume everything laid out in the guide linked above is the same for my project.

    The Always Event
    (This appears to work properly. Upon looking this doesn't appear like it needs to be changed as it is based on the engine timer and should always fire properly..?)

    [ EXAMPLE EVENT ]
    * Loot_HP of OBJECT >= 1
    + Always
    - Set Y position to Y( "OBJECT" ) + ( Game_DeltaTime )


    The Every Event
    (I am not sure how to do this yet as I require an event to fire randomly every 1 to 4 seconds.)

    [ EXAMPLE EVENT ]
    * Every RRandom(1000,4000)
    - PERFORM CUSTOM ACTION


    The Timer is Greater than XX"-XX Event
    (I am sure I just need to change this out to check the "timer" and fire the event once it reaches a certain number.)

    [ EXAMPLE EVENT ]
    * Timer is greater than 20"-00
    + Timer is less than 23"-00
    + Run this event once
    - PERFORM CUSTOM ACTION


    BONUS Odd Issue Event using mod
    (This is more of a question to see if anyone has some thoughts on what could be happening here. As per seeing some information on this forum, I tried replacing the Always event below with a "mod 2" against the timer value. I am new to what mod is and have limited understanding, but my assumption is that if the mod 2 = 0, on every 2nd frame my event would fire. This appears to work fine when I just run the frame of the game. Here is the Bonus odd issue! When I run the application and start on my main menu page, there are two buttons you can click at the bottom of my game. One button moves the camera to the left to a "game" section and once the camera centers here, the Game Frame is loaded. All the movements using the below "mod 2 = 0" code work completely fine and the speed is accurate. BUT if I click the other button, it moves the camera to the right to a "home" section of the main menu frame without loading a new frame. If from here you then click the "game" button, the camera moves to the left to the "game" section and once the camera centers here, the Game Frame is loaded like before, BUT this time the speeds of my objects are reduced even though the framerate, delta_time, etc. appear to be all the same. It is a mystery that has been keeping me up at night because it doesn't make sense...lol)

    [ EXAMPLE EVENT ]
    * Loot_HP of OBJECT >= 1
    + Global Value(timer mod 2) = 0
    - Set Y position to Y( "OBJECT" ) + ( Game_DeltaTime )

  • The Always Event
    (This appears to work properly. Upon looking this doesn't appear like it needs to be changed as it is based on the engine timer and should always fire properly..?)

    [ EXAMPLE EVENT ]
    * Loot_HP of OBJECT >= 1
    + Always
    - Set Y position to Y( "OBJECT" ) + ( Game_DeltaTime )


    There are 3 problems with this event:

    • The Always condition is unnecessary because Loop_HP of OBJECT value comparison condition is already checked every frame
    • Adding Deltatime to Y position? it would make more sense to add a couple a value that's multiplied by Deltatime to Y position (Like Add Spd * Deltatime to Ypos)
    • Position are integer based, you probably want "subpixel" movement (you would still move in pixels, but extra smoothness is faked to the human eye via a delay) so you probably want to use a Y\Xpos value(s) instead (Just like what I did in the first example of the guide):

      Code
      * Loot_HP of OBJECT >= 1
      - Add Spd("OBJECT") * Game_DeltaTime to Ypos of OBJECT
      - Set Y position to Ypos( "OBJECT" ) + ( Game_DeltaTime )

    The Every Event
    (I am not sure how to do this yet as I require an event to fire randomly every 1 to 4 seconds.)

    [ EXAMPLE EVENT ]
    * Every RRandom(1000,4000)
    - PERFORM CUSTOM ACTION


    No need to change anything here, it would work exactly as you expect

    The Timer is Greater than XX"-XX Event
    (I am sure I just need to change this out to check the "timer" and fire the event once it reaches a certain number.)

    [ EXAMPLE EVENT ]
    * Timer is greater than 20"-00
    + Timer is less than 23"-00
    + Run this event once
    - PERFORM CUSTOM ACTION


    This can be done in a better way, instead of comparing if the timer is greated and less than a value to do a range check, why not do it with the range expression, so basically you would compare if the timer is within a specific range, the range expression can be found in the Special system object (the gear looking one), it will ask for 3 parameters, the value you want to clamp (limit), the minimum value, and the maximum value, it would then return the clamped value, so for example, if you test for Range(7, 3, 5) it would return 5, but if you tested for Range(1, 3, 5) it would return 3, here is how you would modify your event:

    Code
    * Timer is equal to Range(Timer, 20000, 23000)
    + Run this event once
    - PERFORM CUSTOM ACTION

    BONUS Odd Issue Event using mod
    (This is more of a question to see if anyone has some thoughts on what could be happening here. As per seeing some information on this forum, I tried replacing the Always event below with a "mod 2" against the timer value. I am new to what mod is and have limited understanding, but my assumption is that if the mod 2 = 0, on every 2nd frame my event would fire. This appears to work fine when I just run the frame of the game. Here is the Bonus odd issue! When I run the application and start on my main menu page, there are two buttons you can click at the bottom of my game. One button moves the camera to the left to a "game" section and once the camera centers here, the Game Frame is loaded. All the movements using the below "mod 2 = 0" code work completely fine and the speed is accurate. BUT if I click the other button, it moves the camera to the right to a "home" section of the main menu frame without loading a new frame. If from here you then click the "game" button, the camera moves to the left to the "game" section and once the camera centers here, the Game Frame is loaded like before, BUT this time the speeds of my objects are reduced even though the framerate, delta_time, etc. appear to be all the same. It is a mystery that has been keeping me up at night because it doesn't make sense...lol)

    [ EXAMPLE EVENT ]
    * Loot_HP of OBJECT >= 1
    + Global Value(timer mod 2) = 0
    - Set Y position to Y( "OBJECT" ) + ( Game_DeltaTime )


    Sorry but I do not understand the question and how would this be related to Deltatime
    In general, mod gives you the remainder of a division, this can be used in many ways, like detecting if a number is odd or event, and doing things based intervals (Like doing something every 30 increase of a value)

    So for example, if you have coins and want to do something every 30 coin change (increase\decrease) to the total coins, you would do something like:

    Code
    * Coins mod 30 = 0
    + One action when event loops
    - Do something

    Game/App developer, artist and a community contributor.
    You can support my work on: Please login to see this link.

    Edited once, last by Linky (November 6, 2023 at 11:45 PM).

Participate now!

Don’t have an account yet? Register yourself now and be a part of our community!