From 4918ae34a5b345b6df8ec1d8d062b20f4712b072 Mon Sep 17 00:00:00 2001 From: CenTdemeern1 Date: Mon, 28 Oct 2024 17:42:31 +0100 Subject: [PATCH 1/2] Upgrade matter-js to version 0.20.0 This version uses fixed rates across platforms in Matter.Runner. This fixes inconsistent rates in `physics.ts`. --- packages/frontend/package.json | 2 +- pnpm-lock.yaml | 86 +++++++++++----------------------- 2 files changed, 28 insertions(+), 60 deletions(-) diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 752b6cb388..4071db9ec0 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -53,7 +53,7 @@ "is-file-animated": "1.0.2", "json5": "2.2.3", "katex": "0.16.10", - "matter-js": "0.19.0", + "matter-js": "0.20.0", "misskey-bubble-game": "workspace:*", "misskey-js": "workspace:*", "misskey-reversi": "workspace:*", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d01454e892..a5751024da 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -821,8 +821,8 @@ importers: specifier: 0.16.10 version: 0.16.10 matter-js: - specifier: 0.19.0 - version: 0.19.0 + specifier: 0.20.0 + version: 0.20.0 misskey-bubble-game: specifier: workspace:* version: link:../misskey-bubble-game @@ -1194,7 +1194,7 @@ importers: version: 7.17.0(eslint@9.14.0)(typescript@5.6.3) '@vitest/coverage-v8': specifier: 1.6.0 - version: 1.6.0(vitest@1.6.0(@types/node@22.9.0)(happy-dom@10.0.3)(jsdom@24.1.1)(sass@1.79.4)(terser@5.36.0)) + version: 1.6.0(vitest@1.6.0(@types/node@22.9.0)(happy-dom@10.0.3)(jsdom@24.1.1(bufferutil@4.0.8)(utf-8-validate@6.0.4))(sass@1.79.4)(terser@5.36.0)) '@vue/runtime-core': specifier: 3.5.12 version: 3.5.12 @@ -2633,7 +2633,6 @@ packages: '@humanwhocodes/config-array@0.11.14': resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} engines: {node: '>=10.10.0'} - deprecated: Use @eslint/config-array instead '@humanwhocodes/module-importer@1.0.1': resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} @@ -2645,7 +2644,6 @@ packages: '@humanwhocodes/object-schema@2.0.3': resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} - deprecated: Use @eslint/object-schema instead '@humanwhocodes/retry@0.3.0': resolution: {integrity: sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==} @@ -4441,7 +4439,6 @@ packages: '@types/form-data@2.5.0': resolution: {integrity: sha512-23/wYiuckYYtFpL+4RPWiWmRQH2BjFuqCUi2+N3amB1a1Drv+i/byTrGvlLwRVLFNAZbwpbQ7JvTK+VCAPMbcg==} - deprecated: This is a stub types definition. form-data provides its own type definitions, so you do not need this installed. '@types/glob@7.2.0': resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} @@ -6494,7 +6491,6 @@ packages: eslint@8.57.0: resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. hasBin: true eslint@9.14.0: @@ -6986,12 +6982,10 @@ packages: glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - deprecated: Glob versions prior to v9 are no longer supported glob@8.1.0: resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} engines: {node: '>=12'} - deprecated: Glob versions prior to v9 are no longer supported global-dirs@3.0.1: resolution: {integrity: sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==} @@ -7286,7 +7280,6 @@ packages: inflight@1.0.6: resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} - deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} @@ -8110,6 +8103,9 @@ packages: matter-js@0.19.0: resolution: {integrity: sha512-v2huwvQGOHTGOkMqtHd2hercCG3f6QAObTisPPHg8TZqq2lz7eIY/5i/5YUV8Ibf3mEioFEmwibcPUF2/fnKKQ==} + matter-js@0.20.0: + resolution: {integrity: sha512-iC9fYR7zVT3HppNnsFsp9XOoQdQN2tUyfaKg4CHLH8bN+j6GT4Gw7IH2rP0tflAebrHFw730RR3DkVSZRX8hwA==} + mdast-util-find-and-replace@3.0.1: resolution: {integrity: sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==} @@ -9667,7 +9663,6 @@ packages: rimraf@3.0.2: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} - deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true rollup@4.26.0: @@ -11810,7 +11805,7 @@ snapshots: '@babel/traverse': 7.23.5 '@babel/types': 7.24.7 convert-source-map: 2.0.0 - debug: 4.3.5(supports-color@5.5.0) + debug: 4.3.7(supports-color@8.1.1) gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -11862,7 +11857,7 @@ snapshots: '@babel/helper-environment-visitor@7.24.7': dependencies: - '@babel/types': 7.24.7 + '@babel/types': 7.25.7 '@babel/helper-function-name@7.24.7': dependencies: @@ -11875,7 +11870,7 @@ snapshots: '@babel/helper-module-imports@7.22.15': dependencies: - '@babel/types': 7.24.7 + '@babel/types': 7.25.7 '@babel/helper-module-imports@7.24.7': dependencies: @@ -11908,7 +11903,7 @@ snapshots: '@babel/helper-simple-access@7.22.5': dependencies: - '@babel/types': 7.24.7 + '@babel/types': 7.25.7 '@babel/helper-simple-access@7.24.7': dependencies: @@ -11919,7 +11914,7 @@ snapshots: '@babel/helper-split-export-declaration@7.24.7': dependencies: - '@babel/types': 7.24.7 + '@babel/types': 7.25.7 '@babel/helper-string-parser@7.24.7': {} @@ -11937,7 +11932,7 @@ snapshots: dependencies: '@babel/template': 7.22.15 '@babel/traverse': 7.24.7 - '@babel/types': 7.24.7 + '@babel/types': 7.25.7 transitivePeerDependencies: - supports-color @@ -12110,8 +12105,8 @@ snapshots: '@babel/template@7.22.15': dependencies: '@babel/code-frame': 7.24.7 - '@babel/parser': 7.24.7 - '@babel/types': 7.24.7 + '@babel/parser': 7.25.7 + '@babel/types': 7.25.7 '@babel/template@7.24.0': dependencies: @@ -12133,9 +12128,9 @@ snapshots: '@babel/helper-function-name': 7.24.7 '@babel/helper-hoist-variables': 7.24.7 '@babel/helper-split-export-declaration': 7.24.7 - '@babel/parser': 7.24.7 - '@babel/types': 7.24.7 - debug: 4.3.5(supports-color@5.5.0) + '@babel/parser': 7.25.7 + '@babel/types': 7.25.7 + debug: 4.3.7(supports-color@8.1.1) globals: 11.12.0 transitivePeerDependencies: - supports-color @@ -12148,9 +12143,9 @@ snapshots: '@babel/helper-function-name': 7.24.7 '@babel/helper-hoist-variables': 7.24.7 '@babel/helper-split-export-declaration': 7.24.7 - '@babel/parser': 7.24.7 - '@babel/types': 7.24.7 - debug: 4.3.5(supports-color@5.5.0) + '@babel/parser': 7.25.7 + '@babel/types': 7.25.7 + debug: 4.3.7(supports-color@8.1.1) globals: 11.12.0 transitivePeerDependencies: - supports-color @@ -15490,7 +15485,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@vitest/coverage-v8@1.6.0(vitest@1.6.0(@types/node@22.9.0)(happy-dom@10.0.3)(jsdom@24.1.1)(sass@1.79.4)(terser@5.36.0))': + '@vitest/coverage-v8@1.6.0(vitest@1.6.0(@types/node@22.9.0)(happy-dom@10.0.3)(jsdom@24.1.1(bufferutil@4.0.8)(utf-8-validate@6.0.4))(sass@1.79.4)(terser@5.36.0))': dependencies: '@ampproject/remapping': 2.2.1 '@bcoe/v8-coverage': 0.2.3 @@ -15505,7 +15500,7 @@ snapshots: std-env: 3.7.0 strip-literal: 2.1.0 test-exclude: 6.0.0 - vitest: 1.6.0(@types/node@22.9.0)(happy-dom@10.0.3)(jsdom@24.1.1)(sass@1.79.4)(terser@5.36.0) + vitest: 1.6.0(@types/node@22.9.0)(happy-dom@10.0.3)(jsdom@24.1.1(bufferutil@4.0.8)(utf-8-validate@6.0.4))(sass@1.79.4)(terser@5.36.0) transitivePeerDependencies: - supports-color @@ -19348,35 +19343,6 @@ snapshots: jsdoc-type-pratt-parser@4.1.0: {} - jsdom@24.1.1: - dependencies: - cssstyle: 4.0.1 - data-urls: 5.0.0 - decimal.js: 10.4.3 - form-data: 4.0.1 - html-encoding-sniffer: 4.0.0 - http-proxy-agent: 7.0.2 - https-proxy-agent: 7.0.5 - is-potential-custom-element-name: 1.0.1 - nwsapi: 2.2.12 - parse5: 7.2.1 - rrweb-cssom: 0.7.1 - saxes: 6.0.0 - symbol-tree: 3.2.4 - tough-cookie: 4.1.4 - w3c-xmlserializer: 5.0.0 - webidl-conversions: 7.0.0 - whatwg-encoding: 3.1.1 - whatwg-mimetype: 4.0.0 - whatwg-url: 14.0.0 - ws: 8.18.0(bufferutil@4.0.7)(utf-8-validate@6.0.3) - xml-name-validator: 5.0.0 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - optional: true - jsdom@24.1.1(bufferutil@4.0.7)(utf-8-validate@6.0.3): dependencies: cssstyle: 4.0.1 @@ -19741,6 +19707,8 @@ snapshots: matter-js@0.19.0: {} + matter-js@0.20.0: {} + mdast-util-find-and-replace@3.0.1: dependencies: '@types/mdast': 4.0.3 @@ -21876,7 +21844,7 @@ snapshots: socks-proxy-agent@8.0.2: dependencies: agent-base: 7.1.0 - debug: 4.3.5(supports-color@5.5.0) + debug: 4.3.7(supports-color@8.1.1) socks: 2.7.1 transitivePeerDependencies: - supports-color @@ -22848,7 +22816,7 @@ snapshots: - supports-color - terser - vitest@1.6.0(@types/node@22.9.0)(happy-dom@10.0.3)(jsdom@24.1.1)(sass@1.79.4)(terser@5.36.0): + vitest@1.6.0(@types/node@22.9.0)(happy-dom@10.0.3)(jsdom@24.1.1(bufferutil@4.0.8)(utf-8-validate@6.0.4))(sass@1.79.4)(terser@5.36.0): dependencies: '@vitest/expect': 1.6.0 '@vitest/runner': 1.6.0 @@ -22873,7 +22841,7 @@ snapshots: optionalDependencies: '@types/node': 22.9.0 happy-dom: 10.0.3 - jsdom: 24.1.1 + jsdom: 24.1.1(bufferutil@4.0.8)(utf-8-validate@6.0.4) transitivePeerDependencies: - less - lightningcss From f9100d4dcf51b7153b787ae09b700a3472f2cce0 Mon Sep 17 00:00:00 2001 From: CenTdemeern1 Date: Mon, 28 Oct 2024 17:52:08 +0100 Subject: [PATCH 2/2] bubble-game: Use setInterval instead of requestAnimationFrame This makes sure Misskey's Bubble Game always runs at a consistent rate, even when the monitor isn't 60hz --- .../src/pages/drop-and-fusion.game.vue | 33 ++++++++++--------- packages/misskey-bubble-game/src/game.ts | 2 +- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/packages/frontend/src/pages/drop-and-fusion.game.vue b/packages/frontend/src/pages/drop-and-fusion.game.vue index fb4d599c28..8d369101af 100644 --- a/packages/frontend/src/pages/drop-and-fusion.game.vue +++ b/packages/frontend/src/pages/drop-and-fusion.game.vue @@ -557,7 +557,7 @@ let bgmNodes: ReturnType | null = null; let renderer: Matter.Render | null = null; let monoTextures: Record = {}; let monoTextureUrls: Record = {}; -let tickRaf: number | null = null; +let tickInterval: number | null = null; let game = new DropAndFusionGame({ seed: seed, gameMode: props.gameMode, @@ -663,13 +663,20 @@ function getTextureImageUrl(mono: Mono) { } } +function startTicking(tickFunction: () => void) { + tickInterval = window.setInterval(tickFunction, game.TICK_DELTA); +} + +function stopTicking() { + if (tickInterval !== null) { + window.clearInterval(tickInterval); + tickInterval = null; + } +} + function tick() { const hasNextTick = game.tick(); - if (hasNextTick) { - tickRaf = window.requestAnimationFrame(tick); - } else { - tickRaf = null; - } + if (!hasNextTick) stopTicking(); } function tickReplay() { @@ -700,11 +707,7 @@ function tickReplay() { if (!hasNextTick) break; } - if (hasNextTick) { - tickRaf = window.requestAnimationFrame(tickReplay); - } else { - tickRaf = null; - } + if (!hasNextTick) stopTicking(); } async function start() { @@ -716,7 +719,7 @@ async function start() { }); Matter.Render.run(renderer); game.start(); - window.requestAnimationFrame(tick); + startTicking(tick); gameLoaded.value = true; @@ -803,9 +806,7 @@ function reset() { function dispose() { game.dispose(); if (renderer) Matter.Render.stop(renderer); - if (tickRaf) { - window.cancelAnimationFrame(tickRaf); - } + stopTicking(); } function backToTitle() { @@ -829,7 +830,7 @@ function replay() { }); Matter.Render.run(renderer); game.start(); - window.requestAnimationFrame(tickReplay); + startTicking(tickReplay); }); } diff --git a/packages/misskey-bubble-game/src/game.ts b/packages/misskey-bubble-game/src/game.ts index 7f230e39cb..ff43488c7d 100644 --- a/packages/misskey-bubble-game/src/game.ts +++ b/packages/misskey-bubble-game/src/game.ts @@ -51,7 +51,7 @@ export class DropAndFusionGame extends EventEmitter<{ public readonly DROP_COOLTIME = 30; // frame public readonly PLAYAREA_MARGIN = 25; private STOCK_MAX = 4; - private TICK_DELTA = 1000 / 60; // 60fps + public readonly TICK_DELTA = 1000 / 60; // 60fps public frame = 0; public engine: Matter.Engine;