blecsd 0.1.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.
Files changed (109) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +220 -0
  3. package/dist/3d/index.d.ts +5 -0
  4. package/dist/3d/index.js +1 -0
  5. package/dist/audio/index.d.ts +177 -0
  6. package/dist/audio/index.js +1 -0
  7. package/dist/border-D_Jb4ZJV.d.ts +257 -0
  8. package/dist/cell-DwIu2ryP.d.ts +505 -0
  9. package/dist/chunk-2UBBZFE4.js +1 -0
  10. package/dist/chunk-35LCBY6P.js +1 -0
  11. package/dist/chunk-3B7MIVW6.js +1 -0
  12. package/dist/chunk-3EGGGI5J.js +3 -0
  13. package/dist/chunk-4LWWONFK.js +1 -0
  14. package/dist/chunk-4X4N4HNQ.js +2 -0
  15. package/dist/chunk-5PELJRUQ.js +1 -0
  16. package/dist/chunk-AEJIX2MW.js +1 -0
  17. package/dist/chunk-AQ7LW75B.js +1 -0
  18. package/dist/chunk-AXZQAH4X.js +1 -0
  19. package/dist/chunk-B6Z2JFRY.js +1 -0
  20. package/dist/chunk-BCADUCOZ.js +1 -0
  21. package/dist/chunk-C5PCEQ6G.js +1 -0
  22. package/dist/chunk-CIK4AMUA.js +1 -0
  23. package/dist/chunk-DNRXW56C.js +1 -0
  24. package/dist/chunk-FC5FFAAC.js +12 -0
  25. package/dist/chunk-FGHEFXLK.js +1 -0
  26. package/dist/chunk-FYEBZAWN.js +1 -0
  27. package/dist/chunk-G7GIWWLE.js +1 -0
  28. package/dist/chunk-GYHI26UE.js +1 -0
  29. package/dist/chunk-H2YAOJDW.js +1 -0
  30. package/dist/chunk-J4JZ2NU2.js +1 -0
  31. package/dist/chunk-JKVHO4LH.js +1 -0
  32. package/dist/chunk-K2B2OXQ5.js +5 -0
  33. package/dist/chunk-K37L3G4Z.js +4 -0
  34. package/dist/chunk-KD55INV7.js +1 -0
  35. package/dist/chunk-KFAK4A3G.js +1 -0
  36. package/dist/chunk-LCN2ZITE.js +1 -0
  37. package/dist/chunk-LYSK5S63.js +1 -0
  38. package/dist/chunk-NZ55KBM6.js +1 -0
  39. package/dist/chunk-OMMJ7B5P.js +1 -0
  40. package/dist/chunk-OUXUPF3V.js +33 -0
  41. package/dist/chunk-OVT2PPGW.js +19 -0
  42. package/dist/chunk-P6CJO3BC.js +1 -0
  43. package/dist/chunk-PSXXMBVJ.js +1 -0
  44. package/dist/chunk-PXXGH3BV.js +1 -0
  45. package/dist/chunk-QIKIOVP2.js +1 -0
  46. package/dist/chunk-SHUC6JWA.js +1 -0
  47. package/dist/chunk-TDXJDLY6.js +6 -0
  48. package/dist/chunk-TWSWTBYL.js +1 -0
  49. package/dist/chunk-TYMY2TBR.js +3 -0
  50. package/dist/chunk-VNZ6CWJA.js +2 -0
  51. package/dist/chunk-VOCM5T2G.js +5 -0
  52. package/dist/chunk-W5OU7Z6J.js +1 -0
  53. package/dist/chunk-WNG4A3K7.js +4 -0
  54. package/dist/chunk-XQIGERNI.js +1 -0
  55. package/dist/chunk-XZA63ZPO.js +1 -0
  56. package/dist/chunk-YAMOSPWB.js +4 -0
  57. package/dist/chunk-YD6ULIUR.js +1 -0
  58. package/dist/chunk-Z4EZERNE.js +1 -0
  59. package/dist/cli/init.d.ts +86 -0
  60. package/dist/cli/init.js +179 -0
  61. package/dist/color-B78w3zH-.d.ts +79 -0
  62. package/dist/components/index.d.ts +10298 -0
  63. package/dist/components/index.js +1 -0
  64. package/dist/core/index.d.ts +6700 -0
  65. package/dist/core/index.js +1 -0
  66. package/dist/debug/index.d.ts +711 -0
  67. package/dist/debug/index.js +1 -0
  68. package/dist/doubleBuffer-CKQFmlPN.d.ts +95 -0
  69. package/dist/errors/index.d.ts +1110 -0
  70. package/dist/errors/index.js +1 -0
  71. package/dist/events-BbbxkgvX.d.ts +125 -0
  72. package/dist/game/index.d.ts +486 -0
  73. package/dist/game/index.js +1 -0
  74. package/dist/gameLoop-BIPW7-OY.d.ts +219 -0
  75. package/dist/index-zSGJ2eUk.d.ts +3156 -0
  76. package/dist/index.d.ts +246 -0
  77. package/dist/index.js +1 -0
  78. package/dist/input/index.d.ts +158 -0
  79. package/dist/input/index.js +1 -0
  80. package/dist/inputActions-CefRUBuT.d.ts +2637 -0
  81. package/dist/keyParser-Bwm8-l7v.d.ts +229 -0
  82. package/dist/mouseParser-Cfrbn3AX.d.ts +177 -0
  83. package/dist/parser-iMHmQuUh.d.ts +265 -0
  84. package/dist/program-BZaKqDKH.d.ts +141 -0
  85. package/dist/renderable-jTMOA-GK.d.ts +302 -0
  86. package/dist/scheduler-DcfoFuum.d.ts +86 -0
  87. package/dist/schemas/index.d.ts +936 -0
  88. package/dist/schemas/index.js +1 -0
  89. package/dist/systems/index.d.ts +4036 -0
  90. package/dist/systems/index.js +1 -0
  91. package/dist/terminal/index.d.ts +7357 -0
  92. package/dist/terminal/index.js +1 -0
  93. package/dist/terminus-14-bold-HWSPRLJD.js +1 -0
  94. package/dist/terminus-14-normal-T3SWMH4D.js +1 -0
  95. package/dist/tilemap-D1HJvKy3.d.ts +1211 -0
  96. package/dist/types-BcsvoKzf.d.ts +68 -0
  97. package/dist/utils/index.d.ts +6104 -0
  98. package/dist/utils/index.js +1 -0
  99. package/dist/viewport3d-xI33-_wq.d.ts +182 -0
  100. package/dist/virtualScrollback-DvZTRU8a.d.ts +274 -0
  101. package/dist/virtualViewport-Dx2iJliO.d.ts +2334 -0
  102. package/dist/virtualizedLineStore-DwPEvPkk.d.ts +297 -0
  103. package/dist/widgets/bigText.d.ts +230 -0
  104. package/dist/widgets/bigText.js +1 -0
  105. package/dist/widgets/fonts/index.d.ts +211 -0
  106. package/dist/widgets/fonts/index.js +1 -0
  107. package/dist/widgets/index.d.ts +8591 -0
  108. package/dist/widgets/index.js +1 -0
  109. package/package.json +213 -0
