@lagless/create 0.0.36 → 0.0.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/LICENSE +26 -0
  2. package/dist/index.js +96 -16
  3. package/dist/index.js.map +1 -1
  4. package/package.json +5 -5
  5. package/templates/pixi-react/AGENTS.md +57 -27
  6. package/templates/pixi-react/CLAUDE.md +225 -49
  7. package/templates/pixi-react/README.md +16 -6
  8. package/templates/pixi-react/__packageName__-backend/package.json +1 -0
  9. package/templates/pixi-react/__packageName__-backend/src/main.ts +2 -0
  10. package/templates/pixi-react/__packageName__-frontend/package.json +8 -1
  11. package/templates/pixi-react/__packageName__-frontend/src/app/game-view/grid-background.tsx +4 -0
  12. package/templates/pixi-react/__packageName__-frontend/src/app/game-view/player-view.tsx +68 -0
  13. package/templates/pixi-react/__packageName__-frontend/src/app/game-view/runner-provider.tsx +57 -0
  14. package/templates/pixi-react/__packageName__-frontend/src/app/hooks/use-start-multiplayer-match.ts +5 -5
  15. package/templates/pixi-react/__packageName__-frontend/src/app/screens/title.screen.tsx +18 -1
  16. package/templates/pixi-react/__packageName__-frontend/{vite.config.ts → vite.config.ts.ejs} +0 -2
  17. package/templates/pixi-react/__packageName__-simulation/package.json +7 -0
  18. package/templates/pixi-react/__packageName__-simulation/src/lib/arena.ts +12 -0
  19. package/templates/pixi-react/__packageName__-simulation/src/lib/schema/ecs.yaml +90 -6
  20. package/templates/pixi-react/__packageName__-simulation/src/lib/systems/apply-move-input.system.ts +73 -0
  21. package/templates/pixi-react/__packageName__-simulation/src/lib/systems/boundary.system.ts +2 -0
  22. package/templates/pixi-react/__packageName__-simulation/src/lib/systems/damping.system.ts +2 -0
  23. package/templates/pixi-react/__packageName__-simulation/src/lib/systems/index.ts +8 -0
  24. package/templates/pixi-react/__packageName__-simulation/src/lib/systems/integrate.system.ts +2 -0
  25. package/templates/pixi-react/__packageName__-simulation/src/lib/systems/physics-step.system.ts +65 -0
  26. package/templates/pixi-react/__packageName__-simulation/src/lib/systems/player-connection.system.ts +158 -0
  27. package/templates/pixi-react/__packageName__-simulation/src/lib/systems/player-leave.system.ts +70 -0
  28. package/templates/pixi-react/__packageName__-simulation/src/lib/systems/save-prev-transform.system.ts +46 -0
  29. package/templates/pixi-react/docs/01-schema-and-codegen.md +244 -0
  30. package/templates/pixi-react/docs/02-ecs-systems.md +293 -0
  31. package/templates/pixi-react/docs/03-determinism.md +204 -0
  32. package/templates/pixi-react/docs/04-input-system.md +255 -0
  33. package/templates/pixi-react/docs/05-signals.md +175 -0
  34. package/templates/pixi-react/docs/06-rendering.md +256 -0
  35. package/templates/pixi-react/docs/07-multiplayer.md +277 -0
  36. package/templates/pixi-react/docs/08-physics2d.md +266 -0
  37. package/templates/pixi-react/docs/08-physics3d.md +312 -0
  38. package/templates/pixi-react/docs/09-recipes.md +362 -0
  39. package/templates/pixi-react/docs/10-common-mistakes.md +224 -0
  40. package/templates/pixi-react/docs/api-quick-reference.md +254 -0
  41. package/templates/pixi-react/package.json +6 -0
  42. /package/templates/pixi-react/__packageName__-backend/{tsconfig.json → tsconfig.json.ejs} +0 -0
  43. /package/templates/pixi-react/__packageName__-frontend/{tsconfig.json → tsconfig.json.ejs} +0 -0
  44. /package/templates/pixi-react/__packageName__-simulation/{.swcrc → .swcrc.ejs} +0 -0
  45. /package/templates/pixi-react/__packageName__-simulation/{tsconfig.json → tsconfig.json.ejs} +0 -0
  46. /package/templates/pixi-react/{tsconfig.base.json → tsconfig.base.json.ejs} +0 -0
