I've inherited a code base in which everything is coded to run at 30 FPS and uses integers.
I would like to upgrade the frame rate to 60 FPS, naturally I thought about using floats but it ain't that easy to do so. I created a git branch and tried to port what appeared to made sense to use float but it ended up catastrophic, things would fly everywhere on the screen, presumably because of rounding issues...
Then I considered why simply not keeping integers as that would be simpler but also not introduce subtle bugs that will be hard to track.
This is an example of how the code is, many things are updated against frame rate ratios:
playerShip.ThrustMagnitude += Timing.Instance.FR15 + 1;
I came up with the following which works well in some cases but not all:
playerShip.ThrustMagnitude += Timing.Scale(Timing.Instance.FR15 + 1, deltaTime);
The helper class in its entirety:
public sealed class Timing : Singleton<Timing>
{
public static double OriginalFrameRate { get; } = 1.0d / 30.0d;
public int FR6 { get; } = 6;
public int FR7 { get; } = 7;
public int FR10 { get; } = 10;
public int FR15 { get; } = 15;
public int FR30 { get; } = 30;
public int FR32 { get; } = 32;
public int FR40 { get; } = 40;
public int FR50 { get; } = 50;
public int FR60 { get; } = 60;
public static int Scale(int value, double deltaTime, int? decimals = null, MidpointRounding? rounding = null)
{
var result = deltaTime / OriginalFrameRate * value;
if (decimals.HasValue)
{
var digits = decimals.Value;
if (rounding.HasValue)
{
result = Math.Round(result, digits, rounding.Value);
}
else
{
result = Math.Round(result, digits);
}
}
return (int)result;
}
}
The main problem I have is that it doesn't work when values are very small, yaw and roll for instance work well because they have large values, but the pitch for instance does not because its range is very small.
Say you have a value of 30 at 30 FPS, X / 30 == 1
, but at 60 FPS it results in X / 60 == 0
.
What approach can you suggest to tackle this problem?