@@ -0,0 +1,1211 @@
1
+ import { E as Entity, W as World } from './types-BcsvoKzf.js';
2
+
3
+ /**
4
+ * Collision component for entity collision detection.
5
+ * @module components/collision
6
+ */
7
+
8
+ /**
9
+ * Collider shape types.
10
+ */
11
+ declare enum ColliderType {
12
+ /** Axis-aligned bounding box */
13
+ BOX = 0,
14
+ /** Circle collider */
15
+ CIRCLE = 1
16
+ }
17
+ /**
18
+ * Collider component store using SoA (Structure of Arrays) for performance.
19
+ *
20
+ * - `type`: Collider shape (BOX or CIRCLE)
21
+ * - `width`, `height`: Dimensions (for BOX, height ignored for CIRCLE where width=diameter)
22
+ * - `offsetX`, `offsetY`: Offset from entity position
23
+ * - `layer`: Collision layer bitmask (what layer this entity is on)
24
+ * - `mask`: Collision mask bitmask (what layers to collide with)
25
+ * - `isTrigger`: Whether collider is a trigger (events only, no physics response)
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * import { setCollider, ColliderType } from 'blecsd';
30
+ *
31
+ * // Box collider
32
+ * setCollider(world, entity, {
33
+ * type: ColliderType.BOX,
34
+ * width: 2,
35
+ * height: 1,
36
+ * });
37
+ *
38
+ * // Circle collider as trigger
39
+ * setCollider(world, entity, {
40
+ * type: ColliderType.CIRCLE,
41
+ * width: 3, // diameter
42
+ * isTrigger: true,
43
+ * });
44
+ * ```
45
+ */
46
+ declare const Collider: {
47
+ /** Collider type (0=BOX, 1=CIRCLE) */
48
+ type: Uint8Array<ArrayBuffer>;
49
+ /** Width (or diameter for circles) */
50
+ width: Float32Array<ArrayBuffer>;
51
+ /** Height (ignored for circles) */
52
+ height: Float32Array<ArrayBuffer>;
53
+ /** X offset from entity position */
54
+ offsetX: Float32Array<ArrayBuffer>;
55
+ /** Y offset from entity position */
56
+ offsetY: Float32Array<ArrayBuffer>;
57
+ /** Collision layer bitmask */
58
+ layer: Uint16Array<ArrayBuffer>;
59
+ /** Collision mask (layers to collide with) */
60
+ mask: Uint16Array<ArrayBuffer>;
61
+ /** Whether this is a trigger (1) or solid (0) */
62
+ isTrigger: Uint8Array<ArrayBuffer>;
63
+ };
64
+ /**
65
+ * Collider data returned by getCollider.
66
+ */
67
+ interface ColliderData {
68
+ readonly type: ColliderType;
69
+ readonly width: number;
70
+ readonly height: number;
71
+ readonly offsetX: number;
72
+ readonly offsetY: number;
73
+ readonly layer: number;
74
+ readonly mask: number;
75
+ readonly isTrigger: boolean;
76
+ }
77
+ /**
78
+ * Options for setting a collider.
79
+ */
80
+ interface ColliderOptions {
81
+ /** Collider type (default: BOX) */
82
+ type?: ColliderType;
83
+ /** Width or diameter (default: 1) */
84
+ width?: number;
85
+ /** Height, ignored for circles (default: 1) */
86
+ height?: number;
87
+ /** X offset from position (default: 0) */
88
+ offsetX?: number;
89
+ /** Y offset from position (default: 0) */
90
+ offsetY?: number;
91
+ /** Collision layer bitmask (default: 1) */
92
+ layer?: number;
93
+ /** Collision mask (default: 0xFFFF - collide with all) */
94
+ mask?: number;
95
+ /** Whether this is a trigger only (default: false) */
96
+ isTrigger?: boolean;
97
+ }
98
+ /**
99
+ * Default collision layer.
100
+ */
101
+ declare const DEFAULT_LAYER = 1;
102
+ /**
103
+ * Default collision mask (collide with all layers).
104
+ */
105
+ declare const DEFAULT_MASK = 65535;
106
+ /**
107
+ * Sets a collider on an entity.
108
+ * Adds the Collider component if not already present.
109
+ *
110
+ * @param world - The ECS world
111
+ * @param eid - The entity ID
112
+ * @param options - Collider options
113
+ * @returns The entity ID for chaining
114
+ *
115
+ * @example
116
+ * ```typescript
117
+ * import { setCollider, ColliderType } from 'blecsd';
118
+ *
119
+ * // Create a box collider
120
+ * setCollider(world, player, {
121
+ * type: ColliderType.BOX,
122
+ * width: 1,
123
+ * height: 2,
124
+ * layer: 0b0001, // Player layer
125
+ * mask: 0b0110, // Collide with enemies and walls
126
+ * });
127
+ *
128
+ * // Create a trigger zone
129
+ * setCollider(world, checkpoint, {
130
+ * type: ColliderType.BOX,
131
+ * width: 3,
132
+ * height: 3,
133
+ * isTrigger: true,
134
+ * });
135
+ * ```
136
+ */
137
+ declare function setCollider(world: World, eid: Entity, options?: ColliderOptions): Entity;
138
+ /**
139
+ * Gets the collider data of an entity.
140
+ *
141
+ * @param world - The ECS world
142
+ * @param eid - The entity ID
143
+ * @returns Collider data or undefined
144
+ *
145
+ * @example
146
+ * ```typescript
147
+ * import { getCollider } from 'blecsd';
148
+ *
149
+ * const collider = getCollider(world, entity);
150
+ * if (collider) {
151
+ * console.log(`Collider: ${collider.width}x${collider.height}`);
152
+ * }
153
+ * ```
154
+ */
155
+ declare function getCollider(world: World, eid: Entity): ColliderData | undefined;
156
+ /**
157
+ * Checks if an entity has a Collider component.
158
+ *
159
+ * @param world - The ECS world
160
+ * @param eid - The entity ID
161
+ * @returns true if entity has Collider component
162
+ */
163
+ declare function hasCollider(world: World, eid: Entity): boolean;
164
+ /**
165
+ * Removes the collider from an entity.
166
+ *
167
+ * @param world - The ECS world
168
+ * @param eid - The entity ID
169
+ * @returns The entity ID for chaining
170
+ */
171
+ declare function removeCollider(world: World, eid: Entity): Entity;
172
+ /**
173
+ * Sets the collision layer for an entity.
174
+ *
175
+ * @param world - The ECS world
176
+ * @param eid - The entity ID
177
+ * @param layer - The collision layer bitmask
178
+ * @returns The entity ID for chaining
179
+ *
180
+ * @example
181
+ * ```typescript
182
+ * import { setCollisionLayer } from 'blecsd';
183
+ *
184
+ * // Put entity on layer 2
185
+ * setCollisionLayer(world, entity, 0b0010);
186
+ * ```
187
+ */
188
+ declare function setCollisionLayer(world: World, eid: Entity, layer: number): Entity;
189
+ /**
190
+ * Sets the collision mask for an entity.
191
+ *
192
+ * @param world - The ECS world
193
+ * @param eid - The entity ID
194
+ * @param mask - The collision mask bitmask
195
+ * @returns The entity ID for chaining
196
+ *
197
+ * @example
198
+ * ```typescript
199
+ * import { setCollisionMask } from 'blecsd';
200
+ *
201
+ * // Only collide with layers 1 and 3
202
+ * setCollisionMask(world, entity, 0b0101);
203
+ * ```
204
+ */
205
+ declare function setCollisionMask(world: World, eid: Entity, mask: number): Entity;
206
+ /**
207
+ * Sets whether the collider is a trigger.
208
+ *
209
+ * @param world - The ECS world
210
+ * @param eid - The entity ID
211
+ * @param isTrigger - Whether collider is trigger-only
212
+ * @returns The entity ID for chaining
213
+ */
214
+ declare function setTrigger(world: World, eid: Entity, isTrigger: boolean): Entity;
215
+ /**
216
+ * Checks if a collider is a trigger.
217
+ *
218
+ * @param world - The ECS world
219
+ * @param eid - The entity ID
220
+ * @returns true if collider is a trigger
221
+ */
222
+ declare function isTrigger(world: World, eid: Entity): boolean;
223
+ /**
224
+ * Checks if two layers can collide based on layer/mask.
225
+ *
226
+ * @param layerA - Layer of entity A
227
+ * @param maskA - Mask of entity A
228
+ * @param layerB - Layer of entity B
229
+ * @param maskB - Mask of entity B
230
+ * @returns true if the entities can collide
231
+ *
232
+ * @example
233
+ * ```typescript
234
+ * import { canLayersCollide } from 'blecsd';
235
+ *
236
+ * // Check if player (layer 1, mask 6) can collide with enemy (layer 2, mask 1)
237
+ * const canCollide = canLayersCollide(1, 6, 2, 1); // true
238
+ * ```
239
+ */
240
+ declare function canLayersCollide(layerA: number, maskA: number, layerB: number, maskB: number): boolean;
241
+ /**
242
+ * Axis-aligned bounding box.
243
+ */
244
+ interface AABB {
245
+ readonly minX: number;
246
+ readonly minY: number;
247
+ readonly maxX: number;
248
+ readonly maxY: number;
249
+ }
250
+ /**
251
+ * Gets the AABB for an entity's collider at a given position.
252
+ *
253
+ * @param eid - The entity ID
254
+ * @param posX - Entity X position
255
+ * @param posY - Entity Y position
256
+ * @returns The AABB bounds
257
+ *
258
+ * @example
259
+ * ```typescript
260
+ * import { getColliderAABB, Position } from 'blecsd';
261
+ *
262
+ * const bounds = getColliderAABB(entity, Position.x[entity], Position.y[entity]);
263
+ * console.log(`Bounds: ${bounds.minX},${bounds.minY} to ${bounds.maxX},${bounds.maxY}`);
264
+ * ```
265
+ */
266
+ declare function getColliderAABB(eid: Entity, posX: number, posY: number): AABB;
267
+ /**
268
+ * Tests if two AABBs overlap.
269
+ *
270
+ * @param a - First AABB
271
+ * @param b - Second AABB
272
+ * @returns true if the AABBs overlap
273
+ *
274
+ * @example
275
+ * ```typescript
276
+ * import { testAABBOverlap } from 'blecsd';
277
+ *
278
+ * const overlaps = testAABBOverlap(boundsA, boundsB);
279
+ * ```
280
+ */
281
+ declare function testAABBOverlap(a: AABB, b: AABB): boolean;
282
+ /**
283
+ * Tests if two circles overlap.
284
+ *
285
+ * @param x1 - Center X of first circle
286
+ * @param y1 - Center Y of first circle
287
+ * @param r1 - Radius of first circle
288
+ * @param x2 - Center X of second circle
289
+ * @param y2 - Center Y of second circle
290
+ * @param r2 - Radius of second circle
291
+ * @returns true if the circles overlap
292
+ */
293
+ declare function testCircleOverlap(x1: number, y1: number, r1: number, x2: number, y2: number, r2: number): boolean;
294
+ /**
295
+ * Tests if a circle overlaps with an AABB.
296
+ *
297
+ * @param cx - Circle center X
298
+ * @param cy - Circle center Y
299
+ * @param radius - Circle radius
300
+ * @param box - The AABB
301
+ * @returns true if they overlap
302
+ */
303
+ declare function testCircleAABBOverlap(cx: number, cy: number, radius: number, box: AABB): boolean;
304
+ /**
305
+ * Tests if two entities' colliders overlap.
306
+ * Handles all combinations of BOX and CIRCLE colliders.
307
+ *
308
+ * @param eidA - First entity
309
+ * @param posAX - First entity X position
310
+ * @param posAY - First entity Y position
311
+ * @param eidB - Second entity
312
+ * @param posBX - Second entity X position
313
+ * @param posBY - Second entity Y position
314
+ * @returns true if the colliders overlap
315
+ *
316
+ * @example
317
+ * ```typescript
318
+ * import { testCollision, Position } from 'blecsd';
319
+ *
320
+ * const colliding = testCollision(
321
+ * entityA, Position.x[entityA], Position.y[entityA],
322
+ * entityB, Position.x[entityB], Position.y[entityB]
323
+ * );
324
+ * ```
325
+ */
326
+ declare function testCollision(eidA: Entity, posAX: number, posAY: number, eidB: Entity, posBX: number, posBY: number): boolean;
327
+ /**
328
+ * Represents a collision between two entities.
329
+ */
330
+ interface CollisionPair {
331
+ readonly entityA: Entity;
332
+ readonly entityB: Entity;
333
+ readonly isTrigger: boolean;
334
+ }
335
+ /**
336
+ * Creates a normalized collision pair (lower entity ID first).
337
+ * This ensures consistent ordering for collision tracking.
338
+ *
339
+ * @param eidA - First entity
340
+ * @param eidB - Second entity
341
+ * @param isTrigger - Whether this is a trigger collision
342
+ * @returns Normalized collision pair
343
+ */
344
+ declare function createCollisionPair(eidA: Entity, eidB: Entity, isTrigger: boolean): CollisionPair;
345
+ /**
346
+ * Creates a unique key for a collision pair.
347
+ *
348
+ * @param pair - The collision pair
349
+ * @returns A unique string key
350
+ */
351
+ declare function collisionPairKey(pair: CollisionPair): string;
352
+
353
+ /**
354
+ * Particle and ParticleEmitter components for visual effects.
355
+ *
356
+ * Provides SoA component stores for particles and emitters,
357
+ * along with helper functions for color interpolation, aging,
358
+ * and emitter configuration.
359
+ *
360
+ * @module components/particle
361
+ */
362
+
363
+ /**
364
+ * Particle component store using SoA (Structure of Arrays).
365
+ *
366
+ * - `lifetime`: Total lifetime in seconds
367
+ * - `age`: Current age in seconds
368
+ * - `fadeOut`: 1 if particle should fade as it ages, 0 otherwise
369
+ * - `char`: Character code point to render
370
+ * - `startFg`: Foreground color at birth (packed RGBA)
371
+ * - `endFg`: Foreground color at death (packed RGBA)
372
+ * - `emitter`: Entity ID of the emitter that spawned this particle
373
+ *
374
+ * @example
375
+ * ```typescript
376
+ * import { Particle, setParticle, getParticle, isParticleDead } from 'blecsd';
377
+ *
378
+ * setParticle(world, entity, {
379
+ * lifetime: 2,
380
+ * char: '*'.codePointAt(0)!,
381
+ * startFg: 0xffff0000,
382
+ * endFg: 0xff880000,
383
+ * fadeOut: true,
384
+ * });
385
+ * ```
386
+ */
387
+ declare const Particle: {
388
+ /** Total lifetime in seconds */
389
+ lifetime: Float32Array<ArrayBuffer>;
390
+ /** Current age in seconds */
391
+ age: Float32Array<ArrayBuffer>;
392
+ /** 1 if particle fades out, 0 otherwise */
393
+ fadeOut: Uint8Array<ArrayBuffer>;
394
+ /** Character code point to render */
395
+ char: Uint32Array<ArrayBuffer>;
396
+ /** Foreground color at birth (packed RGBA) */
397
+ startFg: Uint32Array<ArrayBuffer>;
398
+ /** Foreground color at death (packed RGBA) */
399
+ endFg: Uint32Array<ArrayBuffer>;
400
+ /** Entity ID of the emitter that spawned this particle (0 = none) */
401
+ emitter: Uint32Array<ArrayBuffer>;
402
+ };
403
+ /**
404
+ * ParticleEmitter component store using SoA (Structure of Arrays).
405
+ *
406
+ * - `rate`: Particles per second (continuous emission)
407
+ * - `burstCount`: Number of particles to emit in a burst
408
+ * - `lifetime`: Default lifetime for spawned particles
409
+ * - `spread`: Emission spread angle in radians (0 = forward, PI = half-circle, 2*PI = full circle)
410
+ * - `speed`: Initial speed of spawned particles (cells/sec)
411
+ * - `gravity`: Downward acceleration (cells/sec^2)
412
+ * - `angle`: Base emission angle in radians (0 = right)
413
+ * - `active`: 1 if emitter is actively emitting, 0 if paused
414
+ * - `accumulator`: Internal accumulator for rate-based emission
415
+ *
416
+ * @example
417
+ * ```typescript
418
+ * import { ParticleEmitter, setEmitter, burstParticles } from 'blecsd';
419
+ *
420
+ * setEmitter(world, entity, {
421
+ * rate: 10,
422
+ * lifetime: 1.5,
423
+ * speed: 5,
424
+ * spread: Math.PI / 4,
425
+ * gravity: 2,
426
+ * });
427
+ *
428
+ * burstParticles(world, entity, 20);
429
+ * ```
430
+ */
431
+ declare const ParticleEmitter: {
432
+ /** Particles per second */
433
+ rate: Float32Array<ArrayBuffer>;
434
+ /** Burst count */
435
+ burstCount: Uint16Array<ArrayBuffer>;
436
+ /** Default particle lifetime in seconds */
437
+ lifetime: Float32Array<ArrayBuffer>;
438
+ /** Emission spread angle in radians */
439
+ spread: Float32Array<ArrayBuffer>;
440
+ /** Initial speed in cells per second */
441
+ speed: Float32Array<ArrayBuffer>;
442
+ /** Downward gravity in cells/sec^2 */
443
+ gravity: Float32Array<ArrayBuffer>;
444
+ /** Base emission angle in radians (0 = right) */
445
+ angle: Float32Array<ArrayBuffer>;
446
+ /** 1 if active, 0 if paused */
447
+ active: Uint8Array<ArrayBuffer>;
448
+ /** Internal accumulator for rate-based emission */
449
+ accumulator: Float32Array<ArrayBuffer>;
450
+ };
451
+ /**
452
+ * Particle data returned by getParticle.
453
+ */
454
+ interface ParticleData {
455
+ readonly lifetime: number;
456
+ readonly age: number;
457
+ readonly fadeOut: boolean;
458
+ readonly char: number;
459
+ readonly startFg: number;
460
+ readonly endFg: number;
461
+ readonly emitter: number;
462
+ }
463
+ /**
464
+ * Options for setting a particle.
465
+ */
466
+ interface ParticleOptions {
467
+ /** Total lifetime in seconds */
468
+ lifetime: number;
469
+ /** Character code point to render */
470
+ char: number;
471
+ /** Foreground color at birth (packed RGBA) */
472
+ startFg: number;
473
+ /** Foreground color at death (packed RGBA, default: same as startFg) */
474
+ endFg?: number;
475
+ /** Whether particle fades out (default: false) */
476
+ fadeOut?: boolean;
477
+ /** Entity ID of the emitter (default: 0) */
478
+ emitter?: number;
479
+ }
480
+ /**
481
+ * Emitter data returned by getEmitter.
482
+ */
483
+ interface EmitterData {
484
+ readonly rate: number;
485
+ readonly burstCount: number;
486
+ readonly lifetime: number;
487
+ readonly spread: number;
488
+ readonly speed: number;
489
+ readonly gravity: number;
490
+ readonly angle: number;
491
+ readonly active: boolean;
492
+ }
493
+ /**
494
+ * Options for configuring an emitter.
495
+ */
496
+ interface EmitterOptions {
497
+ /** Particles per second (default: 0, continuous off) */
498
+ rate?: number;
499
+ /** Burst count (default: 0) */
500
+ burstCount?: number;
501
+ /** Default particle lifetime in seconds */
502
+ lifetime: number;
503
+ /** Emission spread angle in radians (default: 2*PI, full circle) */
504
+ spread?: number;
505
+ /** Initial particle speed in cells/sec (default: 3) */
506
+ speed?: number;
507
+ /** Gravity in cells/sec^2 (default: 0) */
508
+ gravity?: number;
509
+ /** Base emission angle in radians (default: 0, right) */
510
+ angle?: number;
511
+ /** Whether emitter is active (default: true) */
512
+ active?: boolean;
513
+ }
514
+ /**
515
+ * Options for configuring emitter characters and colors.
516
+ */
517
+ interface EmitterAppearance {
518
+ /** Characters to randomly pick from for spawned particles */
519
+ chars: ReadonlyArray<number>;
520
+ /** Start foreground color (packed RGBA) */
521
+ startFg: number;
522
+ /** End foreground color (packed RGBA, default: same as startFg) */
523
+ endFg?: number;
524
+ /** Whether particles should fade out (default: true) */
525
+ fadeOut?: boolean;
526
+ }
527
+ /**
528
+ * Sets particle data on an entity.
529
+ *
530
+ * @param world - The ECS world
531
+ * @param eid - The entity ID
532
+ * @param options - Particle configuration
533
+ * @returns The entity ID for chaining
534
+ *
535
+ * @example
536
+ * ```typescript
537
+ * import { setParticle, packColor } from 'blecsd';
538
+ *
539
+ * setParticle(world, entity, {
540
+ * lifetime: 1.5,
541
+ * char: '*'.codePointAt(0)!,
542
+ * startFg: packColor(255, 255, 0),
543
+ * endFg: packColor(255, 0, 0),
544
+ * fadeOut: true,
545
+ * });
546
+ * ```
547
+ */
548
+ declare function setParticle(world: World, eid: Entity, options: ParticleOptions): Entity;
549
+ /**
550
+ * Gets particle data for an entity.
551
+ *
552
+ * @param world - The ECS world
553
+ * @param eid - The entity ID
554
+ * @returns ParticleData or undefined if not a particle
555
+ */
556
+ declare function getParticle(world: World, eid: Entity): ParticleData | undefined;
557
+ /**
558
+ * Checks if an entity has a Particle component.
559
+ */
560
+ declare function hasParticle(world: World, eid: Entity): boolean;
561
+ /**
562
+ * Removes the Particle component from an entity.
563
+ */
564
+ declare function removeParticle(world: World, eid: Entity): Entity;
565
+ /**
566
+ * Checks if a particle has exceeded its lifetime.
567
+ */
568
+ declare function isParticleDead(world: World, eid: Entity): boolean;
569
+ /**
570
+ * Gets the normalized age of a particle (0-1).
571
+ */
572
+ declare function getParticleProgress(world: World, eid: Entity): number;
573
+ /**
574
+ * Interpolates between two packed RGBA colors based on a 0-1 parameter.
575
+ *
576
+ * @param startColor - Start color (packed RGBA)
577
+ * @param endColor - End color (packed RGBA)
578
+ * @param t - Interpolation factor (0 = start, 1 = end)
579
+ * @returns Interpolated packed RGBA color
580
+ *
581
+ * @example
582
+ * ```typescript
583
+ * import { interpolateColor, packColor } from 'blecsd';
584
+ *
585
+ * const red = packColor(255, 0, 0);
586
+ * const blue = packColor(0, 0, 255);
587
+ * const purple = interpolateColor(red, blue, 0.5);
588
+ * ```
589
+ */
590
+ declare function interpolateColor(startColor: number, endColor: number, t: number): number;
591
+ /**
592
+ * Gets the current interpolated color of a particle based on its age.
593
+ */
594
+ declare function getParticleColor(world: World, eid: Entity): number;
595
+ /**
596
+ * Sets emitter data on an entity.
597
+ *
598
+ * @param world - The ECS world
599
+ * @param eid - The entity ID
600
+ * @param options - Emitter configuration
601
+ * @returns The entity ID for chaining
602
+ *
603
+ * @example
604
+ * ```typescript
605
+ * import { setEmitter } from 'blecsd';
606
+ *
607
+ * setEmitter(world, entity, {
608
+ * rate: 20,
609
+ * lifetime: 1,
610
+ * speed: 5,
611
+ * spread: Math.PI / 3,
612
+ * gravity: 9.8,
613
+ * });
614
+ * ```
615
+ */
616
+ declare function setEmitter(world: World, eid: Entity, options: EmitterOptions): Entity;
617
+ /**
618
+ * Gets emitter data for an entity.
619
+ */
620
+ declare function getEmitter(world: World, eid: Entity): EmitterData | undefined;
621
+ /**
622
+ * Checks if an entity has a ParticleEmitter component.
623
+ */
624
+ declare function hasEmitter(world: World, eid: Entity): boolean;
625
+ /**
626
+ * Removes the ParticleEmitter component from an entity.
627
+ */
628
+ declare function removeEmitter(world: World, eid: Entity): Entity;
629
+ /**
630
+ * Sets the visual appearance config for particles spawned by this emitter.
631
+ *
632
+ * @param eid - The emitter entity ID
633
+ * @param appearance - Appearance configuration
634
+ */
635
+ declare function setEmitterAppearance(eid: Entity, appearance: EmitterAppearance): void;
636
+ /**
637
+ * Gets the appearance config for an emitter.
638
+ */
639
+ declare function getEmitterAppearance(eid: Entity): EmitterAppearance | undefined;
640
+ /**
641
+ * Gets the set of particle entity IDs spawned by an emitter.
642
+ */
643
+ declare function getEmitterParticles(eid: Entity): ReadonlySet<number>;
644
+ /**
645
+ * Tracks a particle as belonging to an emitter.
646
+ */
647
+ declare function trackParticle(emitterId: Entity, particleId: Entity): void;
648
+ /**
649
+ * Untracks a particle from its emitter.
650
+ */
651
+ declare function untrackParticle(emitterId: Entity, particleId: Entity): void;
652
+ /**
653
+ * Activates an emitter.
654
+ */
655
+ declare function activateEmitter(world: World, eid: Entity): void;
656
+ /**
657
+ * Pauses an emitter.
658
+ */
659
+ declare function pauseEmitter(world: World, eid: Entity): void;
660
+ /**
661
+ * Checks if an emitter is active.
662
+ */
663
+ declare function isEmitterActive(world: World, eid: Entity): boolean;
664
+ /**
665
+ * Sets the emission rate (particles per second).
666
+ */
667
+ declare function setEmitterRate(world: World, eid: Entity, rate: number): void;
668
+ /**
669
+ * Sets the emitter speed.
670
+ */
671
+ declare function setEmitterSpeed(world: World, eid: Entity, speed: number): void;
672
+ /**
673
+ * Sets the emitter gravity.
674
+ */
675
+ declare function setEmitterGravity(world: World, eid: Entity, gravity: number): void;
676
+ /**
677
+ * Resets all particle/emitter side stores. Useful for testing.
678
+ */
679
+ declare function resetParticleStore(): void;
680
+
681
+ /**
682
+ * TileMap component for 2D tile-based game maps.
683
+ *
684
+ * Provides a tile map data structure with multiple layers,
685
+ * tileset management, and per-entity SoA storage for tile map
686
+ * metadata. Tile data is stored in an external side store
687
+ * (Map-based) for variable-sized arrays.
688
+ *
689
+ * @module components/tilemap
690
+ */
691
+
692
+ /** Empty tile index (no tile rendered) */
693
+ declare const EMPTY_TILE = 0;
694
+ /**
695
+ * A single tile definition in a tileset.
696
+ *
697
+ * @example
698
+ * ```typescript
699
+ * import type { TileDefinition } from 'blecsd';
700
+ *
701
+ * const grass: TileDefinition = { char: '.', fg: 0x00ff00ff, bg: 0x003300ff };
702
+ * const wall: TileDefinition = { char: '#', fg: 0xaaaaaaff, bg: 0x444444ff };
703
+ * ```
704
+ */
705
+ interface TileDefinition {
706
+ /** Character to render for this tile */
707
+ readonly char: string;
708
+ /** Foreground color (packed RGBA) */
709
+ readonly fg: number;
710
+ /** Background color (packed RGBA) */
711
+ readonly bg: number;
712
+ }
713
+ /**
714
+ * Tileset data stored in the tileset store.
715
+ */
716
+ interface TilesetData {
717
+ /** Unique tileset ID */
718
+ readonly id: number;
719
+ /** Human-readable name */
720
+ readonly name: string;
721
+ /** Array of tile definitions (index 0 = empty/transparent) */
722
+ readonly tiles: readonly TileDefinition[];
723
+ }
724
+ /**
725
+ * Options for registering a new tileset.
726
+ */
727
+ interface TilesetOptions {
728
+ /** Human-readable name for the tileset */
729
+ name: string;
730
+ /** Array of tile definitions. Index 0 is conventionally empty/transparent. */
731
+ tiles: TileDefinition[];
732
+ }
733
+ /**
734
+ * Storage for tileset data.
735
+ *
736
+ * @example
737
+ * ```typescript
738
+ * import { registerTileset, getTileset } from 'blecsd';
739
+ *
740
+ * const tilesetId = registerTileset({
741
+ * name: 'dungeon',
742
+ * tiles: [
743
+ * { char: ' ', fg: 0, bg: 0 }, // 0: empty
744
+ * { char: '.', fg: 0x888888ff, bg: 0 }, // 1: floor
745
+ * { char: '#', fg: 0xaaaaaaff, bg: 0x444444ff }, // 2: wall
746
+ * ],
747
+ * });
748
+ * ```
749
+ */
750
+ declare const tilesetStore: {
751
+ /** Map of tileset ID to data */
752
+ tilesets: Map<number, TilesetData>;
753
+ /** Map of tileset name to ID */
754
+ nameToId: Map<string, number>;
755
+ };
756
+ /**
757
+ * Resets the tileset store to initial state. Useful for testing.
758
+ *
759
+ * @example
760
+ * ```typescript
761
+ * import { resetTilesetStore } from 'blecsd';
762
+ *
763
+ * resetTilesetStore();
764
+ * ```
765
+ */
766
+ declare function resetTilesetStore(): void;
767
+ /**
768
+ * Registers a new tileset and returns its ID.
769
+ *
770
+ * @param options - Tileset configuration
771
+ * @returns The tileset ID
772
+ *
773
+ * @example
774
+ * ```typescript
775
+ * import { registerTileset } from 'blecsd';
776
+ *
777
+ * const tilesetId = registerTileset({
778
+ * name: 'overworld',
779
+ * tiles: [
780
+ * { char: ' ', fg: 0, bg: 0 },
781
+ * { char: '.', fg: 0x00ff00ff, bg: 0x003300ff },
782
+ * { char: '~', fg: 0x0000ffff, bg: 0x000066ff },
783
+ * ],
784
+ * });
785
+ * ```
786
+ */
787
+ declare function registerTileset(options: TilesetOptions): number;
788
+ /**
789
+ * Gets a tileset by ID.
790
+ *
791
+ * @param id - The tileset ID
792
+ * @returns The tileset data or undefined
793
+ *
794
+ * @example
795
+ * ```typescript
796
+ * import { getTileset } from 'blecsd';
797
+ *
798
+ * const tileset = getTileset(tilesetId);
799
+ * if (tileset) {
800
+ * console.log(`Tileset: ${tileset.name}, ${tileset.tiles.length} tiles`);
801
+ * }
802
+ * ```
803
+ */
804
+ declare function getTileset(id: number): TilesetData | undefined;
805
+ /**
806
+ * Gets a tileset by name.
807
+ *
808
+ * @param name - The tileset name
809
+ * @returns The tileset data or undefined
810
+ *
811
+ * @example
812
+ * ```typescript
813
+ * import { getTilesetByName } from 'blecsd';
814
+ *
815
+ * const tileset = getTilesetByName('dungeon');
816
+ * ```
817
+ */
818
+ declare function getTilesetByName(name: string): TilesetData | undefined;
819
+ /**
820
+ * Unregisters a tileset.
821
+ *
822
+ * @param id - The tileset ID to remove
823
+ * @returns true if removed, false if not found
824
+ */
825
+ declare function unregisterTileset(id: number): boolean;
826
+ /**
827
+ * A single layer of tile data.
828
+ */
829
+ interface TileMapLayer {
830
+ /** Flat array of tile indices (width * height), row-major order */
831
+ readonly tiles: Uint16Array;
832
+ /** Whether this layer is visible */
833
+ visible: boolean;
834
+ }
835
+ /**
836
+ * Tile map data stored in the side store.
837
+ */
838
+ interface TileMapData {
839
+ /** Map width in tiles */
840
+ readonly width: number;
841
+ /** Map height in tiles */
842
+ readonly height: number;
843
+ /** Array of tile layers (bottom to top) */
844
+ readonly layers: TileMapLayer[];
845
+ }
846
+ /**
847
+ * Storage for tile map layer data.
848
+ * Maps data IDs to their tile data.
849
+ */
850
+ declare const tileMapStore: {
851
+ /** Map of data ID to tile map data */
852
+ data: Map<number, TileMapData>;
853
+ };
854
+ /**
855
+ * Resets the tile map store to initial state. Useful for testing.
856
+ *
857
+ * @example
858
+ * ```typescript
859
+ * import { resetTileMapStore } from 'blecsd';
860
+ *
861
+ * resetTileMapStore();
862
+ * ```
863
+ */
864
+ declare function resetTileMapStore(): void;
865
+ /**
866
+ * Creates tile map data with the specified dimensions and number of layers.
867
+ * Returns the data ID for referencing in the TileMap component.
868
+ *
869
+ * @param width - Map width in tiles
870
+ * @param height - Map height in tiles
871
+ * @param layerCount - Number of layers (default: 1)
872
+ * @returns The data ID
873
+ *
874
+ * @example
875
+ * ```typescript
876
+ * import { createTileData } from 'blecsd';
877
+ *
878
+ * const dataId = createTileData(32, 32, 2); // 32x32 map, 2 layers
879
+ * ```
880
+ */
881
+ declare function createTileData(width: number, height: number, layerCount?: number): number;
882
+ /**
883
+ * Gets tile map data by ID.
884
+ *
885
+ * @param dataId - The data ID
886
+ * @returns The tile map data or undefined
887
+ */
888
+ declare function getTileData(dataId: number): TileMapData | undefined;
889
+ /**
890
+ * Removes tile map data.
891
+ *
892
+ * @param dataId - The data ID to remove
893
+ * @returns true if removed, false if not found
894
+ */
895
+ declare function removeTileData(dataId: number): boolean;
896
+ /**
897
+ * Sets a tile at a specific position in a layer.
898
+ *
899
+ * @param dataId - The tile map data ID
900
+ * @param layerIndex - The layer index (0-based)
901
+ * @param x - X coordinate in tiles
902
+ * @param y - Y coordinate in tiles
903
+ * @param tileIndex - The tile index in the tileset
904
+ * @returns true if set successfully, false if out of bounds or invalid
905
+ *
906
+ * @example
907
+ * ```typescript
908
+ * import { createTileData, setTile } from 'blecsd';
909
+ *
910
+ * const dataId = createTileData(10, 10);
911
+ * setTile(dataId, 0, 5, 3, 2); // Set tile at (5,3) on layer 0 to tile index 2
912
+ * ```
913
+ */
914
+ declare function setTile(dataId: number, layerIndex: number, x: number, y: number, tileIndex: number): boolean;
915
+ /**
916
+ * Gets the tile index at a specific position in a layer.
917
+ *
918
+ * @param dataId - The tile map data ID
919
+ * @param layerIndex - The layer index (0-based)
920
+ * @param x - X coordinate in tiles
921
+ * @param y - Y coordinate in tiles
922
+ * @returns The tile index, or EMPTY_TILE if out of bounds
923
+ *
924
+ * @example
925
+ * ```typescript
926
+ * import { getTile, EMPTY_TILE } from 'blecsd';
927
+ *
928
+ * const tile = getTile(dataId, 0, 5, 3);
929
+ * if (tile !== EMPTY_TILE) {
930
+ * // Tile is not empty
931
+ * }
932
+ * ```
933
+ */
934
+ declare function getTile(dataId: number, layerIndex: number, x: number, y: number): number;
935
+ /**
936
+ * Fills an entire layer with a tile index.
937
+ *
938
+ * @param dataId - The tile map data ID
939
+ * @param layerIndex - The layer index (0-based)
940
+ * @param tileIndex - The tile index to fill with
941
+ * @returns true if filled, false if invalid
942
+ *
943
+ * @example
944
+ * ```typescript
945
+ * import { createTileData, fillTiles } from 'blecsd';
946
+ *
947
+ * const dataId = createTileData(32, 32);
948
+ * fillTiles(dataId, 0, 1); // Fill entire layer with tile 1 (floor)
949
+ * ```
950
+ */
951
+ declare function fillTiles(dataId: number, layerIndex: number, tileIndex: number): boolean;
952
+ /**
953
+ * Fills a rectangular region of a layer with a tile index.
954
+ *
955
+ * @param dataId - The tile map data ID
956
+ * @param layerIndex - The layer index
957
+ * @param x - Start X coordinate
958
+ * @param y - Start Y coordinate
959
+ * @param width - Rectangle width in tiles
960
+ * @param height - Rectangle height in tiles
961
+ * @param tileIndex - The tile index to fill with
962
+ * @returns true if filled, false if invalid
963
+ *
964
+ * @example
965
+ * ```typescript
966
+ * import { fillTileRect } from 'blecsd';
967
+ *
968
+ * // Create a 5x3 wall region at (2, 4)
969
+ * fillTileRect(dataId, 0, 2, 4, 5, 3, 2);
970
+ * ```
971
+ */
972
+ declare function fillTileRect(dataId: number, layerIndex: number, x: number, y: number, width: number, height: number, tileIndex: number): boolean;
973
+ /**
974
+ * Gets the number of layers in a tile map.
975
+ *
976
+ * @param dataId - The tile map data ID
977
+ * @returns The number of layers, or 0 if invalid
978
+ */
979
+ declare function getLayerCount(dataId: number): number;
980
+ /**
981
+ * Adds a new empty layer to the tile map.
982
+ *
983
+ * @param dataId - The tile map data ID
984
+ * @returns The new layer index, or -1 if invalid
985
+ *
986
+ * @example
987
+ * ```typescript
988
+ * import { addLayer } from 'blecsd';
989
+ *
990
+ * const layerIdx = addLayer(dataId);
991
+ * // Now you can set tiles on the new layer
992
+ * ```
993
+ */
994
+ declare function addLayer(dataId: number): number;
995
+ /**
996
+ * Sets the visibility of a layer.
997
+ *
998
+ * @param dataId - The tile map data ID
999
+ * @param layerIndex - The layer index
1000
+ * @param visible - Whether the layer should be visible
1001
+ * @returns true if set, false if invalid
1002
+ *
1003
+ * @example
1004
+ * ```typescript
1005
+ * import { setLayerVisible } from 'blecsd';
1006
+ *
1007
+ * setLayerVisible(dataId, 1, false); // Hide layer 1
1008
+ * ```
1009
+ */
1010
+ declare function setLayerVisible(dataId: number, layerIndex: number, visible: boolean): boolean;
1011
+ /**
1012
+ * Gets the visibility of a layer.
1013
+ *
1014
+ * @param dataId - The tile map data ID
1015
+ * @param layerIndex - The layer index
1016
+ * @returns true if visible, false if hidden or invalid
1017
+ */
1018
+ declare function isLayerVisible(dataId: number, layerIndex: number): boolean;
1019
+ /**
1020
+ * TileMap component store using SoA (Structure of Arrays) for performance.
1021
+ *
1022
+ * - `width`: Map width in tiles
1023
+ * - `height`: Map height in tiles
1024
+ * - `tileWidth`: Tile width in terminal cells (for rendering)
1025
+ * - `tileHeight`: Tile height in terminal cells (for rendering)
1026
+ * - `dataId`: Reference to tile data in tileMapStore
1027
+ * - `tilesetId`: Reference to tileset in tilesetStore
1028
+ *
1029
+ * @example
1030
+ * ```typescript
1031
+ * import { TileMap, setTileMap, getTileMap } from 'blecsd';
1032
+ *
1033
+ * setTileMap(world, entity, {
1034
+ * width: 32,
1035
+ * height: 32,
1036
+ * tileWidth: 1,
1037
+ * tileHeight: 1,
1038
+ * tilesetId: myTilesetId,
1039
+ * });
1040
+ * ```
1041
+ */
1042
+ declare const TileMap: {
1043
+ /** Map width in tiles */
1044
+ width: Uint16Array<ArrayBuffer>;
1045
+ /** Map height in tiles */
1046
+ height: Uint16Array<ArrayBuffer>;
1047
+ /** Tile width in terminal cells */
1048
+ tileWidth: Uint8Array<ArrayBuffer>;
1049
+ /** Tile height in terminal cells */
1050
+ tileHeight: Uint8Array<ArrayBuffer>;
1051
+ /** Reference to tile data in tileMapStore */
1052
+ dataId: Uint32Array<ArrayBuffer>;
1053
+ /** Reference to tileset in tilesetStore */
1054
+ tilesetId: Uint32Array<ArrayBuffer>;
1055
+ };
1056
+ /**
1057
+ * TileMap data returned by getTileMap.
1058
+ */
1059
+ interface TileMapComponentData {
1060
+ readonly width: number;
1061
+ readonly height: number;
1062
+ readonly tileWidth: number;
1063
+ readonly tileHeight: number;
1064
+ readonly dataId: number;
1065
+ readonly tilesetId: number;
1066
+ }
1067
+ /**
1068
+ * Options for creating a tile map on an entity.
1069
+ */
1070
+ interface TileMapOptions {
1071
+ /** Map width in tiles */
1072
+ width: number;
1073
+ /** Map height in tiles */
1074
+ height: number;
1075
+ /** Tile width in terminal cells (default: 1) */
1076
+ tileWidth?: number;
1077
+ /** Tile height in terminal cells (default: 1) */
1078
+ tileHeight?: number;
1079
+ /** Tileset ID to use for rendering */
1080
+ tilesetId: number;
1081
+ /** Number of layers (default: 1) */
1082
+ layerCount?: number;
1083
+ /** Existing data ID to use (skips creating new tile data) */
1084
+ dataId?: number;
1085
+ }
1086
+ /**
1087
+ * Sets a tile map on an entity. Creates tile data if not provided.
1088
+ * Adds the TileMap component if not already present.
1089
+ *
1090
+ * @param world - The ECS world
1091
+ * @param eid - The entity ID
1092
+ * @param options - Tile map options
1093
+ * @returns The entity ID for chaining
1094
+ *
1095
+ * @example
1096
+ * ```typescript
1097
+ * import { createWorld, addEntity } from '../core/ecs';
1098
+ * import { setTileMap, registerTileset } from 'blecsd';
1099
+ *
1100
+ * const world = createWorld();
1101
+ * const entity = addEntity(world);
1102
+ *
1103
+ * const tilesetId = registerTileset({
1104
+ * name: 'dungeon',
1105
+ * tiles: [
1106
+ * { char: ' ', fg: 0, bg: 0 },
1107
+ * { char: '.', fg: 0x888888ff, bg: 0 },
1108
+ * { char: '#', fg: 0xaaaaaaff, bg: 0x444444ff },
1109
+ * ],
1110
+ * });
1111
+ *
1112
+ * setTileMap(world, entity, {
1113
+ * width: 20,
1114
+ * height: 15,
1115
+ * tilesetId,
1116
+ * });
1117
+ * ```
1118
+ */
1119
+ declare function setTileMap(world: World, eid: Entity, options: TileMapOptions): Entity;
1120
+ /**
1121
+ * Gets the tile map data of an entity.
1122
+ *
1123
+ * @param world - The ECS world
1124
+ * @param eid - The entity ID
1125
+ * @returns TileMap component data or undefined
1126
+ *
1127
+ * @example
1128
+ * ```typescript
1129
+ * import { getTileMap } from 'blecsd';
1130
+ *
1131
+ * const tileMap = getTileMap(world, entity);
1132
+ * if (tileMap) {
1133
+ * console.log(`Map: ${tileMap.width}x${tileMap.height}`);
1134
+ * }
1135
+ * ```
1136
+ */
1137
+ declare function getTileMap(world: World, eid: Entity): TileMapComponentData | undefined;
1138
+ /**
1139
+ * Checks if an entity has a TileMap component.
1140
+ *
1141
+ * @param world - The ECS world
1142
+ * @param eid - The entity ID
1143
+ * @returns true if entity has TileMap component
1144
+ */
1145
+ declare function hasTileMap(world: World, eid: Entity): boolean;
1146
+ /**
1147
+ * Removes the tile map from an entity.
1148
+ * Also removes the associated tile data from the store.
1149
+ *
1150
+ * @param world - The ECS world
1151
+ * @param eid - The entity ID
1152
+ * @param keepData - If true, does not remove tile data from store (default: false)
1153
+ * @returns The entity ID for chaining
1154
+ *
1155
+ * @example
1156
+ * ```typescript
1157
+ * import { removeTileMap } from 'blecsd';
1158
+ *
1159
+ * removeTileMap(world, entity);
1160
+ * ```
1161
+ */
1162
+ declare function removeTileMap(world: World, eid: Entity, keepData?: boolean): Entity;
1163
+ /**
1164
+ * Gets the data ID for an entity's tile map.
1165
+ *
1166
+ * @param world - The ECS world
1167
+ * @param eid - The entity ID
1168
+ * @returns The data ID or 0 if not found
1169
+ */
1170
+ declare function getTileMapDataId(world: World, eid: Entity): number;
1171
+ /**
1172
+ * A single rendered cell from the tile map.
1173
+ */
1174
+ interface RenderedTileCell {
1175
+ /** Character to display */
1176
+ readonly char: string;
1177
+ /** Foreground color (packed RGBA) */
1178
+ readonly fg: number;
1179
+ /** Background color (packed RGBA) */
1180
+ readonly bg: number;
1181
+ }
1182
+ /**
1183
+ * Renders a rectangular viewport of the tile map to an array of cells.
1184
+ * Composites all visible layers from bottom to top.
1185
+ * Non-empty tiles on upper layers overwrite lower layers.
1186
+ *
1187
+ * @param dataId - The tile map data ID
1188
+ * @param tilesetId - The tileset ID to use for rendering
1189
+ * @param viewX - Viewport X offset in tiles
1190
+ * @param viewY - Viewport Y offset in tiles
1191
+ * @param viewWidth - Viewport width in tiles
1192
+ * @param viewHeight - Viewport height in tiles
1193
+ * @returns 2D array of rendered cells (row-major: [y][x])
1194
+ *
1195
+ * @example
1196
+ * ```typescript
1197
+ * import { renderTileMapArea } from 'blecsd';
1198
+ *
1199
+ * // Render a 10x8 viewport starting at tile (5, 3)
1200
+ * const cells = renderTileMapArea(dataId, tilesetId, 5, 3, 10, 8);
1201
+ * for (let y = 0; y < cells.length; y++) {
1202
+ * for (let x = 0; x < cells[y].length; x++) {
1203
+ * const cell = cells[y][x];
1204
+ * // Render cell.char with cell.fg and cell.bg
1205
+ * }
1206
+ * }
1207
+ * ```
1208
+ */
1209
+ declare function renderTileMapArea(dataId: number, tilesetId: number, viewX: number, viewY: number, viewWidth: number, viewHeight: number): RenderedTileCell[][];
1210
+
1211
+ export { isEmitterActive as $, type AABB as A, getCollider as B, Collider as C, DEFAULT_LAYER as D, EMPTY_TILE as E, getColliderAABB as F, getEmitter as G, getEmitterAppearance as H, getEmitterParticles as I, getLayerCount as J, getParticle as K, getParticleColor as L, getParticleProgress as M, getTile as N, getTileData as O, Particle as P, getTileMap as Q, type RenderedTileCell as R, getTileMapDataId as S, type TileDefinition as T, getTileset as U, getTilesetByName as V, hasCollider as W, hasEmitter as X, hasParticle as Y, hasTileMap as Z, interpolateColor as _, type ColliderData as a, isLayerVisible as a0, isParticleDead as a1, isTrigger as a2, pauseEmitter as a3, registerTileset as a4, removeCollider as a5, removeEmitter as a6, removeParticle as a7, removeTileData as a8, removeTileMap as a9, renderTileMapArea as aa, resetParticleStore as ab, resetTileMapStore as ac, resetTilesetStore as ad, setCollider as ae, setCollisionLayer as af, setCollisionMask as ag, setEmitter as ah, setEmitterAppearance as ai, setEmitterGravity as aj, setEmitterRate as ak, setEmitterSpeed as al, setLayerVisible as am, setParticle as an, setTile as ao, setTileMap as ap, setTrigger as aq, testAABBOverlap as ar, testCircleAABBOverlap as as, testCircleOverlap as at, testCollision as au, tileMapStore as av, tilesetStore as aw, trackParticle as ax, unregisterTileset as ay, untrackParticle as az, type ColliderOptions as b, ColliderType as c, type CollisionPair as d, DEFAULT_MASK as e, type EmitterAppearance as f, type EmitterData as g, type EmitterOptions as h, type ParticleData as i, ParticleEmitter as j, type ParticleOptions as k, TileMap as l, type TileMapComponentData as m, type TileMapData as n, type TileMapLayer as o, type TileMapOptions as p, type TilesetData as q, type TilesetOptions as r, activateEmitter as s, addLayer as t, canLayersCollide as u, collisionPairKey as v, createCollisionPair as w, createTileData as x, fillTileRect as y, fillTiles as z };