GameTime and its Polymorphic Nature - bryanedds/Nu GitHub Wiki

Polymorphic GameTime

Out of the box, Nu is intended to run at 60 frames per second. While this has been the gold standard for games for a long time, newer games are taking advantage of higher refresh rates and even variable refresh rates on modern display devices. This is exactly why the GameTime type in Nu has a polymorphic definition -

/// Provides a variable representation of time based on whether the engine is configured to use a static or a dynamic
/// frame rate.
and [<Struct; CustomEquality; CustomComparison; TypeConverter (typeof<GameTimeConverter>)>] GameTime =
    | UpdateTime of UpdateTime : int64 // in updates
    | ClockTime of ClockTime : single // in seconds

With no specific configuration, GameTime in Nu will always use the UpdateTime representation, where each unit of measure represents 1 frame out of 60. However, you can alter your project's App.config file like so to change that static frame rate from 60 to another hard-coded value like so -

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <appSettings>
    <add key="DesiredFrameRate" value="[StaticFrameRate 30]"/>
    <add key="VirtualScalar" value="3" />
  </appSettings>
</configuration>

Be careful setting the static frame rate to higher than 60 since doing so will cause the game to run slow for display devices that don't support a refresh rate greater than 60Hz.

The nice thing about writing your game with a locked frame rate is that you don't have to scale all of your game logic by world.ClockDelta. The trade-off is that you had better try to keep a perfect frame rate on all target platforms lest your users experience gameplay slowdown.

If you want your game to operate at a variable frame rate, you can instead configure your project's App.config like so -

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <appSettings>
    <add key="DesiredFrameRate" value="[DynamicFrameRate 360]"/>
    <add key="VirtualScalar" value="3" />
  </appSettings>
</configuration>

This does several things for you -

  1. It sets a maximum frame rate of 360. You can set it to whatever you like up to 1000.
  2. It causes the GameTime type to use the ClockTime representation instead of UpdateTime. Now GameTime values act as single-precision float values rather than 64-bit ints.

The important thing to understand here is that you need to choose up front which representation of time / frame rate you want to ship your game with. This is important because changing your mind later on into the project will mean that your GameTime literals may end up with an incorrect representation.