From 3c0a6aa9baf08344e461ec9aacb2ad19bf847076 Mon Sep 17 00:00:00 2001 From: 2767mr <2767mr@gmx.at> Date: Sun, 13 Sep 2026 11:23:16 +0200 Subject: [PATCH 1/8] Preserve map entity order --- .../app/services/phaser/entities/entity-manager.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/webapp/src/app/services/phaser/entities/entity-manager.ts b/webapp/src/app/services/phaser/entities/entity-manager.ts index 86ee5608..5b489ab4 100644 --- a/webapp/src/app/services/phaser/entities/entity-manager.ts +++ b/webapp/src/app/services/phaser/entities/entity-manager.ts @@ -314,7 +314,15 @@ export class EntityManager extends BaseObject { for (const entity of map.entities) { promises.push(this.generateEntity(entity)); } - await Promise.all(promises); + + const newEntities = await Promise.allSettled(promises); + for (const newEntity of newEntities) { + if (newEntity.status === 'fulfilled') { + this._entities.push(newEntity.value); + } else { + console.error('Error while generating entity: ', newEntity.reason); + } + } } @@ -348,6 +356,7 @@ export class EntityManager extends BaseObject { // TODO: better generate level from collision tiles entity.level = this.map.masterLevel; const e = await this.generateEntity(entity); + this._entities.push(e); // entity manager is activated e.setActive(true); @@ -372,7 +381,6 @@ export class EntityManager extends BaseObject { await ccEntity.setSettings(entity.settings); ccEntity.level = entity.level; ccEntity.setActive(false); - this._entities.push(ccEntity); return ccEntity; } @@ -429,6 +437,7 @@ export class EntityManager extends BaseObject { Vec2.sub(e, offset); Vec2.add(e, mousePos); const newEntity = await this.generateEntity(e); + this._entities.push(newEntity); newEntity.setActive(true); this.selectEntity(newEntity, entities.length > 1); } From 6f5e49c687164ac9561efe6723eb84aa3d8bbdaf Mon Sep 17 00:00:00 2001 From: 2767mr <2767mr@gmx.at> Date: Sun, 13 Sep 2026 11:30:54 +0200 Subject: [PATCH 2/8] Fix race condition for entites.json load --- webapp/src/app/services/phaser/entities/entity-manager.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/webapp/src/app/services/phaser/entities/entity-manager.ts b/webapp/src/app/services/phaser/entities/entity-manager.ts index 5b489ab4..91622a7d 100644 --- a/webapp/src/app/services/phaser/entities/entity-manager.ts +++ b/webapp/src/app/services/phaser/entities/entity-manager.ts @@ -308,6 +308,9 @@ export class EntityManager extends BaseObject { if (!map.entities) { return; } + + // Preload entities since we need it for loadJsonMergedSync in the entities' constructor + await Globals.jsonLoader.loadJsonMerged('entities.json'); // concurrent entity loading const promises: Promise[] = []; From 4c942c73de725432abf1ee88d293924e93db55f4 Mon Sep 17 00:00:00 2001 From: 2767mr <2767mr@gmx.at> Date: Sun, 13 Sep 2026 11:35:50 +0200 Subject: [PATCH 3/8] Move the preload to a place that makes more sense --- webapp/src/app/services/phaser/entities/entity-manager.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/webapp/src/app/services/phaser/entities/entity-manager.ts b/webapp/src/app/services/phaser/entities/entity-manager.ts index 91622a7d..731bb219 100644 --- a/webapp/src/app/services/phaser/entities/entity-manager.ts +++ b/webapp/src/app/services/phaser/entities/entity-manager.ts @@ -308,9 +308,6 @@ export class EntityManager extends BaseObject { if (!map.entities) { return; } - - // Preload entities since we need it for loadJsonMergedSync in the entities' constructor - await Globals.jsonLoader.loadJsonMerged('entities.json'); // concurrent entity loading const promises: Promise[] = []; @@ -377,6 +374,10 @@ export class EntityManager extends BaseObject { const entityClass = Globals.entityRegistry.getEntity(entity.type); console.assert(this.map, 'I dont think map is ever undefined, but if it ever happens check the TODO on private map?: CCMap;'); const map = this.map!; + + // Preload entities since we need it for loadJsonMergedSync in the entity's constructor + await Globals.jsonLoader.loadJsonMerged('entities.json'); + const ccEntity = new entityClass(this.scene, map, entity.x, entity.y, entity.type); if (!entity.settings.mapId) { entity.settings.mapId = map.getUniqueMapid(); From d8d3277afa04bf25dee47f1e53c4aac6223f8143 Mon Sep 17 00:00:00 2001 From: 2767mr <2767mr@gmx.at> Date: Sun, 13 Sep 2026 11:37:38 +0200 Subject: [PATCH 4/8] Add changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b13d7513..147822ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [Unreleased] +### Fixed +- The map editor now preserves the entity order better than before. +- Fixed an issue that could prevent the first few entities from loading. + ## [2.4.4] 2026-07-17 ### Fixed - Reduced HiddenBlock minimum size from 16 to 4 From 2d214cf983b1a6a90a4dc14244d1c40aa7d35d05 Mon Sep 17 00:00:00 2001 From: 2767mr <2767mr@gmx.at> Date: Sun, 13 Sep 2026 15:37:32 +0200 Subject: [PATCH 5/8] Throw exception when an entity fails to load --- .../src/app/services/phaser/entities/entity-manager.ts | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/webapp/src/app/services/phaser/entities/entity-manager.ts b/webapp/src/app/services/phaser/entities/entity-manager.ts index 731bb219..58822d4f 100644 --- a/webapp/src/app/services/phaser/entities/entity-manager.ts +++ b/webapp/src/app/services/phaser/entities/entity-manager.ts @@ -315,14 +315,7 @@ export class EntityManager extends BaseObject { promises.push(this.generateEntity(entity)); } - const newEntities = await Promise.allSettled(promises); - for (const newEntity of newEntities) { - if (newEntity.status === 'fulfilled') { - this._entities.push(newEntity.value); - } else { - console.error('Error while generating entity: ', newEntity.reason); - } - } + this._entities = await Promise.all(promises); } From 1fadd11dbd6c45778d95b701d8a6416ca89f0400 Mon Sep 17 00:00:00 2001 From: 2767mr <2767mr@gmx.at> Date: Sun, 13 Sep 2026 15:45:34 +0200 Subject: [PATCH 6/8] Fix race condition Closes #358 --- webapp/src/app/services/phaser/entities/entity-manager.ts | 4 +++- webapp/src/app/tests/map-loading.spec.ts | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/webapp/src/app/services/phaser/entities/entity-manager.ts b/webapp/src/app/services/phaser/entities/entity-manager.ts index 58822d4f..c15bcc47 100644 --- a/webapp/src/app/services/phaser/entities/entity-manager.ts +++ b/webapp/src/app/services/phaser/entities/entity-manager.ts @@ -304,6 +304,7 @@ export class EntityManager extends BaseObject { this._entities.forEach(e => e.destroy()); } this._entities = []; + const entities = this._entities; // We need to store a reference to the array here to prevent race conditions if this method is called concurrently if (!map.entities) { return; @@ -315,7 +316,8 @@ export class EntityManager extends BaseObject { promises.push(this.generateEntity(entity)); } - this._entities = await Promise.all(promises); + const newEntities = await Promise.all(promises); + entities.unshift(...newEntities); //Add at the start of the array, in case a user somehow managed to add a new entity while the map is loading } diff --git a/webapp/src/app/tests/map-loading.spec.ts b/webapp/src/app/tests/map-loading.spec.ts index 99842b3b..1dee32c6 100644 --- a/webapp/src/app/tests/map-loading.spec.ts +++ b/webapp/src/app/tests/map-loading.spec.ts @@ -16,7 +16,7 @@ class SimpleServiceMock { } } -// TODO: fix map loading, order of entities doesn't matter +// TODO: fix map loading, order of entities does matter describe('Map Loading', () => { let component: PhaserComponent; let fixture: ComponentFixture; From e2a349c3e564a3acc0c56424fc4403cecc68d489 Mon Sep 17 00:00:00 2001 From: 2767mr <2767mr@gmx.at> Date: Sun, 13 Sep 2026 15:51:23 +0200 Subject: [PATCH 7/8] Destroy old entities --- .../src/app/services/phaser/entities/entity-manager.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/webapp/src/app/services/phaser/entities/entity-manager.ts b/webapp/src/app/services/phaser/entities/entity-manager.ts index c15bcc47..09a1e80d 100644 --- a/webapp/src/app/services/phaser/entities/entity-manager.ts +++ b/webapp/src/app/services/phaser/entities/entity-manager.ts @@ -317,7 +317,14 @@ export class EntityManager extends BaseObject { } const newEntities = await Promise.all(promises); - entities.unshift(...newEntities); //Add at the start of the array, in case a user somehow managed to add a new entity while the map is loading + + if (entities === this._entities) { + //Add at the start of the array, in case a user somehow managed to add a new entity while the map is loading + entities.unshift(...newEntities); + } else { + // Someone called `this.initialize` before we finished loading map. Destroy everything. + newEntities.forEach(e => e.destroy()); + } } From ebfd5e2b6dea1d87c8d35a3ebcadf7bee54b1b20 Mon Sep 17 00:00:00 2001 From: 2767mr <2767mr@gmx.at> Date: Sun, 13 Sep 2026 16:00:24 +0200 Subject: [PATCH 8/8] Improve types --- webapp/src/app/services/phaser/entities/entity-manager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webapp/src/app/services/phaser/entities/entity-manager.ts b/webapp/src/app/services/phaser/entities/entity-manager.ts index 09a1e80d..c5b2e569 100644 --- a/webapp/src/app/services/phaser/entities/entity-manager.ts +++ b/webapp/src/app/services/phaser/entities/entity-manager.ts @@ -311,7 +311,7 @@ export class EntityManager extends BaseObject { } // concurrent entity loading - const promises: Promise[] = []; + const promises: Promise[] = []; for (const entity of map.entities) { promises.push(this.generateEntity(entity)); }