Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
21 changes: 18 additions & 3 deletions webapp/src/app/services/phaser/entities/entity-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -304,17 +304,27 @@ 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;
}

// concurrent entity loading
const promises: Promise<any>[] = [];
const promises: Promise<CCEntity>[] = [];
for (const entity of map.entities) {
promises.push(this.generateEntity(entity));
}
await Promise.all(promises);

const newEntities = await Promise.all(promises);

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());
}
}


Expand Down Expand Up @@ -348,6 +358,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);
Expand All @@ -365,14 +376,17 @@ 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();
}
await ccEntity.setSettings(entity.settings);
ccEntity.level = entity.level;
ccEntity.setActive(false);
this._entities.push(ccEntity);
return ccEntity;
}

Expand Down Expand Up @@ -429,6 +443,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);
}
Expand Down
2 changes: 1 addition & 1 deletion webapp/src/app/tests/map-loading.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<PhaserComponent>;
Expand Down
Loading