Lifecycle
Entity lifecycle includes three phases: creation, runtime, and destruction. This section covers how to properly manage entity lifecycles.
Destroying Entities
Section titled “Destroying Entities”Basic Destruction
Section titled “Basic Destruction”// Destroy entityplayer.destroy();
// Check if entity is destroyedif (player.isDestroyed) { console.log("Entity has been destroyed");}When destroying an entity:
- All components are removed (triggering
onRemovedFromEntitycallbacks) - Entity is removed from query systems
- Entity is removed from scene entity list
- All reference tracking is cleaned up
Conditional Destruction
Section titled “Conditional Destruction”// Common pattern: Destroy when health depletedconst health = enemy.getComponent(Health);if (health && health.current <= 0) { enemy.destroy();}Destruction Safety
Section titled “Destruction Safety”Destruction is idempotent—multiple calls won’t cause errors:
player.destroy();player.destroy(); // Safe, no errorPersistent Entities
Section titled “Persistent Entities”By default, entities are destroyed during scene transitions. Persistence allows entities to survive across scenes.
Setting Persistence
Section titled “Setting Persistence”// Method 1: Chain callconst player = scene.createEntity('Player') .setPersistent() .createComponent(PlayerComponent);
// Method 2: Separate callplayer.setPersistent();
// Check persistenceif (player.isPersistent) { console.log("This is a persistent entity");}Removing Persistence
Section titled “Removing Persistence”// Restore to scene-local entityplayer.setSceneLocal();Lifecycle Policies
Section titled “Lifecycle Policies”Entities have two lifecycle policies:
| Policy | Description |
|---|---|
SceneLocal | Default, destroyed with scene |
Persistent | Survives scene transitions |
import { EEntityLifecyclePolicy } from '@esengine/ecs-framework';
// Get current policyconst policy = entity.lifecyclePolicy;
if (policy === EEntityLifecyclePolicy.Persistent) { // Persistent entity}Use Cases
Section titled “Use Cases”Persistent entities are suitable for:
- Player characters
- Global managers
- UI entities
- Game state that needs to survive scene transitions
// Player characterconst player = scene.createEntity('Player') .setPersistent();
// Game managerconst gameManager = scene.createEntity('GameManager') .setPersistent() .createComponent(GameStateComponent);
// Score managerconst scoreManager = scene.createEntity('ScoreManager') .setPersistent() .createComponent(ScoreComponent);Scene Transition Behavior
Section titled “Scene Transition Behavior”// Scene manager switches scenessceneManager.loadScene('Level2');
// During transition:// 1. SceneLocal entities are destroyed// 2. Persistent entities migrate to new scene// 3. New scene entities are createdReference Cleanup
Section titled “Reference Cleanup”The framework provides reference tracking that automatically cleans up references when entities are destroyed:
// Reference tracker cleans up all references to this entity on destructionscene.referenceTracker?.clearReferencesTo(entity.id);Using the @entityRef decorator handles this automatically:
class FollowComponent extends Component { @entityRef() targetId: number | null = null;}
// When target is destroyed, targetId is automatically set to nullSee Component References for details.
Best Practices
Section titled “Best Practices”1. Destroy Unneeded Entities Promptly
Section titled “1. Destroy Unneeded Entities Promptly”// Destroy bullets that fly off screenif (position.x < 0 || position.x > screenWidth) { bullet.destroy();}2. Use Object Pools Instead of Frequent Create/Destroy
Section titled “2. Use Object Pools Instead of Frequent Create/Destroy”class BulletPool { private pool: Entity[] = [];
acquire(scene: Scene): Entity { if (this.pool.length > 0) { const bullet = this.pool.pop()!; bullet.enabled = true; return bullet; } return scene.createEntity('Bullet'); }
release(bullet: Entity) { bullet.enabled = false; this.pool.push(bullet); }}3. Use Persistence Sparingly
Section titled “3. Use Persistence Sparingly”Only use persistence for entities that truly need to survive scene transitions—too many persistent entities increase memory usage.
4. Clean Up References Before Destruction
Section titled “4. Clean Up References Before Destruction”// Notify related systems before destructionconst aiSystem = scene.getSystem(AISystem);aiSystem?.clearTarget(enemy.id);
enemy.destroy();Lifecycle Events
Section titled “Lifecycle Events”You can listen to entity destruction events:
// Method 1: Through event systemscene.eventSystem.on('entity:destroyed', (data) => { console.log(`Entity ${data.entityName} destroyed`);});
// Method 2: In componentclass MyComponent extends Component { onRemovedFromEntity() { console.log('Component removed, entity may be destroying'); // Clean up resources }}Debugging
Section titled “Debugging”// Get entity statusconst debugInfo = entity.getDebugInfo();console.log({ destroyed: debugInfo.destroyed, enabled: debugInfo.enabled, active: debugInfo.active});Next Steps
Section titled “Next Steps”- Component Operations - Adding and removing components
- Scene Management - Scene switching and management