Quick answer: If the game runs twice as fast on a 144 Hz or 240 Hz monitor, some part of it advances “per frame” instead of “per second”. Multiply every per-frame change by the frame’s delta time, move physics and gameplay rules onto a fixed timestep, and stop counting frames in timers and animations. Then test with the frame rate capped at 30 and uncapped at 240 and compare. Players can work around it by capping the frame rate, which is also how you confirm the diagnosis.

This bug is invisible on the machine you built the game on. Your monitor runs at 60 Hz, VSync is on, so one frame equals one sixtieth of a second and everything that moves “five units per frame” moves at a sensible speed. A player with a 144 Hz display gets a game at 2.4x speed: enemies that cannot be dodged, a day-night cycle that lasts a minute, a jump that barely leaves the ground. It is one of the oldest bugs in PC gaming and it still ships every week. Here is how to find it in each engine and fix it for good.

What players report

“The game runs at double speed.” “Everything is too fast on my monitor.” “Jumping is broken.” “The timer counts down in half the time.” Occasionally the opposite: on a laptop that only manages 40 fps, the game feels slow and heavy. The common thread is that the speed of the game depends on the speed of the display, and the player’s display is not yours.

What causes it

  1. Per-frame movement with no delta time. position += speed in a function that runs once per rendered frame. At 60 fps that is 60 steps a second; at 144 fps it is 144.
  2. Physics or gameplay rules in the render loop. Applying forces, checking cooldowns or ticking a state machine in the per-frame update instead of the engine’s fixed-rate update.
  3. Frame counting. A timer that waits 120 frames for “two seconds”, an animation that advances one sprite per frame, a tween that steps a fixed amount per update.
  4. Assuming VSync is on. Many players disable it or use variable refresh rate, so even a “60 Hz” monitor can deliver hundreds of frames a second.
  5. Mixing fixed and variable correctly in code but not in the engine settings, such as a physics tick rate that was raised to match a developer’s monitor.

How to reproduce it on your own PC

You do not need a 240 Hz monitor. Turn VSync off and cap the frame rate from code or a console, run the same section at 30 and at 240, and time something with a stopwatch: a jump arc, a countdown, how far a character walks in ten seconds. If the numbers differ, you have found it. The engine switches are Application.targetFrameRate and QualitySettings.vSyncCount in Unity, Engine.max_fps and the V-Sync Mode project setting in Godot, the t.MaxFPS console variable in Unreal, and game_set_speed or the Game frames per second option in GameMaker. Make the test part of your release checklist; it takes two minutes and the bug is very easy to reintroduce.

Fix in Unity

Anything in Update() that changes a value over time is multiplied by Time.deltaTime; anything that touches a Rigidbody goes in FixedUpdate(), which Unity runs at the fixed timestep in Project Settings > Time regardless of frame rate:

void Update()
{
    transform.position += move * speed * Time.deltaTime;   // units per second
}

void FixedUpdate()
{
    rb.AddForce(thrust);   // runs at Time.fixedDeltaTime, same on every PC
}

Replace frame-counting timers with Time.time comparisons or coroutines using WaitForSeconds. Animator and most tween libraries are time-based already; a hand-rolled frame++ sprite animation is not. Leave Time.fixedDeltaTime at its default unless you have measured a reason to change it, and if a stutter made someone set vSyncCount to 1 as a “fix”, know that it was hiding this bug rather than solving it.

Fix in Godot

Godot hands you the frame time directly. Use the delta argument in _process and keep physics and gameplay rules in _physics_process, which runs at Physics Ticks per Second (60 by default) no matter how fast the screen refreshes:

func _process(delta: float) -> void:
    position += direction * speed * delta

func _physics_process(delta: float) -> void:
    velocity.y += gravity * delta
    move_and_slide()

Timers should be Timer nodes or await get_tree().create_timer(2.0).timeout, never a counter you increment in _process. Tweens made with create_tween() are time-based. If the project’s Max FPS was set to 60 to hide this problem, set it back to 0 after the fix; it also caps players who paid for a faster display.

Fix in Unreal Engine

Multiply by DeltaSeconds (the Delta Seconds pin on Event Tick) for anything you move or accumulate in Tick. Use SetTimer / Set Timer by Event, Delay nodes and Timelines for anything that waits, as they are all time-based. The usual Unreal-specific trap is a Blueprint that increments an integer on every Tick to count frames, or a loop in Tick that adds a constant to a float. The Character Movement Component and physics simulation already handle this correctly; it is your own Tick code that does not. If someone enabled Use Fixed Frame Rate in Project Settings to make the problem go away, disable it and fix the code instead, because that setting does not stop the game from running faster when the real frame rate exceeds it.

Fix in GameMaker

GameMaker’s Step event runs at the room speed, not the monitor refresh rate, so a GameMaker game set to 60 fps does not usually speed up on a 144 Hz display. It does when the game speed was raised, or when an object uses delta_time for some things and frame counts for others. Pick one approach and apply it everywhere: either keep the fixed game speed and accept that everything ticks 60 times a second, or scale every per-step change by delta_time / 1000000 and raise the game speed to match high refresh displays. Alarms and image_speed count steps, so a mixed approach makes animations and cooldowns drift against movement.

What to tell players meanwhile

Until the patch is out, players can cap the frame rate to 60 in their GPU driver (NVIDIA Control Panel Max Frame Rate, AMD Radeon Chill), turn VSync on and set the desktop refresh rate to 60 Hz for the game, or use the game’s own frame cap if you expose one. Say plainly that the fix is coming; players are more forgiving of a known, dated bug than of a mystery.

Catching the cases you did not find

The sweep above fixes the code paths you remember. The one you forget is in a cutscene, a boss you rarely reach or a minigame, and the player who hits it does not know which refresh rate they are on. Bugnet’s Unity, Godot and Unreal SDKs attach the display and hardware details to every report, so a cluster of “too fast” reports with a 144 Hz or 165 Hz monitor in common shows up as one grouped issue instead of a dozen confusing comments. That is usually how the last frame-dependent timer gets found.

Frequently asked questions

Why does my game run faster on a 144 Hz monitor?

Some code advances the game by a fixed amount every rendered frame. At 144 frames per second that code runs 2.4 times as often as at 60, so the game moves 2.4 times as fast. Scaling those changes by the frame’s delta time, or moving them to a fixed-rate update, makes speed independent of the display.

How do I test for frame-rate dependence without a high refresh monitor?

Disable VSync and cap the frame rate in code or the console at 30, then at 240, and time the same action with a stopwatch in both runs. Any difference means something is tied to frame rate.

Should physics use delta time or a fixed timestep?

A fixed timestep. Unity’s FixedUpdate, Godot’s _physics_process and Unreal’s physics simulation all run at a constant rate, which keeps collisions and forces identical on every machine. Variable delta time is for visual movement, camera motion and anything that only needs to look smooth.

Can players fix a game that runs too fast on their monitor?

As a workaround, yes: capping the frame rate to 60 in the GPU driver or enabling VSync at a 60 Hz refresh rate slows the game back to the speed it was built at. The real fix is in the game’s code.

Run the game once with the frame rate capped at 30 and once uncapped before every release. If a jump lands in a different place, you are not done.