Skip to content

v0.0.51

Choose a tag to compare

@mococa mococa released this 14 Jan 05:47
· 580 commits to main since this release

Release Notes - v0.0.51

Release Date: 2026-01-14

🚀 Major Features

Unlimited Component Support

  • Removed 32 component hard limit - ECS now supports unlimited components through dynamic scaling
  • Components scale dynamically at 32 per bitmask word (32, 64, 96, 128, ...)
  • Architecture changed from fixed Int32Array to dynamic Uint32Array[] for better flexibility

Performance Optimizations

  • Cached first word reference for fast path when using <32 components (most common case)
  • Unrolled loops for 1-4 word cases (up to 128 components) - eliminates loop overhead
  • Query mask caching - zero recomputation for frequently used component combinations
  • Uses plain number[] for masks instead of Uint32Array[] to eliminate extra indirection

Performance Impact:

  • Only 5.7% slower compared to the old fixed implementation
  • Complex simulation (10k entities): 10.34ms (98 FPS) on Intel i5-2400 (2011)
  • 25-component stress test: 18.90ms (52 FPS) - still excellent
  • Modern CPUs will perform significantly better

🔧 Improvements

EntityHandle Overhead Adjustment

  • Adjusted benchmark expectations for EntityHandle overhead to account for CI environment variance
  • CI environments show higher variance due to cold JIT and shared resources
  • Typical production overhead remains 5-15% with warmed JIT

Documentation Enhancements

  • Added comprehensive performance section with benchmark results
  • Documented hardware specifications (Intel i5-2400 @ 3.4GHz, 2011)
  • Updated features list to highlight unlimited component support
  • Clarified component scaling behavior (32 components per bitmask word)
  • Removed outdated 32 component limitation from limitations section

📊 Benchmarks (5-run average, Intel i5-2400 @ 3.4GHz)

Complex Simulation (10,000 entities, 10+ systems):

  • 10.34ms average (98 FPS) ✅

25-Component Stress Test (10,000 entities):

  • 18.90ms average (52 FPS) ✅

Query Performance:

  • Single query: 0.209ms for 10,000 entities
  • 100x repeated queries: 0.11ms (query result caching)

Scaling:

  • 500 entities: 0.6-0.7ms (1,500+ FPS)
  • 1,000 entities: 1.1-1.3ms (800+ FPS)
  • 5,000 entities: 5.0-5.5ms (180+ FPS)
  • 10,000 entities: 10.3ms (98 FPS)
  • 25,000 entities: 24ms (42 FPS)

🔨 Technical Details

Component Mask Architecture

  • Old: Fixed Int32Array with 4 words (128 component hard limit)
  • New: Dynamic Uint32Array[] that scales as needed

Key Implementation Changes

  1. Separate Uint32Array per word for better cache locality
  2. Cached componentMasks0 reference for <32 component fast path
  3. Unrolled matchesComponentMask for 1-4 words
  4. Query mask caching using Record<string, number[]>
  5. Cache key: sorted component names joined by comma

Benefits

  • ✅ No hard component limit (scales dynamically)
  • ✅ Better cache locality for <32 component case
  • ✅ Query mask caching (zero recomputation)
  • ✅ Simpler implementation (no interleaved indexing)

📝 Files Changed

  • src/ecs/world.ts - Core ECS implementation with dynamic component support
  • src/ecs/world.test.ts - Updated tests for dynamic scaling
  • src/ecs/README.md - Enhanced documentation with performance metrics
  • src/ecs/benchmark.test.ts - Adjusted EntityHandle overhead expectations

🎯 Migration Guide

No breaking changes! The API remains identical. Existing code will work without modifications and automatically benefit from unlimited component support.

// Works exactly the same, but now supports unlimited components
const world = new World({
  maxEntities: 10000,
  components: [
    // Add as many components as needed - no 32 limit!
    Transform, Velocity, Health, Armor, Stats, AI, Team,
    // ... up to hundreds of components if needed
  ],
});

🙏 Notes

All benchmarks run on Intel i5-2400 (4 cores) @ 3.4GHz from 2011. Modern CPUs (2020+) will show significantly better performance across all metrics.