Skip to content

Commit 9c1afa5

Browse files
committed
PRDs
1 parent 39679c1 commit 9c1afa5

7 files changed

Lines changed: 1158 additions & 0 deletions

docs/0-navigation.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,12 @@ graph TD
7070
Implementation --> TSyringeRemoval[4-6 TSyringe Removal Status]
7171
Implementation --> HierarchySystem[4-7 Unity-Like Hierarchy System]
7272
Implementation --> ScriptSystem[4-8 Unity-Like Script System]
73+
Implementation --> InGameUI[4-9 In-Game UI System]
74+
Implementation --> ParticleSystem[4-10 Particle System]
75+
Implementation --> CommandSystem[4-11 Command System]
76+
Implementation --> AssetPipeline[4-12 Asset Pipeline]
77+
Implementation --> CollisionDetection[4-13 Collision Detection System]
78+
Implementation --> NetworkingSystem[4-14 Networking System]
7379
7480
%% Supporting Documentation
7581
Patterns[🎨 Patterns] --> GamePatterns[5-1 Game Patterns]
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
# Particle System PRD
2+
3+
## Overview
4+
5+
### Context & Goals
6+
7+
- Add GPU-accelerated particle effects (muzzle flash, smoke, sparks).
8+
- Author effects via ECS `ParticleComponent` plus presets.
9+
- Support bursts and continuous emitters with lifetime curves.
10+
11+
### Current Pain Points
12+
13+
- No standardized particle effects pipeline.
14+
- Visual feedback missing for actions and impacts.
15+
- Manual effect coding increases coupling and regressions.
16+
17+
## Proposed Solution
18+
19+
### High‑level Summary
20+
21+
- Introduce `ParticleSystem` updating emitter state and GPU buffers.
22+
- Define `ParticleComponent` schema (Zod) with emission and material params.
23+
- Implement instanced/points-based renderer with curves (size, color over time).
24+
- Provide presets and editor-friendly parameters.
25+
26+
### Architecture & Directory Structure
27+
28+
```
29+
/src/core/
30+
├── systems/
31+
│ └── ParticleSystem.ts
32+
├── lib/particles/
33+
│ ├── curves.ts
34+
│ ├── gpuBuffers.ts
35+
│ └── materials.ts
36+
└── components/particles/
37+
├── ParticleEmitter.tsx
38+
└── ParticleComponent.schema.ts
39+
```
40+
41+
## Implementation Plan
42+
43+
1. Phase 1: Core (1 day)
44+
45+
1. Component schema + emitter lifecycle
46+
2. CPU sim baseline; instanced rendering
47+
3. Curves and color/size over lifetime
48+
49+
2. Phase 2: GPU Path (1 day)
50+
51+
1. GPU buffer management
52+
2. Materials and sorting strategies
53+
3. Perf instrumentation
54+
55+
3. Phase 3: Presets & Events (0.5 day)
56+
1. Common presets (smoke/sparks)
57+
2. Trigger via events (e.g., collision)
58+
59+
## File and Directory Structures
60+
61+
```
62+
/docs/implementation/
63+
└── 4-10-particle-system-prd.md
64+
```
65+
66+
## Technical Details
67+
68+
```ts
69+
export interface IParticleComponent {
70+
maxParticles: number;
71+
emissionRate?: number; // particles/sec
72+
burst?: { count: number; interval: number };
73+
lifetime: [number, number]; // min,max
74+
startColor?: [number, number, number, number];
75+
endColor?: [number, number, number, number];
76+
startSize?: number;
77+
endSize?: number;
78+
worldSpace?: boolean;
79+
}
80+
81+
export interface IParticleSystemApi {
82+
triggerBurst(entityId: number, count?: number): void;
83+
}
84+
```
85+
86+
### Editor & Component Integration
87+
88+
```ts
89+
// 1) Add a new KnownComponentType
90+
// src/core/lib/ecs/IComponent.ts
91+
export const KnownComponentTypes = {
92+
// ...existing,
93+
PARTICLES: 'Particles',
94+
} as const;
95+
96+
// 2) Schema & data type
97+
// src/core/components/particles/ParticleComponent.schema.ts
98+
import { z } from 'zod';
99+
export const ParticleComponentSchema = z.object({
100+
enabled: z.boolean().default(true),
101+
maxParticles: z.number().int().positive().default(1024),
102+
emissionRate: z.number().nonnegative().default(0),
103+
burst: z.object({ count: z.number().int().positive(), interval: z.number().positive() }).optional(),
104+
lifetime: z.tuple([z.number().positive(), z.number().positive()]).default([0.5, 1.5]),
105+
startColor: z.tuple([z.number(), z.number(), z.number(), z.number()]).default([1,1,1,1]),
106+
endColor: z.tuple([z.number(), z.number(), z.number(), z.number()]).default([1,1,1,0]),
107+
startSize: z.number().positive().default(0.1),
108+
endSize: z.number().positive().default(0.01),
109+
worldSpace: z.boolean().default(true),
110+
});
111+
export type ParticleData = z.infer<typeof ParticleComponentSchema>;
112+
113+
// 3) Inspector adapter
114+
// src/editor/components/inspector/adapters/ParticleAdapter.tsx
115+
export const ParticleAdapter: React.FC<{
116+
particleComponent: IComponent<ParticleData> | null;
117+
updateComponent: (type: string, data: unknown) => boolean;
118+
removeComponent: (type: string) => boolean;
119+
}> = ({ particleComponent, updateComponent, removeComponent }) => {
120+
// form controls for emission, lifetime, colors, sizes
121+
return null;
122+
};
123+
124+
// 4) Add menu entry + defaults
125+
// src/editor/components/menus/AddComponentMenu.tsx
126+
COMPONENT_DEFINITIONS.push({
127+
id: KnownComponentTypes.PARTICLES,
128+
name: 'Particles',
129+
description: 'GPU-accelerated particle emitter',
130+
icon: /* choose icon */, category: 'VFX',
131+
});
132+
// handle defaultData
133+
case KnownComponentTypes.PARTICLES:
134+
defaultData = { enabled: true, maxParticles: 1024, emissionRate: 50, lifetime: [0.5,1.5] };
135+
break;
136+
137+
// 5) Visualization (optional)
138+
// src/editor/components/panels/ViewportPanel/components/ParticleVisualization.tsx
139+
// draw emitter gizmos, bounds, trajectories when selected
140+
141+
// 6) Runtime registration
142+
// src/core/systems/ParticleSystem.ts
143+
registerSystem({ id: 'core.particles', order: 70, update: (dt) => particleSystem.update(dt) });
144+
```
145+
146+
## Usage Examples
147+
148+
```ts
149+
// Create an emitter and trigger a burst
150+
particles.triggerBurst(entityId, 30);
151+
```
152+
153+
## Testing Strategy
154+
155+
- Unit: curve evaluation, lifetime pool reuse, schema validation.
156+
- Integration: emitter updates in step loop, rendering stability under load.
157+
158+
## Edge Cases
159+
160+
| Edge Case | Remediation |
161+
| ------------------- | --------------------------------------------------- |
162+
| Excess particles | Cap by `maxParticles` with LRU replacement |
163+
| Transparent sorting | Use approximate back-to-front or disable depthWrite |
164+
165+
## Sequence Diagram
166+
167+
```mermaid
168+
sequenceDiagram
169+
participant ECS
170+
participant ParticleSystem
171+
participant Renderer
172+
ECS->>ParticleSystem: update emitters
173+
ParticleSystem->>Renderer: upload buffers
174+
Renderer-->>ParticleSystem: frame rendered
175+
```
176+
177+
## Risks & Mitigations
178+
179+
| Risk | Mitigation |
180+
| ------------ | ------------------------------------------ |
181+
| GPU overdraw | Limit size, soft particle options, pooling |
182+
| GC pressure | Reuse buffers; object pools |
183+
184+
## Timeline
185+
186+
- Total: ~2.5 days (Core 1, GPU 1, Presets 0.5)
187+
188+
## Acceptance Criteria
189+
190+
- Emitters spawn particles with curves and pooling.
191+
- GPU path sustains target FPS for 5k particles.
192+
- Event-triggered effects work (e.g., collisions).
193+
194+
## Conclusion
195+
196+
Adds a scalable particle pipeline with ECS-first authoring and GPU efficiency.
197+
198+
## Assumptions & Dependencies
199+
200+
- Three.js renderer; existing event bus; Zod available.
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
# Command System PRD
2+
3+
## Overview
4+
5+
### Context & Goals
6+
7+
- Provide undo/redo for gameplay/editor operations.
8+
- Enable AI/behavior scripts to enqueue reversible actions.
9+
- Standardize transactional changes across ECS.
10+
11+
### Current Pain Points
12+
13+
- No unified command contract or history.
14+
- Hard to revert multi-entity operations safely.
15+
- Limited observability for action auditing.
16+
17+
## Proposed Solution
18+
19+
### High‑level Summary
20+
21+
- Define `ICommand` with `do/undo/serialize` and idempotency.
22+
- Maintain command stacks with grouping and checkpoints.
23+
- Emit events for telemetry and AI integration.
24+
- Persist compact history (optional caps, pruning).
25+
26+
### Architecture & Directory Structure
27+
28+
```
29+
/src/core/
30+
├── lib/commands/
31+
│ ├── CommandBus.ts
32+
│ ├── CommandHistory.ts
33+
│ └── commands/
34+
│ ├── TransformCommands.ts
35+
│ └── ComponentCommands.ts
36+
└── systems/
37+
└── CommandSystem.ts
38+
```
39+
40+
## Implementation Plan
41+
42+
1. Phase 1: Contracts (0.5 day)
43+
44+
1. Define `ICommand` and bus/history APIs
45+
2. Add grouping and checkpoint semantics
46+
47+
2. Phase 2: Core Commands (0.5 day)
48+
49+
1. Transform add/update/remove
50+
2. Generic component add/remove/update
51+
52+
3. Phase 3: Integration (0.5 day)
53+
1. Event emission for telemetry
54+
2. Script API bridge for AI
55+
56+
## File and Directory Structures
57+
58+
```
59+
/docs/implementation/
60+
└── 4-11-command-system-prd.md
61+
```
62+
63+
## Technical Details
64+
65+
```ts
66+
export interface ICommand<T = unknown> {
67+
id: string;
68+
do(context?: T): Promise<void> | void;
69+
undo(context?: T): Promise<void> | void;
70+
serialize?(): Record<string, unknown>;
71+
}
72+
73+
export interface ICommandBus {
74+
execute(cmd: ICommand): Promise<void>;
75+
undo(): Promise<void>;
76+
redo(): Promise<void>;
77+
beginGroup(label?: string): void;
78+
endGroup(): void;
79+
}
80+
```
81+
82+
### Editor Integration
83+
84+
```ts
85+
// 1) Wrap component mutations in CommandBus
86+
// src/editor/components/menus/AddComponentMenu.tsx
87+
// instead of componentManager.addComponent(...)
88+
await commandBus.execute(new AddComponentCommand({ entityId, type: componentType, data: defaultData }));
89+
90+
// src/editor/components/inspector/adapters/*
91+
// replace updateComponent/removeComponent calls similarly via commands
92+
93+
// 2) Toolbar bindings (undo/redo)
94+
// src/editor/store/editorStore.ts
95+
import { commandBus } from '@/core/lib/commands/CommandBus';
96+
undo: async () => { await commandBus.undo(); },
97+
redo: async () => { await commandBus.redo(); },
98+
99+
// 3) Command examples
100+
// src/core/lib/commands/commands/ComponentCommands.ts
101+
export class AddComponentCommand implements ICommand {
102+
constructor(private p: { entityId: number; type: string; data: unknown }) {}
103+
async do() { componentManager.addComponent(this.p.entityId, this.p.type, this.p.data); }
104+
async undo() { componentManager.removeComponent(this.p.entityId, this.p.type); }
105+
}
106+
107+
export class UpdateComponentCommand implements ICommand {
108+
constructor(private p: { entityId: number; type: string; prev: unknown; next: unknown }) {}
109+
async do() { componentManager.updateComponent(this.p.entityId, this.p.type, this.p.next); }
110+
async undo() { componentManager.updateComponent(this.p.entityId, this.p.type, this.p.prev); }
111+
}
112+
113+
// 4) System registration (optional for telemetry/cleanup)
114+
// src/core/systems/CommandSystem.ts
115+
registerSystem({ id: 'core.commands', order: 10, update: () => commandBus.flush() });
116+
117+
// 5) Script API bridge (for AI)
118+
// src/core/lib/scripting/ScriptAPI.ts
119+
export const createCommandAPI = (bus: ICommandBus) => ({
120+
execute: (cmd: ICommand) => bus.execute(cmd),
121+
undo: () => bus.undo(),
122+
redo: () => bus.redo(),
123+
});
124+
```
125+
126+
## Usage Examples
127+
128+
```ts
129+
await commandBus.execute(new SetTransform({ entityId, position }));
130+
await commandBus.undo();
131+
```
132+
133+
## Testing Strategy
134+
135+
- Unit: idempotency, grouping behavior, history bounds.
136+
- Integration: ECS changes reversible across systems.
137+
138+
## Edge Cases
139+
140+
| Edge Case | Remediation |
141+
| ------------------ | ------------------------------------------ |
142+
| Long chains | Cap history; periodic checkpoints |
143+
| Non-reversible ops | Gate behind safeguards; skip serialization |
144+
145+
## Sequence Diagram
146+
147+
```mermaid
148+
sequenceDiagram
149+
participant Client
150+
participant CommandBus
151+
participant ECS
152+
Client->>CommandBus: execute(cmd)
153+
CommandBus->>ECS: apply changes
154+
Client->>CommandBus: undo()
155+
CommandBus->>ECS: revert changes
156+
```
157+
158+
## Risks & Mitigations
159+
160+
| Risk | Mitigation |
161+
| ------------------ | --------------------------------------------- |
162+
| Inconsistent state | Snapshot before group; validation after apply |
163+
| Performance | Batch updates; coalesce trivial commands |
164+
165+
## Timeline
166+
167+
- Total: ~1.5 days (Contracts 0.5, Core 0.5, Integration 0.5)
168+
169+
## Acceptance Criteria
170+
171+
- Reversible transform/component changes.
172+
- Grouped actions undo/redo atomically.
173+
- Events emitted for telemetry.
174+
175+
## Conclusion
176+
177+
Creates a robust foundation for undoable gameplay/editor operations and AI control.
178+
179+
## Assumptions & Dependencies
180+
181+
- Event bus available; ECS component manager supports diffing.

0 commit comments

Comments
 (0)