Skip to content

v0.0.43

Choose a tag to compare

@mococa mococa released this 30 Dec 11:02
· 611 commits to main since this release

Release Notes - v0.0.43

ECS Performance & Ergonomics Update

🚀 Performance Optimizations

Query Performance - 55-67% faster in query-heavy workloads

  • 8x loop unrolling with write cursor pattern
  • 10k entities, 100 queries: 10.41ms → 4.66ms

Component Operations - Up to 12% faster updates

  • Fast paths for single and dual-field updates (covers 90% of use cases)
  • Loop unrolling for 2/3/4-field components
  • Zero allocation for common update patterns

Math Operations - 2-3% improvement

  • Inlined Math.max/Math.min in hot paths
  • Eliminated function call overhead

✨ New Features

EntityHandle Fluent API

Chainable interface with minimal overhead for better code ergonomics:

const player = world.entity(world.spawn())
  .add(Transform, { x: 0, y: 0, rotation: 0 })
  .add(Health, { current: 100, max: 100 })
  .update(Transform, { x: 10 });

Performance characteristics:

  • 7.8% average overhead (within JIT variance)
  • 37.6% faster entity creation due to JIT optimization
  • Zero-cost abstraction in production with warmed JIT

📊 Production Benchmarks

Results averaged across 5 runs using bun test --rerun-each=5:

Entities Avg Frame Std Dev FPS 60fps Budget 30fps Budget
500 0.62ms ±0.15ms 1,623 ✅ 3.7% ✅ 1.8%
1,000 0.96ms ±0.09ms 1,037 ✅ 5.8% ✅ 2.9%
5,000 4.91ms ±0.24ms 204 ✅ 29.5% ✅ 14.7%
10,000 9.54ms ±0.10ms 105 ✅ 57.2% ✅ 28.6%
25,000 23.55ms ±0.24ms 42 ❌ 141.3% ✅ 70.7%
50,000 46.55ms ±0.71ms 21 ❌ 279.3% ⚠️ 139.7%

Key takeaways:

  • ✅ 10k entities fits comfortably in 60 FPS budget (57% utilization)
  • ✅ 25k entities achieves stable 30 FPS (70% utilization)
  • Low standard deviations indicate stable, predictable performance

Memory Scaling

Perfect linear scaling at 24 bytes/entity (TypedArray-based storage):

  • Transform: 12 bytes (x, y, rotation: f32)
  • Health: 4 bytes (current, max: u16)
  • Overhead: 8 bytes (bitmask + index)

🔧 Testing & Validation

  • Added memory scaling benchmark proving O(n) memory complexity
  • Added EntityHandle vs Raw API comparison benchmark
  • All benchmarks use --rerun-each for statistical accuracy
  • 49 passing tests with comprehensive performance validation

📚 Documentation

  • Updated README with averaged benchmark results (5 runs)
  • Added EntityHandle API documentation with usage examples
  • Documented all optimization techniques applied
  • Clear methodology notes for reproducible benchmarks

Migration Guide

No breaking changes. The new EntityHandle API is opt-in:

// Old way (still works)
const id = world.spawn();
world.add(id, Transform, { x: 0, y: 0, rotation: 0 });

// New way (recommended for better ergonomics)
const entity = world.entity(world.spawn())
  .add(Transform, { x: 0, y: 0, rotation: 0 });

// Mix both freely
world.add(entity.id, Health, { current: 100, max: 100 });

The optimizations are automatic and require no code changes.