diff --git a/game/game.js b/game/game.js index 8fd70dc..3f89bd9 100644 --- a/game/game.js +++ b/game/game.js @@ -19669,7 +19669,7 @@ var version = "v1.18.1"; } } const loopingSpriteSheet = makeSprite({ - render({ props: e }) { + render({ props: e, fps }) { const t = ja(e.frameRate, e.rows, e.columns, e.maxIndex); return [ spriteSheetPrimitive( @@ -19683,29 +19683,29 @@ var version = "v1.18.1"; }, (a) => { const i = e.frame % (t + 1); - a.index = Math.floor(i / e.frameRate); + a.index = Math.floor(i / (e.frameRate)); }, ), ]; }, }), triggerableSpriteSheet = makeSprite({ - init({ props: e }) { - const t = ja(e.frameRate, e.rows, e.columns, e.maxIndex); + init({ props: e, fps }) { + const t = ja(e.frameRate, e.rows, e.columns, e.maxIndex) / fps; return { - frame: Math.min(e.startFrame || 0, t - 1), + frame: Math.min((e.startFrame) || 0, t - 1) / fps, maxFrame: ja(e.frameRate, e.rows, e.columns, e.maxIndex), }; }, - loop({ state: e, props: t }) { + loop({ state: e, props: t, fps }) { t.paused || - e.frame === e.maxFrame - 1 || - (e.frame === e.maxFrame - 2 && t.onEnd && t.onEnd(), - (e.frame += t.df)); + e.frame >= e.maxFrame - 1 / fps || + (e.frame >= e.maxFrame - 2 / fps && t.onEnd && t.onEnd(), + (e.frame += t.df / fps)); }, - render: ({ state: e, props: t }) => [ + render: ({ state: e, props: t, fps }) => [ ifConditional( - () => !(t.hideOnEnd && e.frame === e.maxFrame - 1), + () => !(t.hideOnEnd && e.frame >= e.maxFrame - 1 / fps), () => [ loopingSpriteSheet.Single( { @@ -19733,10 +19733,10 @@ var version = "v1.18.1"; Ha = (e) => e.scale <= e.maxScale, //death anim Xa = makeSprite({ - init({ props: e, device: t }) { + init({ props: e, device: t, fps }) { const a = Array.from({ length: 12 }, () => ({ angle: 360 * t.random(), - speed: 3 + 6 * t.random(), + speed: (3 + 6 * t.random()) / fps, rotation: 360 * t.random(), opacity: 0.5, scale: 1 - 0.2 * t.random(), @@ -19748,8 +19748,8 @@ var version = "v1.18.1"; x: 0, y: 0, rotation: 360 * t.random(), - speedX: 6 * t.random() - 3, - speedY: 8 * t.random(), + speedX: (6 * t.random() - 3) / fps, + speedY: (8 * t.random()), })); return { justDestroyed: e.justDestroyed, @@ -19757,19 +19757,19 @@ var version = "v1.18.1"; squares: i, }; }, - loop({ state: e, props: t }) { + loop({ state: e, props: t, fps }) { if (!t.paused) { for (const t of e.triangles) - ((t.radius = t.radius + t.speed), + ((t.radius += t.speed / fps), (t.opacity = 1), - (t.scale = t.scale - 0.1), - (t.speed = t.speed + 0.2)); + (t.scale -= 0.1 / fps), + (t.speed += 0.2 / fps)); lt(e.triangles, Va); for (const t of e.squares) - ((t.scale = t.scale + 0.02), - (t.x = t.x + t.speedX), - (t.y = t.y + t.speedY), - (t.speedY = t.speedY - 0.3)); + ((t.scale += 0.02 / fps), + (t.x += t.speedX), + (t.y += t.speedY / fps), + (t.speedY -= 0.3 / fps)); lt(e.squares, Ha); } }, @@ -30520,12 +30520,13 @@ var version = "v1.18.1"; scale: a, rotation: i, height: n, - df: s, + df: df, paused: o, animationRenderer: r, batchLength: l, batchIndex: c, }, + fps, state: d, spriteToGameCoords: u, utils: h, @@ -30533,7 +30534,7 @@ var version = "v1.18.1"; const { runtime: { skeleton: p, animationState: g }, } = d; - (o || (g.update(zs * s), g.apply(p)), + (o || (g.update(zs * df / fps), g.apply(p)), u(e, t - n / 2, p), void 0 !== i && (p.getRootBone().rotation = -i), void 0 !== a && ((p.scaleX = a.x / 3), (p.scaleY = a.y / 3)), @@ -36047,11 +36048,11 @@ var version = "v1.18.1"; }, loop({ state: e, - props: { shouldShow: t, fadeFrames: a = 10, fadeInc: i = 1 }, + props: { shouldShow: t, fadeFrames: a = 10, fadeInc: i = 1, fps }, }) { t - ? e.fade < a && ((e.fade += i), (e.opacity.ref = e.fade / a)) - : e.fade > 0 && (e.fade--, (e.opacity.ref = e.fade / a)); + ? e.fade < a && ((e.fade += i / fps), (e.opacity.ref = e.fade / a)) + : e.fade > 0 && ((e.fade -= 1 / fps), (e.opacity.ref = e.fade / a)); }, render: ({ props: e, state: t }) => [ ifConditional( @@ -36110,8 +36111,9 @@ var version = "v1.18.1"; loop({ state: e, props: { targetOpacity: t, targetColor: targetColor }, + fps }) { - e.opacity.ref += (t - e.opacity.ref) / 10; + e.opacity.ref += (t - e.opacity.ref) / 10 / fps; if (!(t == 0) && targetColor) { if (e.opacity.ref < 0.5 && t > 0) { e.color.ref = targetColor || "#000000"; @@ -36121,9 +36123,9 @@ var version = "v1.18.1"; ? e.color.trueRef : calculateRGB(e.color.ref, 255); var newRgb = calculateRGB(targetColor, 255); - e.color.trueRef.r += (newRgb.r - current.r) / 5; - e.color.trueRef.g += (newRgb.g - current.g) / 5; - e.color.trueRef.b += (newRgb.b - current.b) / 5; + e.color.trueRef.r += (newRgb.r - current.r) / 5 / fps; + e.color.trueRef.g += (newRgb.g - current.g) / 5 / fps; + e.color.trueRef.b += (newRgb.b - current.b) / 5 / fps; e.color.ref = `#${componentToHex(e.color.trueRef.r, true)}${componentToHex(e.color.trueRef.g, true)}${componentToHex(e.color.trueRef.b, true)}`; } @@ -36613,7 +36615,7 @@ var version = "v1.18.1"; }), fanParticles = makeSprite({ init: ({ props, device }) => ({ particles: [], frame: 0 }), - loop({ state, props, device }) { + loop({ state, props, device, fps }) { if (props.paused) { return; } @@ -36622,11 +36624,11 @@ var version = "v1.18.1"; (path, index) => { if (path[1][1] < 60) { if (path[1][1] > -30) { - path[0][1] += 5 + path[0][1] += 5 / fps } - path[1][1] += 5 + path[1][1] += 5 / fps } else { - path[0][1] += 5; + path[0][1] += 5 / fps; } path[0][1] = Math.min(path[0][1], path[1][1]); if (path[0][1] == path[1][1]) { @@ -36634,9 +36636,8 @@ var version = "v1.18.1"; }; } ); - console.warn(state.particles, state.particles.filter((e) => e !== null)) state.particles = state.particles.filter((e) => e !== null); - if (state.particles.length < 10 && state.frame % 2 === 0) { + if (state.particles.length < 10 && Math.round(state.frame / fps) % 2 === 0) { let x = device.random() * 90 - 45; state.particles.push([ [ @@ -43651,7 +43652,8 @@ var version = "v1.18.1"; const dl = function (e) { var t, a, i, n, s, o, r, l, c, d, u, h, p, g, m, f, y, E, b, S; - const { + var { + fps, playerInput, level: _, sfx: v, @@ -43672,7 +43674,9 @@ var version = "v1.18.1"; freezeOnDeath } = e, { levelState: U } = L; - + if (fps !== 1) { + df /= fps; + } let freeze = (U.crashed || U.finishedLevel) && freezeOnDeath; if (!useBoosterDebug || N) { @@ -43706,7 +43710,7 @@ var version = "v1.18.1"; ? ("up" == playerInput && (U.justDownInputTimer = 0), "up" !== playerInput) : true) && - U.justDownInputTimer--, + (U.justDownInputTimer -= df), "justDown" !== playerInput || (skating ? void 0 : (U.justDownInputTimer = 10))); const inViewLayout = @@ -44603,7 +44607,10 @@ var version = "v1.18.1"; if (-1 !== idx) { const spring = inViewLayout.springs[idx]; if (spring.kind === "fan") { - setGradY(Math.max(gradY + (V - gradY) / 5 * (spring.direction < 0 ? -0.5 : 1), -V)); + setGradY(Math.max( + gradY + (V - gradY) / 5 * (spring.direction < 0 ? -0.5 : 1) * df, + -V * df + )); return; }; (stack || @@ -45471,7 +45478,7 @@ var version = "v1.18.1"; (e) => e.item === "skateboard" || e.item === "spaceship", )), onCrash(U.checkpoint.index), - N && (L.resetTimer = 60)))); + N && (L.resetTimer = 60 * fps)))); U.playerOnGroundY = U.flyingAnchor === null ? U.playerOnGroundY : U.flyingAnchor; let ge = U.explosions.length; @@ -45485,7 +45492,7 @@ var version = "v1.18.1"; ), )), 0 === ge && (U.explosions.length = 0)), - L.landTimer > 0 && L.landTimer--, + L.landTimer > 0 && (L.landTimer = Math.max(0, L.landTimer - df)), U.flyingAnchor === null && (U.playerOnGroundY = null != Q ? Q : U.playerOnGroundY), (U.playerWasOnGroundCooldown = Math.max( @@ -55520,16 +55527,16 @@ var version = "v1.18.1"; ), frame: 0 }), - loop({state, props: e}) { + loop({state, props: e, fps}) { if (e.paused) { return void 0; } state.path.forEach((e) => { - e.opacity -= 0.1; + e.opacity -= 0.1 / fps; e.justAdded = false; }) - state.frame++; - if (state.frame % 5 > 0) { + state.frame += 1 / fps; + if (!(state.frame % Math.floor(5) <= 1)) { return void 0; } state.path.shift(); @@ -55568,7 +55575,7 @@ var version = "v1.18.1"; ] }), playerTrailStrip = makeSprite({ - init: ({ props: e, device: t }) => ({ + init: ({ props: e, device: t, fps }) => ({ followY: e.playerY, width: 1, widthDir: -0.01 - 0.04 * t.random(), @@ -55577,20 +55584,20 @@ var version = "v1.18.1"; offsetY: 3.75 * t.random() * 2 - 3.75, offsetYDir: -0.005 - 0.005 * t.random(), bottomPath: Array.from( - { length: e.playerScaleOff ? 0 : eg }, + { length: e.playerScaleOff ? 0 : Math.round(eg * fps) }, () => [e.playerX, e.playerY], ), middlePath: Array.from( - { length: e.playerScaleOff ? 0 : 6 }, + { length: e.playerScaleOff ? 0 : Math.round(6 * fps) }, () => [e.playerX, e.playerY], ), - topPath: Array.from({ length: e.playerScaleOff ? 0 : 2 }, () => [ + topPath: Array.from({ length: e.playerScaleOff ? 0 : Math.round(2 * fps) }, () => [ e.playerX, e.playerY, ]), bottomWidth: eg, }), - loop({ state: e, props: t, device: a }) { + loop({ state: e, props: t, device: a, fps }) { if (t.paused) return; if (t.crashed || t.playerScaleOff) return ( @@ -55608,25 +55615,25 @@ var version = "v1.18.1"; ((e.followY = B.clamp2( t.playerY - 15, t.playerY + 15, - e.followY + (t.playerY - e.followY) / 4, + e.followY + (t.playerY - e.followY) / 4 / fps, )), (e.width += e.widthDir), e.width < 0.9 - ? ((e.width = 0.9), (e.widthDir = 0.01 + 0.04 * a.random())) + ? ((e.width = 0.9), (e.widthDir = 0.01 + 0.04 * a.random() / fps)) : e.width > 1.5 && - ((e.width = 1.5), (e.widthDir = -0.01 - 0.04 * a.random())), + ((e.width = 1.5), (e.widthDir = -0.01 - 0.04 * a.random() / fps)), (e.offsetX += e.offsetXDir), e.offsetX < -30 - ? ((e.offsetX = -30), (e.offsetXDir = 0.5 + 1.5 * a.random())) + ? ((e.offsetX = -30), (e.offsetXDir = 0.5 + 1.5 * a.random() / fps)) : e.offsetX > 0 && - ((e.offsetX = 0), (e.offsetXDir = -0.5 - 1.5 * a.random())), + ((e.offsetX = 0), (e.offsetXDir = -0.5 - 1.5 * a.random() / fps)), (e.offsetY += e.offsetYDir), e.offsetY < -3.75 ? ((e.offsetY = -3.75), - (e.offsetYDir = 0.005 + 0.005 * a.random())) + (e.offsetYDir = 0.005 + 0.005 * a.random() / fps)) : e.offsetY > 3.75 && ((e.offsetY = 3.75), - (e.offsetYDir = -0.005 - 0.005 * a.random()))); + (e.offsetYDir = -0.005 - 0.005 * a.random() / fps))); const i = t.playerX + t.playerDir * (e.offsetX - 7.5 * globalPlayerScale), @@ -55653,15 +55660,15 @@ var version = "v1.18.1"; !fullTopPath || Math.abs(i - o[0]) > 60 * t.playerSpeedMultiplier || Math.abs(n - o[1]) > 60) && - ((e.bottomPath = Array.from({ length: eg }, () => [ + ((e.bottomPath = Array.from({ length: Math.round(eg * fps) }, () => [ t.playerX, t.playerY, ])), - (e.middlePath = Array.from({ length: 6 }, () => [ + (e.middlePath = Array.from({ length: Math.round(6 * fps) }, () => [ t.playerX, t.playerY, ])), - (e.topPath = Array.from({ length: 2 }, () => [ + (e.topPath = Array.from({ length: Math.round(2 * fps) }, () => [ t.playerX, t.playerY, ])))); @@ -56019,11 +56026,11 @@ var version = "v1.18.1"; }), sg = makeSprite({ init: ({ props: e }) => ({ fade: 0, text: e.text }), - loop({ props: e, state: t }) { + loop({ props: e, state: t, fps }) { if (e.text !== t.text) { - if (t.fade > 0) return void t.fade--; + if (t.fade > 0) return void (t.fade -= 1 / fps); ((t.fade = 0), (t.text = e.text)); - } else t.fade < 30 && t.fade++; + } else t.fade < 30 && (t.fade += 1 / fps); }, render: ({ state: e }) => [ c({ font: { size: 20 }, color: "white" }, (t) => { @@ -56033,14 +56040,14 @@ var version = "v1.18.1"; }), og = makeCustomSprite({ init: ({ props: e }) => ({ fade: 0, text: e.text, timer: 0 }), - loop: ({ state: e, props: t }) => + loop: ({ state: e, props: t, fps }) => e.timer > t.showTime ? e.fade > 0 - ? Object.assign(Object.assign({}, e), { fade: e.fade - 1 }) + ? Object.assign(Object.assign({}, e), { fade: e.fade - 1 / fps }) : Object.assign(Object.assign({}, e), { fade: 0 }) : e.fade < 30 && e.timer > t.delay - ? Object.assign(Object.assign({}, e), { fade: e.fade + 1 }) - : Object.assign(Object.assign({}, e), { timer: e.timer + 1 }), + ? Object.assign(Object.assign({}, e), { fade: e.fade + 1 / fps }) + : Object.assign(Object.assign({}, e), { timer: e.timer + 1 / fps }), render: ({ state: e }) => [ n({ font: { size: 20 }, @@ -62324,34 +62331,34 @@ var version = "v1.18.1"; ), ], }), - hm = (y, cameraY, finished, anchor, useGround) => { + hm = (y, cameraY, finished, anchor, useGround, df) => { if (anchor) { - return cameraY + (anchor - cameraY) / 5; + return cameraY + (anchor - cameraY) / 5 / df; } - if (finished) return cameraY + (y - cameraY) / 10; + if (finished) return cameraY + (y - cameraY) / 10 / df; const i = et.initialPosition.y + 105, n = et.initialPosition.y; let isGrounded = false; if (y <= 30 && !(y - cameraY > i) && useGround) { - cameraY = cameraY + (30 - cameraY) / 4; + cameraY = cameraY + (30 - cameraY) / 4 / df; isGrounded = true; } cameraY = y - cameraY > i && !isGrounded - ? cameraY + (5 + y - cameraY - i) / 4 + ? cameraY + (5 + y - cameraY - i) / 4 / df : y - cameraY < n && !isGrounded - ? cameraY + (-5 + y - cameraY - n) / 4 + ? cameraY + (-5 + y - cameraY - n) / 4 / df : cameraY; return cameraY; }, - pm = (e, t, a) => { - const i = a + pm = (cameraXOffset, playerDir, finishedLevel, df) => { + const i = finishedLevel ? et.initialPosition.x - : 1 === t + : 1 === playerDir ? 0 : 2 * et.initialPosition.x, - n = e - i; - return 0 === n || Math.abs(n) < 1 ? i : e - n / 4; + n = cameraXOffset - i; + return 0 === n || Math.abs(n) < 1 ? i : (cameraXOffset - n / 4 / df); }, gm = (e, t) => e - et.initialPosition.x + t; var mm = function (e, t, a, i) { @@ -64749,8 +64756,8 @@ var version = "v1.18.1"; } return { frame: 0, opacity: 0 }; }, - loop({ state: e }) { - e.opacity >= 1 || (e.frame++, e.frame > 100 && (e.opacity += 0.1)); + loop({ state: e, fps }) { + e.opacity >= 1 || ((e.frame += 1 / fps), e.frame > 100 && (e.opacity += 0.1 / fps)); }, render({ props: e, getContext: t, state: a, device: i }) { const { animationAssets: n, animationRenderer: s } = t(Ws); @@ -65255,6 +65262,7 @@ var version = "v1.18.1"; device: a, getInputs: i, getContext: n, + fps, }) { var s, o, r, l, c, d, u, h, p, g, m; const f = i(), @@ -65348,7 +65356,7 @@ var version = "v1.18.1"; ) { t.mutValues.levelState.frameCountSinceHistoryPush++; const newFrameCountSinceHistoryPush = - 37.5 / Math.max(v, Math.abs(R)); + 37.5 / Math.max(v, Math.abs(R)) * fps; if ( t.mutValues.levelState.frameCountSinceHistoryPush >= newFrameCountSinceHistoryPush @@ -65368,11 +65376,13 @@ var version = "v1.18.1"; finishedLevel, flyingAnchor, t.bigMutValues.inViewLayout.properties.useGround, + fps )), (t.mutValues.levelState.cameraXOffset = pm( t.mutValues.levelState.cameraXOffset, O, finishedLevel, + fps ))); const isClassic = isSpecialTheme( t.bigMutValues.inViewLayout.properties.theme.id, @@ -65476,6 +65486,7 @@ var version = "v1.18.1"; !t.mutValues.levelState.crashed && (t.mutValues.levelState.crashed = true), dl({ + fps: fps, useBoosterDebug: y.showDebug, mutValues: t.mutValues, bigMutValues: t.bigMutValues, @@ -74384,10 +74395,10 @@ var version = "v1.18.1"; { loading: true, frame: 0, modal: null, menuMusicFile: o, readNews: true } ); }, - loop({ state: e }) { + loop({ state: e, fps }) { if (e.loading) return e; - const t = e.frame + 1; - let newArrowY = e.arrowY + 0.3; + const t = e.frame + 1 / fps; + let newArrowY = e.arrowY + 0.3 / fps; newArrowY > 10 && (newArrowY = -10); return Object.assign(Object.assign({}, e), { frame: t >= eE() ? t - eE() : t, @@ -74400,6 +74411,7 @@ var version = "v1.18.1"; device: a, getContext: i, updateState: updateState, + fps: df, }) { const { news: newsMessage, id: newsID, title: newsTitle } = _NEWS; const { @@ -75398,20 +75410,21 @@ var version = "v1.18.1"; cameraY: e.viewingPlayer.state.mutValues.levelState.playerY, cameraXOffset: 0, }), - loop({ state: e, props: t }) { + loop({ state: e, props: t, fps }) { var a; (null === (a = t.loop) || void 0 === a || a.call(t), (e.cameraY = hm( t.viewingPlayer.state.mutValues.levelState.playerY, e.cameraY, false, - t.viewingPlayer.state.mutValues.levelState.flyingAnchor, + t.viewingPlayer.state.mutValues.levelState.flyingAnchor )), (e.cameraScale = 2), (e.cameraXOffset = pm( e.cameraXOffset, t.viewingPlayer.state.mutValues.levelState.playerDir, false, + fps ))); }, render({ props: e, state: t }) { @@ -77925,7 +77938,7 @@ var version = "v1.18.1"; }, PE = ["#6b0d54", "#be1c6a", "#c5452d", "#11b07f", "#c59413"], ME = makeCustomSprite({ - init({ device: { random: e, size: t } }) { + init({ device: { random: e, size: t }, fps }) { const a = t.width + 2 * t.widthMargin, i = t.height + 2 * t.heightMargin; return { @@ -77933,9 +77946,9 @@ var version = "v1.18.1"; const s = 1 * e() + 1, o = e() * Math.PI * 2; return { - speedX: Math.cos(o) * s, - speedY: Math.sin(o) * s, - rotSpeed: ot(e) * (1 * e() + 1), + speedX: Math.cos(o) * s / fps, + speedY: Math.sin(o) * s / fps, + rotSpeed: ot(e) * (1 * e() + 1) / fps, x: e() * a - a / 2, y: e() * i - i / 2, rot: 360 * e(), diff --git a/game/renderCanvas.js b/game/renderCanvas.js index ecb4481..01e9d77 100644 --- a/game/renderCanvas.js +++ b/game/renderCanvas.js @@ -398,6 +398,7 @@ var renderCanvas; state: e.state, parentGlobalId: l, utils: r, + fps: REPLAY_FRAMES_PER_SECOND / 60, spriteToGameCoords: (e, t, r) => { const i = c.multiplyPooled( n.getTopStack().transformationGameCoords, @@ -458,7 +459,8 @@ var renderCanvas; d.renderTexture(n.getTopStack(), g, d.getInitTextureState(g), null); } } - const S = (1 / 60) * 1e3; + const REPLAY_FRAMES_PER_SECOND = 144; + var REPLAY_TIME_PER_UPDATE_MS = (1 / REPLAY_FRAMES_PER_SECOND) * 1e3; function E(e, t, n, i, o, s, l, c) { const { spriteObj: u, props: d } = e, p = [], @@ -482,6 +484,7 @@ var renderCanvas; .transformationGameCoords, (null == h ? void 0 : h.inputs) || i() ), + fps: REPLAY_FRAMES_PER_SECOND / 60, updateState: f, getContext: (e) => { const t = c.find((t) => t.context === e); @@ -529,6 +532,7 @@ var renderCanvas; props: e, state: this.state, device: t, + fps: REPLAY_FRAMES_PER_SECOND / 60, getInputs: () => n(r.transformationGameCoords, this.inputs), updateState: f, getState: y, @@ -541,6 +545,7 @@ var renderCanvas; props: e, state: this.state, device: t, + fps: REPLAY_FRAMES_PER_SECOND / 60, getInputs: () => n(r.transformationGameCoords, this.inputs), updateState: f, getState: y, @@ -809,6 +814,7 @@ var renderCanvas; state: o, parentGlobalId: d, utils: r, + fps: REPLAY_FRAMES_PER_SECOND / 60, spriteToGameCoords: (e, t, r) => { const i = c.multiplyPooled( n.getTopStack().transformationGameCoords, @@ -949,6 +955,7 @@ var renderCanvas; ); return _.state; }, + fps: REPLAY_FRAMES_PER_SECOND / 60, getInputs: () => o( n.getStack((null == _ ? void 0 : _.stackIndex) || 0) @@ -965,6 +972,7 @@ var renderCanvas; props: x, state: A, device: t, + fps: REPLAY_FRAMES_PER_SECOND / 60, getInputs: () => o( n.getStack((null == _ ? void 0 : _.stackIndex) || 0) @@ -986,6 +994,7 @@ var renderCanvas; props: x, state: A, device: t, + fps: REPLAY_FRAMES_PER_SECOND / 60, getInputs: () => o( n.getStack((null == _ ? void 0 : _.stackIndex) || 0) @@ -3253,7 +3262,7 @@ var renderCanvas; runNextFrame(n, u) { const d = n - v; (v = n), (y += d); - let h = Math.round(y / S); + let h = Math.round(y / REPLAY_TIME_PER_UPDATE_MS); for ( t.nativeSpriteUtils.didResize && (l.stack[0].transformation = c.getScaleMatrix( @@ -3263,8 +3272,8 @@ var renderCanvas; h > 0; ) { - (y -= S), h--; - const n = y / S, + (y -= REPLAY_TIME_PER_UPDATE_MS), h--; + const n = y / REPLAY_TIME_PER_UPDATE_MS, l = w(i.size, m), c = 0 === h; c && x.isEmpty