"매 bitECS Component = TypedArray on SAB". bitECS의 매 SoA layout 은 매 SharedArrayBuffer 와 매 자연스럽게 결합 — 매 component data 가 매 worker 에서 매 zero-copy 공유. 매 system 분산 + 매 stripe partition 으로 매 100k+ entity 를 매 60fps 에서 매 simulate 가능.
매 핵심
매 bitECS 구조
Entity: 32-bit integer ID.
Component: 매 TypedArray (Float32Array, Int32Array 등) per field, 매 indexed by entity ID.
System: query → process loop.
매 SoA (Struct of Arrays) → 매 cache-friendly + SIMD-friendly.
매 SAB 통합 핵심
bitECS 의 매 component 매 backing TypedArray 의 매 buffer 를 매 SAB 로 교체.
매 worker 에서 매 동일 component 에 매 동시 접근 가능.
매 system 별로 매 worker 분배 — 또는 매 entity range 별 분배.
매 partition strategy
System-level: physics worker, AI worker, render worker 매 별도.
Entity-level: entity ID 매 mod N → worker N 개에 분산.
Stripe-level: contiguous range, cache-friendly.
Hybrid: 매 read-heavy system 매 모든 worker, write 매 owner worker 만.
매 응용
Boid/flocking: 100k boids 매 4 worker 에서 stripe.
Particle system: SAB Float32 의 매 position/velocity, 매 worker 별 batch.
Pathfinding: A* 매 worker pool, 매 result 매 SAB 에 적재.
Voxel chunk update: 매 chunk 별 worker, 매 mesh build 매 OffscreenCanvas worker.
💻 패턴
Pattern 1: bitECS component → SAB-backed
// main.ts
import{createWorld,defineComponent,Types}from"bitecs";constMAX_ENTITIES=100_000;constsab=newSharedArrayBuffer(MAX_ENTITIES*3*4*2);// pos+vel, f32
// SAB 위에 매 직접 component 정의 (bitECS 0.4+ allows custom buffer)
constPosition={x: newFloat32Array(sab,0,MAX_ENTITIES),y: newFloat32Array(sab,MAX_ENTITIES*4,MAX_ENTITIES),};constVelocity={x: newFloat32Array(sab,MAX_ENTITIES*8,MAX_ENTITIES),y: newFloat32Array(sab,MAX_ENTITIES*12,MAX_ENTITIES),};constworld=createWorld();// ... addEntity, addComponent (writes go into SAB views)
// shared int32 frame counter
constsync=newInt32Array(sab,syncOffset,4);// sync[0] = workersReady, sync[1] = generation
functionworkerStep() {// do work
doStripe();// barrier
if(Atomics.add(sync,0,1)+1===N_WORKERS){Atomics.store(sync,0,0);Atomics.add(sync,1,1);Atomics.notify(sync,1,N_WORKERS-1);}else{constgen=Atomics.load(sync,1);Atomics.wait(sync,1,gen);}}
Pattern 5: read-only system on all workers
// AI system: read pos/vel of others, write own intent → no contention
functionaiSystem(workerId: number){for(leti=start;i<end;i++){letnearestX=0,nearestY=0,nearestDist=Infinity;for(letj=0;j<maxEntities;j++){if(j===i)continue;constdx=px[j]-px[i],dy=py[j]-py[i];constd=dx*dx+dy*dy;if(d<nearestDist){nearestDist=d;nearestX=px[j];nearestY=py[j];}}// write only own intent slot
intent[i]=computeIntent(px[i],py[i],nearestX,nearestY);}}
Pattern 6: render thread on main, worker writes only
// main thread: requestAnimationFrame → read SAB, render
functionframe() {for(leti=0;i<activeCount;i++){ctx.fillRect(px[i],py[i],2,2);}requestAnimationFrame(frame);}// 매 race: workers writing while main reads — visual tearing 가능, 대부분 게임에서 허용.
// strict 의 매 double buffer (front/back) → flip on barrier.
Pattern 7: double-buffered position
constpxA=newFloat32Array(sab,offA,max);constpxB=newFloat32Array(sab,offB,max);letfrontIdx=0;functionworkerStep() {constfront=frontIdx===0?pxA : pxB;constback=frontIdx===0?pxB : pxA;// read front, write back
for(leti=start;i<end;i++)back[i]=front[i]+vx[i]*dt;// barrier → main flips frontIdx
}
Pattern 8: SoA SIMD (WASM SIMD or manual unroll)
// 매 4-wide unroll — JIT가 종종 SIMD화
for(leti=start;i<end;i+=4){px[i]+=vx[i]*dt;px[i+1]+=vx[i+1]*dt;px[i+2]+=vx[i+2]*dt;px[i+3]+=vx[i+3]*dt;}
Pattern 9: spawn/kill queue (lock-free SPSC)
// 매 main 만 spawn, worker 만 kill — single-producer queue
// 매 ring buffer of entity IDs, Atomics-driven head/tail
매 결정 기준
상황
Approach
<1k entities
Single thread, 매 충분
1k–10k, simple physics
bitECS single-thread
10k+, heavy AI/physics
bitECS + SAB + worker pool
Render heavy
OffscreenCanvas worker
Voxel/chunk world
Per-chunk worker assignment
기본값: 매 single thread first. 매 measure → SAB 매 4 worker 부터 의미 있을 때만.
🔗 Graph
부모: ECS · bitECS · Web Worker · SharedArrayBuffer
변형: Bevy ECS · Flecs · Unity DOTS
응용: Browser Game Engine · Particle System · Boid Simulation
Adjacent: Web Worker와 SharedArrayBuffer를 이용한 실제 고부하 병렬 처리 구현체 (실패_성공 포함) · OffscreenCanvas · 가변적 LOD(Level of Detail) 시스템
🤖 LLM 활용
언제: 매 large-scale entity simulation in browser. 매 60fps 매 100k+ entity.
언제 X: 매 small game, 매 single-thread bitECS 충분 — 매 SAB 의 debug 비용 매 큼.
❌ 안티패턴
Anti1: 매 component write 매 worker 동시: race. 매 ownership 명확히.
Anti2: 매 frame SAB 재생성: GC 폭발. startup 1번.
Anti3: 매 worker 마다 component query: query overhead 누적. 매 main 에서 ID list 한번 + worker 에 stripe.
Anti4: false sharing — 매 worker 가 인접 entity write: 매 stripe 대신 매 mod 분산은 false sharing 위험. stripe 사용.
Anti5: render race 무시: visual artifact. 매 double buffer or 매 tolerate.
🧪 검증 / 중복
Verified (bitECS GitHub, 2025–2026 Web Worker SAB ecosystem).