From 05dbc7d1c69349705aaf0c36fc1b87dea91e1aec Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 6 Jan 2026 11:59:13 +0000 Subject: [PATCH 1/3] Initial plan From 4b2ca8a6b44238c2a0d13eadb239ea77a66e5a73 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 6 Jan 2026 12:06:51 +0000 Subject: [PATCH 2/3] Fix sync race conditions and endless loop potential Co-authored-by: L3P3 <4629449+L3P3@users.noreply.github.com> --- src/game/m_world_store.js | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/game/m_world_store.js b/src/game/m_world_store.js index 97b7e42..ae60409 100644 --- a/src/game/m_world_store.js +++ b/src/game/m_world_store.js @@ -177,11 +177,10 @@ export const world_store_lists_merge = config => { world_local.label + locale_warn_world_remote_missing_2 ); - debugger; - /*defer(); + defer(); actions.world_prop(world_local.id, { mod_r: WORLD_STORED_NOT, - });*/ + }); } world_list.push({ @@ -222,6 +221,14 @@ export const world_store_sync_check = async () => { ) ) { await world_store_sync(world_syncable); + // Mark as synced in the current list to prevent re-syncing + // before state updates propagate + if (world_syncable.local < world_syncable.remote) { + world_syncable.local = world_syncable.remote; + } + else { + world_syncable.remote = world_syncable.local; + } actions.state_patch({ world_syncing: null, }); @@ -284,7 +291,6 @@ const world_store_sync = async world => { const data_promise = chunks_get(id); let id_new = id; - let rename_promise = null; // world must be registered first? if (world.remote === WORLD_STORED_SHOULD) { const response_register = await fetch_(API + 'world', { @@ -295,7 +301,8 @@ const world_store_sync = async world => { }), }); const result_register = await response_parse(response_register); - rename_promise = chunks_rename( + // Await rename before upload to avoid inconsistent state if upload fails + await chunks_rename( world_renamed_id_old = id, world_renamed_id_new = id_new = result_register.id ); @@ -317,7 +324,6 @@ const world_store_sync = async world => { mod_l: result_upload.modified, mod_r: result_upload.modified, }); - await rename_promise; } else { actions.world_prop(id, { From 5dfdf99953bd13e8ba6ec5a7ddc471b055a4786a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 6 Jan 2026 12:08:33 +0000 Subject: [PATCH 3/3] Improve code clarity based on review feedback Co-authored-by: L3P3 <4629449+L3P3@users.noreply.github.com> --- src/game/m_world_store.js | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/game/m_world_store.js b/src/game/m_world_store.js index ae60409..132fcfa 100644 --- a/src/game/m_world_store.js +++ b/src/game/m_world_store.js @@ -223,12 +223,8 @@ export const world_store_sync_check = async () => { await world_store_sync(world_syncable); // Mark as synced in the current list to prevent re-syncing // before state updates propagate - if (world_syncable.local < world_syncable.remote) { - world_syncable.local = world_syncable.remote; - } - else { - world_syncable.remote = world_syncable.local; - } + const synced_time = Math_max(world_syncable.local, world_syncable.remote); + world_syncable.local = world_syncable.remote = synced_time; actions.state_patch({ world_syncing: null, }); @@ -301,11 +297,11 @@ const world_store_sync = async world => { }), }); const result_register = await response_parse(response_register); + id_new = result_register.id; // Await rename before upload to avoid inconsistent state if upload fails - await chunks_rename( - world_renamed_id_old = id, - world_renamed_id_new = id_new = result_register.id - ); + world_renamed_id_old = id; + world_renamed_id_new = id_new; + await chunks_rename(id, id_new); } const response_upload = await fetch_(API + 'world', {