跳到內容

aiecsjs — 實體元件系統

import { Aside } from ‘@astrojs/starlight/components’;

aiecsjs 是一個 TypeScript 優先的 archetype ECS(Entity Component System)。核心特性是 archetype table:擁有相同 component 組合的 entity 存在同一個連續陣列裡,查詢時以直線 for 迴圈走 TypedArray,cache 友善。

Terminal window
pnpm add aiecsjs
import {
createWorld,
createEntity,
addComponent,
defineComponent,
defineQuery,
pipe,
forEachEntityIndexed,
Types,
} from "aiecsjs";
// 1. 定義 components(SoA 欄位)
const Position = defineComponent({ x: Types.f32, y: Types.f32 });
const Velocity = defineComponent({ x: Types.f32, y: Types.f32 });
// 2. 建立 world 與 entity
const world = createWorld();
const eid = createEntity(world);
addComponent(world, eid, Position, { x: 0, y: 0 });
addComponent(world, eid, Velocity, { x: 1, y: 2 });
// 3. 定義 query:有 Position + Velocity 的所有 entity
const movers = defineQuery([Position, Velocity]);
// 4. System 是純函數,用 pipe 串接
const movement = (w: typeof world, dt: number) => {
forEachEntityIndexed(w, movers, (e, i, pos, vel) => {
// i 是安全的欄位下標,不要用 e(entity id ≠ column index)
pos.x[i] += vel.x[i] * dt;
pos.y[i] += vel.y[i] * dt;
});
return w;
};
// 每幀
pipe(movement)(world, 1 / 60);
World
└── Archetype Table(每種 component 組合一張表)
└── TypedArray 欄位(SoA:同類型資料連續存放)
Entity 重用 EntityId 的 generation bits(ABA 安全)
  • defineComponent:定義一個 SoA component,欄位型別用 Types.f32 / i32 / ui32 / f64
  • defineQuery:宣告查詢,回傳可在 forEachEntityIndexed 中使用的 query 物件
  • pipe:將多個 system 串成一條執行管線
  • forEachEntityIndexed:推薦的欄位走訪 API,callback 同時提供 e(EntityId)與 i(欄位下標)
Subpath用途
aiecsjs核心 API
aiecsjs/looprequestAnimationFrame 整合輔助
aiecsjs/commandsCommand buffer,延遲 structural change
aiecsjs/observersenterQuery / exitQuery 觀察 component 變化
aiecsjs/serializetoJSON / fromJSON 序列化 snapshot
aiecsjs/workerSAB snapshot transport,跨 Worker 傳輸
aiecsjs/relationsEntity 間的關係(parent/child 等)
  • aipooljs 搭配:Pool 管理 PixiJS Sprite 物件,ECS 管理資料邏輯
  • aiquadtreejs 搭配:ECS entity 的 AABB 欄位直接 insert 進 quadtree 做廣泛相碰撞查詢
  • aifsmjs 搭配:entity 的行為狀態(idle/walk/attack)存成 FSM snapshot component
  • aibridgejs 搭配:用 aiecsjs/serialize 序列化 world snapshot,再透過 bridge 傳到另一個 context