diff --git a/index.html b/index.html
index 5e07223..775de82 100644
--- a/index.html
+++ b/index.html
@@ -105,6 +105,7 @@
+
diff --git a/src/main.js b/src/main.js
index 74497a4..45c84bf 100644
--- a/src/main.js
+++ b/src/main.js
@@ -2,30 +2,13 @@
const { Engine, Render, Runner, World, Body, Constraint, Events, Vector } =
Matter;
- const { scenes = [], defaultSceneId } = window.PhysilinksScenes || {};
- const getSceneById = (sceneId) =>
- scenes.find((candidate) => candidate.id === sceneId) || null;
-
- const getSceneIdFromUrl = () => {
- try {
- const params = new URLSearchParams(window.location.search);
- const urlScene = params.get("scene");
- return getSceneById(urlScene) ? urlScene : null;
- } catch (err) {
- return null;
- }
- };
-
- const setSceneIdInUrl = (sceneId) => {
- if (!sceneId) return;
- try {
- const url = new URL(window.location.href);
- url.searchParams.set("scene", sceneId);
- history.replaceState({}, "", `${url.pathname}${url.search}${url.hash}`);
- } catch (err) {
- // ignore history failures (blocked or unsupported)
- }
- };
+ const {
+ scenes = [],
+ defaultSceneId,
+ order: sceneOrder = [],
+ } = window.PhysilinksScenes || {};
+ const { getSceneById, getSceneIdFromUrl, setSceneIdInUrl, getNextSceneId } =
+ window.PhysilinksSceneRegistry || {};
const defaultMessageConfig = {
durationMs: 4200,
@@ -206,28 +189,6 @@
updateHud();
};
- const getNextSceneId = () => {
- const order = window.PhysilinksScenes?.order || [];
- const currentId = currentScene?.id;
- const orderedExisting = order.filter((id) =>
- scenes.some((s) => s.id === id),
- );
- if (orderedExisting.length > 0 && currentId) {
- const idx = orderedExisting.indexOf(currentId);
- if (idx >= 0 && idx < orderedExisting.length - 1) {
- return orderedExisting[idx + 1];
- }
- if (idx === orderedExisting.length - 1) {
- return orderedExisting[0];
- }
- }
- const fallbackIdx = scenes.findIndex((s) => s.id === currentId);
- if (fallbackIdx >= 0 && fallbackIdx < scenes.length - 1) {
- return scenes[fallbackIdx + 1].id;
- }
- return scenes[0]?.id || defaultSceneId;
- };
-
const chain = {
active: false,
color: null,
@@ -782,7 +743,12 @@
onPauseToggle: () => setPaused(!isPaused),
onRestart: restartGame,
onSceneChange: (id) => applyScene(id),
- onWinNext: () => applyScene(getNextSceneId()),
+ onWinNext: () =>
+ applyScene(
+ getNextSceneId
+ ? getNextSceneId(scenes, sceneOrder, currentScene) || currentScene?.id
+ : currentScene?.id,
+ ),
});
ui.setSceneOptions(
scenes,
diff --git a/src/scene-registry.js b/src/scene-registry.js
new file mode 100644
index 0000000..14c4f74
--- /dev/null
+++ b/src/scene-registry.js
@@ -0,0 +1,53 @@
+(() => {
+ const getSceneById = (scenes, sceneId) =>
+ scenes.find((candidate) => candidate.id === sceneId) || null;
+
+ const getSceneIdFromUrl = (scenes) => {
+ try {
+ const params = new URLSearchParams(window.location.search);
+ const urlScene = params.get("scene");
+ return getSceneById(scenes, urlScene) ? urlScene : null;
+ } catch (err) {
+ return null;
+ }
+ };
+
+ const setSceneIdInUrl = (sceneId) => {
+ if (!sceneId) return;
+ try {
+ const url = new URL(window.location.href);
+ url.searchParams.set("scene", sceneId);
+ history.replaceState({}, "", `${url.pathname}${url.search}${url.hash}`);
+ } catch (err) {
+ // ignore history failures (blocked or unsupported)
+ }
+ };
+
+ const getNextSceneId = (scenes, order, currentScene) => {
+ const currentId = currentScene?.id;
+ const orderedExisting = order.filter((id) =>
+ scenes.some((s) => s.id === id),
+ );
+ if (orderedExisting.length > 0 && currentId) {
+ const idx = orderedExisting.indexOf(currentId);
+ if (idx >= 0 && idx < orderedExisting.length - 1) {
+ return orderedExisting[idx + 1];
+ }
+ if (idx === orderedExisting.length - 1) {
+ return orderedExisting[0];
+ }
+ }
+ const fallbackIdx = scenes.findIndex((s) => s.id === currentId);
+ if (fallbackIdx >= 0 && fallbackIdx < scenes.length - 1) {
+ return scenes[fallbackIdx + 1].id;
+ }
+ return scenes[0]?.id || null;
+ };
+
+ window.PhysilinksSceneRegistry = {
+ getSceneById,
+ getSceneIdFromUrl,
+ setSceneIdInUrl,
+ getNextSceneId,
+ };
+})();