Successfully migrated ~15% of hot path functions from 3 critical systems to TypeScript:
physics.core.ts- Movement and collision calculationsmusic-reactivity.core.ts- Reactivity and culling logicweather.core.ts- Weather state and growth calculations
Based on profiling data, the following functions are called most frequently in hot paths:
Current: Iterates 3000+ objects per frame (60 FPS)
Functions to migrate:
calculateLightFactor()- Called per visible objectcalculateChannelIndex()- Called per reactive objectisObjectVisible()- Distance + frustum culling per object
Expected improvement: 2-3x faster with WASM SIMD operations
Migration strategy:
// Create assembly/music-reactivity.ts
export function batchCalculateLightFactors(
objects: Float32Array, // [minLight, maxLight, ...] packed
globalLight: f32,
results: Float32Array // Output: lightFactor per object
): void {
// WASM SIMD batch processing
}Current: Complex movement calculations every frame
Functions to migrate:
calculateMovementInput()- Vector math- Collision detection loops (when implemented)
Expected improvement: 1.5-2x faster
Current: Many calculations but less frequent
Functions to migrate:
calculateMushroomGrowthRate()- Affects all mushrooms- Batch weather calculations
Expected improvement: 1.2-1.5x faster
Before migrating to WASM, we need concrete performance data:
# Enable profiler in main.js
profiler.toggle()
# Look for functions taking >3ms in:
# - MusicReact
# - Physics
# - Weather# Install AssemblyScript if needed
npm install --save-dev assemblyscript
# Create new WASM module
# assembly/reactivity.tsFollow the 15% rule - migrate only the single hottest function first:
- Profile and identify the #1 hottest function
- Create AssemblyScript version
- Create JS wrapper for WASM calls
- Test performance (must show >20% improvement)
- If successful, migrate next hottest function
Always keep JS/TS versions as fallbacks for:
- Browsers without WASM support
- Development/debugging
- Error recovery
Only migrate if profiling shows:
- Function takes >3ms per frame (16ms budget @ 60 FPS)
- WASM version shows >20% improvement
- Function is called >100 times per frame
WASM requires careful memory management:
- Use linear memory for data transfer
- Batch operations to minimize JS↔WASM overhead
- Reuse memory buffers (no GC in WASM)
Only for the absolute hottest paths (<1% of code):
- SIMD operations for bulk calculations
- Multi-threaded particle systems
- Custom algorithms requiring C++ libraries
GPU acceleration for:
- Particle physics (compute shaders)
- Mass foliage animation
- Custom render pipelines
Is function taking >3ms/frame?
├─ No → Leave in JS/TS
└─ Yes → Is it called >100 times/frame?
├─ No → Move to TS only (Phase 1) ✅ DONE
└─ Yes → Profile WASM version
├─ <20% faster → Keep in TS
└─ >20% faster → Migrate to WASM (Phase 2)
✅ Phase 1 Complete: TypeScript migration done
⏸️ Phase 2 Blocked: Needs profiling data first
📊 Action Required: Run profiler and gather metrics
// In browser console or main.js
profiler.toggle()
// Shows real-time frame breakdown// After enabling profiler, watch for:
// - MusicReact > 5ms
// - Physics > 3ms
// - Red bars (>10ms functions)npm run build:wasm
# Verify candy_physics.wasm is generated- Don't prematurely optimize - always profile first
- The 15% rule applies to every phase
- JS remains the "Drafting Ground" forever
- Type safety from TS helps WASM migration
- Document every migration decision
PERFORMANCE_MIGRATION_STRATEGY.md- Main strategy guidePHASE1_MIGRATION_SUMMARY.md- Phase 1 completion reportassembly/index.ts- Existing WASM physics module (example)