User:Bitmode/Framerate

From Hearts of Iron 4 Wiki
Jump to navigation Jump to search

Why do I only get 30 fps on speed 5 despite having X GPU and Y CPU?

Although some specific tasks get offloaded to worker threads, hoi4 essentially runs on a single core. It cannot render a frame and advance the in-game clock to the next hour simultaneously.

With this in mind, there are three main ways how frame rendering is interleaved with game calculations (my short-hand names in parenthesis):

  • a game hour just finished simulating, render a frame to show the new state (state rendering)
  • the next game hour is not yet scheduled to be simulated, render frames at will (idle rendering)
  • at a few dozen points during the simulation, frames can be rendered as necessary (frame smoothing)

The game attempts to advance to the next hour in these intervals (NGame.GAME_SPEED_SECONDS):

  • speed 1: 2 seconds
  • speed 2: 0.5 seconds
  • speed 3: 0.2 seconds
  • speed 4: 0.1 seconds
  • speed 5: 0.0 seconds

In the early game or at low speeds, the CPU will usually be idle, leading to the desired frame rate through idle rendering. But no matter how fast your machine is, on speed 5 the next game hour is always scheduled immediately. There is never any idle rendering. At least starting in the mid-game, your CPU will not be able to run 60 (or whichever many fps you want) game hours in one second, so state rendering alone will not achieve the target fps either.

Which leads to the third category, frame smoothing. It uses the following target frame times (hard-coded):

  • paused, speed 1 & 2: 16.6 ms (60fps)
  • speed 3 & 4: 33.3 ms (30 fps)
  • speed 5: 50 ms (20 fps)

So although frame smoothing is able to render up to several dozen additional frames during one simulation, it will only do so to the extent of achieving these lower frame rates. For comparison purposes, frame smoothing can be toggled on/off with the console command debug_smooth.

It may be possible to change the frame smoothing times using a cheat engine (gGameSpeedRenderInterval, 6 32-bit floats).