Files
synthesis/.cursor/rules/ecs-patterns.mdc
Денис Шкабатур 10bd67c951 Phase 0: Project setup for agent-driven development
- Phaser 3 + bitECS 0.4 + TypeScript + Vite stack
- BootScene with title screen
- 6 cursor rules (project context, agent workflow, ECS, chemistry, Phaser, data)
- Vitest configured with happy-dom
- GDD, engine analysis, implementation plan, progress tracking

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-12 11:59:41 +03:00

66 lines
1.9 KiB
Plaintext

---
description: bitECS 0.4 component and system conventions
globs: src/ecs/**/*.ts
alwaysApply: false
---
# ECS Patterns (bitECS 0.4)
## Components — Plain Objects with Arrays
```typescript
// ✅ GOOD: plain object with number arrays
export const Position = { x: [] as number[], y: [] as number[] };
export const Health = { current: [] as number[], max: [] as number[] };
// ❌ BAD: old API (defineComponent, Types) — removed in 0.4
```
## Entity Lifecycle
```typescript
import { createWorld, addEntity, addComponent, removeEntity } from 'bitecs';
const world = createWorld();
const eid = addEntity(world);
addComponent(world, eid, Position);
Position.x[eid] = 100;
Position.y[eid] = 200;
```
## Queries — Direct Function Calls
```typescript
import { query, Not } from 'bitecs';
// ✅ 0.4 API: query(world, components)
const entities = query(world, [Position, Velocity]);
for (const eid of entities) {
Position.x[eid] += Velocity.x[eid] * delta;
}
// Operators: Not, And, Or, Any, None
const stationary = query(world, [Position, Not(Velocity)]);
```
## Observers (replace enterQuery/exitQuery)
```typescript
import { observe, onAdd, onRemove } from 'bitecs';
observe(world, onAdd(Position), (eid) => { /* entity gained Position */ });
observe(world, onRemove(Position), (eid) => { /* entity lost Position */ });
```
## Systems — Pure Functions
```typescript
export const movementSystem = (world: World, delta: number) => {
for (const eid of query(world, [Position, Velocity])) {
Position.x[eid] += Velocity.x[eid] * delta;
Position.y[eid] += Velocity.y[eid] * delta;
}
};
```
## Rules
- Components = plain objects with `[] as number[]` fields
- Never store strings in components — use numeric IDs, look up in registry
- Systems must not create Phaser objects — only the sync bridge does that
- Parameter order: `addComponent(world, eid, component)` (world first, then eid)