merge: scenario 2400 long-run parity

This commit is contained in:
2026-08-04 18:19:53 +00:00
30 changed files with 517 additions and 183 deletions
+3 -3
View File
@@ -19,9 +19,9 @@ const requireSafeTick = (tick: number): number => {
};
const tickOffsetMilliseconds = (tick: number, ticksPerSecond: number): number => {
const wholeSeconds = Math.trunc(tick / ticksPerSecond);
const wholeSeconds = Math.floor(tick / ticksPerSecond);
const remainingTicks = tick - wholeSeconds * ticksPerSecond;
const milliseconds = wholeSeconds * 1_000 + Math.round((remainingTicks * 1_000) / ticksPerSecond);
const milliseconds = wholeSeconds * 1_000 + Math.floor((remainingTicks * 1_000) / ticksPerSecond);
if (!Number.isSafeInteger(milliseconds)) {
throw new Error(`Game tick offset is outside the safe millisecond range: ${milliseconds}`);
}
@@ -119,7 +119,7 @@ export class GameClock {
const wholeSeconds = Math.trunc(milliseconds / 1_000);
const remainingMilliseconds = milliseconds - wholeSeconds * 1_000;
return requireSafeTick(
wholeSeconds * this.ticksPerSecond + Math.round((remainingMilliseconds * this.ticksPerSecond) / 1_000)
wholeSeconds * this.ticksPerSecond + Math.trunc((remainingMilliseconds * this.ticksPerSecond) / 1_000)
);
}
}
+13
View File
@@ -61,4 +61,17 @@ describe('GameClock', () => {
expect(Number.isNaN(projected.getTime())).toBe(false);
expect(clock.dateToTick(projected)).toBe(tick);
});
it('truncates sub-millisecond projections like Ref GameClock', () => {
const clock = new GameClock({
baseTime,
tick: 0,
mode: 'manual',
wallAnchor: baseTime,
turnSeconds: 600,
});
expect(clock.tickToDate(14_115_919).toISOString()).toBe('2042-01-01T00:03:55.265Z');
expect(clock.tickToDate(-1).toISOString()).toBe('2041-12-31T23:59:59.999Z');
});
});