@sadhaka/loom-engine 0.11.0 → 0.13.0
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.
- package/COMMERCIAL_LICENSE_TERMS.md +74 -0
- package/README.md +230 -6
- package/dist/components/peer-sprite.d.ts +25 -0
- package/dist/components/peer-sprite.d.ts.map +1 -0
- package/dist/components/peer-sprite.js +48 -0
- package/dist/components/peer-sprite.js.map +1 -0
- package/dist/engine.d.ts +6 -1
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +35 -1
- package/dist/engine.js.map +1 -1
- package/dist/index.d.ts +19 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -2
- package/dist/index.js.map +1 -1
- package/dist/network/mock-multiplayer-bridge.d.ts +34 -0
- package/dist/network/mock-multiplayer-bridge.d.ts.map +1 -0
- package/dist/network/mock-multiplayer-bridge.js +91 -0
- package/dist/network/mock-multiplayer-bridge.js.map +1 -0
- package/dist/network/multiplayer-bridge.d.ts +45 -0
- package/dist/network/multiplayer-bridge.d.ts.map +1 -0
- package/dist/network/multiplayer-bridge.js +34 -0
- package/dist/network/multiplayer-bridge.js.map +1 -0
- package/dist/network/peer-pool.d.ts +46 -0
- package/dist/network/peer-pool.d.ts.map +1 -0
- package/dist/network/peer-pool.js +185 -0
- package/dist/network/peer-pool.js.map +1 -0
- package/dist/network/sse-multiplayer-bridge.d.ts +36 -0
- package/dist/network/sse-multiplayer-bridge.d.ts.map +1 -0
- package/dist/network/sse-multiplayer-bridge.js +264 -0
- package/dist/network/sse-multiplayer-bridge.js.map +1 -0
- package/dist/renderer/shaders/sprite-shader-source.d.ts +4 -0
- package/dist/renderer/shaders/sprite-shader-source.d.ts.map +1 -0
- package/dist/renderer/shaders/sprite-shader-source.js +83 -0
- package/dist/renderer/shaders/sprite-shader-source.js.map +1 -0
- package/dist/renderer/sprite-batcher.d.ts +30 -0
- package/dist/renderer/sprite-batcher.d.ts.map +1 -0
- package/dist/renderer/sprite-batcher.js +146 -0
- package/dist/renderer/sprite-batcher.js.map +1 -0
- package/dist/renderer/texture-atlas.d.ts +24 -0
- package/dist/renderer/texture-atlas.d.ts.map +1 -0
- package/dist/renderer/texture-atlas.js +173 -0
- package/dist/renderer/texture-atlas.js.map +1 -0
- package/dist/renderer/webgl2-device.d.ts +53 -0
- package/dist/renderer/webgl2-device.d.ts.map +1 -0
- package/dist/renderer/webgl2-device.js +596 -0
- package/dist/renderer/webgl2-device.js.map +1 -0
- package/dist/systems/peer-presence-system.d.ts +19 -0
- package/dist/systems/peer-presence-system.d.ts.map +1 -0
- package/dist/systems/peer-presence-system.js +118 -0
- package/dist/systems/peer-presence-system.js.map +1 -0
- package/package.json +11 -5
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Loom Engine - Commercial License Terms (Outline)
|
|
2
|
+
|
|
3
|
+
This document is a starting point for negotiation, not a binding offer.
|
|
4
|
+
Final terms are agreed in writing between Misha Mitiev (Licensor) and
|
|
5
|
+
the commercial licensee.
|
|
6
|
+
|
|
7
|
+
## When a commercial license is required
|
|
8
|
+
|
|
9
|
+
When your gross revenue from any product, game, or service that
|
|
10
|
+
incorporates the Loom Engine exceeds **USD $1,000,000 in any consecutive
|
|
11
|
+
12-month period**, you must obtain a commercial license to continue
|
|
12
|
+
using the engine in production.
|
|
13
|
+
|
|
14
|
+
Below this threshold, the [Business Source License 1.1](./LICENSE)
|
|
15
|
+
applies and no commercial license is required.
|
|
16
|
+
|
|
17
|
+
## Standard terms
|
|
18
|
+
|
|
19
|
+
- **Royalty**: 5% of gross revenue above the $1,000,000 threshold per
|
|
20
|
+
license-year, paid quarterly.
|
|
21
|
+
- **Reporting**: Quarterly revenue statement, audit-on-request clause
|
|
22
|
+
(audits limited to once per year, 30-day notice).
|
|
23
|
+
- **Sub-licensing**: Not permitted without separate written agreement.
|
|
24
|
+
- **Patent grant**: Limited grant covering normal engine use; does not
|
|
25
|
+
extend to derivative engines or competing engine products. See
|
|
26
|
+
PRIOR-ART.md for the patent-strategy scope.
|
|
27
|
+
- **Term**: Annual, auto-renewing on the anniversary of the agreement.
|
|
28
|
+
- **Termination**: 90 days notice either side. Royalty obligations
|
|
29
|
+
survive termination for revenue earned during the licensed period.
|
|
30
|
+
- **Jurisdiction**: To be agreed; default Thailand or licensee's home
|
|
31
|
+
jurisdiction with mutual consent.
|
|
32
|
+
|
|
33
|
+
## Negotiable alternatives
|
|
34
|
+
|
|
35
|
+
The Licensor is open to non-standard arrangements, including:
|
|
36
|
+
|
|
37
|
+
- **Lump-sum buyout**: One-time payment in lieu of royalties, scoped to
|
|
38
|
+
a specific product or product line. Pricing varies by project size +
|
|
39
|
+
expected revenue.
|
|
40
|
+
- **Equity-for-license**: Early-stage studios may exchange equity for a
|
|
41
|
+
perpetual royalty-free license. Typical range 0.5%-2% equity for a
|
|
42
|
+
full commercial grant.
|
|
43
|
+
- **Reduced royalty rate**: For OSS projects, cooperatively-owned
|
|
44
|
+
studios, or non-profit ventures, royalty may be reduced or waived.
|
|
45
|
+
- **Distribution-based fees**: For middleware, SDKs, or engine-derived
|
|
46
|
+
toolchains, per-distribution fees may replace revenue royalties.
|
|
47
|
+
|
|
48
|
+
## Pre-publish window (0.10.0 grandfathering)
|
|
49
|
+
|
|
50
|
+
If your project pinned to `@sadhaka/loom-engine@0.10.0` (the only
|
|
51
|
+
release published under MIT) before 2026-05-08, you may continue using
|
|
52
|
+
that version under MIT terms indefinitely. No commercial license is
|
|
53
|
+
required for that specific version.
|
|
54
|
+
|
|
55
|
+
Upgrading to 0.11.0 or later requires accepting BUSL-1.1 terms and, if
|
|
56
|
+
above the revenue threshold, a commercial license.
|
|
57
|
+
|
|
58
|
+
## Contact
|
|
59
|
+
|
|
60
|
+
Email: `licensor@theworldtable.ai`
|
|
61
|
+
|
|
62
|
+
Please include in your inquiry:
|
|
63
|
+
- Company name and primary use case
|
|
64
|
+
- Estimated annual revenue from the product/service using the engine
|
|
65
|
+
- Distribution model (B2C, B2B, internal, etc.)
|
|
66
|
+
- Preferred negotiation framing (royalty / lump-sum / equity / other)
|
|
67
|
+
|
|
68
|
+
Response time: typically within 5 business days.
|
|
69
|
+
|
|
70
|
+
## Disclaimer
|
|
71
|
+
|
|
72
|
+
These outline terms do not constitute a binding offer or contract. A
|
|
73
|
+
commercial license is only effective when both parties have signed a
|
|
74
|
+
written agreement that supersedes this outline.
|
package/README.md
CHANGED
|
@@ -117,9 +117,9 @@ var recovery = new SnapshotRecoveryHelper({
|
|
|
117
117
|
});
|
|
118
118
|
```
|
|
119
119
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
120
|
+
The override hooks have always existed; 0.10.1 documents them.
|
|
121
|
+
Internal security audit references are kept in the repository, not
|
|
122
|
+
shipped with the npm package.
|
|
123
123
|
|
|
124
124
|
## Status
|
|
125
125
|
|
|
@@ -144,10 +144,92 @@ public API surface will evolve until 1.0.
|
|
|
144
144
|
| 9.3 | shipped | TypeDoc public-API site with auto-deploy |
|
|
145
145
|
| 11A.2 | shipped | docs hosting migrated to Cloudflare Pages |
|
|
146
146
|
| 11B.3 | shipped | MIT license + npm publish posture (this release) |
|
|
147
|
+
| 12.4 | shipped | License pivot from MIT to BUSL 1.1 with $1M revenue cap |
|
|
148
|
+
| 13.2 | shipped | Engine hardening: 12.6 audit lows L-08..L-12 closed |
|
|
149
|
+
| 14.1 | shipped | WebGL2 instanced sprite batcher |
|
|
150
|
+
| 15.1 | shipped | Multiplayer presence: pluggable bridge (SSE / Mock), peer pool with per-peer linear interpolation, render system (this release) |
|
|
147
151
|
|
|
148
152
|
See [LOOM-ENGINE-SPEC.md](../docker/LOOM-ENGINE-SPEC.md) Section 7
|
|
149
153
|
for the full phase plan with effort estimates.
|
|
150
154
|
|
|
155
|
+
## Renderer backends
|
|
156
|
+
|
|
157
|
+
Two backends ship behind the same `IGraphicsDevice` contract:
|
|
158
|
+
|
|
159
|
+
| Backend | Status | When to use |
|
|
160
|
+
|---|---|---|
|
|
161
|
+
| `canvas2d` | default, stable | Hundreds to ~2k sprites; broadest browser coverage |
|
|
162
|
+
| `webgl2` | 0.12.0+, opt-in | Thousands of sprites; instanced batching with atlas grouping |
|
|
163
|
+
|
|
164
|
+
Existing consumers do not need to change anything - `Engine.create({ canvas })`
|
|
165
|
+
keeps the Canvas2D path it has always had, with byte-for-byte
|
|
166
|
+
compatibility on every public API.
|
|
167
|
+
|
|
168
|
+
### Opt into WebGL2
|
|
169
|
+
|
|
170
|
+
```ts
|
|
171
|
+
import { Engine, WebGL2Device } from '@sadhaka/loom-engine';
|
|
172
|
+
|
|
173
|
+
// Importing WebGL2Device side-effect-registers the 'webgl2' backend
|
|
174
|
+
// factory. The string-based form then works:
|
|
175
|
+
var engine = Engine.create({ canvas: myCanvas, backend: 'webgl2' });
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Or inject a pre-built device for absolute control over construction
|
|
179
|
+
(useful when sharing the GL context with another renderer):
|
|
180
|
+
|
|
181
|
+
```ts
|
|
182
|
+
import { Engine, WebGL2Device } from '@sadhaka/loom-engine';
|
|
183
|
+
|
|
184
|
+
var device = new WebGL2Device(myCanvas);
|
|
185
|
+
var engine = Engine.create({ canvas: myCanvas, device: device });
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### How batching works
|
|
189
|
+
|
|
190
|
+
Every `drawSprite` / `drawTile` / `drawParticle` / `drawText` call
|
|
191
|
+
flows through `SpriteBatcher`, which accumulates per-instance data
|
|
192
|
+
(screen-space origin + size, atlas UV rect, RGBA tint) into a single
|
|
193
|
+
Float32Array. A flush triggers when the next call uses a different
|
|
194
|
+
atlas or blend mode, and at `endFrame`. Each flush issues exactly
|
|
195
|
+
one `drawArraysInstanced` for the batch.
|
|
196
|
+
|
|
197
|
+
For maximum throughput, group draws by atlas at the system level
|
|
198
|
+
(e.g. render all hamlet props from one atlas, all NPCs from another).
|
|
199
|
+
The default `SpriteRenderSystem` already sorts globally by iso depth
|
|
200
|
+
key; submission order within an atlas-bounded run is preserved
|
|
201
|
+
through the batcher.
|
|
202
|
+
|
|
203
|
+
### Tree-shake story
|
|
204
|
+
|
|
205
|
+
`engine.ts` deliberately does **not** statically import
|
|
206
|
+
`WebGL2Device`. A consumer that only uses Canvas2D never pulls
|
|
207
|
+
WebGL2-specific code into their bundle - the only way the WebGL2
|
|
208
|
+
path enters the dependency graph is via an explicit
|
|
209
|
+
`import { WebGL2Device }`, which also triggers backend registration
|
|
210
|
+
through a `/*#__PURE__*/`-marked side effect.
|
|
211
|
+
|
|
212
|
+
### WebGL2 limits + fallback
|
|
213
|
+
|
|
214
|
+
- WebGL2 contexts can be lost (GPU crash, long backgrounded tab,
|
|
215
|
+
extension hijack). The device handles `webglcontextlost` /
|
|
216
|
+
`webglcontextrestored` automatically: every atlas re-uploads from
|
|
217
|
+
its cached source image; frames during the lost interval no-op.
|
|
218
|
+
- Browsers without WebGL2 (Safari < 15, very old Chrome/Firefox)
|
|
219
|
+
throw at `WebGL2Device` construction. Wrap the upgrade in a
|
|
220
|
+
feature check and fall back to Canvas2D:
|
|
221
|
+
```ts
|
|
222
|
+
function pickBackend() {
|
|
223
|
+
var probe = document.createElement('canvas').getContext('webgl2');
|
|
224
|
+
return probe ? 'webgl2' : 'canvas2d';
|
|
225
|
+
}
|
|
226
|
+
var engine = Engine.create({ canvas: myCanvas, backend: pickBackend() });
|
|
227
|
+
```
|
|
228
|
+
- Performance characterization lands in phase 14.3 (synthetic 5k+
|
|
229
|
+
sprite bench, frame-time histograms, pareto-front against
|
|
230
|
+
Canvas2D). Until then, treat WebGL2 as opt-in for scale-bound
|
|
231
|
+
scenes only.
|
|
232
|
+
|
|
151
233
|
## Build
|
|
152
234
|
|
|
153
235
|
```sh
|
|
@@ -160,19 +242,161 @@ npm run test # tsx tests/*.test.ts
|
|
|
160
242
|
npm run clean # remove dist + compiled demo
|
|
161
243
|
```
|
|
162
244
|
|
|
163
|
-
## Run the
|
|
245
|
+
## Run the demos
|
|
164
246
|
|
|
165
247
|
```sh
|
|
166
248
|
npm run build:all
|
|
167
249
|
python -m http.server 8765
|
|
168
|
-
# browse http://localhost:8765/demo/
|
|
250
|
+
# browse http://localhost:8765/demo/
|
|
169
251
|
```
|
|
170
252
|
|
|
171
|
-
|
|
253
|
+
`http://localhost:8765/demo/` is the gallery index. The same tree is
|
|
254
|
+
published to [loom-engine.pages.dev/demo/](https://loom-engine.pages.dev/demo/)
|
|
255
|
+
on every push to `main`.
|
|
256
|
+
|
|
257
|
+
## Examples
|
|
258
|
+
|
|
259
|
+
Three minimal, copy-paste-ready starters live under `demo/`. Each is
|
|
260
|
+
roughly 150 lines of TypeScript, imports from `@sadhaka/loom-engine`
|
|
261
|
+
(resolved via `importmap` to the local engine bundle), and runs in
|
|
262
|
+
the browser without a build step on the consumer side.
|
|
263
|
+
|
|
264
|
+
- **[Survivor Mini](./demo/survivor-mini/)** - 100-line autobattler.
|
|
265
|
+
Player at center auto-fires at the nearest mob; mobs spawn from
|
|
266
|
+
random screen edges and pursue. Showcases ECS pools (Transform /
|
|
267
|
+
Sprite / Health / Pursue / RangedAttack), `MOB_CATALOG`, projectile
|
|
268
|
+
physics, system-phase ordering.
|
|
269
|
+
- **[Plaza Mini](./demo/plaza-mini/)** - walkable iso plaza wired to
|
|
270
|
+
a mock Director bridge. WASD to walk; the narrator overlay below
|
|
271
|
+
the canvas pulses every five seconds with a synthetic
|
|
272
|
+
`narrator.line` event drained from `MockDirectorBridge`. Demonstrates
|
|
273
|
+
iso projection, input snapshot, the bridge / event-log / DOM-overlay
|
|
274
|
+
boundary.
|
|
275
|
+
- **[Dialogue Mini](./demo/dialogue-mini/)** - branching dialogue
|
|
276
|
+
tree, no movement, no combat. Click a choice or press 1 / 2 / 3.
|
|
277
|
+
Demonstrates that the same ECS / resource model that runs the action
|
|
278
|
+
demos also fits a UI-only game: custom `Resource`, custom `System`
|
|
279
|
+
reading both `InputSnapshot` and DOM events, DOM as the primary UI.
|
|
280
|
+
- **[Plaza Multiplayer](./demo/plaza-multiplayer/)** - walkable iso
|
|
281
|
+
plaza with three synthetic peers wandering randomly, driven by a
|
|
282
|
+
`MockMultiplayerBridge`. WASD to walk; the local player broadcasts
|
|
283
|
+
position at 10 Hz and the three peers (Alice / Bob / Carol) lerp
|
|
284
|
+
smoothly between presence updates. Demonstrates the pluggable
|
|
285
|
+
multiplayer bridge, `PeerPool` linear interpolation, and the
|
|
286
|
+
`PeerPresenceSystem` / `PeerRenderSystem` pipeline. See the
|
|
287
|
+
[Multiplayer](#multiplayer) section below for the wire protocol.
|
|
288
|
+
|
|
289
|
+
The legacy reference demos (Phase 6 director, Phase 7 combat, Phase 8
|
|
290
|
+
ARPG slice) stay accessible from the gallery index.
|
|
291
|
+
|
|
292
|
+
Controls in the legacy director demo (`demo/director.html`):
|
|
172
293
|
- **Arrow keys / WASD**: pan camera
|
|
173
294
|
- **Click**: burst 24 particles + play SFX chirp (after first click, AudioContext unlocks)
|
|
174
295
|
- **Hover**: stats panel shows the iso tile under the cursor
|
|
175
296
|
|
|
297
|
+
## Multiplayer
|
|
298
|
+
|
|
299
|
+
Phase 15.1 adds a thin presence layer for showing other players in
|
|
300
|
+
real time on the same world. The transport is pluggable: the engine
|
|
301
|
+
ships an `SSEMultiplayerBridge` (server-sent events) and a
|
|
302
|
+
`MockMultiplayerBridge` (in-process; tests + offline demos), and the
|
|
303
|
+
`IMultiplayerBridge` interface is small enough to swap in WebSocket
|
|
304
|
+
or WebRTC without touching anything above it. No CRDT - peers carry
|
|
305
|
+
position only, and conflict resolution is "last write wins" at the
|
|
306
|
+
server. Shared state beyond position is deferred to a later phase.
|
|
307
|
+
|
|
308
|
+
### Wire protocol
|
|
309
|
+
|
|
310
|
+
The bridge layer hides this from gameplay code, but for anyone
|
|
311
|
+
implementing a server (or a custom transport) the contract is:
|
|
312
|
+
|
|
313
|
+
**Server -> client (SSE event types):**
|
|
314
|
+
- `presence.snapshot` `{ peers: [{ character_id, x, y, zone, ts_ms, name? }] }`
|
|
315
|
+
emitted once on connect with the full current peer roster. The
|
|
316
|
+
client treats this as authoritative and drops any peer not in the
|
|
317
|
+
snapshot.
|
|
318
|
+
- `presence.update` `{ character_id, x, y, zone, ts_ms, name? }`
|
|
319
|
+
emitted as peers move.
|
|
320
|
+
- `presence.depart` `{ character_id }`
|
|
321
|
+
emitted when a peer disconnects.
|
|
322
|
+
|
|
323
|
+
**Client -> server (HTTP POST):**
|
|
324
|
+
- `POST <broadcastUrl>` `{ character_id, x, y, zone, ts_ms }`
|
|
325
|
+
the engine rate-limits to **10 Hz** (`BROADCAST_HZ`); excess calls
|
|
326
|
+
to `broadcastPosition()` are silently dropped and counted in
|
|
327
|
+
`bridge.stats().rateLimitedDrops`. Calling once per frame is fine.
|
|
328
|
+
|
|
329
|
+
`ts_ms` is the wall clock at which the position was true. The
|
|
330
|
+
`PeerPool` uses it to interpolate between successive samples so peers
|
|
331
|
+
don't jitter at the network rate. Acceptable lag is ~150 ms (one
|
|
332
|
+
update interval at 10 Hz), imperceptible at walk speed.
|
|
333
|
+
|
|
334
|
+
### Setup
|
|
335
|
+
|
|
336
|
+
```ts
|
|
337
|
+
import {
|
|
338
|
+
Engine,
|
|
339
|
+
// Multiplayer
|
|
340
|
+
MockMultiplayerBridge, // or SSEMultiplayerBridge
|
|
341
|
+
PeerPool,
|
|
342
|
+
PeerSpritePool,
|
|
343
|
+
PeerPresenceSystem,
|
|
344
|
+
PeerRenderSystem,
|
|
345
|
+
POOL_PEER_SPRITE,
|
|
346
|
+
RESOURCE_MULTIPLAYER_BRIDGE,
|
|
347
|
+
RESOURCE_PEER_POOL,
|
|
348
|
+
SYSTEM_PHASE_INPUT,
|
|
349
|
+
SYSTEM_PHASE_RENDER,
|
|
350
|
+
} from '@sadhaka/loom-engine';
|
|
351
|
+
|
|
352
|
+
const engine = Engine.create({ canvas });
|
|
353
|
+
|
|
354
|
+
// 1. Create a bridge. Production code uses SSEMultiplayerBridge:
|
|
355
|
+
//
|
|
356
|
+
// const bridge = new SSEMultiplayerBridge({
|
|
357
|
+
// baseUrl: '/api/v1/loom/presence/events',
|
|
358
|
+
// characterId: 'me',
|
|
359
|
+
// zone: 'plaza',
|
|
360
|
+
// });
|
|
361
|
+
//
|
|
362
|
+
// Tests + offline dev use the in-process mock:
|
|
363
|
+
const bridge = new MockMultiplayerBridge();
|
|
364
|
+
bridge.connect();
|
|
365
|
+
|
|
366
|
+
// 2. PeerPool stores all known peers + their interpolated positions.
|
|
367
|
+
// Self-filter: tell the pool which character_id is the local player
|
|
368
|
+
// so it isn't rendered as a ghost when the server echoes it back.
|
|
369
|
+
const peerPool = new PeerPool();
|
|
370
|
+
peerPool.setLocalCharacterId('me');
|
|
371
|
+
|
|
372
|
+
// 3. PeerSpritePool maps character_id -> rendering hint. A default
|
|
373
|
+
// atlas + frame is enough for an undifferentiated demo; setOverride()
|
|
374
|
+
// lets you assign per-class sprites or cosmetic shards.
|
|
375
|
+
const peerSprites = new PeerSpritePool({ defaultAtlas: peerAtlas });
|
|
376
|
+
|
|
377
|
+
engine.world.resources.set(RESOURCE_MULTIPLAYER_BRIDGE, bridge);
|
|
378
|
+
engine.world.resources.set(RESOURCE_PEER_POOL, peerPool);
|
|
379
|
+
engine.world.registerPool(POOL_PEER_SPRITE, peerSprites);
|
|
380
|
+
|
|
381
|
+
// 4. Wire the systems. PeerPresenceSystem drains the bridge each
|
|
382
|
+
// frame; PeerRenderSystem submits a drawSprite + name label per
|
|
383
|
+
// peer at their interpolated position.
|
|
384
|
+
engine.world.addSystem(new PeerPresenceSystem(), SYSTEM_PHASE_INPUT);
|
|
385
|
+
engine.world.addSystem(new PeerRenderSystem(), SYSTEM_PHASE_RENDER);
|
|
386
|
+
|
|
387
|
+
// 5. Inside your walk-system, call broadcastPosition() each frame.
|
|
388
|
+
// The bridge enforces the 10 Hz wire rate.
|
|
389
|
+
bridge.broadcastPosition(playerX, playerY, 'plaza', Date.now());
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
### Swapping transports
|
|
393
|
+
|
|
394
|
+
The bridge interface is just five methods (`connect`, `disconnect`,
|
|
395
|
+
`status`, `pollMessages`, `broadcastPosition`, plus `stats`). To use
|
|
396
|
+
WebSocket or WebRTC, implement `IMultiplayerBridge` with the same
|
|
397
|
+
`PresenceMessage` shape (`update` / `depart` / `snapshot`); none of
|
|
398
|
+
the systems above the bridge change.
|
|
399
|
+
|
|
176
400
|
## Layout
|
|
177
401
|
|
|
178
402
|
```
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { AtlasHandle } from '../renderer/graphics-device.js';
|
|
2
|
+
import type { ColorRGBA } from '../util/color.js';
|
|
3
|
+
export interface PeerSpriteEntry {
|
|
4
|
+
atlas: AtlasHandle;
|
|
5
|
+
frame: number;
|
|
6
|
+
tint: Readonly<ColorRGBA> | null;
|
|
7
|
+
}
|
|
8
|
+
export interface PeerSpritePoolOptions {
|
|
9
|
+
defaultAtlas: AtlasHandle;
|
|
10
|
+
defaultFrame?: number;
|
|
11
|
+
defaultTint?: Readonly<ColorRGBA>;
|
|
12
|
+
}
|
|
13
|
+
export declare class PeerSpritePool {
|
|
14
|
+
private readonly defaultEntry;
|
|
15
|
+
private overrides;
|
|
16
|
+
constructor(opts: PeerSpritePoolOptions);
|
|
17
|
+
setOverride(characterId: string, entry: PeerSpriteEntry): void;
|
|
18
|
+
removeOverride(characterId: string): void;
|
|
19
|
+
resolve(characterId: string): Readonly<PeerSpriteEntry>;
|
|
20
|
+
getDefault(): Readonly<PeerSpriteEntry>;
|
|
21
|
+
hasOverride(characterId: string): boolean;
|
|
22
|
+
clear(): void;
|
|
23
|
+
}
|
|
24
|
+
export declare const POOL_PEER_SPRITE = "peer_sprite";
|
|
25
|
+
//# sourceMappingURL=peer-sprite.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"peer-sprite.d.ts","sourceRoot":"","sources":["../../src/components/peer-sprite.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElD,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,WAAW,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,QAAQ,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC;CAClC;AAED,MAAM,WAAW,qBAAqB;IAEpC,YAAY,EAAE,WAAW,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;CACnC;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAkB;IAC/C,OAAO,CAAC,SAAS,CAA2C;gBAEhD,IAAI,EAAE,qBAAqB;IAWvC,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,GAAG,IAAI;IAI9D,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAMzC,OAAO,CAAC,WAAW,EAAE,MAAM,GAAG,QAAQ,CAAC,eAAe,CAAC;IAIvD,UAAU,IAAI,QAAQ,CAAC,eAAe,CAAC;IAIvC,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO;IAIzC,KAAK,IAAI,IAAI;CAGd;AAED,eAAO,MAAM,gBAAgB,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// PeerSpritePool - per-peer rendering hints (atlas, frame, tint,
|
|
2
|
+
// optional name label) keyed by character_id rather than by EntityId.
|
|
3
|
+
//
|
|
4
|
+
// Peers don't get a stable EntityId because they appear and disappear
|
|
5
|
+
// based on network presence, not gameplay state. The PeerPresenceSystem
|
|
6
|
+
// resolves a peer's interpolated (x, y) from PeerPool each frame and
|
|
7
|
+
// draws via this pool's per-peer atlas/frame.
|
|
8
|
+
//
|
|
9
|
+
// Default style: unspecified peers render with a fallback atlas/frame
|
|
10
|
+
// supplied at pool construction. That keeps single-line setup simple
|
|
11
|
+
// for the demo while still allowing per-peer customization (cosmetic
|
|
12
|
+
// shards, visible class, etc.) once the dev wants to differentiate.
|
|
13
|
+
export class PeerSpritePool {
|
|
14
|
+
defaultEntry;
|
|
15
|
+
overrides = new Map();
|
|
16
|
+
constructor(opts) {
|
|
17
|
+
this.defaultEntry = {
|
|
18
|
+
atlas: opts.defaultAtlas,
|
|
19
|
+
frame: opts.defaultFrame ?? 0,
|
|
20
|
+
tint: opts.defaultTint ?? null,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
// Per-peer override. Apply once on join (e.g. after a server-emitted
|
|
24
|
+
// class hint) and forget; the pool keeps it until clear() / removed
|
|
25
|
+
// explicitly.
|
|
26
|
+
setOverride(characterId, entry) {
|
|
27
|
+
this.overrides.set(characterId, entry);
|
|
28
|
+
}
|
|
29
|
+
removeOverride(characterId) {
|
|
30
|
+
this.overrides.delete(characterId);
|
|
31
|
+
}
|
|
32
|
+
// Resolve the rendering entry for a peer. Returns the override if
|
|
33
|
+
// one exists, otherwise the default. Never null for a known peer.
|
|
34
|
+
resolve(characterId) {
|
|
35
|
+
return this.overrides.get(characterId) ?? this.defaultEntry;
|
|
36
|
+
}
|
|
37
|
+
getDefault() {
|
|
38
|
+
return this.defaultEntry;
|
|
39
|
+
}
|
|
40
|
+
hasOverride(characterId) {
|
|
41
|
+
return this.overrides.has(characterId);
|
|
42
|
+
}
|
|
43
|
+
clear() {
|
|
44
|
+
this.overrides.clear();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
export const POOL_PEER_SPRITE = 'peer_sprite';
|
|
48
|
+
//# sourceMappingURL=peer-sprite.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"peer-sprite.js","sourceRoot":"","sources":["../../src/components/peer-sprite.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,sEAAsE;AACtE,EAAE;AACF,sEAAsE;AACtE,wEAAwE;AACxE,qEAAqE;AACrE,8CAA8C;AAC9C,EAAE;AACF,sEAAsE;AACtE,qEAAqE;AACrE,qEAAqE;AACrE,oEAAoE;AAkBpE,MAAM,OAAO,cAAc;IACR,YAAY,CAAkB;IACvC,SAAS,GAAiC,IAAI,GAAG,EAAE,CAAC;IAE5D,YAAY,IAA2B;QACrC,IAAI,CAAC,YAAY,GAAG;YAClB,KAAK,EAAE,IAAI,CAAC,YAAY;YACxB,KAAK,EAAE,IAAI,CAAC,YAAY,IAAI,CAAC;YAC7B,IAAI,EAAE,IAAI,CAAC,WAAW,IAAI,IAAI;SAC/B,CAAC;IACJ,CAAC;IAED,qEAAqE;IACrE,oEAAoE;IACpE,cAAc;IACd,WAAW,CAAC,WAAmB,EAAE,KAAsB;QACrD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IACzC,CAAC;IAED,cAAc,CAAC,WAAmB;QAChC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IACrC,CAAC;IAED,kEAAkE;IAClE,kEAAkE;IAClE,OAAO,CAAC,WAAmB;QACzB,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC;IAC9D,CAAC;IAED,UAAU;QACR,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAED,WAAW,CAAC,WAAmB;QAC7B,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IACzC,CAAC;IAED,KAAK;QACH,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;IACzB,CAAC;CACF;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAG,aAAa,CAAC"}
|
package/dist/engine.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { IGraphicsDevice } from './renderer/graphics-device.js';
|
|
1
|
+
import type { IGraphicsDevice, DeviceBackend } from './renderer/graphics-device.js';
|
|
2
2
|
import { type CameraView } from './renderer/camera.js';
|
|
3
3
|
import { World } from './world.js';
|
|
4
4
|
import { AudioBus } from './audio/audio-bus.js';
|
|
@@ -7,7 +7,12 @@ export interface EngineOptions {
|
|
|
7
7
|
canvas: HTMLCanvasElement;
|
|
8
8
|
inputWindow?: Window | null;
|
|
9
9
|
skipAudio?: boolean;
|
|
10
|
+
backend?: DeviceBackend;
|
|
11
|
+
device?: IGraphicsDevice;
|
|
10
12
|
}
|
|
13
|
+
export type DeviceFactory = (canvas: HTMLCanvasElement) => IGraphicsDevice;
|
|
14
|
+
export declare function registerBackend(name: DeviceBackend, factory: DeviceFactory): void;
|
|
15
|
+
export declare function isBackendRegistered(name: DeviceBackend): boolean;
|
|
11
16
|
export declare class Engine {
|
|
12
17
|
readonly device: IGraphicsDevice;
|
|
13
18
|
readonly world: World;
|
package/dist/engine.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACpF,OAAO,EAAgB,KAAK,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAAE,KAAK,EAA+B,MAAM,YAAY,CAAC;AA2BhE,OAAO,EAAE,QAAQ,EAAsB,MAAM,sBAAsB,CAAC;AACpE,OAAO,EACL,YAAY,EAGb,MAAM,0BAA0B,CAAC;AAsBlC,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,iBAAiB,CAAC;IAI1B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAI5B,SAAS,CAAC,EAAE,OAAO,CAAC;IASpB,OAAO,CAAC,EAAE,aAAa,CAAC;IAIxB,MAAM,CAAC,EAAE,eAAe,CAAC;CAC1B;AAQD,MAAM,MAAM,aAAa,GAAG,CAAC,MAAM,EAAE,iBAAiB,KAAK,eAAe,CAAC;AAQ3E,wBAAgB,eAAe,CAAC,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,aAAa,GAAG,IAAI,CAEjF;AAID,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAEhE;AAOD,qBAAa,MAAM;IACjB,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IACjC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAC;IAEhC,OAAO,CAAC,IAAI,CAAe;IAC3B,OAAO,CAAC,UAAU,CAAa;IAE/B,OAAO;IA0BP,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM;IAsF1C,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAmBzB,SAAS,IAAI,IAAI;IAOjB,OAAO,IAAI,IAAI;CAKhB"}
|
package/dist/engine.js
CHANGED
|
@@ -44,6 +44,20 @@ import { KnotContextResource } from './director/knot-context-resource.js';
|
|
|
44
44
|
import { RESOURCE_DIRECTOR_LOG, createDirectorEventLog, } from './director/director-system.js';
|
|
45
45
|
import { RESOURCE_TIME, RESOURCE_CAMERA, RESOURCE_DEVICE, createTimeResource, } from './resources.js';
|
|
46
46
|
import { clamp } from './util/math.js';
|
|
47
|
+
const backendRegistry = new Map();
|
|
48
|
+
backendRegistry.set('canvas2d', (canvas) => new Canvas2DDevice(canvas));
|
|
49
|
+
// Register a backend factory. Devices call this from their module
|
|
50
|
+
// load to make the string-based `backend:` selection work without
|
|
51
|
+
// engine.ts knowing about them. Idempotent: re-registration replaces
|
|
52
|
+
// the prior factory.
|
|
53
|
+
export function registerBackend(name, factory) {
|
|
54
|
+
backendRegistry.set(name, factory);
|
|
55
|
+
}
|
|
56
|
+
// Probe whether a backend is registered. Useful for diagnostic code
|
|
57
|
+
// or tests asserting a backend was loaded.
|
|
58
|
+
export function isBackendRegistered(name) {
|
|
59
|
+
return backendRegistry.has(name);
|
|
60
|
+
}
|
|
47
61
|
// Max delta clamp. Long pauses (background tab, breakpoint) shouldn't
|
|
48
62
|
// produce one giant dt that breaks physics. 1/30s is the spec frame
|
|
49
63
|
// loop guidance.
|
|
@@ -67,8 +81,28 @@ export class Engine {
|
|
|
67
81
|
// Constructs an Engine + default resources + default pools +
|
|
68
82
|
// default render system. Caller registers their own systems
|
|
69
83
|
// afterward via engine.world.addSystem.
|
|
84
|
+
//
|
|
85
|
+
// Backend selection precedence:
|
|
86
|
+
// 1. opts.device - if provided, used as-is (tree-shake friendly)
|
|
87
|
+
// 2. opts.backend - looked up in backendRegistry; throws if a
|
|
88
|
+
// non-default backend is requested but its device module was
|
|
89
|
+
// never imported.
|
|
90
|
+
// 3. 'canvas2d' default factory.
|
|
70
91
|
static create(opts) {
|
|
71
|
-
|
|
92
|
+
let device;
|
|
93
|
+
if (opts.device) {
|
|
94
|
+
device = opts.device;
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
const backend = opts.backend ?? 'canvas2d';
|
|
98
|
+
const factory = backendRegistry.get(backend);
|
|
99
|
+
if (!factory) {
|
|
100
|
+
throw new Error("Engine.create: backend '" + backend + "' is not registered. " +
|
|
101
|
+
"For 'webgl2', import { WebGL2Device } from '@sadhaka/loom-engine' before calling Engine.create - " +
|
|
102
|
+
"the module self-registers on import. Alternatively pass opts.device directly.");
|
|
103
|
+
}
|
|
104
|
+
device = factory(opts.canvas);
|
|
105
|
+
}
|
|
72
106
|
const camera = createCamera(opts.canvas.width, opts.canvas.height);
|
|
73
107
|
const world = new World();
|
|
74
108
|
const time = createTimeResource();
|
package/dist/engine.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,EAAE;AACF,gEAAgE;AAChE,mEAAmE;AACnE,mEAAmE;AACnE,EAAE;AACF,6CAA6C;AAC7C,2BAA2B;AAC3B,2BAA2B;AAC3B,gCAAgC;AAChC,yBAAyB;AACzB,iCAAiC;AACjC,2BAA2B;AAC3B,wDAAwD;AACxD,uBAAuB;AACvB,EAAE;AACF,oEAAoE;AACpE,+CAA+C;AAE/C,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAE/D,OAAO,EAAE,YAAY,EAAmB,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AACxE,OAAO,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3E,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACnF,OAAO,EACL,eAAe,EACf,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,qBAAqB,EACrB,yBAAyB,GAC1B,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,wBAAwB,EACxB,oBAAoB,GACrB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,EACL,YAAY,EACZ,sBAAsB,EACtB,cAAc,GACf,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,qBAAqB,GACtB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,EACL,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,aAAa,EACb,eAAe,EACf,eAAe,EACf,kBAAkB,GAEnB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,EAAE;AACF,gEAAgE;AAChE,mEAAmE;AACnE,mEAAmE;AACnE,EAAE;AACF,6CAA6C;AAC7C,2BAA2B;AAC3B,2BAA2B;AAC3B,gCAAgC;AAChC,yBAAyB;AACzB,iCAAiC;AACjC,2BAA2B;AAC3B,wDAAwD;AACxD,uBAAuB;AACvB,EAAE;AACF,oEAAoE;AACpE,+CAA+C;AAE/C,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAE/D,OAAO,EAAE,YAAY,EAAmB,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AACxE,OAAO,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3E,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACnF,OAAO,EACL,eAAe,EACf,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,qBAAqB,EACrB,yBAAyB,GAC1B,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,wBAAwB,EACxB,oBAAoB,GACrB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,EACL,YAAY,EACZ,sBAAsB,EACtB,cAAc,GACf,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,qBAAqB,GACtB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,EACL,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,aAAa,EACb,eAAe,EACf,eAAe,EACf,kBAAkB,GAEnB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAkCvC,MAAM,eAAe,GAAsC,IAAI,GAAG,EAAE,CAAC;AACrE,eAAe,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC;AAExE,kEAAkE;AAClE,kEAAkE;AAClE,qEAAqE;AACrE,qBAAqB;AACrB,MAAM,UAAU,eAAe,CAAC,IAAmB,EAAE,OAAsB;IACzE,eAAe,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AACrC,CAAC;AAED,oEAAoE;AACpE,2CAA2C;AAC3C,MAAM,UAAU,mBAAmB,CAAC,IAAmB;IACrD,OAAO,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACnC,CAAC;AAED,sEAAsE;AACtE,oEAAoE;AACpE,iBAAiB;AACjB,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE,CAAC;AAE9B,MAAM,OAAO,MAAM;IACR,MAAM,CAAkB;IACxB,KAAK,CAAQ;IACb,MAAM,CAAa;IACnB,KAAK,CAAe;IACpB,KAAK,CAAkB;IAExB,IAAI,CAAe;IACnB,UAAU,GAAW,CAAC,CAAC;IAE/B,YACE,MAAuB,EACvB,KAAY,EACZ,MAAkB,EAClB,IAAkB,EAClB,KAAmB,EACnB,KAAsB;QAEtB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IAED,6DAA6D;IAC7D,4DAA4D;IAC5D,wCAAwC;IACxC,EAAE;IACF,gCAAgC;IAChC,oEAAoE;IACpE,gEAAgE;IAChE,kEAAkE;IAClE,uBAAuB;IACvB,mCAAmC;IACnC,MAAM,CAAC,MAAM,CAAC,IAAmB;QAC/B,IAAI,MAAuB,CAAC;QAC5B,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QACvB,CAAC;aAAM,CAAC;YACN,MAAM,OAAO,GAAkB,IAAI,CAAC,OAAO,IAAI,UAAU,CAAC;YAC1D,MAAM,OAAO,GAAG,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAC7C,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,MAAM,IAAI,KAAK,CACb,0BAA0B,GAAG,OAAO,GAAG,uBAAuB;oBAC9D,mGAAmG;oBACnG,+EAA+E,CAChF,CAAC;YACJ,CAAC;YACD,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAChC,CAAC;QACD,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACnE,MAAM,KAAK,GAAG,IAAI,KAAK,EAAE,CAAC;QAC1B,MAAM,IAAI,GAAG,kBAAkB,EAAE,CAAC;QAElC,iEAAiE;QACjE,8DAA8D;QAC9D,MAAM,KAAK,GAAG,IAAI,YAAY,EAAE,CAAC;QACjC,IAAI,IAAI,CAAC,WAAW,KAAK,IAAI,EAAE,CAAC;YAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,IAAI,CAAC,OAAO,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAChF,IAAI,GAAG;gBAAE,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC1C,CAAC;QAED,iEAAiE;QACjE,wDAAwD;QACxD,IAAI,KAAK,GAAoB,IAAI,CAAC;QAClC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,KAAK,IAAI,IAAI,OAAO,YAAY,KAAK,WAAW,CAAC;QACjF,IAAI,SAAS,EAAE,CAAC;YACd,IAAI,CAAC;gBACH,KAAK,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC;YAC5B,CAAC;YAAC,MAAM,CAAC;gBACP,KAAK,GAAG,IAAI,CAAC;YACf,CAAC;QACH,CAAC;QAED,YAAY;QACZ,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;QACzC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;QAC7C,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;QAC7C,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,oBAAoB,EAAE,wBAAwB,EAAE,CAAC,CAAC;QACtE,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,sBAAsB,EAAE,KAAK,CAAC,CAAC;QACnD,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,cAAc,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;QACtD,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,iBAAiB,EAAE,mBAAmB,EAAE,CAAC,CAAC;QAC9D,IAAI,KAAK;YAAE,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,kBAAkB,EAAE,KAAK,CAAC,CAAC;QAE1D,+DAA+D;QAC/D,yDAAyD;QACzD,gEAAgE;QAChE,mEAAmE;QACnE,6DAA6D;QAC7D,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,qBAAqB,EAAE,IAAI,mBAAmB,EAAE,CAAC,CAAC;QACtE,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,qBAAqB,EAAE,sBAAsB,EAAE,CAAC,CAAC;QAErE,QAAQ;QACR,KAAK,CAAC,YAAY,CAAC,cAAc,EAAE,IAAI,aAAa,EAAE,CAAC,CAAC;QACxD,KAAK,CAAC,YAAY,CAAC,WAAW,EAAE,IAAI,UAAU,EAAE,CAAC,CAAC;QAClD,KAAK,CAAC,YAAY,CAAC,cAAc,EAAE,IAAI,kBAAkB,EAAE,CAAC,CAAC;QAC7D,KAAK,CAAC,YAAY,CAAC,aAAa,EAAE,IAAI,YAAY,EAAE,CAAC,CAAC;QACtD,KAAK,CAAC,YAAY,CAAC,YAAY,EAAE,IAAI,mBAAmB,EAAE,CAAC,CAAC;QAC5D,KAAK,CAAC,YAAY,CAAC,WAAW,EAAE,IAAI,UAAU,EAAE,CAAC,CAAC;QAClD,KAAK,CAAC,YAAY,CAAC,WAAW,EAAE,IAAI,UAAU,EAAE,CAAC,CAAC;QAClD,KAAK,CAAC,YAAY,CAAC,WAAW,EAAE,IAAI,gBAAgB,EAAE,CAAC,CAAC;QACxD,KAAK,CAAC,YAAY,CAAC,eAAe,EAAE,IAAI,cAAc,EAAE,CAAC,CAAC;QAC1D,KAAK,CAAC,YAAY,CAAC,iBAAiB,EAAE,IAAI,gBAAgB,EAAE,CAAC,CAAC;QAC9D,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,kBAAkB,EAAE,IAAI,QAAQ,EAAE,CAAC,CAAC;QACxD,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,mBAAmB,EAAE,eAAe,EAAE,CAAC,CAAC;QAC5D,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,yBAAyB,EAAE,qBAAqB,EAAE,CAAC,CAAC;QAExE,gEAAgE;QAChE,8CAA8C;QAC9C,8DAA8D;QAC9D,6DAA6D;QAC7D,8CAA8C;QAE9C,OAAO,IAAI,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IAC/D,CAAC;IAED,sDAAsD;IACtD,gEAAgE;IAChE,4DAA4D;IAC5D,wBAAwB;IACxB,IAAI,CAAC,KAAa;QAChB,IAAI,EAAE,GAAG,CAAC,CAAC;QACX,IAAI,IAAI,CAAC,UAAU,GAAG,CAAC,EAAE,CAAC;YACxB,EAAE,GAAG,KAAK,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,cAAc,CAAC,CAAC;QAClE,CAAC;QACD,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QAExB,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;QACrB,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;QACxB,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC;QAErB,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;QACzB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACtB,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;IACzB,CAAC;IAED,gEAAgE;IAChE,oEAAoE;IACpE,qDAAqD;IACrD,SAAS;QACP,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC;QACpB,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;QACpB,IAAI,CAAC,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC;QACtB,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;IACtB,CAAC;IAED,OAAO;QACL,qCAAqC;QACrC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;QACpB,IAAI,IAAI,CAAC,KAAK;YAAE,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;IACvC,CAAC;CACF"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const LOOM_ENGINE_VERSION = "0.
|
|
1
|
+
export declare const LOOM_ENGINE_VERSION = "0.13.0";
|
|
2
2
|
export type { Vec2, Vec3, Rect } from './util/math.js';
|
|
3
3
|
export { vec2, vec3, rect, clamp, lerp, smoothstep, approxEq, rectContains, rectIntersects, visibleInView, } from './util/math.js';
|
|
4
4
|
export type { ColorRGBA } from './util/color.js';
|
|
@@ -13,12 +13,17 @@ export { SYSTEM_PHASE_INPUT, SYSTEM_PHASE_LOGIC, SYSTEM_PHASE_PHYSICS, SYSTEM_PH
|
|
|
13
13
|
export type { TimeResource, VeilBudgetResource } from './resources.js';
|
|
14
14
|
export { ResourceRegistry, createTimeResource, createVeilBudgetResource, RESOURCE_TIME, RESOURCE_CAMERA, RESOURCE_DEVICE, RESOURCE_VEIL_BUDGET, } from './resources.js';
|
|
15
15
|
export { SpriteRenderSystem } from './systems/sprite-render-system.js';
|
|
16
|
-
export { Engine } from './engine.js';
|
|
17
|
-
export type { EngineOptions } from './engine.js';
|
|
16
|
+
export { Engine, registerBackend, isBackendRegistered } from './engine.js';
|
|
17
|
+
export type { EngineOptions, DeviceFactory } from './engine.js';
|
|
18
18
|
export type { IGraphicsDevice, AtlasHandle, AtlasDescriptor, TextStyle, DeviceBackend, } from './renderer/graphics-device.js';
|
|
19
19
|
export type { CameraView } from './renderer/camera.js';
|
|
20
20
|
export { createCamera, getCameraViewRect, worldToScreen, screenToWorld, } from './renderer/camera.js';
|
|
21
21
|
export { Canvas2DDevice, } from './renderer/canvas2d-device.js';
|
|
22
|
+
export { WebGL2Device } from './renderer/webgl2-device.js';
|
|
23
|
+
export { TextureAtlas, makeParticleDiscAtlas, } from './renderer/texture-atlas.js';
|
|
24
|
+
export { SpriteBatcher, FLOATS_PER_INSTANCE, } from './renderer/sprite-batcher.js';
|
|
25
|
+
export type { BlendMode, FlushHandler, } from './renderer/sprite-batcher.js';
|
|
26
|
+
export { SPRITE_VERT_SRC, SPRITE_FRAG_SRC, UNIT_QUAD_VERTICES, } from './renderer/shaders/sprite-shader-source.js';
|
|
22
27
|
export { ISO_TILE_WIDTH, ISO_TILE_HEIGHT, ISO_HALF_W, ISO_HALF_H, ISO_Z_SCALE, tileToIso, worldToIso, isoToTile, isoDepthKey, } from './renderer/iso-projection.js';
|
|
23
28
|
export type { SpriteFrame, SpriteAnchor, SpriteSheetManifest, LoadedSpriteSheet, LoaderOptions, } from './asset/sprite-sheet-loader.js';
|
|
24
29
|
export { loadSpriteSheet, computeFrameIndex, SpriteSheetLoadError, } from './asset/sprite-sheet-loader.js';
|
|
@@ -82,4 +87,15 @@ export type { InteractableKind, InteractableConfig, } from './components/interac
|
|
|
82
87
|
export { InteractablePool, POOL_INTERACTABLE, INTERACTABLE_FLAG_ACTIVE, } from './components/interactable.js';
|
|
83
88
|
export type { LastInteractionResource, InteractionSystemOptions, } from './systems/interaction-system.js';
|
|
84
89
|
export { InteractionSystem, createLastInteraction, RESOURCE_LAST_INTERACTION, } from './systems/interaction-system.js';
|
|
90
|
+
export type { IMultiplayerBridge, MultiplayerBridgeStatus, MultiplayerBridgeStats, PresenceMessage, PresenceUpdate, PresenceDepart, PresenceSnapshot, } from './network/multiplayer-bridge.js';
|
|
91
|
+
export { RESOURCE_MULTIPLAYER_BRIDGE, RESOURCE_PEER_POOL, BROADCAST_HZ, BROADCAST_MIN_INTERVAL_MS, } from './network/multiplayer-bridge.js';
|
|
92
|
+
export type { PeerEntry, RenderedPeerView } from './network/peer-pool.js';
|
|
93
|
+
export { PeerPool } from './network/peer-pool.js';
|
|
94
|
+
export type { MockMultiplayerBridgeOptions } from './network/mock-multiplayer-bridge.js';
|
|
95
|
+
export { MockMultiplayerBridge } from './network/mock-multiplayer-bridge.js';
|
|
96
|
+
export type { SSEMultiplayerBridgeOptions } from './network/sse-multiplayer-bridge.js';
|
|
97
|
+
export { SSEMultiplayerBridge } from './network/sse-multiplayer-bridge.js';
|
|
98
|
+
export type { PeerSpriteEntry, PeerSpritePoolOptions } from './components/peer-sprite.js';
|
|
99
|
+
export { PeerSpritePool, POOL_PEER_SPRITE } from './components/peer-sprite.js';
|
|
100
|
+
export { PeerPresenceSystem, PeerRenderSystem, } from './systems/peer-presence-system.js';
|
|
85
101
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,mBAAmB,WAAW,CAAC;AAG5C,YAAY,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EACL,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,KAAK,EACL,IAAI,EACJ,UAAU,EACV,QAAQ,EACR,YAAY,EACZ,cAAc,EACd,aAAa,GACd,MAAM,gBAAgB,CAAC;AAExB,YAAY,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EACL,IAAI,EACJ,SAAS,EACT,eAAe,EACf,eAAe,EACf,SAAS,EACT,WAAW,EACX,WAAW,EACX,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,cAAc,EACd,iBAAiB,GAClB,MAAM,iBAAiB,CAAC;AAGzB,YAAY,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EACL,eAAe,EACf,WAAW,EACX,WAAW,EACX,gBAAgB,EAChB,UAAU,GACX,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,sBAAsB,EACtB,qBAAqB,EACrB,yBAAyB,GAC1B,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EACL,UAAU,EACV,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,wBAAwB,CAAC;AAGhC,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAChE,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,oBAAoB,EACpB,sBAAsB,EACtB,mBAAmB,EACnB,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACvE,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,wBAAwB,EACxB,aAAa,EACb,eAAe,EACf,eAAe,EACf,oBAAoB,GACrB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AAGvE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|