Skip to content

Commit

Permalink
Fix GameConditionManager.MapBrightnessTracker (Unnatural Darkness) de…
Browse files Browse the repository at this point in the history
…syncs (#453)

GameConditionManager.MapBrightnessTracker:Tick uses Time.deltaTime, the value of which will be different between the players. With similar FPS they'll be very close to one another, but if there's a big change between FPS values (for example, 60 and 144) the issue will be much bigger.

The issue with MapBrightnessTracker is the map will get darker at a different rate for each player - in one of my tests, the client finished the transition 10 ticks faster than the host.

The fix here is rather simple - replace `deltaTime` with a constant value of `1 / 60` or `0.166666...` to ensure each 60 ticks in-game will be treated as a second, no matter the game speed.
  • Loading branch information
SokyranTheDragon authored May 24, 2024
1 parent c80de56 commit d980e3b
Showing 1 changed file with 33 additions and 0 deletions.
33 changes: 33 additions & 0 deletions Source/Client/Patches/Determinism.cs
Original file line number Diff line number Diff line change
Expand Up @@ -491,4 +491,37 @@ private static int NewCacheTicks(int gameTick)
}
}

[HarmonyPatch(typeof(GameConditionManager.MapBrightnessTracker), nameof(GameConditionManager.MapBrightnessTracker.Tick))]
static class MapBrightnessLerpPatch
{
static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instr)
{
var patchCount = 0;

// The method is using delta time for darkness changes,
// which is not good for MP since it's tied to the FPS.
var target = AccessTools.DeclaredPropertyGetter(typeof(Time), nameof(Time.deltaTime));

foreach (var ci in instr)
{
if (ci.Calls(target))
{
// Replace deltaTime with a constant value.
// We use 1/60 since 1 second at speed 1 the deltaTime
// should (in perfect situation) be 60 ticks.
ci.opcode = OpCodes.Ldc_R4;
ci.operand = 1f / 60f;

patchCount++;
}

yield return ci;
}

const int expectedPatches = 1;
if (patchCount != expectedPatches)
Log.Error($"Replaced an incorrect amount of Time.deltaTime calls for GameConditionManager.MapBrightnessTracker:Tick (expected: {expectedPatches}, patched: {patchCount}). Was the original method changed?");
}
}

}

0 comments on commit d980e3b

Please sign in to comment.