@@ -0,0 +1,254 @@
1
+ # API Quick Reference
2
+
3
+ ## Entity Management
4
+
5
+ ```typescript
6
+ // Create entity
7
+ const entity = entities.createEntity();
8
+
9
+ // Remove entity (recycled to LIFO stack)
10
+ entities.removeEntity(entity);
11
+
12
+ // Add component to entity
13
+ entities.addComponent(entity, MyComponent);
14
+
15
+ // Remove component from entity
16
+ entities.removeComponent(entity, MyComponent);
17
+
18
+ // Check if entity has component
19
+ entities.hasComponent(entity, MyComponent); // boolean
20
+ ```
21
+
22
+ ## Component Access
23
+
24
+ ```typescript
25
+ // Hot path — typed array access (fastest, use in system loops)
26
+ component.unsafe.fieldName[entity] // read
27
+ component.unsafe.fieldName[entity] = value; // write
28
+
29
+ // Convenient — cursor (single entity, creates object)
30
+ const cursor = component.getCursor(entity);
31
+ cursor.fieldName; // read
32
+ cursor.fieldName = value; // write
33
+
34
+ // Bulk set — multiple fields at once
35
+ component.set(entity, { fieldA: 1, fieldB: 2 });
36
+ ```
37
+
38
+ ## Singletons
39
+
40
+ ```typescript
41
+ // Direct property access
42
+ singleton.fieldName // read
43
+ singleton.fieldName = value // write
44
+ ```
45
+
46
+ ## Player Resources
47
+
48
+ ```typescript
49
+ // Indexed by player slot (0 to maxPlayers-1)
50
+ playerResource.fieldName[slot] // read
51
+ playerResource.fieldName[slot] = value // write
52
+ ```
53
+
54
+ ## Filters
55
+
56
+ ```typescript
57
+ // Iterate matching entities
58
+ for (const entity of filter) { ... }
59
+
60
+ // Entity count
61
+ filter.length
62
+
63
+ // Raw entity array
64
+ filter.entities // number[]
65
+ ```
66
+
67
+ ## Input (RPCs)
68
+
69
+ ```typescript
70
+ // Client side — send input (in drainInputs callback)
71
+ addRPC(InputClass, { field1: value1, field2: value2 });
72
+
73
+ // System side — read inputs for current tick
74
+ const rpcs = inputProvider.collectTickRPCs(tick, InputClass);
75
+ for (const rpc of rpcs) {
76
+ rpc.meta.playerSlot // which player (255 = server)
77
+ rpc.meta.seq // sequence number
78
+ rpc.data.field1 // input data fields
79
+ }
80
+
81
+ // Get all RPCs at a tick (regardless of type)
82
+ const buffer = inputProvider.getFrameRPCBuffer(tick);
83
+ ```
84
+
85
+ ## Signals
86
+
87
+ ```typescript
88
+ // Define
89
+ @ECSSignal()
90
+ class MySignal extends Signal<{ value: number }> {}
91
+
92
+ // Emit (in system)
93
+ signal.emit(tick, { value: 42 });
94
+
95
+ // Subscribe (in view)
96
+ signal.Predicted.subscribe(event => { ... }); // instant
97
+ signal.Verified.subscribe(event => { ... }); // permanent
98
+ signal.Cancelled.subscribe(event => { ... }); // rolled back
99
+
100
+ // Unsubscribe
101
+ const sub = signal.Predicted.subscribe(handler);
102
+ sub.unsubscribe();
103
+ ```
104
+
105
+ ## PRNG (Deterministic Random)
106
+
107
+ ```typescript
108
+ prng.getFloat() // [0, 1)
109
+ prng.getRandomInt(from, to) // [from, to) exclusive upper
110
+ prng.getRandomIntInclusive(from, to) // [from, to] inclusive upper
111
+ ```
112
+
113
+ ## MathOps (Deterministic Math)
114
+
115
+ ```typescript
116
+ import { MathOps } from '@lagless/math';
117
+
118
+ await MathOps.init(); // must call before use
119
+
120
+ MathOps.sin(x)
121
+ MathOps.cos(x)
122
+ MathOps.tan(x)
123
+ MathOps.atan2(y, x)
124
+ MathOps.sqrt(x)
125
+ MathOps.pow(base, exp)
126
+ MathOps.log(x)
127
+ MathOps.exp(x)
128
+ MathOps.clamp(value, min, max)
129
+
130
+ // Safe JS Math (no MathOps needed):
131
+ Math.abs(x), Math.min(a,b), Math.max(a,b)
132
+ Math.floor(x), Math.ceil(x), Math.round(x), Math.trunc(x)
133
+ Math.sign(x), Math.fround(x)
134
+ ```
135
+
136
+ ## ECSConfig
137
+
138
+ ```typescript
139
+ config.maxEntities // default 1024
140
+ config.maxPlayers // default 4
141
+ config.tickRate // ticks per second (e.g., 20)
142
+ config.frameLength // seconds per tick (e.g., 0.05)
143
+ config.snapshotRate // ticks between snapshots
144
+ config.inputDelay // default input delay ticks
145
+ ```
146
+
147
+ ## ECSSimulation
148
+
149
+ ```typescript
150
+ simulation.tick // current tick number
151
+ simulation.interpolationFactor // 0-1, for visual interpolation
152
+ simulation.clock.deltaTime // render frame delta time
153
+ simulation.mem.buffer // raw ArrayBuffer
154
+
155
+ // Hash tracking
156
+ simulation.enableHashTracking(interval);
157
+
158
+ // State transfer
159
+ simulation.applyExternalState(buffer, tick);
160
+
161
+ // Callbacks
162
+ simulation.onTick(callback);
163
+ simulation.onRollback(callback);
164
+ ```
165
+
166
+ ## ECSRunner
167
+
168
+ ```typescript
169
+ runner.start() // begin simulation
170
+ runner.update(deltaTime) // advance one frame
171
+ runner.dispose() // cleanup
172
+
173
+ runner.Simulation // ECSSimulation instance
174
+ runner.InputProviderInstance // input provider
175
+ runner.DIContainer // DI container
176
+ runner.Core // typed access to all ECS objects
177
+ ```
178
+
179
+ ## Prefabs
180
+
181
+ ```typescript
182
+ import { Prefab } from '@lagless/core';
183
+
184
+ const entity = Prefab.create(entities)
185
+ .with(ComponentA, { field: value })
186
+ .with(ComponentB, { field: value })
187
+ .build();
188
+ ```
189
+
190
+ ## VisualSmoother2d
191
+
192
+ ```typescript
193
+ import { VisualSmoother2d } from '@lagless/misc';
194
+
195
+ const smoother = new VisualSmoother2d();
196
+
197
+ const pos = smoother.update(
198
+ prevX, prevY, // previous tick position
199
+ currX, currY, // current tick position
200
+ interpFactor, // 0-1 interpolation factor
201
+ deltaTime, // render frame dt
202
+ );
203
+ // pos.x, pos.y — smoothed position
204
+ ```
205
+
206
+ ## FilterViews (Pixi.js)
207
+
208
+ ```tsx
209
+ import { FilterViews, filterView } from '@lagless/pixi-react';
210
+ import { RunnerTicker } from '@lagless/pixi-react';
211
+
212
+ // Auto-manage entity views
213
+ <FilterViews filter={runner.Core.MyFilter} View={MyView} />
214
+
215
+ // Define view
216
+ const MyView = filterView(
217
+ ({ entity, runner }, ref) => <pixiContainer ref={ref} />,
218
+ {
219
+ onUpdate: ({ entity, runner }, container) => { ... },
220
+ onDestroy: ({ entity, runner }, container) => { ... },
221
+ },
222
+ );
223
+
224
+ // Connect simulation to Pixi render loop
225
+ <RunnerTicker runner={runner} />
226
+ ```
227
+
228
+ ## Relay (Multiplayer)
229
+
230
+ ```typescript
231
+ // Client
232
+ import { RelayConnection } from '@lagless/relay-client';
233
+ const conn = new RelayConnection({ serverUrl, scope });
234
+ await conn.connect();
235
+
236
+ // Server
237
+ import { RelayGameServer } from '@lagless/relay-game-server';
238
+ const server = new RelayGameServer({ port, roomType, matchmaking });
239
+ server.start();
240
+
241
+ // Server hooks — ctx methods
242
+ ctx.emitServerEvent(InputClass, data);
243
+ ctx.getPlayers();
244
+ ctx.endMatch(results);
245
+ ```
246
+
247
+ ## Debug
248
+
249
+ ```tsx
250
+ import { DebugPanel } from '@lagless/react';
251
+
252
+ <DebugPanel runner={runner} hashVerification={true} />
253
+ // Toggle with F3
254
+ ```
@@ -1,8 +1,14 @@
1
1
  {
2
2
  "private": true,
3
3
  "scripts": {
4
+ "dev": "concurrently -k -n backend,frontend,player -c blue,green,yellow \"pnpm dev:backend\" \"pnpm dev:frontend\" \"pnpm dev:player\"",
4
5
  "dev:frontend": "pnpm --filter <%= packageName %>-frontend dev",
5
6
  "dev:backend": "pnpm --filter <%= packageName %>-backend dev",
7
+ "dev:player": "lagless-dev-player --game-url http://localhost:<%= frontendPort %> --server-url ws://localhost:<%= serverPort %> --scope <%= packageName %>",
6
8
  "codegen": "npx @lagless/codegen -c <%= packageName %>-simulation/src/lib/schema/ecs.yaml"
9
+ },
10
+ "devDependencies": {
11
+ "@lagless/dev-player": "^<%= laglessVersion %>",
12
+ "concurrently": "^9.1.0"
7
13
  }
8
14
  }