diff --git a/apps/backend/src/app/modules/session/run/run-processor.class.ts b/apps/backend/src/app/modules/session/run/run-processor.class.ts index 2171d956f..5f59893df 100644 --- a/apps/backend/src/app/modules/session/run/run-processor.class.ts +++ b/apps/backend/src/app/modules/session/run/run-processor.class.ts @@ -4,7 +4,7 @@ import { RunValidationError, RunValidationErrorType as ErrorType, Segment, - Tickrates, + TickIntervals, TrackType, RunSplits } from '@momentum/constants'; @@ -260,7 +260,7 @@ export class RunProcessor { if (header.gamemode !== session.gamemode) throw new RunValidationError(ErrorType.BAD_META); - if (!approxEq(header.tickInterval, Tickrates.get(session.gamemode))) + if (header.tickInterval !== TickIntervals.get(session.gamemode)) throw new RunValidationError(ErrorType.OUT_OF_SYNC); const { diff --git a/libs/constants/src/index.ts b/libs/constants/src/index.ts index 9034ac4e9..677086531 100644 --- a/libs/constants/src/index.ts +++ b/libs/constants/src/index.ts @@ -25,7 +25,7 @@ export * from './enums/leaderboard-type.enum'; export * from './enums/killswitch.enum'; export * from './maps/gamemodes.map'; export * from './maps/map-credit-name.map'; -export * from './maps/tickrates.map'; +export * from './maps/tick-intervals.map'; export * from './maps/map-status-name.map'; export * from './maps/incompatible-gamemodes.map'; export * from './maps/map-status-change-rules.map'; diff --git a/libs/constants/src/maps/tick-intervals.map.ts b/libs/constants/src/maps/tick-intervals.map.ts new file mode 100644 index 000000000..a352fb31f --- /dev/null +++ b/libs/constants/src/maps/tick-intervals.map.ts @@ -0,0 +1,32 @@ +import { Gamemode } from '../enums/gamemode.enum'; +import { float } from '../types/utils/numeric.type'; + +/** + * The tick intervals (inverse of tickrate) each gamemode uses. In Source + * they're floats (32-bit), so take care to use f32 rounded values in JS. + * + * @see (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround) + * + * | Tick Rate | Tick Interval | + * |-----------|---------------| + * | 66 | 0.015 | + * | 100 | 0.01 | + * | 125 | 0.008 | + * | 128 | 0.0078125 | + */ +// prettier-ignore +export const TickIntervals: ReadonlyMap = new Map([ + [Gamemode.AHOP, Math.fround(0.015)], + [Gamemode.BHOP, Math.fround(0.01)], + [Gamemode.BHOP_HL1, Math.fround(0.004)], + [Gamemode.CLIMB_MOM, Math.fround(0.01)], + [Gamemode.CLIMB_KZT, Math.fround(0.01)], + [Gamemode.CLIMB_16, Math.fround(0.01)], + [Gamemode.CONC, Math.fround(0.01)], + [Gamemode.DEFRAG_CPM, Math.fround(0.008)], + [Gamemode.DEFRAG_VQ3, Math.fround(0.008)], + [Gamemode.DEFRAG_VTG, Math.fround(0.008)], + [Gamemode.RJ, Math.fround(0.015)], + [Gamemode.SJ, Math.fround(0.015)], + [Gamemode.SURF, Math.fround(0.015)] +]); diff --git a/libs/constants/src/maps/tickrates.map.ts b/libs/constants/src/maps/tickrates.map.ts deleted file mode 100644 index 56c620bf6..000000000 --- a/libs/constants/src/maps/tickrates.map.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Gamemode } from '../enums/gamemode.enum'; - -/** - * The tickrates each gamemode uses. May change in future when we allow surf - * 100 tick etc. 0.015 <=> 66 - * 0.01 <=> 100 - * 0.008 <=> 125 - * 0.0078125 <=> 128 - */ -// prettier-ignore -export const Tickrates: ReadonlyMap = new Map([ - [Gamemode.AHOP, 0.015], - [Gamemode.BHOP, 0.01], - [Gamemode.BHOP_HL1, 0.004], - [Gamemode.CLIMB_MOM, 0.01], - [Gamemode.CLIMB_KZT, 0.01], - [Gamemode.CLIMB_16, 0.01], - [Gamemode.CONC, 0.01], - [Gamemode.DEFRAG_CPM, 0.008], - [Gamemode.DEFRAG_VQ3, 0.008], - [Gamemode.DEFRAG_VTG, 0.008], - [Gamemode.RJ, 0.015], - [Gamemode.SJ, 0.015], - [Gamemode.SURF, 0.015] -]); diff --git a/libs/formats/replay/src/replay-reader.spec.ts b/libs/formats/replay/src/replay-reader.spec.ts index c4979782f..a71693230 100644 --- a/libs/formats/replay/src/replay-reader.spec.ts +++ b/libs/formats/replay/src/replay-reader.spec.ts @@ -25,7 +25,7 @@ describe('Replay Reader', () => { gamemode: Gamemode.BHOP, playerSteamID: 76561198039308694n, playerName: 'fingerprince', - tickInterval: expect.any(Number), + tickInterval: Math.fround(0.01), trackType: TrackType.MAIN, trackNum: 1, runTime: 30.584999316371977 @@ -33,7 +33,6 @@ describe('Replay Reader', () => { const header = readHeader(buffer); expect(header).toEqual(expectedHeader); - expect(header.tickInterval).toBeCloseTo(0.01, 5); }); it('should throw ReplayReadError on invalid buffer', () => { diff --git a/libs/test-utils/src/utils/run-tester.util.ts b/libs/test-utils/src/utils/run-tester.util.ts index 10520031a..301a2eb17 100644 --- a/libs/test-utils/src/utils/run-tester.util.ts +++ b/libs/test-utils/src/utils/run-tester.util.ts @@ -2,7 +2,7 @@ import { Gamemode, RunSplits, - Tickrates, + TickIntervals, TrackType } from '@momentum/constants'; import { sleep } from '@momentum/util-fn'; @@ -207,7 +207,7 @@ export class RunTester { mapName: this.props.mapName, mapHash: this.props.mapHash, gamemode: this.props.gamemode, - tickInterval: Tickrates.get(this.props.gamemode), + tickInterval: TickIntervals.get(this.props.gamemode), playerSteamID: this.props.steamID, playerName: this.props.playerName, trackType: this.props.trackType,