@utsp/core 0.16.1 → 0.17.0-nightly.20260120215017.712755a

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/dist/index.d.ts CHANGED
@@ -1,16 +1,15 @@
1
1
  import * as _utsp_types from '@utsp/types';
2
- import { Vector2, ScalingModeValue, AxisSource, ButtonSource, InputBindingLoadPacket, AxisBinding, ButtonBinding, TouchZoneBinding, SoundInstanceId, AudioConfigCommand, PlaySoundCommand, StopSoundCommand, FadeOutSoundCommand, PauseSoundCommand, ResumeSoundCommand, SetSoundEffectsCommand, IAudioProcessor, VibrationPattern, GamepadVibrationOptions, GamepadVibrationCommand, IGamepadVibrationProcessor, MobileVibrationCommand, IMobileVibrationProcessor, AudioAck, PostProcessConfig, PostProcessCommand, ScalingMode, GridConfig, SoundFormat, SoundLoadType, SoundLoadPacket, SoundExternalLoadPacket, UserRenderState } from '@utsp/types';
2
+ import { PostProcessConfig, ScalingMode, GridConfig, Vector2, ScalingModeValue, AxisSource, ButtonSource, InputBindingLoadPacket, AxisBinding, ButtonBinding, TouchZoneBinding, SoundInstanceId, AudioConfigCommand, PlaySoundCommand, StopSoundCommand, FadeOutSoundCommand, PauseSoundCommand, ResumeSoundCommand, SetSoundEffectsCommand, IAudioProcessor, VibrationPattern, GamepadVibrationOptions, GamepadVibrationCommand, IGamepadVibrationProcessor, MobileVibrationCommand, IMobileVibrationProcessor, AudioAck, PostProcessCommand, SoundFormat, SoundLoadType, SoundLoadPacket, SoundExternalLoadPacket, UserRenderState } from '@utsp/types';
3
3
  export { AxisBinding, AxisSource, ButtonBinding, ButtonSource, InputBindingLoadPacket, RenderState, RenderedCell, ScalingModeValue, UserRenderState, Vector2 } from '@utsp/types';
4
4
 
5
5
  /**
6
6
  * Font system for UTSP Core
7
- * Supports WebFont (CSS-based), BitmapFont (pixel-based), and ImageFont (PNG atlas-based)
7
+ * Supports BitmapFont (pixel-based) and ImageFont (PNG atlas-based)
8
8
  */
9
9
  /**
10
10
  * Font type enumeration
11
11
  */
12
12
  declare enum FontType {
13
- Web = "web",
14
13
  Bitmap = "bitmap",
15
14
  Image = "image"
16
15
  }
@@ -47,140 +46,6 @@ declare function getAtlasDimensions(blocks: AtlasBlocks, glyphSize: GlyphSize):
47
46
  width: number;
48
47
  height: number;
49
48
  };
50
- /**
51
- * WebFont configuration
52
- * For CSS-based fonts rendered by the browser
53
- */
54
- interface WebFontConfig {
55
- fontFamily: string;
56
- fontSize: number;
57
- offsetX?: number;
58
- offsetY?: number;
59
- charSpacing?: number;
60
- lineHeight?: number;
61
- fontWeight?: string;
62
- fontStyle?: string;
63
- }
64
- /**
65
- * WebFont class
66
- * Represents a CSS-based font for browser rendering
67
- */
68
- declare class WebFont {
69
- private fontId;
70
- private config;
71
- constructor(fontId: number, config: WebFontConfig);
72
- /**
73
- * Get the unique font ID
74
- */
75
- getFontId(): number;
76
- /**
77
- * Get the full configuration (copy)
78
- */
79
- getConfig(): WebFontConfig;
80
- /**
81
- * Get the font family
82
- */
83
- getFontFamily(): string;
84
- /**
85
- * Get the font size in pixels
86
- */
87
- getFontSize(): number;
88
- /**
89
- * Get the horizontal offset
90
- */
91
- getOffsetX(): number;
92
- /**
93
- * Get the vertical offset
94
- */
95
- getOffsetY(): number;
96
- /**
97
- * Get the character spacing
98
- */
99
- getCharSpacing(): number;
100
- /**
101
- * Get the line height multiplier
102
- */
103
- getLineHeight(): number;
104
- /**
105
- * Get the font weight
106
- */
107
- getFontWeight(): string;
108
- /**
109
- * Get the font style
110
- */
111
- getFontStyle(): string;
112
- /**
113
- * Generate CSS declaration for this font
114
- * @returns CSS string (e.g., "font-family: Consolas; font-size: 16px;")
115
- */
116
- toCSS(): string;
117
- }
118
- /**
119
- * BitmapFont configuration
120
- * For pixel-based fonts with custom glyph data
121
- */
122
- interface BitmapFontConfig {
123
- charWidth: number;
124
- charHeight: number;
125
- cellWidth?: number;
126
- cellHeight?: number;
127
- glyphs: Map<number, Uint8Array>;
128
- }
129
- /**
130
- * BitmapFont class
131
- * Represents a pixel-based font with custom glyph bitmaps
132
- * Corresponds to LoadType 0x04 (Charset) in UTSP protocol
133
- */
134
- declare class BitmapFont {
135
- private fontId;
136
- private config;
137
- constructor(fontId: number, config: BitmapFontConfig);
138
- /**
139
- * Get the unique font ID
140
- */
141
- getFontId(): number;
142
- /**
143
- * Get the full configuration (deep copy)
144
- */
145
- getConfig(): BitmapFontConfig;
146
- /**
147
- * Get the glyph width in pixels (actual bitmap size)
148
- */
149
- getCharWidth(): number;
150
- /**
151
- * Get the glyph height in pixels (actual bitmap size)
152
- */
153
- getCharHeight(): number;
154
- /**
155
- * Get the target cell width in pixels (rendering size)
156
- * Defaults to glyph width if not specified
157
- */
158
- getCellWidth(): number;
159
- /**
160
- * Get the target cell height in pixels (rendering size)
161
- * Defaults to glyph height if not specified
162
- */
163
- getCellHeight(): number;
164
- /**
165
- * Get the bitmap data for a specific character
166
- * @param charCode Character code (0-255)
167
- * @returns Bitmap data or undefined if not found
168
- */
169
- getGlyph(charCode: number): Uint8Array | undefined;
170
- /**
171
- * Check if a glyph exists for a character
172
- * @param charCode Character code (0-255)
173
- */
174
- hasGlyph(charCode: number): boolean;
175
- /**
176
- * Get the number of glyphs in this font
177
- */
178
- getGlyphCount(): number;
179
- /**
180
- * Get all character codes that have glyphs
181
- */
182
- getCharCodes(): number[];
183
- }
184
49
  /**
185
50
  * ImageFont configuration
186
51
  * For PNG atlas-based fonts with pre-rendered glyphs
@@ -191,7 +56,6 @@ interface ImageFontConfig {
191
56
  cellWidth?: number;
192
57
  cellHeight?: number;
193
58
  atlasBlocks: AtlasBlocks;
194
- imageData: Uint8Array;
195
59
  }
196
60
  /**
197
61
  * ImageFont class
@@ -220,13 +84,22 @@ declare class ImageFont {
220
84
  private config;
221
85
  private readonly atlasColumns;
222
86
  private readonly maxCharCode;
87
+ private blocks;
223
88
  constructor(fontId: number, config: ImageFontConfig);
89
+ /**
90
+ * Add image data for a specific block
91
+ */
92
+ addBlock(blockIndex: number, data: Uint8Array): void;
93
+ /**
94
+ * Get image data for a specific block
95
+ */
96
+ getBlock(blockIndex: number): Uint8Array | undefined;
224
97
  /**
225
98
  * Get the unique font ID
226
99
  */
227
100
  getFontId(): number;
228
101
  /**
229
- * Get the full configuration (copy with new imageData reference)
102
+ * Get the full configuration
230
103
  */
231
104
  getConfig(): ImageFontConfig;
232
105
  /**
@@ -257,10 +130,6 @@ declare class ImageFont {
257
130
  * Get the maximum supported charCode
258
131
  */
259
132
  getMaxCharCode(): number;
260
- /**
261
- * Get the PNG image data
262
- */
263
- getImageData(): Uint8Array;
264
133
  /**
265
134
  * Get the atlas dimensions in pixels
266
135
  */
@@ -321,14 +190,21 @@ declare class ImageFontRegistry {
321
190
  */
322
191
  private allocateId;
323
192
  /**
324
- * Register a new ImageFont with auto-assigned ID
193
+ * Register a new ImageFont structure (no data)
194
+ * Use addBlock() to add image data
325
195
  * @param name Human-readable name for the font
326
196
  * @param options Font options (glyph size, atlas blocks)
327
- * @param imageData PNG image data
328
197
  * @returns The assigned font ID (0-255)
329
198
  * @throws Error if name already exists
330
199
  */
331
- registerFont(name: string, options: ImageFontOptions, imageData: Uint8Array): number;
200
+ registerFont(name: string, options: ImageFontOptions): number;
201
+ /**
202
+ * Add a data block to an existing font
203
+ * @param fontId The font ID
204
+ * @param blockIndex Block index (0-15)
205
+ * @param data PNG image data
206
+ */
207
+ addBlock(fontId: number, blockIndex: number, data: Uint8Array): void;
332
208
  /**
333
209
  * Load a new ImageFont into the registry with specific ID (low-level API)
334
210
  * @param fontId Unique font identifier (0-255)
@@ -1269,8 +1145,8 @@ declare function getMacroEventTypeName(type: MacroEventType): string;
1269
1145
 
1270
1146
  /**
1271
1147
  * CharCode mode for layers
1272
- * - '8bit': Uses Uint8Array, limited to 256 characters (ASCII/CP437), optimized bandwidth
1273
- * - '16bit': Uses Uint16Array, supports 65536 characters (Unicode BMP), universal
1148
+ * - '8bit': 256 char codes (CP437 default)
1149
+ * - '16bit': 65536 char codes (256 atlas blocks × 256 chars)
1274
1150
  */
1275
1151
  type CharCodeMode = '8bit' | '16bit';
1276
1152
  interface Cell {
@@ -1279,19 +1155,16 @@ interface Cell {
1279
1155
  bgColorCode: number;
1280
1156
  }
1281
1157
  /**
1282
- * Optimized buffer for cells with TypedArray
1283
- * Separate arrays for charCodes and colors for optimal memory layout
1158
+ * Optimized buffer for cells
1284
1159
  *
1285
1160
  * CharCode storage depends on mode:
1286
- * - 8-bit mode: Uint8Array (1 byte per charCode) - network optimized
1287
- * - 16-bit mode: Uint16Array (2 bytes per charCode) - full Unicode BMP
1161
+ * - 8-bit mode: 256 char codes
1162
+ * - 16-bit mode: 65536 char codes (atlas indices)
1288
1163
  *
1289
1164
  * Colors are always 8-bit (256 palette colors)
1290
1165
  *
1291
1166
  * Performance:
1292
1167
  * - clear(): ~5-10μs (vs 826μs with object array)
1293
- * - Better cache locality
1294
- * - Less GC pressure
1295
1168
  */
1296
1169
  declare class CellBuffer {
1297
1170
  private charCodes;
@@ -1403,7 +1276,7 @@ declare class CellBuffer {
1403
1276
  /**
1404
1277
  * Optimized buffer to store only charcodes (unicolor sprites)
1405
1278
  * Simple structure: [char0, char1, char2, ...]
1406
- * Always uses 16-bit charCodes to support full Unicode BMP
1279
+ * Always uses 16-bit charCodes to support atlas indices (0-65535)
1407
1280
  *
1408
1281
  * Performance:
1409
1282
  * - Less memory than CellBuffer (2 bytes vs 4 bytes per cell)
@@ -1492,11 +1365,10 @@ declare enum LoadType {
1492
1365
  ColorPalette = 1,
1493
1366
  Sprite = 2,
1494
1367
  MulticolorSprite = 3,
1495
- BitmapFont = 4,// Formerly "Charset" - pixel-based fonts (bitpacking)
1496
1368
  Sound = 5,
1497
- WebFont = 6,// CSS-based fonts for browser rendering
1498
1369
  Macro = 7,// Macro template for client-side feedback
1499
- ImageFont = 8
1370
+ ImageFont = 8,// Header for PNG atlas-based fonts (structure only)
1371
+ ImageFontBlock = 9
1500
1372
  }
1501
1373
  /**
1502
1374
  * Color definition with RGBA+E values
@@ -1514,12 +1386,12 @@ interface Color {
1514
1386
  * Loads a palette of RGBA+E colors
1515
1387
  *
1516
1388
  * When slotId is provided, the palette is loaded into a named slot for later switching.
1517
- * When slotId is undefined/absent, the palette is loaded as the main active palette.
1389
+ * When slotId is undefined/absent, the palette is loaded into the default slot (0).
1518
1390
  *
1519
1391
  * @example
1520
1392
  * ```typescript
1521
- * // Main palette (backward compatible)
1522
- * { loadType: LoadType.ColorPalette, colors: [...] }
1393
+ * // Default slot (backward compatible)
1394
+ * { loadType: LoadType.ColorPalette, colors: [...] } // → treated as slot 0
1523
1395
  *
1524
1396
  * // Palette slot for dynamic switching
1525
1397
  * { loadType: LoadType.ColorPalette, slotId: 1, colors: [...] }
@@ -1564,40 +1436,6 @@ interface MulticolorSpriteLoad {
1564
1436
  data: MulticolorCell[];
1565
1437
  }>;
1566
1438
  }
1567
- /**
1568
- * BitmapFont Load (LoadType 0x04)
1569
- * Custom character definitions (monochrome bitmaps)
1570
- * Formerly known as "Charset" - renamed to BitmapFont for clarity
1571
- */
1572
- interface BitmapFontLoad {
1573
- loadType: LoadType.BitmapFont;
1574
- fontId: number;
1575
- width: number;
1576
- height: number;
1577
- cellWidth: number;
1578
- cellHeight: number;
1579
- characters: Array<{
1580
- charCode: number;
1581
- bitmap: Uint8Array;
1582
- }>;
1583
- }
1584
- /**
1585
- * WebFont Load (LoadType 0x06)
1586
- * CSS-based font definitions for browser rendering
1587
- * Note: The default font is "Courier New" (monospace), but users can specify non-monospace fonts
1588
- */
1589
- interface WebFontLoad {
1590
- loadType: LoadType.WebFont;
1591
- fontId: number;
1592
- fontFamily: string;
1593
- fontSize: number;
1594
- offsetX?: number;
1595
- offsetY?: number;
1596
- charSpacing?: number;
1597
- lineHeight?: number;
1598
- fontWeight?: string;
1599
- fontStyle?: string;
1600
- }
1601
1439
  /**
1602
1440
  * Sound Load (LoadType 0x05)
1603
1441
  * MIDI sound data for audio playback
@@ -1612,31 +1450,31 @@ interface SoundLoad {
1612
1450
  /**
1613
1451
  * ImageFont Load (LoadType 0x08)
1614
1452
  * PNG atlas-based fonts for extended character sets (256, 1024, or 4096 chars)
1615
- *
1616
- * Atlas layout (example for 4 blocks = 1024 chars):
1617
- * ```
1618
- * ┌─────────┬─────────┐
1619
- * │ 0-255 │ 256-511 │ 32×32 grid
1620
- * ├─────────┼─────────┤ = 1024 chars
1621
- * │ 512-767 │768-1023 │
1622
- * └─────────┴─────────┘
1623
- * ```
1453
+ * Note: Protocol supports only ONE active ImageFont.
1624
1454
  */
1625
1455
  interface ImageFontLoad {
1626
1456
  loadType: LoadType.ImageFont;
1627
- fontId: number;
1628
1457
  glyphWidth: number;
1629
1458
  glyphHeight: number;
1630
1459
  cellWidth: number;
1631
1460
  cellHeight: number;
1632
1461
  atlasBlocks: AtlasBlocks;
1462
+ }
1463
+ /**
1464
+ * ImageFont Block Load (LoadType 0x09)
1465
+ * Contains one block of PNG data for the active ImageFont.
1466
+ * One block = 256 characters (16x16 grid).
1467
+ */
1468
+ interface ImageFontBlockLoad {
1469
+ loadType: LoadType.ImageFontBlock;
1470
+ blockIndex: number;
1633
1471
  imageData: Uint8Array;
1634
1472
  }
1635
1473
 
1636
1474
  /**
1637
1475
  * Union type for all load types
1638
1476
  */
1639
- type AnyLoad = ColorPaletteLoad | SpriteLoad | MulticolorSpriteLoad | BitmapFontLoad | SoundLoad | WebFontLoad | MacroLoad | ImageFontLoad;
1477
+ type AnyLoad = ColorPaletteLoad | SpriteLoad | MulticolorSpriteLoad | SoundLoad | MacroLoad | ImageFontLoad | ImageFontBlockLoad;
1640
1478
 
1641
1479
  /**
1642
1480
  * Central registry to manage unicolor and multicolor sprites
@@ -2497,6 +2335,46 @@ type GamepadVibrationOrder = GamepadVibrateOrder | GamepadCancelOrder;
2497
2335
  */
2498
2336
  type AnyVibrationOrder = MobileVibrateOrder | MobileCancelOrder | GamepadVibrateOrder | GamepadCancelOrder;
2499
2337
 
2338
+ /**
2339
+ * Internal command sink used by `Display` to enqueue network commands via `User`.
2340
+ * @internal
2341
+ */
2342
+ interface DisplayCommandSink {
2343
+ setPostProcess(displayId: number, config: PostProcessConfig | null): void;
2344
+ setScanlinesEnabled(displayId: number, enabled: boolean): void;
2345
+ setScanlinesOpacity(displayId: number, opacity: number): void;
2346
+ setScanlinesPattern(displayId: number, pattern: 'horizontal' | 'vertical' | 'grid'): void;
2347
+ setAmbientEffect(displayId: number, config: boolean | {
2348
+ blur?: number;
2349
+ scale?: number;
2350
+ }): void;
2351
+ setAmbientEffectEnabled(displayId: number, enabled: boolean): void;
2352
+ setAmbientEffectBlur(displayId: number, blur: number): void;
2353
+ setAmbientEffectScale(displayId: number, scale: number): void;
2354
+ isAmbientEffectEnabled(displayId: number): boolean;
2355
+ getAmbientEffectConfig(displayId: number): {
2356
+ enabled: boolean;
2357
+ blur: number;
2358
+ scale: number;
2359
+ } | null;
2360
+ getPostProcessConfig(displayId: number): PostProcessConfig | null;
2361
+ setScalingMode(displayId: number, mode: ScalingMode): void;
2362
+ getScalingMode(displayId: number): ScalingMode | null;
2363
+ setCellSize(displayId: number, width: number, height: number): void;
2364
+ getCellSize(displayId: number): {
2365
+ cellWidth: number;
2366
+ cellHeight: number;
2367
+ };
2368
+ setGrid(displayId: number, config: boolean | GridConfig): void;
2369
+ setGridEnabled(displayId: number, enabled: boolean): void;
2370
+ isGridEnabled(displayId: number): boolean;
2371
+ getGridConfig(displayId: number): GridConfig | null;
2372
+ switchPalette(displayId: number, slotId: number): void;
2373
+ getCurrentPaletteSlotId(displayId: number): number | null;
2374
+ }
2375
+ /**
2376
+ * Render pass definition for multi-pass rendering.
2377
+ */
2500
2378
  interface RenderPassConfig {
2501
2379
  id: number;
2502
2380
  zMin: number;
@@ -2504,156 +2382,411 @@ interface RenderPassConfig {
2504
2382
  enabled?: boolean;
2505
2383
  }
2506
2384
  /**
2507
- * Represents a display (camera) in the virtual world
2385
+ * Represents a display (camera) in the virtual world.
2508
2386
  *
2509
- * ARCHITECTURE (new protocol):
2510
- * - Display = camera looking into the virtual world
2511
- * - LAYERS are NO LONGER in Display, they are at User level
2512
- * - Display only defines WHICH PART of the world we see (origin)
2387
+ * Architecture:
2388
+ * - `Display` is a camera looking into the world.
2389
+ * - Layers are managed at the `User` level.
2390
+ * - `Display` defines viewport origin/size and display-specific settings.
2513
2391
  */
2514
2392
  declare class Display {
2515
2393
  private id;
2516
2394
  private origin;
2517
2395
  private size;
2396
+ private commandSink?;
2518
2397
  private previousOrigin;
2519
2398
  private previousSize;
2520
- private toDraw;
2521
2399
  private renderPasses;
2400
+ /**
2401
+ * Creates a new display.
2402
+ *
2403
+ * @param id - Display ID (0-255).
2404
+ * @param sizeX - Width in cells (1-256).
2405
+ * @param sizeY - Height in cells (1-256).
2406
+ *
2407
+ * @example
2408
+ * const display = new Display(0, 80, 45);
2409
+ *
2410
+ * @throws Error if `id`, `sizeX`, or `sizeY` are out of bounds.
2411
+ */
2522
2412
  constructor(id?: number, sizeX?: number, sizeY?: number);
2523
2413
  /**
2524
- * Gets the display ID (0-255)
2414
+ * Returns the display ID (0-255).
2415
+ *
2416
+ * @returns The display ID.
2525
2417
  */
2526
2418
  getId(): number;
2527
2419
  /**
2528
- * Gets the origin position in the world
2420
+ * Injects the command sink (set by `User`).
2421
+ * @internal
2422
+ */
2423
+ setCommandSink(sink: DisplayCommandSink): void;
2424
+ /**
2425
+ * Returns the display origin in world space.
2426
+ *
2427
+ * @returns The current origin.
2428
+ *
2429
+ * @example
2430
+ * const origin = display.getOrigin();
2529
2431
  */
2530
2432
  getOrigin(): Vector2;
2531
2433
  /**
2532
- * Sets the origin position in the world
2434
+ * Sets the display origin in world space.
2435
+ *
2436
+ * @param origin - New world position.
2437
+ *
2438
+ * @example
2439
+ * display.setOrigin(new Vector2(10, 5));
2533
2440
  */
2534
2441
  setOrigin(origin: Vector2): void;
2535
2442
  /**
2536
- * Moves the origin in the world
2443
+ * Moves the display origin by a delta.
2444
+ *
2445
+ * @param deltaX - Delta X in world cells.
2446
+ * @param deltaY - Delta Y in world cells.
2447
+ *
2448
+ * @example
2449
+ * display.moveOrigin(1, 0);
2537
2450
  */
2538
2451
  moveOrigin(deltaX: number, deltaY: number): void;
2539
2452
  /**
2540
- * Checks if display origin has changed since last tick
2541
- * @internal - Used to calculate if update should be sent
2453
+ * Returns `true` if the origin changed since the last tick.
2454
+ *
2455
+ * @returns Whether the origin has changed.
2456
+ * @internal
2542
2457
  */
2543
2458
  hasOriginChanged(): boolean;
2544
2459
  /**
2545
- * Checks if display size has changed since last tick
2546
- * @internal - Used to calculate if update should be sent
2460
+ * Returns `true` if the size changed since the last tick.
2461
+ *
2462
+ * @returns Whether the size has changed.
2463
+ * @internal
2547
2464
  */
2548
2465
  hasSizeChanged(): boolean;
2549
2466
  /**
2550
- * Checks if display has changed (origin OR size)
2467
+ * Returns `true` if origin or size changed since the last tick.
2468
+ *
2469
+ * @returns Whether origin or size has changed.
2551
2470
  * @internal
2552
2471
  */
2553
2472
  hasChanged(): boolean;
2554
2473
  /**
2555
- * Resets change tracking
2556
- * @internal - Called by Core.endTick() after sending updates
2474
+ * Resets change tracking to the current state.
2475
+ * @internal
2557
2476
  */
2558
2477
  resetChangeTracking(): void;
2559
2478
  /**
2560
- * Gets the display size
2479
+ * Returns the display size in cells.
2480
+ *
2481
+ * @returns The current size in cells.
2482
+ *
2483
+ * @example
2484
+ * const size = display.getSize();
2561
2485
  */
2562
2486
  getSize(): Vector2;
2563
2487
  /**
2564
- * Sets the display size
2488
+ * Sets the display size in cells.
2489
+ *
2490
+ * @param size - New size in cells (1-256).
2491
+ *
2492
+ * @example
2493
+ * display.setSize(new Vector2(80, 45));
2494
+ *
2495
+ * @throws Error if width/height are out of bounds.
2565
2496
  */
2566
2497
  setSize(size: Vector2): void;
2567
2498
  /**
2568
- * Returns the validated render passes (undefined = single pass [0,255])
2499
+ * Returns the injected command sink.
2500
+ * @throws Error if this display is not attached to a `User`.
2569
2501
  */
2570
- getRenderPasses(): RenderPassConfig[] | undefined;
2502
+ private getSink;
2571
2503
  /**
2572
- * Sets the render passes configuration (0..4 passes). Applies clamping and swap.
2573
- * Passing undefined resets to single pass behavior.
2504
+ * Sets the post-process configuration for this display.
2505
+ *
2506
+ * @param config - Post-process config or `null` to disable.
2507
+ *
2508
+ * @example
2509
+ * display.setPostProcess({
2510
+ * scanlines: { enabled: true, opacity: 0.2, pattern: 'horizontal' },
2511
+ * });
2512
+ *
2513
+ * @throws Error if the display is not attached to a `User`.
2574
2514
  */
2575
- setRenderPasses(passes: RenderPassConfig[] | undefined): void;
2576
- private normalizePass;
2515
+ setPostProcess(config: PostProcessConfig | null): void;
2577
2516
  /**
2578
- * Returns a debug-friendly snapshot of this display (metadata only)
2517
+ * Enables or disables scanlines for this display.
2518
+ *
2519
+ * @param enabled - Whether scanlines are enabled.
2520
+ *
2521
+ * @example
2522
+ * display.setScanlinesEnabled(true);
2579
2523
  */
2580
- getDebugInfo(): {
2581
- id: number;
2582
- origin: {
2583
- x: number;
2584
- y: number;
2585
- };
2586
- size: {
2587
- x: number;
2588
- y: number;
2589
- };
2590
- renderPasses?: RenderPassConfig[];
2591
- };
2592
- }
2593
-
2594
- /**
2595
- * Network representation of a display
2596
- * Layers are NO LONGER under displays - they are at User level
2597
- */
2598
- interface NetworkDisplay {
2599
- /** Display ID (0-255) */
2600
- id: number;
2601
- /** Origin X position in virtual world (0-65535) */
2602
- originX: number;
2603
- /** Origin Y position in virtual world (0-65535) */
2604
- originY: number;
2605
- /** Display width in cells (1-256) */
2606
- sizeX: number;
2607
- /** Display height in cells (1-256) */
2608
- sizeY: number;
2609
- /** Optional render pass configuration (max 4 passes) */
2610
- renderPasses?: RenderPassConfig[];
2611
- }
2612
-
2613
- interface NetworkLayer {
2614
- id: number;
2615
- updateFlags: number;
2616
- zIndex: number;
2617
- originX: number;
2618
- originY: number;
2619
- width: number;
2620
- height: number;
2621
- orderCount: number;
2622
- orders: AnyNetworkOrder[];
2623
- /** Optional decoded byte size of this layer segment in the update packet */
2624
- byteSize?: number;
2524
+ setScanlinesEnabled(enabled: boolean): void;
2625
2525
  /**
2626
- * CharCode mode for this layer
2627
- * - false: 8-bit charCodes (0-255)
2628
- * - true: 16-bit charCodes (0-65535)
2629
- * Encoded in updateFlags bit 6
2526
+ * Sets scanlines opacity for this display.
2527
+ *
2528
+ * @param opacity - Opacity in range [0, 1].
2529
+ *
2530
+ * @example
2531
+ * display.setScanlinesOpacity(0.35);
2630
2532
  */
2631
- is16bit: boolean;
2632
- }
2633
-
2634
- /**
2635
- * UTSP Post-Process Order Types Enumeration
2636
- *
2637
- * Post-process orders control visual effects like scanlines and ambient effect.
2638
- * They are included in the UpdatePacket and processed by the renderer.
2639
- *
2640
- * This separation ensures:
2641
- * - Clear distinction between render, audio, and post-process orders
2642
- * - Independent type numbering
2643
- * - Perfect frame-level synchronization
2644
- */
2645
- declare enum PostProcessOrderType {
2533
+ setScanlinesOpacity(opacity: number): void;
2646
2534
  /**
2647
- * 0x01 - SetConfig: Set full post-process configuration
2535
+ * Sets the scanlines pattern for this display.
2648
2536
  *
2649
- * Parameters: flags, scanlines config?, ambient effect config?
2537
+ * @param pattern - Pattern type.
2538
+ *
2539
+ * @example
2540
+ * display.setScanlinesPattern('grid');
2650
2541
  */
2651
- SetConfig = 1,
2542
+ setScanlinesPattern(pattern: 'horizontal' | 'vertical' | 'grid'): void;
2652
2543
  /**
2653
- * 0x02 - SetScanlines: Set scanlines configuration only
2544
+ * Enables or configures the ambient effect for this display.
2654
2545
  *
2655
- * Parameters: enabled, opacity?, pattern?, colorR?, colorG?, colorB?
2656
- */
2546
+ * @param config - `true`/`false` or an object with `blur`/`scale`.
2547
+ *
2548
+ * @example
2549
+ * display.setAmbientEffect({ blur: 40, scale: 1.4 });
2550
+ */
2551
+ setAmbientEffect(config: boolean | {
2552
+ blur?: number;
2553
+ scale?: number;
2554
+ }): void;
2555
+ /**
2556
+ * Enables or disables the ambient effect for this display.
2557
+ *
2558
+ * @param enabled - Whether the effect is enabled.
2559
+ *
2560
+ * @example
2561
+ * display.setAmbientEffectEnabled(false);
2562
+ */
2563
+ setAmbientEffectEnabled(enabled: boolean): void;
2564
+ /**
2565
+ * Sets ambient blur intensity for this display.
2566
+ *
2567
+ * @param blur - Blur amount in pixels.
2568
+ *
2569
+ * @example
2570
+ * display.setAmbientEffectBlur(60);
2571
+ */
2572
+ setAmbientEffectBlur(blur: number): void;
2573
+ /**
2574
+ * Sets ambient effect scale for this display.
2575
+ *
2576
+ * @param scale - Scale factor (>= 1).
2577
+ *
2578
+ * @example
2579
+ * display.setAmbientEffectScale(1.5);
2580
+ */
2581
+ setAmbientEffectScale(scale: number): void;
2582
+ /**
2583
+ * Returns whether the ambient effect is enabled.
2584
+ *
2585
+ * @returns `true` if enabled.
2586
+ */
2587
+ isAmbientEffectEnabled(): boolean;
2588
+ /**
2589
+ * Returns the current ambient effect configuration, or `null` if disabled.
2590
+ *
2591
+ * @returns The ambient effect config or `null`.
2592
+ */
2593
+ getAmbientEffectConfig(): {
2594
+ enabled: boolean;
2595
+ blur: number;
2596
+ scale: number;
2597
+ } | null;
2598
+ /**
2599
+ * Returns the current post-process configuration, or `null` if none.
2600
+ *
2601
+ * @returns The post-process config or `null`.
2602
+ */
2603
+ getPostProcessConfig(): PostProcessConfig | null;
2604
+ /**
2605
+ * Sets the pixel-perfect scaling mode for this display.
2606
+ *
2607
+ * @param mode - Scaling mode.
2608
+ *
2609
+ * @example
2610
+ * display.setScalingMode('integer');
2611
+ */
2612
+ setScalingMode(mode: ScalingMode): void;
2613
+ /**
2614
+ * Returns the current scaling mode for this display, if set.
2615
+ *
2616
+ * @returns The scaling mode or `null`.
2617
+ */
2618
+ getScalingMode(): ScalingMode | null;
2619
+ /**
2620
+ * Sets the cell size (in pixels) for this display.
2621
+ *
2622
+ * @param width - Cell width in pixels.
2623
+ * @param height - Cell height in pixels.
2624
+ *
2625
+ * @example
2626
+ * display.setCellSize(8, 16);
2627
+ */
2628
+ setCellSize(width: number, height: number): void;
2629
+ /**
2630
+ * Returns the current cell size for this display.
2631
+ *
2632
+ * @returns The cell size in pixels.
2633
+ */
2634
+ getCellSize(): {
2635
+ cellWidth: number;
2636
+ cellHeight: number;
2637
+ };
2638
+ /**
2639
+ * Enables or configures the debug grid overlay.
2640
+ *
2641
+ * @param config - `true`/`false` or a `GridConfig` object.
2642
+ *
2643
+ * @example
2644
+ * display.setGrid({ enabled: true, color: '#00ff00', lineWidth: 2 });
2645
+ */
2646
+ setGrid(config: boolean | GridConfig): void;
2647
+ /**
2648
+ * Enables or disables the debug grid overlay.
2649
+ *
2650
+ * @param enabled - Whether the grid is enabled.
2651
+ */
2652
+ setGridEnabled(enabled: boolean): void;
2653
+ /**
2654
+ * Returns whether the debug grid is enabled.
2655
+ *
2656
+ * @returns `true` if enabled.
2657
+ */
2658
+ isGridEnabled(): boolean;
2659
+ /**
2660
+ * Returns the current grid configuration, or `null` if none.
2661
+ *
2662
+ * @returns The grid configuration or `null`.
2663
+ */
2664
+ getGridConfig(): GridConfig | null;
2665
+ /**
2666
+ * Switches to a preloaded palette slot for this display.
2667
+ *
2668
+ * @param slotId - Palette slot ID (0-255).
2669
+ *
2670
+ * @example
2671
+ * display.switchPalette(2);
2672
+ */
2673
+ switchPalette(slotId: number): void;
2674
+ /**
2675
+ * Returns the active palette slot ID for this display, or `null`.
2676
+ *
2677
+ * @returns The current palette slot ID or `null`.
2678
+ */
2679
+ getCurrentPaletteSlotId(): number | null;
2680
+ /**
2681
+ * Returns the render passes configuration.
2682
+ *
2683
+ * @returns Array of passes or `undefined` for single pass.
2684
+ */
2685
+ getRenderPasses(): RenderPassConfig[] | undefined;
2686
+ /**
2687
+ * Sets render passes configuration (0..4 passes).
2688
+ *
2689
+ * @param passes - Pass definitions or `undefined` to reset.
2690
+ *
2691
+ * @example
2692
+ * display.setRenderPasses([
2693
+ * { id: 0, zMin: 0, zMax: 127 },
2694
+ * { id: 1, zMin: 128, zMax: 255 },
2695
+ * ]);
2696
+ *
2697
+ * @throws Error if more than 4 passes are provided.
2698
+ */
2699
+ setRenderPasses(passes: RenderPassConfig[] | undefined): void;
2700
+ private normalizePass;
2701
+ /**
2702
+ * Returns a debug-friendly snapshot of this display (metadata only).
2703
+ *
2704
+ * @returns Debug info snapshot.
2705
+ */
2706
+ getDebugInfo(): {
2707
+ id: number;
2708
+ origin: {
2709
+ x: number;
2710
+ y: number;
2711
+ };
2712
+ size: {
2713
+ x: number;
2714
+ y: number;
2715
+ };
2716
+ renderPasses?: RenderPassConfig[];
2717
+ };
2718
+ }
2719
+
2720
+ /**
2721
+ * Network representation of a display
2722
+ * Layers are NO LONGER under displays - they are at User level
2723
+ */
2724
+ interface NetworkDisplay {
2725
+ /** Display ID (0-255) */
2726
+ id: number;
2727
+ /** Origin X position in virtual world (0-65535) */
2728
+ originX: number;
2729
+ /** Origin Y position in virtual world (0-65535) */
2730
+ originY: number;
2731
+ /** Display width in cells (1-256) */
2732
+ sizeX: number;
2733
+ /** Display height in cells (1-256) */
2734
+ sizeY: number;
2735
+ /** Optional render pass configuration (max 4 passes) */
2736
+ renderPasses?: RenderPassConfig[];
2737
+ }
2738
+
2739
+ interface NetworkLayer {
2740
+ id: number;
2741
+ updateFlags: number;
2742
+ zIndex: number;
2743
+ originX: number;
2744
+ originY: number;
2745
+ width: number;
2746
+ height: number;
2747
+ orderCount: number;
2748
+ orders: AnyNetworkOrder[];
2749
+ /** Optional decoded byte size of this layer segment in the update packet */
2750
+ byteSize?: number;
2751
+ /**
2752
+ * Macro layer flag
2753
+ * - false: standard layer
2754
+ * - true: macro layer (ephemeral, local effects)
2755
+ * Encoded in updateFlags bit 5
2756
+ */
2757
+ isMacroLayer: boolean;
2758
+ /**
2759
+ * CharCode mode for this layer
2760
+ * - false: 8-bit charCodes (0-255)
2761
+ * - true: 16-bit charCodes (0-65535)
2762
+ * Encoded in updateFlags bit 6
2763
+ */
2764
+ is16bit: boolean;
2765
+ }
2766
+
2767
+ /**
2768
+ * UTSP Post-Process Order Types Enumeration
2769
+ *
2770
+ * Post-process orders control visual effects like scanlines and ambient effect.
2771
+ * They are included in the UpdatePacket and processed by the renderer.
2772
+ *
2773
+ * This separation ensures:
2774
+ * - Clear distinction between render, audio, and post-process orders
2775
+ * - Independent type numbering
2776
+ * - Perfect frame-level synchronization
2777
+ */
2778
+ declare enum PostProcessOrderType {
2779
+ /**
2780
+ * 0x01 - SetConfig: Set full post-process configuration
2781
+ *
2782
+ * Parameters: flags, scanlines config?, ambient effect config?
2783
+ */
2784
+ SetConfig = 1,
2785
+ /**
2786
+ * 0x02 - SetScanlines: Set scanlines configuration only
2787
+ *
2788
+ * Parameters: enabled, opacity?, pattern?, colorR?, colorG?, colorB?
2789
+ */
2657
2790
  SetScanlines = 2,
2658
2791
  /**
2659
2792
  * 0x03 - SetAmbientEffect: Set ambient effect configuration only
@@ -2933,39 +3066,51 @@ interface UpdatePacket {
2933
3066
  }
2934
3067
 
2935
3068
  /**
2936
- * Maximum number of orders per layer (encoded as 1 byte)
2937
- * Exceeding this limit will cause packet corruption!
3069
+ * Maximum number of orders per layer (encoded as 1 byte).
3070
+ * Exceeding this limit will cause packet corruption.
2938
3071
  */
2939
3072
  declare const MAX_ORDERS_PER_LAYER = 255;
2940
3073
  /**
2941
- * Layer configuration options
3074
+ * Layer configuration options.
2942
3075
  */
2943
3076
  interface LayerOptions {
2944
- /** Optional layer name for tooling/debug */
3077
+ /** Optional layer name for tooling/debug. */
2945
3078
  name?: string;
2946
3079
  /**
2947
3080
  * CharCode mode for this layer (immutable after creation)
2948
- * - '8bit': Uses Uint8Array, limited to 256 characters (ASCII/CP437), optimized bandwidth
2949
- * - '16bit': Uses Uint16Array, supports 65536 characters (Unicode BMP), universal
3081
+ * - '8bit': 256 char codes (CP437 default)
3082
+ * - '16bit': 65536 char codes (256 atlas blocks × 256 chars)
2950
3083
  * @default '8bit'
2951
3084
  */
2952
3085
  charCodeMode?: CharCodeMode;
2953
3086
  /**
2954
- * Static layer (sent only once to client)
3087
+ * If true, the layer is sent on the reliable channel.
3088
+ * @default false
3089
+ */
3090
+ mustBeReliable?: boolean;
3091
+ /**
3092
+ * If true, the layer is considered a macro layer (ephemeral, local effects).
2955
3093
  * @default false
2956
3094
  */
2957
- isStatic?: boolean;
3095
+ isMacroLayer?: boolean;
2958
3096
  }
3097
+ /**
3098
+ * Represents a renderable layer in world space.
3099
+ *
3100
+ * Layers store rendering orders and metadata (position, z-order, size)
3101
+ * and can be composed by displays at the `User` level.
3102
+ */
2959
3103
  declare class Layer {
2960
3104
  private id;
2961
3105
  private name?;
3106
+ private isMacroLayer;
2962
3107
  private origin;
2963
3108
  private orders;
2964
3109
  private zOrder;
2965
3110
  private data;
2966
3111
  private width;
2967
3112
  private height;
2968
- private isStatic;
3113
+ private mustBeReliable;
2969
3114
  private spriteRegistry?;
2970
3115
  private mode;
2971
3116
  private charCodeMode;
@@ -2976,99 +3121,137 @@ declare class Layer {
2976
3121
  private needsCommit;
2977
3122
  private static rasterizer;
2978
3123
  /**
2979
- * Creates a new Layer
3124
+ * Creates a new layer.
3125
+ *
3126
+ * @param origin - Layer origin in world space.
3127
+ * @param zOrder - Z-order for stacking (higher = on top).
3128
+ * @param width - Layer width in cells (1-256).
3129
+ * @param height - Layer height in cells (1-256).
3130
+ * @param options - Layer options.
2980
3131
  *
2981
- * @param origin - Layer origin in world space
2982
- * @param zOrder - Z-order for layer stacking (higher = on top)
2983
- * @param width - Layer width in cells (1-256)
2984
- * @param height - Layer height in cells (1-256)
2985
- * @param options - Layer options (charCodeMode, isStatic)
3132
+ * Options:
3133
+ * - `name`: Optional name for tooling/debug.
3134
+ * - `charCodeMode`: `'8bit'` (default) or `'16bit'`.
3135
+ * - `mustBeReliable`: `true` to use reliable channel, `false` for volatile.
3136
+ * - `isMacroLayer`: `true` for macro effects, `false` for standard layers.
2986
3137
  *
2987
3138
  * @example
2988
- * // 8-bit layer (default) - optimized for ASCII/CP437 text
3139
+ * // 8-bit layer (default) - CP437 (block 0) only
2989
3140
  * const gameLayer = new Layer(new Vector2(0, 0), 0, 80, 25);
2990
3141
  *
2991
- * // 16-bit layer - full Unicode support (emoji, CJK, symbols)
2992
- * const unicodeLayer = new Layer(new Vector2(0, 0), 10, 40, 10, { charCodeMode: '16bit' });
3142
+ * @example
3143
+ * // 16-bit layer - atlas blocks beyond CP437
3144
+ * const atlasLayer = new Layer(new Vector2(0, 0), 10, 40, 10, { charCodeMode: '16bit' });
3145
+ *
3146
+ * @throws Error if width/height are out of bounds.
2993
3147
  */
2994
3148
  constructor(origin: Vector2, zOrder: number, width: number, height: number, options?: LayerOptions | boolean);
2995
3149
  /**
2996
- * Gets the layer's charCode mode (immutable)
2997
- * @returns '8bit' or '16bit'
3150
+ * Returns whether the layer is a macro layer.
3151
+ */
3152
+ getIsMacroLayer(): boolean;
3153
+ /**
3154
+ * Returns the layer's charCode mode (immutable).
3155
+ *
3156
+ * @returns `'8bit'` or `'16bit'`.
2998
3157
  */
2999
3158
  getCharCodeMode(): CharCodeMode;
3000
3159
  /**
3001
- * Configures the layer's execution mode (called by User)
3160
+ * Configures the layer's execution mode.
3002
3161
  * @internal
3003
3162
  */
3004
3163
  setMode(mode: CoreMode): void;
3005
3164
  /**
3006
- * Injects the SpriteRegistry into the layer (called by Core)
3165
+ * Injects the SpriteRegistry into the layer.
3007
3166
  * @internal
3008
3167
  */
3009
3168
  setSpriteRegistry(registry: SpriteRegistry): void;
3169
+ /**
3170
+ * Returns all orders currently stored in this layer.
3171
+ *
3172
+ * @returns The order list.
3173
+ */
3010
3174
  getOrders(): AnyNetworkOrder[];
3011
3175
  /**
3012
- * Adds orders to the layer (incremental mode)
3013
- * Re-rasterizes all orders to ensure consistent state
3176
+ * Adds orders to the layer (incremental mode).
3177
+ * Re-rasterizes all orders to ensure consistent state.
3178
+ *
3179
+ * @param orders - Orders to append.
3180
+ *
3181
+ * @example
3182
+ * layer.addOrders([orderA, orderB]);
3014
3183
  */
3015
3184
  addOrders(orders: AnyNetworkOrder[]): void;
3016
3185
  /**
3017
- * Adds temporary orders that are rasterized but not stored
3018
- * Used for macro-generated content (particles, UI) that is regenerated each frame
3186
+ * Adds temporary orders that are rasterized but not stored.
3187
+ * Used for macro-generated content (particles/UI) regenerated each frame.
3188
+ *
3189
+ * @param orders - Orders to rasterize temporarily.
3019
3190
  */
3020
3191
  addTemporaryOrders(orders: AnyNetworkOrder[]): void;
3021
3192
  /**
3022
- * Replaces all orders in the layer (reset mode)
3023
- * Automatically rasterizes all orders
3193
+ * Replaces all orders in the layer (reset mode).
3194
+ * Automatically rasterizes all orders.
3195
+ *
3196
+ * @param orders - New orders to set.
3024
3197
  */
3025
3198
  setOrders(orders: AnyNetworkOrder[]): void;
3026
3199
  /**
3027
- * Clears all orders and cleans the buffer
3200
+ * Clears all orders and resets the buffer.
3028
3201
  */
3029
3202
  clearOrders(): void;
3030
- getOrigin(): Vector2;
3031
3203
  /**
3032
- * Updates the layer's origin and rasterizes if necessary
3204
+ * Returns the layer origin in world space.
3033
3205
  *
3034
- * In client mode, this method automatically rasterizes the layer
3035
- * to reflect the new position.
3206
+ * @returns The current origin.
3207
+ */
3208
+ getOrigin(): Vector2;
3209
+ /**
3210
+ * Updates the layer's origin.
3036
3211
  *
3037
- * @param origin - New layer origin
3212
+ * @param origin - New layer origin.
3038
3213
  */
3039
3214
  setOrigin(origin: Vector2): void;
3215
+ /**
3216
+ * Returns the layer's z-order.
3217
+ *
3218
+ * @returns Z-order value.
3219
+ */
3040
3220
  getZOrder(): number;
3041
3221
  /**
3042
- * Updates the layer's z-order
3222
+ * Updates the layer's z-order.
3043
3223
  *
3044
- * @param zOrder - New z-order
3224
+ * @param zOrder - New z-order.
3045
3225
  */
3046
3226
  setZOrder(zOrder: number): void;
3047
3227
  /**
3048
- * Gets the layer's unique ID
3228
+ * Returns the layer's unique ID.
3049
3229
  *
3050
- * Used for client-side reconstruction when applying UpdatePackets.
3051
- * The ID allows associating a NetworkLayer with its corresponding Layer.
3052
- *
3053
- * @returns Layer ID (0-65535)
3230
+ * @returns Layer ID (0-65535).
3054
3231
  */
3055
3232
  getId(): number;
3056
3233
  /**
3057
- * Gets the layer's optional name (debug/metadata only)
3234
+ * Returns the layer's optional name (debug/metadata only).
3235
+ *
3236
+ * @returns Name or `undefined`.
3058
3237
  */
3059
3238
  getName(): string | undefined;
3060
3239
  /**
3061
- * Sets the layer's optional name (debug/metadata only)
3240
+ * Sets the layer's optional name (debug/metadata only).
3241
+ *
3242
+ * @param name - New name or `undefined` to clear.
3062
3243
  */
3063
3244
  setName(name: string | undefined): void;
3064
3245
  /**
3065
- * Returns a debug-friendly snapshot of this layer (metadata only)
3246
+ * Returns a debug-friendly snapshot of this layer (metadata only).
3247
+ *
3248
+ * @returns Debug info snapshot.
3066
3249
  */
3067
3250
  getDebugInfo(): {
3068
3251
  id: number;
3069
3252
  name?: string;
3070
3253
  z: number;
3071
- isStatic: boolean;
3254
+ mustBeReliable: boolean;
3072
3255
  charCodeMode: CharCodeMode;
3073
3256
  width: number;
3074
3257
  height: number;
@@ -3082,58 +3265,74 @@ declare class Layer {
3082
3265
  ordersCount: number;
3083
3266
  };
3084
3267
  /**
3085
- * Sets the layer's unique ID
3086
- *
3087
- * @internal - Used by User.applyUpdate() during reconstruction
3088
- * @param id - Unique layer ID (0-65535)
3268
+ * Sets the layer's unique ID.
3269
+ * @internal
3270
+ * @param id - Unique layer ID (0-65535).
3271
+ */
3272
+ private setIdInternal;
3273
+ /**
3274
+ * Returns the internal cell buffer.
3275
+ * @returns The `CellBuffer` instance.
3276
+ * @internal
3089
3277
  */
3090
- setId(id: number): void;
3091
3278
  getData(): CellBuffer;
3279
+ /**
3280
+ * Returns the layer width in cells.
3281
+ * @returns Width in cells.
3282
+ */
3092
3283
  getWidth(): number;
3284
+ /**
3285
+ * Returns the layer height in cells.
3286
+ * @returns Height in cells.
3287
+ */
3093
3288
  getHeight(): number;
3094
- getCellAt(x: number, y: number): Cell | null;
3095
3289
  /**
3096
- * Marks this layer as static or dynamic
3290
+ * Returns the cell at the given coordinates.
3097
3291
  *
3098
- * Static layer: Sent only once to client via reliable channel,
3099
- * but continues to be rasterized client-side every frame.
3100
- * Used for UI elements, backgrounds, elements that never change.
3101
- *
3102
- * Dynamic layer: Sent every tick via volatile channel.
3103
- * Used for animated elements, players, projectiles, etc.
3292
+ * @param x - X coordinate (0..width-1).
3293
+ * @param y - Y coordinate (0..height-1).
3294
+ * @returns The cell or `null` if out of bounds.
3295
+ */
3296
+ getCellAt(x: number, y: number): Cell | null;
3297
+ /**
3298
+ * Marks this layer as reliable or volatile for network transport.
3104
3299
  *
3105
- * @param isStatic - true for static, false for dynamic
3300
+ * @param mustBeReliable - `true` for reliable channel, `false` for volatile.
3106
3301
  */
3107
- setStatic(isStatic: boolean): void;
3302
+ setMustBeReliable(mustBeReliable: boolean): void;
3108
3303
  /**
3109
- * Checks if this layer is static
3304
+ * Returns whether this layer must be sent reliably.
3305
+ *
3306
+ * @returns `true` if reliable.
3110
3307
  */
3111
- getStatic(): boolean;
3308
+ getMustBeReliable(): boolean;
3112
3309
  /**
3113
- * Enables or disables the layer
3114
- * A disabled layer will not be rendered by DisplayRasterizer
3310
+ * Enables or disables the layer.
3311
+ * A disabled layer will not be rendered by the display rasterizer.
3115
3312
  *
3116
- * @param enabled - true to enable, false to disable
3313
+ * @param enabled - `true` to enable, `false` to disable.
3117
3314
  */
3118
3315
  setEnabled(enabled: boolean): void;
3119
3316
  /**
3120
- * Checks if layer is enabled
3317
+ * Returns whether the layer is enabled.
3318
+ *
3319
+ * @returns `true` if enabled.
3121
3320
  */
3122
3321
  isEnabled(): boolean;
3123
3322
  /**
3124
- * Checks if layer origin changed since last tick
3125
- * @internal - Used to calculate UpdateFlags
3323
+ * Returns `true` if the origin changed since the last tick.
3324
+ * @internal
3126
3325
  */
3127
3326
  hasOriginChanged(): boolean;
3128
3327
  /**
3129
- * Checks if layer z-order changed since last tick
3130
- * @internal - Used to calculate UpdateFlags
3328
+ * Returns `true` if the z-order changed since the last tick.
3329
+ * @internal
3131
3330
  */
3132
3331
  hasZOrderChanged(): boolean;
3133
3332
  /**
3134
- * Calculates UpdateFlags based on layer state and changes
3135
- * @internal - Used by Core.endTick()
3136
- * @returns Bitpacked flags (0x00 to 0x0F)
3333
+ * Calculates UpdateFlags based on layer state and changes.
3334
+ * @internal
3335
+ * @returns Bitpacked flags (0x00 to 0x0F).
3137
3336
  *
3138
3337
  * Flag structure:
3139
3338
  * - Bit 0 (0x01): Layer Enabled (1=active, 0=disabled)
@@ -3143,35 +3342,33 @@ declare class Layer {
3143
3342
  */
3144
3343
  calculateUpdateFlags(): number;
3145
3344
  /**
3146
- * Resets change tracking after sending a tick
3147
- * @internal - Used by Core.endTick()
3345
+ * Resets change tracking after sending a tick.
3346
+ * @internal
3148
3347
  */
3149
3348
  resetChangeTracking(): void;
3150
3349
  /**
3151
- * Marks the layer as needing to be sent on next tick
3350
+ * Marks the layer as needing to be sent on the next tick.
3152
3351
  *
3153
3352
  * Used to optimize bandwidth by sending only modified layers.
3154
3353
  *
3155
3354
  * @example
3156
- * ```typescript
3157
3355
  * layer.addOrders([...]);
3158
- * layer.commit(); // Layer will be sent on next tick
3159
- * ```
3356
+ * layer.commit();
3160
3357
  */
3161
3358
  commit(): void;
3162
3359
  /**
3163
- * Returns a breakdown of order types for debugging
3360
+ * Returns a breakdown of order types for debugging.
3164
3361
  * @internal
3165
3362
  */
3166
3363
  private getOrdersBreakdown;
3167
3364
  /**
3168
- * Checks if layer needs to be sent
3169
- * @internal - Used by Core.endTick()
3365
+ * Returns `true` if the layer needs to be sent.
3366
+ * @internal
3170
3367
  */
3171
3368
  getNeedsCommit(): boolean;
3172
3369
  /**
3173
- * Resets commit flag after sending
3174
- * @internal - Used by Core.endTick()
3370
+ * Resets the commit flag after sending.
3371
+ * @internal
3175
3372
  */
3176
3373
  resetCommit(): void;
3177
3374
  }
@@ -3709,8 +3906,8 @@ declare class InputBindingRegistry {
3709
3906
  }
3710
3907
 
3711
3908
  /**
3712
- * Per-user performance statistics
3713
- * Collects user-specific metrics
3909
+ * Per-user performance statistics.
3910
+ * Collects user-specific metrics per tick.
3714
3911
  */
3715
3912
  interface UserTickStats {
3716
3913
  userId: string;
@@ -3739,85 +3936,276 @@ declare class UserStats {
3739
3936
  private _userName;
3740
3937
  constructor(userId: string, userName: string);
3741
3938
  /**
3742
- * Enables or disables statistics collection
3939
+ * Enables or disables statistics collection.
3940
+ *
3941
+ * @param enabled - Whether to collect stats.
3942
+ *
3943
+ * @example
3944
+ * ```typescript
3945
+ * user.getStats().setEnabled(true);
3946
+ * ```
3743
3947
  */
3744
3948
  setEnabled(enabled: boolean): void;
3949
+ /**
3950
+ * Returns whether statistics collection is enabled.
3951
+ *
3952
+ * @returns true if enabled.
3953
+ */
3745
3954
  isEnabled(): boolean;
3746
- /** User ID */
3955
+ /**
3956
+ * Returns the user ID.
3957
+ *
3958
+ * @returns User ID.
3959
+ *
3960
+ * @example
3961
+ * ```typescript
3962
+ * const id = user.getStats().userId;
3963
+ * ```
3964
+ */
3747
3965
  get userId(): string;
3748
- /** User name */
3966
+ /**
3967
+ * Returns the user name.
3968
+ *
3969
+ * @returns User name.
3970
+ *
3971
+ * @example
3972
+ * ```typescript
3973
+ * const name = user.getStats().userName;
3974
+ * ```
3975
+ */
3749
3976
  get userName(): string;
3750
- /** Current tick number */
3751
- get tick(): number;
3752
- /** Current tick timestamp */
3753
- get timestamp(): number;
3754
- /** Number of displays */
3977
+ /**
3978
+ * Returns the current tick number.
3979
+ *
3980
+ * @returns Tick number.
3981
+ *
3982
+ * @example
3983
+ * ```typescript
3984
+ * const tick = user.getStats().tick;
3985
+ * ```
3986
+ */
3987
+ get tick(): number;
3988
+ /**
3989
+ * Returns the current tick timestamp.
3990
+ *
3991
+ * @returns Timestamp in ms.
3992
+ *
3993
+ * @example
3994
+ * ```typescript
3995
+ * const ts = user.getStats().timestamp;
3996
+ * ```
3997
+ */
3998
+ get timestamp(): number;
3999
+ /**
4000
+ * Returns the number of displays.
4001
+ *
4002
+ * @returns Display count.
4003
+ *
4004
+ * @example
4005
+ * ```typescript
4006
+ * const count = user.getStats().displayCount;
4007
+ * ```
4008
+ */
3755
4009
  get displayCount(): number;
3756
- /** Total display surface area (width × height) */
4010
+ /**
4011
+ * Returns the total display surface area (width × height).
4012
+ *
4013
+ * @returns Total display area.
4014
+ *
4015
+ * @example
4016
+ * ```typescript
4017
+ * const area = user.getStats().totalDisplayArea;
4018
+ * ```
4019
+ */
3757
4020
  get totalDisplayArea(): number;
3758
- /** Total number of layers */
4021
+ /**
4022
+ * Returns the total number of layers.
4023
+ *
4024
+ * @returns Total layer count.
4025
+ *
4026
+ * @example
4027
+ * ```typescript
4028
+ * const total = user.getStats().totalLayers;
4029
+ * ```
4030
+ */
3759
4031
  get totalLayers(): number;
3760
- /** Visible layers in displays */
4032
+ /**
4033
+ * Returns the number of visible layers in displays.
4034
+ *
4035
+ * @returns Visible layer count.
4036
+ *
4037
+ * @example
4038
+ * ```typescript
4039
+ * const visible = user.getStats().visibleLayers;
4040
+ * ```
4041
+ */
3761
4042
  get visibleLayers(): number;
3762
- /** Static layers */
4043
+ /**
4044
+ * Returns the number of reliable layers.
4045
+ *
4046
+ * @returns Reliable layer count.
4047
+ *
4048
+ * @example
4049
+ * ```typescript
4050
+ * const reliable = user.getStats().staticLayers;
4051
+ * ```
4052
+ */
3763
4053
  get staticLayers(): number;
3764
- /** Dynamic layers */
4054
+ /**
4055
+ * Returns the number of volatile layers.
4056
+ *
4057
+ * @returns Volatile layer count.
4058
+ *
4059
+ * @example
4060
+ * ```typescript
4061
+ * const volatile = user.getStats().dynamicLayers;
4062
+ * ```
4063
+ */
3765
4064
  get dynamicLayers(): number;
3766
- /** Total orders for this user */
4065
+ /**
4066
+ * Returns the total number of orders for this user.
4067
+ *
4068
+ * @returns Total order count.
4069
+ *
4070
+ * @example
4071
+ * ```typescript
4072
+ * const orders = user.getStats().totalOrders;
4073
+ * ```
4074
+ */
3767
4075
  get totalOrders(): number;
3768
- /** Orders par layer ID */
4076
+ /**
4077
+ * Returns order counts per layer ID.
4078
+ *
4079
+ * @returns Map of layerId → order count.
4080
+ *
4081
+ * @example
4082
+ * ```typescript
4083
+ * const byLayer = user.getStats().ordersByLayer;
4084
+ * const uiOrders = byLayer.get(2) ?? 0;
4085
+ * ```
4086
+ */
3769
4087
  get ordersByLayer(): Map<number, number>;
3770
- /** Taille du packet statique (octets) */
4088
+ /**
4089
+ * Returns the static packet size in bytes.
4090
+ *
4091
+ * @returns Static packet size.
4092
+ *
4093
+ * @example
4094
+ * ```typescript
4095
+ * const size = user.getStats().staticPacketSize;
4096
+ * ```
4097
+ */
3771
4098
  get staticPacketSize(): number;
3772
- /** Taille du packet dynamique (octets) */
4099
+ /**
4100
+ * Returns the dynamic packet size in bytes.
4101
+ *
4102
+ * @returns Dynamic packet size.
4103
+ *
4104
+ * @example
4105
+ * ```typescript
4106
+ * const size = user.getStats().dynamicPacketSize;
4107
+ * ```
4108
+ */
3773
4109
  get dynamicPacketSize(): number;
3774
- /** Taille totale des packets (static + dynamic) */
4110
+ /**
4111
+ * Returns the total packet size (static + dynamic) in bytes.
4112
+ *
4113
+ * @returns Total packet size.
4114
+ *
4115
+ * @example
4116
+ * ```typescript
4117
+ * const total = user.getStats().totalPacketSize;
4118
+ * ```
4119
+ */
3775
4120
  get totalPacketSize(): number;
3776
- /** Estimated size after gzip compression (25% of original size) */
4121
+ /**
4122
+ * Returns the estimated compressed size (25% of original).
4123
+ *
4124
+ * @returns Estimated compressed size.
4125
+ *
4126
+ * @example
4127
+ * ```typescript
4128
+ * const compressed = user.getStats().compressedPacketSize;
4129
+ * ```
4130
+ */
3777
4131
  get compressedPacketSize(): number;
3778
- /** If user sent input this tick */
4132
+ /**
4133
+ * Returns whether the user sent input this tick.
4134
+ *
4135
+ * @returns true if input was sent.
4136
+ *
4137
+ * @example
4138
+ * ```typescript
4139
+ * if (user.getStats().hasInput) {
4140
+ * console.log('Input received this tick');
4141
+ * }
4142
+ * ```
4143
+ */
3779
4144
  get hasInput(): boolean;
3780
- /** Number of bound axes */
4145
+ /**
4146
+ * Returns the number of bound axes.
4147
+ *
4148
+ * @returns Axis count.
4149
+ *
4150
+ * @example
4151
+ * ```typescript
4152
+ * const axes = user.getStats().axisCount;
4153
+ * ```
4154
+ */
3781
4155
  get axisCount(): number;
3782
- /** Number of bound buttons */
4156
+ /**
4157
+ * Returns the number of bound buttons.
4158
+ *
4159
+ * @returns Button count.
4160
+ *
4161
+ * @example
4162
+ * ```typescript
4163
+ * const buttons = user.getStats().buttonCount;
4164
+ * ```
4165
+ */
3783
4166
  get buttonCount(): number;
3784
4167
  /**
4168
+ * Starts collection for a new tick.
3785
4169
  * @internal
3786
- * Starts collection for a new tick
3787
4170
  */
3788
4171
  startTick(tickNumber: number): void;
3789
4172
  /**
4173
+ * Records display information.
3790
4174
  * @internal
3791
- * Records display information
3792
4175
  */
3793
4176
  recordDisplays(displayCount: number, totalArea: number): void;
3794
4177
  /**
4178
+ * Records layer information.
3795
4179
  * @internal
3796
- * Enregistre les informations des layers
3797
4180
  */
3798
4181
  recordLayers(total: number, visible: number, staticCount: number, dynamicCount: number): void;
3799
4182
  /**
4183
+ * Records order count for a layer.
3800
4184
  * @internal
3801
- * Enregistre les orders d'un layer
3802
4185
  */
3803
4186
  recordLayerOrders(layerId: number, orderCount: number): void;
3804
4187
  /**
4188
+ * Records network packet sizes.
3805
4189
  * @internal
3806
- * Records network packet sizes
3807
4190
  */
3808
4191
  recordPacketSizes(staticSize: number, dynamicSize: number): void;
3809
4192
  /**
4193
+ * Records input information.
3810
4194
  * @internal
3811
- * Records input information
3812
4195
  */
3813
4196
  recordInput(hasInput: boolean, axisCount: number, buttonCount: number): void;
3814
4197
  /**
4198
+ * Finalizes current tick stats.
3815
4199
  * @internal
3816
- * Finalizes current tick stats
3817
4200
  */
3818
4201
  endTick(): void;
3819
4202
  /**
3820
- * Resets statistics
4203
+ * Resets statistics.
4204
+ *
4205
+ * @example
4206
+ * ```typescript
4207
+ * user.getStats().reset();
4208
+ * ```
3821
4209
  */
3822
4210
  reset(): void;
3823
4211
  }
@@ -3879,6 +4267,10 @@ declare class User<TData = Record<string, any>> {
3879
4267
  private currentTickBytesSent;
3880
4268
  private currentTickBytesReceived;
3881
4269
  private availableViewports;
4270
+ /**
4271
+ * Display command sink (used by Display to enqueue network commands)
4272
+ */
4273
+ private readonly displayCommandSink;
3882
4274
  /**
3883
4275
  * Application-specific data storage
3884
4276
  * Use this to store game state, player data, or any custom information
@@ -3890,11 +4282,28 @@ declare class User<TData = Record<string, any>> {
3890
4282
  * @internal
3891
4283
  */
3892
4284
  setSpriteRegistry(registry: SpriteRegistry): void;
4285
+ /**
4286
+ * Returns all displays for this user.
4287
+ *
4288
+ * @returns Array of displays.
4289
+ *
4290
+ * @example
4291
+ * ```typescript
4292
+ * const displays = user.getDisplays();
4293
+ * const mainDisplay = displays[0];
4294
+ * ```
4295
+ */
3893
4296
  getDisplays(): Display[];
3894
4297
  /**
3895
4298
  * Adds a display to the user
3896
4299
  *
3897
4300
  * @param display - The display to add
4301
+ *
4302
+ * @example
4303
+ * ```typescript
4304
+ * const display = new Display(0, 80, 25);
4305
+ * user.addDisplay(display);
4306
+ * ```
3898
4307
  */
3899
4308
  addDisplay(display: Display): void;
3900
4309
  /**
@@ -3902,10 +4311,21 @@ declare class User<TData = Record<string, any>> {
3902
4311
  *
3903
4312
  * @param display - The display to remove
3904
4313
  * @returns true if display was removed, false otherwise
4314
+ *
4315
+ * @example
4316
+ * ```typescript
4317
+ * const ok = user.removeDisplay(display);
4318
+ * if (!ok) console.warn('Display not found');
4319
+ * ```
3905
4320
  */
3906
4321
  removeDisplay(display: Display): boolean;
3907
4322
  /**
3908
4323
  * Removes all displays from the user
4324
+ *
4325
+ * @example
4326
+ * ```typescript
4327
+ * user.clearDisplays();
4328
+ * ```
3909
4329
  */
3910
4330
  clearDisplays(): void;
3911
4331
  /**
@@ -3947,6 +4367,12 @@ declare class User<TData = Record<string, any>> {
3947
4367
  * Gets all available viewports (in pixels)
3948
4368
  *
3949
4369
  * @returns Map of displayId → viewport size
4370
+ *
4371
+ * @example
4372
+ * ```typescript
4373
+ * const viewports = user.getAllDisplayViewports();
4374
+ * const display0 = viewports.get(0);
4375
+ * ```
3950
4376
  */
3951
4377
  getAllDisplayViewports(): Map<number, {
3952
4378
  pixelWidth: number;
@@ -3980,12 +4406,29 @@ declare class User<TData = Record<string, any>> {
3980
4406
  cols: number;
3981
4407
  rows: number;
3982
4408
  } | null;
4409
+ /**
4410
+ * Returns all layers for this user.
4411
+ *
4412
+ * @returns Array of layers.
4413
+ *
4414
+ * @example
4415
+ * ```typescript
4416
+ * const layers = user.getLayers();
4417
+ * const uiLayer = layers.find((l) => l.getName() === 'ui');
4418
+ * ```
4419
+ */
3983
4420
  getLayers(): Layer[];
3984
4421
  /**
3985
4422
  * Gets a layer by its ID
3986
4423
  *
3987
4424
  * @param layerId - The layer ID to find
3988
4425
  * @returns The layer, or undefined if not found
4426
+ *
4427
+ * @example
4428
+ * ```typescript
4429
+ * const layer = user.getLayerById(2);
4430
+ * if (layer) layer.setZOrder(10);
4431
+ * ```
3989
4432
  */
3990
4433
  getLayerById(layerId: number): Layer | undefined;
3991
4434
  /**
@@ -3994,6 +4437,12 @@ declare class User<TData = Record<string, any>> {
3994
4437
  *
3995
4438
  * @param layer - The layer to add
3996
4439
  * @param name - Optional name for macro system (used in createInstance)
4440
+ *
4441
+ * @example
4442
+ * ```typescript
4443
+ * const layer = new Layer(new Vector2(0, 0), 0, 80, 25);
4444
+ * user.addLayer(layer, 'game');
4445
+ * ```
3997
4446
  */
3998
4447
  addLayer(layer: Layer, name?: string): void;
3999
4448
  /**
@@ -4001,10 +4450,20 @@ declare class User<TData = Record<string, any>> {
4001
4450
  *
4002
4451
  * @param layer - The layer to remove
4003
4452
  * @returns true if layer was removed, false otherwise
4453
+ *
4454
+ * @example
4455
+ * ```typescript
4456
+ * user.removeLayer(layer);
4457
+ * ```
4004
4458
  */
4005
4459
  removeLayer(layer: Layer): boolean;
4006
4460
  /**
4007
4461
  * Removes all layers from the user
4462
+ *
4463
+ * @example
4464
+ * ```typescript
4465
+ * user.clearLayers();
4466
+ * ```
4008
4467
  */
4009
4468
  clearLayers(): void;
4010
4469
  /**
@@ -4556,11 +5015,27 @@ declare class User<TData = Record<string, any>> {
4556
5015
  /**
4557
5016
  * Gets total bytes sent to this user (server-side)
4558
5017
  * Excludes bridge messages.
5018
+ *
5019
+ * @returns Total bytes sent.
5020
+ *
5021
+ * @example
5022
+ * ```typescript
5023
+ * const total = user.getTotalBytesSent();
5024
+ * console.log(`Sent: ${total} bytes`);
5025
+ * ```
4559
5026
  */
4560
5027
  getTotalBytesSent(): number;
4561
5028
  /**
4562
5029
  * Gets total bytes received by this user (client-side)
4563
5030
  * Excludes bridge messages.
5031
+ *
5032
+ * @returns Total bytes received.
5033
+ *
5034
+ * @example
5035
+ * ```typescript
5036
+ * const total = user.getTotalBytesReceived();
5037
+ * console.log(`Received: ${total} bytes`);
5038
+ * ```
4564
5039
  */
4565
5040
  getTotalBytesReceived(): number;
4566
5041
  /**
@@ -4575,12 +5050,22 @@ declare class User<TData = Record<string, any>> {
4575
5050
  recordBytesReceived(bytes: number): void;
4576
5051
  /**
4577
5052
  * Resets byte counters (useful for periodic stats)
5053
+ *
5054
+ * @example
5055
+ * ```typescript
5056
+ * user.resetByteCounters();
5057
+ * ```
4578
5058
  */
4579
5059
  resetByteCounters(): void;
4580
5060
  /**
4581
5061
  * Sets the tick rate for bytes-per-second calculation
4582
5062
  * Call this when the runtime tick rate changes
4583
5063
  * @param tickRate - The tick rate in ticks per second
5064
+ *
5065
+ * @example
5066
+ * ```typescript
5067
+ * user.setBytesTickRate(60);
5068
+ * ```
4584
5069
  */
4585
5070
  setBytesTickRate(tickRate: number): void;
4586
5071
  /**
@@ -4592,11 +5077,21 @@ declare class User<TData = Record<string, any>> {
4592
5077
  /**
4593
5078
  * Gets bytes sent per second (sliding window over last second)
4594
5079
  * @returns Bytes sent per second
5080
+ *
5081
+ * @example
5082
+ * ```typescript
5083
+ * const sentPerSec = user.getBytesSentPerSecond();
5084
+ * ```
4595
5085
  */
4596
5086
  getBytesSentPerSecond(): number;
4597
5087
  /**
4598
5088
  * Gets bytes received per second (sliding window over last second)
4599
5089
  * @returns Bytes received per second
5090
+ *
5091
+ * @example
5092
+ * ```typescript
5093
+ * const recvPerSec = user.getBytesReceivedPerSecond();
5094
+ * ```
4600
5095
  */
4601
5096
  getBytesReceivedPerSecond(): number;
4602
5097
  /**
@@ -4604,6 +5099,11 @@ declare class User<TData = Record<string, any>> {
4604
5099
  *
4605
5100
  * @param name - Axis name
4606
5101
  * @returns bindingId or null if not found
5102
+ *
5103
+ * @example
5104
+ * ```typescript
5105
+ * const id = user.getAxisBindingId('MoveHorizontal');
5106
+ * ```
4607
5107
  */
4608
5108
  getAxisBindingId(name: string): number | null;
4609
5109
  /**
@@ -4611,6 +5111,11 @@ declare class User<TData = Record<string, any>> {
4611
5111
  *
4612
5112
  * @param name - Button name
4613
5113
  * @returns bindingId or null if not found
5114
+ *
5115
+ * @example
5116
+ * ```typescript
5117
+ * const id = user.getButtonBindingId('Jump');
5118
+ * ```
4614
5119
  */
4615
5120
  getButtonBindingId(name: string): number | null;
4616
5121
  /**
@@ -5240,6 +5745,13 @@ declare class User<TData = Record<string, any>> {
5240
5745
  *
5241
5746
  * @param soundId - The sound ID to check
5242
5747
  * @returns true if the sound is loaded
5748
+ *
5749
+ * @example
5750
+ * ```typescript
5751
+ * if (user.isSoundLoaded(3)) {
5752
+ * console.log('Sound 3 is ready');
5753
+ * }
5754
+ * ```
5243
5755
  */
5244
5756
  isSoundLoaded(soundId: number): boolean;
5245
5757
  /**
@@ -5247,12 +5759,24 @@ declare class User<TData = Record<string, any>> {
5247
5759
  *
5248
5760
  * @param soundId - The sound ID to check
5249
5761
  * @returns Error message if failed, undefined otherwise
5762
+ *
5763
+ * @example
5764
+ * ```typescript
5765
+ * const error = user.getSoundLoadError(3);
5766
+ * if (error) console.warn(error);
5767
+ * ```
5250
5768
  */
5251
5769
  getSoundLoadError(soundId: number): string | undefined;
5252
5770
  /**
5253
5771
  * Get all loaded sounds on the client
5254
5772
  *
5255
5773
  * @returns Map of soundId to load info
5774
+ *
5775
+ * @example
5776
+ * ```typescript
5777
+ * const loaded = user.getLoadedSounds();
5778
+ * console.log(`Loaded: ${loaded.size}`);
5779
+ * ```
5256
5780
  */
5257
5781
  getLoadedSounds(): ReadonlyMap<number, {
5258
5782
  name: string;
@@ -5262,6 +5786,12 @@ declare class User<TData = Record<string, any>> {
5262
5786
  * Get all sound load errors
5263
5787
  *
5264
5788
  * @returns Map of soundId to error info
5789
+ *
5790
+ * @example
5791
+ * ```typescript
5792
+ * const errors = user.getSoundLoadErrors();
5793
+ * errors.forEach((info, id) => console.warn(id, info.error));
5794
+ * ```
5265
5795
  */
5266
5796
  getSoundLoadErrors(): ReadonlyMap<number, {
5267
5797
  name: string;
@@ -5273,12 +5803,25 @@ declare class User<TData = Record<string, any>> {
5273
5803
  *
5274
5804
  * @param instanceId - The instance ID to check
5275
5805
  * @returns true if the instance is playing
5806
+ *
5807
+ * @example
5808
+ * ```typescript
5809
+ * if (user.isSoundPlaying(musicId)) {
5810
+ * console.log('Music is playing');
5811
+ * }
5812
+ * ```
5276
5813
  */
5277
5814
  isSoundPlaying(instanceId: SoundInstanceId): boolean;
5278
5815
  /**
5279
5816
  * Get all currently playing sounds on the client
5280
5817
  *
5281
5818
  * @returns Map of instanceId to playback info
5819
+ *
5820
+ * @example
5821
+ * ```typescript
5822
+ * const playing = user.getPlayingSounds();
5823
+ * playing.forEach((info, id) => console.log(id, info.soundId));
5824
+ * ```
5282
5825
  */
5283
5826
  getPlayingSounds(): ReadonlyMap<SoundInstanceId, {
5284
5827
  soundId: number;
@@ -5286,6 +5829,13 @@ declare class User<TData = Record<string, any>> {
5286
5829
  }>;
5287
5830
  /**
5288
5831
  * Get the number of sounds currently playing on the client
5832
+ *
5833
+ * @returns Count of active sound instances.
5834
+ *
5835
+ * @example
5836
+ * ```typescript
5837
+ * const count = user.getPlayingSoundCount();
5838
+ * ```
5289
5839
  */
5290
5840
  getPlayingSoundCount(): number;
5291
5841
  /**
@@ -5411,6 +5961,12 @@ declare class User<TData = Record<string, any>> {
5411
5961
  *
5412
5962
  * @param instanceName - Instance name
5413
5963
  * @param eventType - Event type to remove (optional, removes all if not specified)
5964
+ *
5965
+ * @example
5966
+ * ```typescript
5967
+ * user.offMacroEvent('btn-play', 'click');
5968
+ * user.offMacroEvent('btn-play'); // remove all handlers for instance
5969
+ * ```
5414
5970
  */
5415
5971
  offMacroEvent(instanceName: string, eventType?: string): void;
5416
5972
  /**
@@ -5460,6 +6016,11 @@ declare class User<TData = Record<string, any>> {
5460
6016
  *
5461
6017
  * @param name - Layer name (used in createInstance)
5462
6018
  * @param layer - The layer object
6019
+ *
6020
+ * @example
6021
+ * ```typescript
6022
+ * user.registerLayerName('ui', uiLayer);
6023
+ * ```
5463
6024
  */
5464
6025
  registerLayerName(name: string, layer: Layer): void;
5465
6026
  /**
@@ -5476,6 +6037,12 @@ declare class User<TData = Record<string, any>> {
5476
6037
  * Should be called once per tick (tick-based updates)
5477
6038
  *
5478
6039
  * @returns Update result with events and sounds to play
6040
+ *
6041
+ * @example
6042
+ * ```typescript
6043
+ * const result = user.updateMacros();
6044
+ * user.processMacroEvents(result);
6045
+ * ```
5479
6046
  */
5480
6047
  updateMacros(): MacroUpdateResult;
5481
6048
  /**
@@ -5483,6 +6050,12 @@ declare class User<TData = Record<string, any>> {
5483
6050
  * Dispatches events to registered handlers (used in standalone mode)
5484
6051
  *
5485
6052
  * @param result - The result from updateMacros()
6053
+ *
6054
+ * @example
6055
+ * ```typescript
6056
+ * const result = user.updateMacros();
6057
+ * user.processMacroEvents(result);
6058
+ * ```
5486
6059
  */
5487
6060
  processMacroEvents(result: MacroUpdateResult): void;
5488
6061
  /**
@@ -5492,6 +6065,11 @@ declare class User<TData = Record<string, any>> {
5492
6065
  * @param displayX - Mouse X position in display cells (local to display)
5493
6066
  * @param displayY - Mouse Y position in display cells (local to display)
5494
6067
  * @param isDown - Whether the mouse button is pressed
6068
+ *
6069
+ * @example
6070
+ * ```typescript
6071
+ * user.updateMacroMouse(mouseX, mouseY, mouseDown);
6072
+ * ```
5495
6073
  */
5496
6074
  updateMacroMouse(displayX: number, displayY: number, isDown: boolean): void;
5497
6075
  /**
@@ -5500,12 +6078,24 @@ declare class User<TData = Record<string, any>> {
5500
6078
  * by subtracting the display's origin.
5501
6079
  *
5502
6080
  * @returns Map of layerId → render orders (in display coordinates)
6081
+ *
6082
+ * @example
6083
+ * ```typescript
6084
+ * const ordersByLayer = user.getMacroRenderOrders();
6085
+ * const uiOrders = ordersByLayer.get(uiLayerId) ?? [];
6086
+ * ```
5503
6087
  */
5504
6088
  getMacroRenderOrders(): Map<number, AnyNetworkOrder[]>;
5505
6089
  /**
5506
6090
  * Get the effect offset (for screen shake, etc.)
5507
6091
  *
5508
6092
  * @returns Current offset from effect macros
6093
+ *
6094
+ * @example
6095
+ * ```typescript
6096
+ * const offset = user.getMacroEffectOffset();
6097
+ * camera.setShake(offset.x, offset.y);
6098
+ * ```
5509
6099
  */
5510
6100
  getMacroEffectOffset(): {
5511
6101
  x: number;
@@ -5518,14 +6108,29 @@ declare class User<TData = Record<string, any>> {
5518
6108
  getMacroEngine(): MacroEngine;
5519
6109
  /**
5520
6110
  * Move focus to next focusable macro element
6111
+ *
6112
+ * @example
6113
+ * ```typescript
6114
+ * user.macroFocusNext();
6115
+ * ```
5521
6116
  */
5522
6117
  macroFocusNext(): void;
5523
6118
  /**
5524
6119
  * Move focus to previous focusable macro element
6120
+ *
6121
+ * @example
6122
+ * ```typescript
6123
+ * user.macroFocusPrevious();
6124
+ * ```
5525
6125
  */
5526
6126
  macroFocusPrevious(): void;
5527
6127
  /**
5528
6128
  * Activate the currently focused macro element
6129
+ *
6130
+ * @example
6131
+ * ```typescript
6132
+ * user.macroActivateFocused();
6133
+ * ```
5529
6134
  */
5530
6135
  macroActivateFocused(): void;
5531
6136
  /**
@@ -5552,7 +6157,7 @@ declare class User<TData = Record<string, any>> {
5552
6157
  * user.setPostProcess(0, null);
5553
6158
  * ```
5554
6159
  */
5555
- setPostProcess(displayId: number, config: PostProcessConfig | null): void;
6160
+ private setPostProcess;
5556
6161
  /**
5557
6162
  * Enable or disable scanlines effect with default/current settings for a specific display
5558
6163
  *
@@ -5565,7 +6170,7 @@ declare class User<TData = Record<string, any>> {
5565
6170
  * user.setScanlinesEnabled(0, false); // Disable on display 0
5566
6171
  * ```
5567
6172
  */
5568
- setScanlinesEnabled(displayId: number, enabled: boolean): void;
6173
+ private setScanlinesEnabled;
5569
6174
  /**
5570
6175
  * Set scanlines opacity (0-1) for a specific display
5571
6176
  *
@@ -5580,14 +6185,14 @@ declare class User<TData = Record<string, any>> {
5580
6185
  * user.setScanlinesOpacity(0, 0.5); // Strong effect on display 0
5581
6186
  * ```
5582
6187
  */
5583
- setScanlinesOpacity(displayId: number, opacity: number): void;
6188
+ private setScanlinesOpacity;
5584
6189
  /**
5585
6190
  * Set scanlines pattern for a specific display
5586
6191
  *
5587
6192
  * @param displayId - Display ID (0-255)
5588
6193
  * @param pattern - Pattern type: 'horizontal', 'vertical', or 'grid'
5589
6194
  */
5590
- setScanlinesPattern(displayId: number, pattern: 'horizontal' | 'vertical' | 'grid'): void;
6195
+ private setScanlinesPattern;
5591
6196
  /**
5592
6197
  * Enable or configure ambient effect for a specific display
5593
6198
  *
@@ -5611,10 +6216,7 @@ declare class User<TData = Record<string, any>> {
5611
6216
  * user.setAmbientEffect(1, { blur: 50, scale: 1.5 });
5612
6217
  * ```
5613
6218
  */
5614
- setAmbientEffect(displayId: number, config: boolean | {
5615
- blur?: number;
5616
- scale?: number;
5617
- }): void;
6219
+ private setAmbientEffect;
5618
6220
  /**
5619
6221
  * Enable or disable ambient effect for a specific display
5620
6222
  *
@@ -5627,7 +6229,7 @@ declare class User<TData = Record<string, any>> {
5627
6229
  * user.setAmbientEffectEnabled(0, false); // Disable on display 0
5628
6230
  * ```
5629
6231
  */
5630
- setAmbientEffectEnabled(displayId: number, enabled: boolean): void;
6232
+ private setAmbientEffectEnabled;
5631
6233
  /**
5632
6234
  * Set ambient effect blur intensity for a specific display
5633
6235
  *
@@ -5640,7 +6242,7 @@ declare class User<TData = Record<string, any>> {
5640
6242
  * user.setAmbientEffectBlur(0, 15); // Less blur on display 0
5641
6243
  * ```
5642
6244
  */
5643
- setAmbientEffectBlur(displayId: number, blur: number): void;
6245
+ private setAmbientEffectBlur;
5644
6246
  /**
5645
6247
  * Set ambient effect scale factor for a specific display
5646
6248
  *
@@ -5653,23 +6255,19 @@ declare class User<TData = Record<string, any>> {
5653
6255
  * user.setAmbientEffectScale(0, 1.1); // Smaller glow area on display 0
5654
6256
  * ```
5655
6257
  */
5656
- setAmbientEffectScale(displayId: number, scale: number): void;
6258
+ private setAmbientEffectScale;
5657
6259
  /**
5658
6260
  * Check if ambient effect is currently enabled
5659
6261
  */
5660
- isAmbientEffectEnabled(): boolean;
6262
+ private isAmbientEffectEnabled;
5661
6263
  /**
5662
6264
  * Get current ambient effect configuration
5663
6265
  */
5664
- getAmbientEffectConfig(): {
5665
- enabled: boolean;
5666
- blur: number;
5667
- scale: number;
5668
- } | null;
6266
+ private getAmbientEffectConfig;
5669
6267
  /**
5670
6268
  * Get current post-process configuration
5671
6269
  */
5672
- getPostProcessConfig(): PostProcessConfig | null;
6270
+ private getPostProcessConfig;
5673
6271
  /**
5674
6272
  * Check if there are pending post-process commands
5675
6273
  * @internal
@@ -5709,7 +6307,7 @@ declare class User<TData = Record<string, any>> {
5709
6307
  * user.setScalingMode(0, 'none');
5710
6308
  * ```
5711
6309
  */
5712
- setScalingMode(displayId: number, mode: ScalingMode): void;
6310
+ private setScalingMode;
5713
6311
  /**
5714
6312
  * Get current scaling mode for a display
5715
6313
  *
@@ -5717,7 +6315,7 @@ declare class User<TData = Record<string, any>> {
5717
6315
  * @param displayId - Display ID (0-255)
5718
6316
  * @returns Current scaling mode or null if not set
5719
6317
  */
5720
- getScalingMode(displayId: number): ScalingMode | null;
6318
+ private getScalingMode;
5721
6319
  /** Current cell size configuration per display (Map<displayId, {width, height}>) */
5722
6320
  private currentCellSizes;
5723
6321
  /**
@@ -5745,17 +6343,14 @@ declare class User<TData = Record<string, any>> {
5745
6343
  * user.setCellSize(1, 16, 16);
5746
6344
  * ```
5747
6345
  */
5748
- setCellSize(displayId: number, width: number, height: number): void;
6346
+ private setCellSize;
5749
6347
  /**
5750
6348
  * Get current cell size for a display
5751
6349
  *
5752
6350
  * @param displayId - Display ID (0-255)
5753
6351
  * @returns Object with cellWidth and cellHeight in pixels, or default 8x8 if not set
5754
6352
  */
5755
- getCellSize(displayId: number): {
5756
- cellWidth: number;
5757
- cellHeight: number;
5758
- };
6353
+ private getCellSize;
5759
6354
  /** Current grid configuration per display (Map<displayId, GridConfig>) */
5760
6355
  private currentGridConfigs;
5761
6356
  /**
@@ -5783,7 +6378,7 @@ declare class User<TData = Record<string, any>> {
5783
6378
  * user.setGrid(0, { enabled: true, color: '#ff0000', lineWidth: 2 });
5784
6379
  * ```
5785
6380
  */
5786
- setGrid(displayId: number, config: boolean | GridConfig): void;
6381
+ private setGrid;
5787
6382
  /**
5788
6383
  * Enable or disable the grid for a specific display
5789
6384
  *
@@ -5796,19 +6391,19 @@ declare class User<TData = Record<string, any>> {
5796
6391
  * user.setGridEnabled(0, false); // Hide grid on display 0
5797
6392
  * ```
5798
6393
  */
5799
- setGridEnabled(displayId: number, enabled: boolean): void;
6394
+ private setGridEnabled;
5800
6395
  /**
5801
6396
  * Check if grid is currently enabled for a display
5802
6397
  *
5803
6398
  * @param displayId - Display ID (0-255)
5804
6399
  */
5805
- isGridEnabled(displayId: number): boolean;
6400
+ private isGridEnabled;
5806
6401
  /**
5807
6402
  * Get current grid configuration for a display
5808
6403
  *
5809
6404
  * @param displayId - Display ID (0-255)
5810
6405
  */
5811
- getGridConfig(displayId: number): GridConfig | null;
6406
+ private getGridConfig;
5812
6407
  /** Currently active palette slot ID per display (Map<displayId, slotId>) */
5813
6408
  private currentPaletteSlotIds;
5814
6409
  /**
@@ -5845,14 +6440,14 @@ declare class User<TData = Record<string, any>> {
5845
6440
  * user.switchPalette(1, nightPalette); // Player 2 display
5846
6441
  * ```
5847
6442
  */
5848
- switchPalette(displayId: number, slotId: number): void;
6443
+ private switchPalette;
5849
6444
  /**
5850
6445
  * Get the currently active palette slot ID for a display
5851
6446
  *
5852
6447
  * @param displayId - Display ID (0-255)
5853
6448
  * @returns The active slot ID, or null if no palette has been switched yet
5854
6449
  */
5855
- getCurrentPaletteSlotId(displayId: number): number | null;
6450
+ private getCurrentPaletteSlotId;
5856
6451
  /**
5857
6452
  * Send data through the bridge channel to the client application
5858
6453
  *
@@ -5939,6 +6534,60 @@ declare class User<TData = Record<string, any>> {
5939
6534
  };
5940
6535
  }
5941
6536
 
6537
+ /**
6538
+ * Encoder for UTSP Update Packets (new protocol)
6539
+ * Layers are now at User level, not under displays
6540
+ *
6541
+ * Structure:
6542
+ * - Tick: 8 bytes (big-endian)
6543
+ * - DisplayCount: 1 byte (8-bit unsigned integer, max 255 displays)
6544
+ * - For each Display:
6545
+ * - DisplayId: 1 byte
6546
+ * - OriginX: 2 bytes (big-endian)
6547
+ * - OriginY: 2 bytes (big-endian)
6548
+ * - SizeX: 1 byte (1-256, encoded as 0-255)
6549
+ * - SizeY: 1 byte (1-256, encoded as 0-255)
6550
+ * - PassCount: 1 byte (0-4 render passes)
6551
+ * - RenderPasses: 4 bytes each (Id + zMin + zMax + flags)
6552
+ * - LayerCount: 2 bytes (big-endian)
6553
+ * - For each Layer: (encoded by LayerEncoder)
6554
+ * - AudioOrderCount: 1 byte (max 255 audio orders per frame)
6555
+ * - For each AudioOrder: (encoded by AudioOrderEncoder)
6556
+ * - VibrationOrderCount: 1 byte (max 255 vibration orders per frame)
6557
+ * - For each VibrationOrder: (encoded by VibrationOrderEncoder)
6558
+ * - MacroOrderCount: 1 byte (max 255 macro orders per frame)
6559
+ * - For each MacroOrder: (encoded by MacroOrderEncoder)
6560
+ * - PostProcessOrderCount: 1 byte (max 255 post-process orders per frame)
6561
+ * - For each PostProcessOrder: (encoded by PostProcessOrderEncoder)
6562
+ */
6563
+ declare class UpdatePacketEncoder {
6564
+ private layerEncoder;
6565
+ private audioOrderEncoder;
6566
+ private vibrationOrderEncoder;
6567
+ private macroOrderEncoder;
6568
+ private postProcessOrderEncoder;
6569
+ private displayEncoder;
6570
+ constructor();
6571
+ /**
6572
+ * Encodes an UpdatePacket to binary buffer
6573
+ *
6574
+ * Minimum packet size: 15 bytes (Tick=8 + DisplayCount=1 + LayerCount=2 + AudioOrderCount=1 + VibrationOrderCount=1 + MacroOrderCount=1 + PostProcessOrderCount=1)
6575
+ */
6576
+ encode(packet: UpdatePacket): Uint8Array;
6577
+ /**
6578
+ * Calculates the size of an encoded update packet without actually encoding it
6579
+ */
6580
+ calculateSize(packet: UpdatePacket): number;
6581
+ /**
6582
+ * Creates an empty update packet (useful for keep-alive or no-op updates)
6583
+ */
6584
+ static createEmptyPacket(tick: number | bigint): UpdatePacket;
6585
+ /**
6586
+ * Encodes an empty update packet (15 bytes minimum)
6587
+ */
6588
+ encodeEmpty(tick: number | bigint): Uint8Array;
6589
+ }
6590
+
5942
6591
  /**
5943
6592
  * UTSP engine performance statistics
5944
6593
  * Collects metrics per tick for analysis and optimization
@@ -6025,7 +6674,7 @@ declare class CoreStats {
6025
6674
  /** Details of all layers processed this tick */
6026
6675
  get layerDetails(): Array<{
6027
6676
  layerId: number;
6028
- isStatic: boolean;
6677
+ mustBeReliable: boolean;
6029
6678
  orderCount: number;
6030
6679
  updateFlags: number;
6031
6680
  }> | undefined;
@@ -6060,7 +6709,7 @@ declare class CoreStats {
6060
6709
  /**
6061
6710
  * Records individual layer information
6062
6711
  */
6063
- recordLayerInfo(layerId: number, isStatic: boolean, orderCount: number, updateFlags: number): void;
6712
+ recordLayerInfo(layerId: number, mustBeReliable: boolean, orderCount: number, updateFlags: number): void;
6064
6713
  /**
6065
6714
  * Records rendered cell statistics
6066
6715
  */
@@ -6084,119 +6733,6 @@ declare class CoreStats {
6084
6733
  reset(): void;
6085
6734
  }
6086
6735
 
6087
- /**
6088
- * WebFontRegistry - Registry for CSS-based fonts
6089
- */
6090
-
6091
- /**
6092
- * Registry for managing WebFont instances
6093
- * Each font is identified by a unique fontId (0-255)
6094
- */
6095
- declare class WebFontRegistry {
6096
- private fonts;
6097
- /**
6098
- * Load a new WebFont into the registry
6099
- * @param fontId Unique font identifier (0-255)
6100
- * @param config WebFont configuration
6101
- * @throws Error if font ID already exists
6102
- */
6103
- loadFont(fontId: number, config: WebFontConfig): void;
6104
- /**
6105
- * Get a WebFont by ID
6106
- * @param fontId Font identifier
6107
- * @returns WebFont instance or undefined if not found
6108
- */
6109
- getFont(fontId: number): WebFont | undefined;
6110
- /**
6111
- * Check if a font exists in the registry
6112
- * @param fontId Font identifier
6113
- * @returns true if font exists, false otherwise
6114
- */
6115
- hasFont(fontId: number): boolean;
6116
- /**
6117
- * Remove a WebFont from the registry
6118
- * @param fontId Font identifier
6119
- * @returns true if font was removed, false if not found
6120
- */
6121
- unloadFont(fontId: number): boolean;
6122
- /**
6123
- * Remove all fonts from the registry
6124
- */
6125
- clearFonts(): void;
6126
- /**
6127
- * Get all font IDs in the registry
6128
- * @returns Array of font IDs, sorted in ascending order
6129
- */
6130
- getFontIds(): number[];
6131
- /**
6132
- * Get all WebFont instances in the registry
6133
- * @returns Array of WebFont instances, sorted by font ID
6134
- */
6135
- getAllFonts(): WebFont[];
6136
- /**
6137
- * Get the number of fonts in the registry
6138
- * @returns Number of fonts
6139
- */
6140
- getFontCount(): number;
6141
- }
6142
-
6143
- /**
6144
- * BitmapFontRegistry - Registry for pixel-based bitmap fonts
6145
- */
6146
-
6147
- /**
6148
- * Registry for managing BitmapFont instances
6149
- * Each font is identified by a unique fontId (0-255)
6150
- * BitmapFonts correspond to LoadType 0x04 (Charset) in UTSP protocol
6151
- */
6152
- declare class BitmapFontRegistry {
6153
- private fonts;
6154
- /**
6155
- * Load a new BitmapFont into the registry
6156
- * @param fontId Unique font identifier (0-255)
6157
- * @param config BitmapFont configuration
6158
- * @throws Error if font ID already exists
6159
- */
6160
- loadFont(fontId: number, config: BitmapFontConfig): void;
6161
- /**
6162
- * Get a BitmapFont by ID
6163
- * @param fontId Font identifier
6164
- * @returns BitmapFont instance or undefined if not found
6165
- */
6166
- getFont(fontId: number): BitmapFont | undefined;
6167
- /**
6168
- * Check if a font exists in the registry
6169
- * @param fontId Font identifier
6170
- * @returns true if font exists, false otherwise
6171
- */
6172
- hasFont(fontId: number): boolean;
6173
- /**
6174
- * Remove a BitmapFont from the registry
6175
- * @param fontId Font identifier
6176
- * @returns true if font was removed, false if not found
6177
- */
6178
- unloadFont(fontId: number): boolean;
6179
- /**
6180
- * Remove all fonts from the registry
6181
- */
6182
- clearFonts(): void;
6183
- /**
6184
- * Get all font IDs in the registry
6185
- * @returns Array of font IDs, sorted in ascending order
6186
- */
6187
- getFontIds(): number[];
6188
- /**
6189
- * Get all BitmapFont instances in the registry
6190
- * @returns Array of BitmapFont instances, sorted by font ID
6191
- */
6192
- getAllFonts(): BitmapFont[];
6193
- /**
6194
- * Get the number of fonts in the registry
6195
- * @returns Number of fonts
6196
- */
6197
- getFontCount(): number;
6198
- }
6199
-
6200
6736
  /**
6201
6737
  * SoundRegistry - Server-side registry for audio assets
6202
6738
  *
@@ -6348,156 +6884,363 @@ declare class SoundRegistry {
6348
6884
  }
6349
6885
 
6350
6886
  /**
6351
- * Engine execution context type
6887
+ * AudioOrderCollector - Converts high-level audio commands to binary AudioOrders
6888
+ *
6889
+ * This class bridges the gap between the User's high-level audio API
6890
+ * (playSound, stopSound, etc.) and the binary AudioOrder protocol.
6891
+ *
6892
+ * It takes SoundRegistry to resolve sound names to IDs, and produces
6893
+ * AudioOrders ready for binary encoding in UpdatePacket.
6894
+ *
6895
+ * @example
6896
+ * ```typescript
6897
+ * const collector = new AudioOrderCollector(soundRegistry);
6898
+ *
6899
+ * // Convert User's pending commands to orders
6900
+ * const audioOrders = collector.collectFromUser(user);
6901
+ *
6902
+ * // audioOrders can now be added to UpdatePacket
6903
+ * ```
6352
6904
  */
6353
- type CoreMode = 'server' | 'client' | 'standalone';
6905
+
6354
6906
  /**
6355
- * UTSP engine configuration options
6907
+ * Collects and converts audio commands to binary AudioOrders
6356
6908
  */
6357
- interface CoreOptions {
6909
+ declare class AudioOrderCollector {
6910
+ private soundRegistry;
6911
+ constructor(soundRegistry: SoundRegistry);
6358
6912
  /**
6359
- * Execution mode: "server", "client" or "standalone"
6360
- *
6361
- * - "server": Server-side engine
6362
- * → Marks layers as dirty (change tracking)
6363
- * → Does NOT rasterize (CPU savings, client-side rasterization)
6364
- * → Manages multiple users (limited by maxUsers)
6365
- *
6366
- * - "client": Client-side engine
6367
- * → Does NOT mark as dirty (no tracking needed)
6368
- * → Rasterizes immediately (local rendering for display)
6369
- * → Manages ONE local user only (fixed limit)
6913
+ * Collect all pending audio orders from a user
6370
6914
  *
6371
- * - "standalone": Standalone engine (preview, tests, debug)
6372
- * Marks as dirty AND rasterizes
6373
- * → Manages multiple users
6374
- * → Useful for getRenderState(), tests, simulations
6915
+ * This flushes the user's sound and config command queues,
6916
+ * converts them to binary AudioOrders, and returns them.
6375
6917
  *
6376
- * @default "server"
6918
+ * @param user - The user to collect orders from
6919
+ * @returns Array of AudioOrders ready for encoding
6377
6920
  */
6378
- mode?: CoreMode;
6921
+ collectFromUser(user: User): AnyAudioOrder[];
6379
6922
  /**
6380
- * Maximum number of users allowed (server mode only)
6381
- *
6382
- * In client mode, this option is ignored (fixed limit of 1 user)
6383
- *
6384
- * @default 64
6923
+ * Convert a sound command to an AudioOrder
6385
6924
  */
6386
- maxUsers?: number;
6925
+ private convertSoundCommand;
6387
6926
  /**
6388
- * Enable strict validations (useful in development)
6389
- *
6390
- * @default false
6927
+ * Convert PlaySoundCommand to PlaySoundOrder or PlayGlobalSoundOrder
6391
6928
  */
6392
- strictMode?: boolean;
6393
- }
6394
- /**
6395
- * Core - UTSP data management engine
6396
- *
6397
- * Passive API: no loop, no network, no callbacks.
6398
- * Parent package (utsp-server, utsp-client) controls execution flow.
6399
- *
6400
- * Responsibilities:
6401
- * - Store and manage users
6402
- * - Provide data manipulation methods
6403
- * - Pure and predictable API
6404
- *
6405
- * What the core does NOT do:
6406
- * - No tick loop (server/client manages it)
6407
- * - No network (server/client manages it)
6408
- * - No callbacks/events (core is a passive slave)
6409
- */
6410
- declare class Core {
6411
- private users;
6412
- private readonly mode;
6413
- private readonly maxUsers;
6414
- private readonly strictMode;
6415
- private currentTick;
6416
- private encoder;
6417
- private displayRasterizer;
6418
- private colorPalette;
6419
- private static readonly ANSI_VGA_COLORS;
6420
- private stats;
6421
- private spriteRegistry;
6422
- private webFontRegistry;
6423
- private bitmapFontRegistry;
6424
- private imageFontRegistry;
6425
- private soundRegistry;
6426
- private audioOrderCollector;
6427
- private vibrationOrderCollector;
6428
- private postProcessOrderCollector;
6429
- private activeWebFontId;
6430
- private _renderCallCount;
6431
- private paletteSlots;
6432
- private onPaletteChangedCallback?;
6433
- private onBitmapFontChangedCallback?;
6434
- private onImageFontChangedCallback?;
6929
+ private convertPlayCommand;
6435
6930
  /**
6436
- * Creates a new UTSP engine instance
6437
- *
6438
- * @param options - Configuration options
6439
- *
6440
- * @example
6441
- * ```typescript
6442
- * // Server with 100 max users
6443
- * const engine = new Core({
6444
- * mode: "server",
6445
- * maxUsers: 100
6446
- * });
6447
- *
6448
- * // Simple client
6449
- * const engine = new Core({
6450
- * mode: "client"
6451
- * });
6452
- *
6453
- * // Default mode (server)
6454
- * const engine = new Core();
6455
- * ```
6931
+ * Convert StopSoundCommand to StopSoundOrder
6456
6932
  */
6457
- constructor(options?: CoreOptions);
6933
+ private convertStopCommand;
6458
6934
  /**
6459
- * Initialize default color palette (15 reserved UI colors + free colors)
6460
- * @private
6935
+ * Convert FadeOutSoundCommand to FadeOutSoundOrder
6461
6936
  */
6462
- private initializeDefaultPalette;
6937
+ private convertFadeOutCommand;
6463
6938
  /**
6464
- * Returns current execution mode
6465
- *
6466
- * @returns "server", "client" or "standalone"
6939
+ * Convert PauseSoundCommand to PauseSoundOrder
6467
6940
  */
6468
- getMode(): CoreMode;
6941
+ private convertPauseCommand;
6469
6942
  /**
6470
- * Returns maximum allowed users
6471
- *
6472
- * @returns Max number of users
6943
+ * Convert ResumeSoundCommand to ResumeSoundOrder
6473
6944
  */
6474
- getMaxUsers(): number;
6945
+ private convertResumeCommand;
6475
6946
  /**
6476
- * Indicates if strict mode is enabled
6477
- *
6478
- * @returns true if strict mode is enabled
6947
+ * Convert SetSoundEffectsCommand to SetSoundEffectsOrder
6479
6948
  */
6480
- isStrictMode(): boolean;
6949
+ private convertSetEffectsCommand;
6481
6950
  /**
6482
- * Checks if core is in server mode
6483
- *
6484
- * @returns true if server mode
6951
+ * Convert AudioConfigCommand to SetListenerPositionOrder or ConfigureSpatialOrder
6485
6952
  */
6486
- isServer(): boolean;
6953
+ private convertConfigCommand;
6487
6954
  /**
6488
- * Checks if core is in client mode
6489
- *
6490
- * @returns true if client mode
6955
+ * Resolve sound name or ID to a numeric soundId
6491
6956
  */
6492
- isClient(): boolean;
6957
+ private resolveSoundId;
6493
6958
  /**
6494
- * Checks if core is in standalone mode
6495
- *
6496
- * @returns true if standalone mode
6959
+ * Resolve target (instanceId, soundName, or 'all') to targetType and value
6497
6960
  */
6498
- isStandalone(): boolean;
6961
+ private resolveTarget;
6499
6962
  /**
6500
- * Creates a new user in the engine
6963
+ * Encode volume (0.0-1.0) to byte (0-255)
6964
+ */
6965
+ private encodeVolume;
6966
+ /**
6967
+ * Encode pitch (0.25x-4.0x) to byte (0-255, 128=1.0x)
6968
+ * Formula: pitch = 0.25 * 2^(byte/64)
6969
+ * Inverse: byte = 64 * log2(pitch / 0.25)
6970
+ */
6971
+ private encodePitch;
6972
+ /**
6973
+ * Encode fade time (seconds) to byte (1/10 seconds, 0-25.5s)
6974
+ */
6975
+ private encodeFadeTime;
6976
+ /**
6977
+ * Encode distance for spatial audio (scale: 0-25500 → 0-255)
6978
+ */
6979
+ private encodeDistance;
6980
+ /**
6981
+ * Encode rolloff factor (0.0-2.55 → 0-255)
6982
+ */
6983
+ private encodeRolloff;
6984
+ /**
6985
+ * Encode pan spread (0.0-1.0 → 0-255)
6986
+ */
6987
+ private encodePanSpread;
6988
+ /**
6989
+ * Encode position coordinate for spatial audio (clamp to 0-65535 for Uint16)
6990
+ */
6991
+ private encodePosition;
6992
+ /**
6993
+ * Encode filter frequency (100-25500 Hz) to byte (1-255, * 100 = Hz)
6994
+ * 0 means disabled
6995
+ */
6996
+ private encodeFilterFreq;
6997
+ /**
6998
+ * Encode reverb wet mix (0.0-1.0) to byte (0-255)
6999
+ */
7000
+ private encodeReverb;
7001
+ }
7002
+
7003
+ /**
7004
+ * VibrationOrderCollector - Converts high-level vibration commands to binary VibrationOrders
7005
+ *
7006
+ * This class bridges the gap between the User's high-level vibration API
7007
+ * (vibrate, vibrateGamepad, etc.) and the binary VibrationOrder protocol.
7008
+ *
7009
+ * It produces VibrationOrders ready for binary encoding in UpdatePacket.
7010
+ * Supports both mobile vibration (pattern-based) and gamepad vibration (dual-motor).
7011
+ *
7012
+ * @example
7013
+ * ```typescript
7014
+ * const collector = new VibrationOrderCollector();
7015
+ *
7016
+ * // Convert User's pending commands to orders
7017
+ * const vibrationOrders = collector.collectFromUser(user);
7018
+ *
7019
+ * // vibrationOrders can now be added to UpdatePacket
7020
+ * ```
7021
+ */
7022
+
7023
+ /**
7024
+ * Collects and converts vibration commands to binary VibrationOrders
7025
+ */
7026
+ declare class VibrationOrderCollector {
7027
+ /**
7028
+ * Collect all pending vibration orders from a user
7029
+ *
7030
+ * This flushes the user's vibration command queues (mobile + gamepad),
7031
+ * converts them to binary VibrationOrders, and returns them.
7032
+ *
7033
+ * @param user - The user to collect orders from
7034
+ * @returns Array of VibrationOrders ready for encoding
7035
+ */
7036
+ collectFromUser(user: User): AnyVibrationOrder[];
7037
+ /**
7038
+ * Convert a mobile vibration command to a VibrationOrder
7039
+ * Accepts both old format (without target) and new format (with target: 'mobile')
7040
+ */
7041
+ private convertMobileCommand;
7042
+ /**
7043
+ * Convert MobileVibrateCommand to MobileVibrateOrder
7044
+ * Accepts both old format { pattern, intensity? } and new format { target: 'mobile', pattern, intensity? }
7045
+ */
7046
+ private convertMobileVibrateCommand;
7047
+ /**
7048
+ * Convert MobileCancelVibrationCommand to MobileCancelOrder
7049
+ */
7050
+ private convertMobileCancelCommand;
7051
+ /**
7052
+ * Convert a gamepad vibration command to a VibrationOrder
7053
+ * Accepts both old format (without target) and new format (with target: 'gamepad')
7054
+ */
7055
+ private convertGamepadCommand;
7056
+ /**
7057
+ * Convert GamepadVibrateCommand to GamepadVibrateOrder
7058
+ */
7059
+ private convertGamepadVibrateCommand;
7060
+ /**
7061
+ * Convert GamepadCancelVibrationCommand to GamepadCancelOrder
7062
+ */
7063
+ private convertGamepadCancelCommand;
7064
+ }
7065
+
7066
+ /**
7067
+ * PostProcessOrderCollector - Converts high-level post-process commands to binary PostProcessOrders
7068
+ *
7069
+ * This class bridges the gap between the User's high-level post-process API
7070
+ * (setPostProcess, setAmbientEffect, etc.) and the binary PostProcessOrder protocol.
7071
+ *
7072
+ * It converts PostProcessCommands to PostProcessOrders ready for binary encoding in UpdatePacket.
7073
+ *
7074
+ * @example
7075
+ * ```typescript
7076
+ * const collector = new PostProcessOrderCollector();
7077
+ *
7078
+ * // Convert User's pending commands to orders
7079
+ * const postProcessOrders = collector.collectFromUser(user);
7080
+ *
7081
+ * // postProcessOrders can now be added to UpdatePacket
7082
+ * ```
7083
+ */
7084
+
7085
+ /**
7086
+ * Collects and converts post-process commands to binary PostProcessOrders
7087
+ */
7088
+ declare class PostProcessOrderCollector {
7089
+ /**
7090
+ * Collect all pending post-process orders from a user
7091
+ *
7092
+ * This flushes the user's post-process command queue,
7093
+ * converts them to binary PostProcessOrders, and returns them.
7094
+ *
7095
+ * @param user - The user to collect orders from
7096
+ * @returns Array of PostProcessOrders ready for encoding
7097
+ */
7098
+ collectFromUser(user: User): AnyPostProcessOrder[];
7099
+ /**
7100
+ * Convert an array of post-process commands to PostProcessOrders
7101
+ *
7102
+ * This is the core conversion logic used by both:
7103
+ * - Server: collectFromUser() → encode → network
7104
+ * - Local: convertCommands() → applyPostProcessOrders() (no encoding)
7105
+ *
7106
+ * @param commands - Array of PostProcessCommands to convert
7107
+ * @returns Array of PostProcessOrders
7108
+ */
7109
+ convertCommands(commands: PostProcessCommand[]): AnyPostProcessOrder[];
7110
+ /**
7111
+ * Convert a post-process command to a PostProcessOrder
7112
+ */
7113
+ private convertCommand;
7114
+ /**
7115
+ * Convert a full set-config command to a SetConfigOrder
7116
+ */
7117
+ private convertSetConfig;
7118
+ /**
7119
+ * Create a SetScanlinesOrder with given parameters
7120
+ */
7121
+ private createSetScanlinesOrder;
7122
+ /**
7123
+ * Create a SetAmbientEffectOrder with given parameters
7124
+ */
7125
+ private createSetAmbientEffectOrder;
7126
+ /**
7127
+ * Convert pattern string to ScanlinesPatternType
7128
+ */
7129
+ private patternToType;
7130
+ /**
7131
+ * Create a SetScalingModeOrder with given scaling mode
7132
+ */
7133
+ private createSetScalingModeOrder;
7134
+ /**
7135
+ * Create a SetGridOrder with given grid configuration
7136
+ */
7137
+ private createSetGridOrder;
7138
+ /**
7139
+ * Create a SwitchPaletteOrder with given slot ID
7140
+ */
7141
+ private createSwitchPaletteOrder;
7142
+ /**
7143
+ * Create a SetCellSizeOrder with given dimensions
7144
+ */
7145
+ private createSetCellSizeOrder;
7146
+ /**
7147
+ * Parse CSS color string to RGBA components
7148
+ */
7149
+ private parseColor;
7150
+ }
7151
+
7152
+ /**
7153
+ * Engine execution context type
7154
+ */
7155
+ type CoreMode = 'server' | 'client' | 'standalone';
7156
+ /**
7157
+ * UTSP engine configuration options
7158
+ */
7159
+ interface CoreOptions {
7160
+ /**
7161
+ * Execution mode: "server", "client" or "standalone"
7162
+ */
7163
+ mode?: CoreMode;
7164
+ /**
7165
+ * Maximum number of users allowed (server mode only)
7166
+ * Default: 100
7167
+ */
7168
+ maxUsers?: number;
7169
+ }
7170
+ declare class Core {
7171
+ static readonly ANSI_VGA_COLORS: {
7172
+ colorId: number;
7173
+ r: number;
7174
+ g: number;
7175
+ b: number;
7176
+ a: number;
7177
+ e: number;
7178
+ }[];
7179
+ readonly mode: CoreMode;
7180
+ readonly maxUsers: number;
7181
+ strictMode: boolean;
7182
+ currentTick: number;
7183
+ readonly stats: CoreStats;
7184
+ readonly spriteRegistry: SpriteRegistry;
7185
+ readonly imageFontRegistry: ImageFontRegistry;
7186
+ readonly soundRegistry: SoundRegistry;
7187
+ readonly audioOrderCollector: AudioOrderCollector;
7188
+ readonly vibrationOrderCollector: VibrationOrderCollector;
7189
+ readonly postProcessOrderCollector: PostProcessOrderCollector;
7190
+ readonly encoder: UpdatePacketEncoder;
7191
+ private readonly users;
7192
+ private readonly colorPalette;
7193
+ private readonly paletteSlots;
7194
+ private readonly displayRasterizer;
7195
+ private _renderCallCount;
7196
+ private onPaletteChangedCallback?;
7197
+ private onFontAllocatedCallback?;
7198
+ private onFontBlockAddedCallback?;
7199
+ /** @deprecated Use onFontAllocated/onFontBlockAdded */
7200
+ private onImageFontChangedCallback?;
7201
+ constructor(options?: CoreOptions);
7202
+ private initializeDefaultPalette;
7203
+ /**
7204
+ * Checks if core is in server mode
7205
+ *
7206
+ * @returns true if server mode
7207
+ *
7208
+ * @example
7209
+ * ```typescript
7210
+ * if (engine.isServer()) {
7211
+ * // Server-specific logic
7212
+ * }
7213
+ * ```
7214
+ */
7215
+ isServer(): boolean;
7216
+ /**
7217
+ * Checks if core is in client mode
7218
+ *
7219
+ * @returns true if client mode
7220
+ *
7221
+ * @example
7222
+ * ```typescript
7223
+ * if (engine.isClient()) {
7224
+ * // Client-specific logic
7225
+ * }
7226
+ * ```
7227
+ */
7228
+ isClient(): boolean;
7229
+ /**
7230
+ * Checks if core is in standalone mode
7231
+ *
7232
+ * @returns true if standalone mode
7233
+ *
7234
+ * @example
7235
+ * ```typescript
7236
+ * if (engine.isStandalone()) {
7237
+ * // Local preview or tests
7238
+ * }
7239
+ * ```
7240
+ */
7241
+ isStandalone(): boolean;
7242
+ /**
7243
+ * Creates a new user in the engine
6501
7244
  *
6502
7245
  * @param id - Unique user ID (string)
6503
7246
  * @param name - User name
@@ -6629,7 +7372,7 @@ declare class Core {
6629
7372
  /**
6630
7373
  * Register a callback to be notified when palette changes
6631
7374
  *
6632
- * Use this to update the renderer when palette is modified via loadPalette() or setColor().
7375
+ * Use this to update the renderer when palette is modified via setColor() or resetPalette().
6633
7376
  *
6634
7377
  * @param callback - Function called with the new palette
6635
7378
  *
@@ -6649,23 +7392,7 @@ declare class Core {
6649
7392
  e: number;
6650
7393
  }>) => void): void;
6651
7394
  /**
6652
- * Register a callback to be notified when a bitmap font is loaded.
6653
- *
6654
- * Use this to update the renderer when a font is loaded via loadBitmapFontById().
6655
- *
6656
- * @param callback - Function called with the fontId
6657
- *
6658
- * @example
6659
- * ```typescript
6660
- * core.onBitmapFontChanged((fontId) => {
6661
- * const font = core.getBitmapFont(fontId);
6662
- * if (font) renderer.uploadFontToGPU(font);
6663
- * });
6664
- * ```
6665
- */
6666
- onBitmapFontChanged(callback: (fontId: number) => void): void;
6667
- /**
6668
- * Gets a color from the palette
7395
+ * Gets a color from the palette
6669
7396
  *
6670
7397
  * @param colorId - Color ID (0-255)
6671
7398
  * @returns RGBA+E color or null if ID doesn't exist
@@ -6686,38 +7413,6 @@ declare class Core {
6686
7413
  a: number;
6687
7414
  e: number;
6688
7415
  } | null;
6689
- /**
6690
- * Loads a complete color palette
6691
- *
6692
- * Replaces existing colors for the specified IDs.
6693
- *
6694
- * 🎨 RESERVED COLORS (automatically forced):
6695
- * - ColorIDs 240-254: Standard UI palette (will be overridden even if provided)
6696
- * - ColorID 255: Skip/transparent color (will be overridden even if provided)
6697
- * - ColorIDs 0-239: Free for application use
6698
- *
6699
- * @param colors - Array of colors to load (any ColorIDs 0-255)
6700
- *
6701
- * @example
6702
- * ```typescript
6703
- * engine.loadPalette([
6704
- * { colorId: 0, r: 255, g: 0, b: 0, a: 255, e: 0 }, // ✅ Custom color (free range)
6705
- * { colorId: 1, r: 255, g: 255, b: 255, a: 255, e: 0 }, // ✅ Custom white
6706
- * { colorId: 2, r: 255, g: 0, b: 0, a: 255, e: 0 }, // ✅ Custom red
6707
- * { colorId: 3, r: 0, g: 255, b: 255, a: 255, e: 255 }, // ✅ Bright cyan
6708
- * { colorId: 250, r: 255, g: 0, b: 0, a: 255, e: 0 }, // ⚠️ Will be ignored (reserved)
6709
- * ]);
6710
- * // ColorIDs 240-254 and 255 will be forced to standard values
6711
- * ```
6712
- */
6713
- loadPalette(colors: Array<{
6714
- colorId: number;
6715
- r: number;
6716
- g: number;
6717
- b: number;
6718
- a: number;
6719
- e?: number;
6720
- }>): void;
6721
7416
  /**
6722
7417
  * Gets the entire color palette
6723
7418
  *
@@ -6750,7 +7445,7 @@ declare class Core {
6750
7445
  /**
6751
7446
  * Load a palette into a slot for later switching
6752
7447
  *
6753
- * Palettes are stored in the Core and can be switched per-user at runtime.
7448
+ * Palettes are stored in the Core and can be switched per-display at runtime.
6754
7449
  * This allows preloading multiple palettes (e.g., day/night themes)
6755
7450
  * and switching between them without re-sending the palette data.
6756
7451
  *
@@ -6763,8 +7458,9 @@ declare class Core {
6763
7458
  * core.loadPaletteToSlot(0, dayColors);
6764
7459
  * core.loadPaletteToSlot(1, nightColors);
6765
7460
  *
6766
- * // Later, switch user to night palette
6767
- * user.switchPalette(1);
7461
+ * // Later, switch display to night palette
7462
+ * const display = user.getDisplays()[0];
7463
+ * display.switchPalette(1);
6768
7464
  * ```
6769
7465
  */
6770
7466
  loadPaletteToSlot(slotId: number, colors: Array<{
@@ -6801,16 +7497,33 @@ declare class Core {
6801
7497
  *
6802
7498
  * @param slotId - Slot ID (0-255)
6803
7499
  * @returns true if the slot has a palette loaded
7500
+ *
7501
+ * @example
7502
+ * ```typescript
7503
+ * if (core.hasPaletteSlot(1)) {
7504
+ * console.log('Slot 1 is ready');
7505
+ * }
7506
+ * ```
6804
7507
  */
6805
7508
  hasPaletteSlot(slotId: number): boolean;
6806
7509
  /**
6807
7510
  * Clear a palette slot
6808
7511
  *
6809
7512
  * @param slotId - Slot ID (0-255)
7513
+ *
7514
+ * @example
7515
+ * ```typescript
7516
+ * core.clearPaletteSlot(1);
7517
+ * ```
6810
7518
  */
6811
7519
  clearPaletteSlot(slotId: number): void;
6812
7520
  /**
6813
7521
  * Clear all palette slots
7522
+ *
7523
+ * @example
7524
+ * ```typescript
7525
+ * core.clearAllPaletteSlots();
7526
+ * ```
6814
7527
  */
6815
7528
  clearAllPaletteSlots(): void;
6816
7529
  /**
@@ -7065,11 +7778,9 @@ declare class Core {
7065
7778
  *
7066
7779
  * This method automatically decodes the binary buffer and applies
7067
7780
  * the asset to the Core according to its LoadType:
7068
- * - ColorPalette → loadPalette()
7781
+ * - ColorPalette → loadPaletteToSlot()
7069
7782
  * - Sprite → loadUnicolorSprites()
7070
7783
  * - MulticolorSprite → loadMulticolorSprites()
7071
- * - BitmapFont → loadBitmapFontById()
7072
- * - WebFont → loadWebFontById()
7073
7784
  * - Sound → (TODO: implement audio system)
7074
7785
  *
7075
7786
  * @param buffer - Encoded binary buffer received via WebSocket
@@ -7084,23 +7795,6 @@ declare class Core {
7084
7795
  * ```
7085
7796
  */
7086
7797
  applyLoadPacket(buffer: Uint8Array): boolean;
7087
- /**
7088
- * Generates a LoadPacket for the current color palette (SERVER-SIDE)
7089
- *
7090
- * Encodes the complete palette in binary format ready to send to clients.
7091
- *
7092
- * @returns Encoded binary buffer (or null if palette empty)
7093
- *
7094
- * @example
7095
- * ```typescript
7096
- * // Server side
7097
- * const palettePacket = core.generatePaletteLoadPacket();
7098
- * if (palettePacket) {
7099
- * websocket.emit('load', palettePacket);
7100
- * }
7101
- * ```
7102
- */
7103
- generatePaletteLoadPacket(): Uint8Array | null;
7104
7798
  /**
7105
7799
  * Generates a LoadPacket for a specific palette slot (SERVER-SIDE)
7106
7800
  *
@@ -7164,39 +7858,7 @@ declare class Core {
7164
7858
  */
7165
7859
  generateMulticolorSpritesLoadPacket(): Uint8Array | null;
7166
7860
  /**
7167
- * Generates LoadPackets for all web fonts (SERVER-SIDE)
7168
- *
7169
- * Returns an array of buffers (one font = one packet)
7170
- *
7171
- * @returns Array of encoded buffers (or empty array if no fonts)
7172
- *
7173
- * @example
7174
- * ```typescript
7175
- * const fontPackets = core.generateWebFontsLoadPackets();
7176
- * fontPackets.forEach(packet => {
7177
- * websocket.emit('load', packet);
7178
- * });
7179
- * ```
7180
- */
7181
- generateWebFontsLoadPackets(): Uint8Array[];
7182
- /**
7183
- * Generates LoadPackets for all bitmap fonts (SERVER-SIDE)
7184
- *
7185
- * Returns an array of buffers (one font = one packet)
7186
- *
7187
- * @returns Array of encoded buffers (or empty array if no fonts)
7188
- *
7189
- * @example
7190
- * ```typescript
7191
- * const fontPackets = core.generateBitmapFontsLoadPackets();
7192
- * fontPackets.forEach(packet => {
7193
- * websocket.emit('load', packet);
7194
- * });
7195
- * ```
7196
- */
7197
- generateBitmapFontsLoadPackets(): Uint8Array[];
7198
- /**
7199
- * Generates ALL LoadPackets (palette + sprites + fonts) (SERVER-SIDE)
7861
+ * Generates ALL LoadPackets (palette slots + sprites + fonts) (SERVER-SIDE)
7200
7862
  *
7201
7863
  * Useful when a client initially connects to send them
7202
7864
  * all assets at once.
@@ -7395,6 +8057,26 @@ declare class Core {
7395
8057
  * ```
7396
8058
  */
7397
8059
  loadMulticolorSprites(loadData: MulticolorSpriteLoad): void;
8060
+ /**
8061
+ * Load Font structure (allocate font)
8062
+ * Defines the font dimensions and allocates the atlas in memory (empty)
8063
+ *
8064
+ * @param glyphWidth Width of each glyph source in pixels
8065
+ * @param glyphHeight Height of each glyph source in pixels
8066
+ * @param atlasBlocks Number of 256-char blocks (1, 4, or 16)
8067
+ * @param cellWidth Target rendering width
8068
+ * @param cellHeight Target rendering height
8069
+ */
8070
+ loadFont(glyphWidth: number, glyphHeight: number, atlasBlocks: AtlasBlocks, cellWidth: number, cellHeight: number): void;
8071
+ /**
8072
+ * Load Font data block
8073
+ * Uploads a PNG chunk (256 chars) to the previously allocated font atlas
8074
+ *
8075
+ * @param blockIndex Index of the block (0-15)
8076
+ * @param pathOrData Path to the PNG file (string) or raw data (Uint8Array)
8077
+ */
8078
+ loadFontBlock(blockIndex: number, path: string): Promise<void>;
8079
+ loadFontBlock(blockIndex: number, data: Uint8Array): void;
7398
8080
  /**
7399
8081
  * Unloads a unicolor sprite from memory
7400
8082
  *
@@ -7584,9 +8266,9 @@ declare class Core {
7584
8266
  */
7585
8267
  private detectSoundFormat;
7586
8268
  /**
7587
- * Loads sound data from path (isomorphic: Node.js or browser)
8269
+ * Loads resource data from path (isomorphic: Node.js or browser)
7588
8270
  */
7589
- private loadSoundData;
8271
+ private readResource;
7590
8272
  /**
7591
8273
  * Registers a sound with embedded data (File mode) - Low-level API
7592
8274
  *
@@ -7660,548 +8342,253 @@ declare class Core {
7660
8342
  */
7661
8343
  generateSoundLoadPackets(): Array<_utsp_types.SoundLoadPacket | _utsp_types.SoundExternalLoadPacket>;
7662
8344
  /**
7663
- * Loads the default web font (Courier New, 16px, monospace)
7664
- *
7665
- * This font is loaded automatically during engine initialization.
7666
- * It uses fontId 0 (reserved for the default font).
7667
- *
7668
- * @private
7669
- */
7670
- private loadDefaultWebFont;
7671
- /**
7672
- * Loads a web font into the registry
7673
- *
7674
- * Web fonts use the CSS system for rendering (fontFamily, fontSize, etc.)
7675
- * FontID 0 is reserved for the default font.
7676
- *
7677
- * @param font - WebFont instance to load
7678
- * @throws Error if fontId is already in use
8345
+ * Loads an image font from a PNG file path
7679
8346
  *
7680
- * @example
7681
- * ```typescript
7682
- * const customFont = new WebFont(1, {
7683
- * fontFamily: "Arial",
7684
- * fontSize: 20,
7685
- * fontWeight: "bold"
7686
- * });
7687
- * engine.loadWebFont(customFont);
7688
- * ```
7689
- */
7690
- loadWebFont(font: WebFont): void;
7691
- /**
7692
- * Gets a web font by its ID
8347
+ * Works identically on server (Node.js) and client (browser).
8348
+ * The PNG is loaded and registered with an auto-assigned ID.
7693
8349
  *
7694
- * @param fontId - Font ID (0-255)
7695
- * @returns The WebFont instance or null if not found
8350
+ * @param name - Human-readable name for the font (e.g., 'tileset', 'icons')
8351
+ * @param path - Path to the PNG atlas file
8352
+ * @param options - Font configuration options
8353
+ * @returns Promise resolving to the assigned font ID (0-255)
7696
8354
  *
7697
8355
  * @example
7698
8356
  * ```typescript
7699
- * const font = engine.getWebFont(1);
7700
- * if (font) {
7701
- * console.log(font.toCSS());
8357
+ * // In init() - same code works on server and client
8358
+ * async init(core: Core): Promise<void> {
8359
+ * await core.loadImageFont('tileset', './fonts/tileset.png', {
8360
+ * glyphWidth: 16,
8361
+ * glyphHeight: 16,
8362
+ * atlasBlocks: 4, // 1024 chars
8363
+ * });
7702
8364
  * }
7703
- * ```
7704
- */
7705
- getWebFont(fontId: number): WebFont | null;
7706
- /**
7707
- * Checks if a web font exists
7708
- *
7709
- * @param fontId - Font ID (0-255)
7710
- * @returns true if font exists
7711
8365
  *
7712
- * @example
7713
- * ```typescript
7714
- * if (engine.hasWebFont(1)) {
7715
- * console.log("Font 1 is loaded");
7716
- * }
8366
+ * // Later, use by name or ID
8367
+ * const id = core.getImageFontId('tileset');
7717
8368
  * ```
7718
8369
  */
7719
- hasWebFont(fontId: number): boolean;
8370
+ loadImageFont(name: string, path: string, options: ImageFontOptions): Promise<number>;
7720
8371
  /**
7721
- * Unloads a web font from the registry
7722
- *
7723
- * Note: Cannot unload the default font (fontId 0)
8372
+ * Loads multiple image fonts at once
7724
8373
  *
7725
- * @param fontId - Font ID to unload (1-255)
7726
- * @returns true if font was unloaded
7727
- * @throws Error if attempting to unload default font (fontId 0)
8374
+ * @param fonts - Object mapping font names to { path, options }
8375
+ * @returns Promise resolving to object mapping names to IDs
7728
8376
  *
7729
8377
  * @example
7730
8378
  * ```typescript
7731
- * const removed = engine.unloadWebFont(1);
7732
- * if (removed) {
7733
- * console.log("Font 1 unloaded");
8379
+ * async init(core: Core): Promise<void> {
8380
+ * await core.loadImageFonts({
8381
+ * tileset: {
8382
+ * path: './fonts/tileset.png',
8383
+ * options: { glyphWidth: 16, glyphHeight: 16, atlasBlocks: 4 }
8384
+ * },
8385
+ * icons: {
8386
+ * path: './fonts/icons.png',
8387
+ * options: { glyphWidth: 8, glyphHeight: 8, atlasBlocks: 1 }
8388
+ * }
8389
+ * });
7734
8390
  * }
7735
8391
  * ```
7736
8392
  */
7737
- unloadWebFont(fontId: number): boolean;
8393
+ loadImageFonts(fonts: Record<string, {
8394
+ path: string;
8395
+ options: ImageFontOptions;
8396
+ }>): Promise<Record<string, number>>;
7738
8397
  /**
7739
- * Clears all web fonts (except default font)
7740
- *
7741
- * @example
7742
- * ```typescript
7743
- * engine.clearWebFonts();
7744
- * console.log("All custom web fonts cleared");
7745
- * ```
8398
+ * Loads image data from path (isomorphic: Node.js or browser)
7746
8399
  */
7747
- clearWebFonts(): void;
8400
+ private loadImageData;
7748
8401
  /**
7749
- * Sets the active web font
7750
- *
7751
- * The active font is used by default for character rendering.
8402
+ * Gets the font ID for a named image font
7752
8403
  *
7753
- * @param fontId - Font ID to activate (0-255)
7754
- * @throws Error if font doesn't exist
8404
+ * @param name - Font name
8405
+ * @returns Font ID or undefined if not found
7755
8406
  *
7756
8407
  * @example
7757
8408
  * ```typescript
7758
- * engine.setActiveWebFont(1);
7759
- * console.log(`Active font: ${engine.getActiveWebFontId()}`);
8409
+ * const id = core.getImageFontId('tileset');
8410
+ * if (id !== undefined) {
8411
+ * console.log(`Tileset font ID: ${id}`);
8412
+ * }
7760
8413
  * ```
7761
8414
  */
7762
- setActiveWebFont(fontId: number): void;
8415
+ getImageFontId(name: string): number | undefined;
7763
8416
  /**
7764
- * Gets the active web font ID
8417
+ * Gets an image font by its name
7765
8418
  *
7766
- * @returns Active font ID (0-255)
8419
+ * @param name - Font name
8420
+ * @returns The ImageFont instance or null if not found
7767
8421
  *
7768
8422
  * @example
7769
8423
  * ```typescript
7770
- * const activeFontId = engine.getActiveWebFontId();
7771
- * console.log(`Current font: ${activeFontId}`);
8424
+ * const font = core.getImageFontByName('tileset');
8425
+ * if (font) {
8426
+ * console.log(`Max charCode: ${font.getMaxCharCode()}`);
8427
+ * }
7772
8428
  * ```
7773
8429
  */
7774
- getActiveWebFontId(): number;
8430
+ getImageFontByName(name: string): ImageFont | null;
7775
8431
  /**
7776
- * Gets the active web font
8432
+ * Registers a callback for image font changes
7777
8433
  *
7778
- * @returns The active WebFont instance
8434
+ * Called when an image font is loaded.
7779
8435
  *
7780
- * @example
7781
- * ```typescript
7782
- * const activeFont = engine.getActiveWebFont();
7783
- * console.log(activeFont.toCSS());
7784
- * ```
7785
- */
7786
- getActiveWebFont(): WebFont;
8436
+ * @param callback - Function called with the fontId
7787
8437
  /**
7788
- * Counts the number of loaded web fonts
7789
- *
7790
- * @returns Number of web fonts in memory
7791
- *
7792
- * @example
7793
- * ```typescript
7794
- * const count = engine.getWebFontCount();
7795
- * console.log(`${count} web fonts loaded`);
7796
- * ```
8438
+ * Register a callback for when a font structure is allocated
8439
+ * (Does not imply data is ready, just dimensions)
7797
8440
  */
7798
- getWebFontCount(): number;
8441
+ onFontAllocated(callback: () => void): void;
7799
8442
  /**
7800
- * Gets all loaded web font IDs
7801
- *
7802
- * @returns Array of fontIds (0-255)
7803
- *
7804
- * @example
7805
- * ```typescript
7806
- * const fontIds = engine.getWebFontIds();
7807
- * console.log(`Loaded fonts: ${fontIds.join(", ")}`);
7808
- * ```
8443
+ * Register a callback for when a font data block is added
7809
8444
  */
7810
- getWebFontIds(): number[];
8445
+ onFontBlockAdded(callback: (blockIndex: number) => void): void;
7811
8446
  /**
7812
- * Gets the web font registry
8447
+ * Register a callback for when an image font is changed (loaded or updated)
8448
+ * DEPRECATED: Use onFontAllocated/onFontBlockAdded for granular updates
7813
8449
  *
7814
- * @returns WebFontRegistry instance
8450
+ * @param callback Function to call when an image font changes
7815
8451
  *
7816
8452
  * @example
7817
8453
  * ```typescript
7818
- * const registry = engine.getWebFontRegistry();
7819
- * console.log(`Total fonts: ${registry.getFontCount()}`);
8454
+ * core.onImageFontChanged((fontId) => {
8455
+ * // Legacy support
8456
+ * });
7820
8457
  * ```
7821
8458
  */
7822
- getWebFontRegistry(): WebFontRegistry;
8459
+ onImageFontChanged(callback: (fontId: number) => void): void;
7823
8460
  /**
7824
- * Gets the bitmap font registry
8461
+ * Gets the image font registry (low-level API)
7825
8462
  *
7826
- * @returns BitmapFontRegistry instance
8463
+ * @returns The ImageFontRegistry instance
7827
8464
  *
7828
8465
  * @example
7829
8466
  * ```typescript
7830
- * const registry = engine.getBitmapFontRegistry();
7831
- * console.log(`Total fonts: ${registry.getFontCount()}`);
8467
+ * const registry = engine.getImageFontRegistry();
8468
+ * const font = registry.getFont(1);
7832
8469
  * ```
7833
8470
  */
7834
- getBitmapFontRegistry(): BitmapFontRegistry;
8471
+ getImageFontRegistry(): ImageFontRegistry;
7835
8472
  /**
7836
- * Loads a web font directly with its ID and configuration
8473
+ * Loads an image font (PNG atlas) by ID (low-level API)
7837
8474
  *
7838
- * Simplified method that creates and loads the font in one step.
8475
+ * Prefer using loadImageFont() with a name for simpler usage.
7839
8476
  *
7840
- * @param fontId - Unique font ID (0-255, 0 reserved for default font)
7841
- * @param config - Web font configuration
8477
+ * @param fontId - Unique font ID (0-255)
8478
+ * @param config - Image font configuration
7842
8479
  * @throws Error if fontId is already in use
7843
8480
  *
7844
8481
  * @example
7845
8482
  * ```typescript
7846
- * // Load a custom font
7847
- * engine.loadWebFontById(1, {
7848
- * fontFamily: "Arial",
7849
- * fontSize: 20,
7850
- * fontWeight: "bold"
7851
- * });
7852
- *
7853
- * // Load a monospace font
7854
- * engine.loadWebFontById(2, {
7855
- * fontFamily: "Consolas",
7856
- * fontSize: 16,
7857
- * charSpacing: 2
8483
+ * engine.loadImageFontById(1, {
8484
+ * glyphWidth: 16,
8485
+ * glyphHeight: 16,
8486
+ * atlasBlocks: 4,
8487
+ * imageData: pngBuffer
7858
8488
  * });
7859
8489
  * ```
7860
8490
  */
7861
- loadWebFontById(fontId: number, config: WebFontConfig): void;
8491
+ loadImageFontById(fontId: number, config: ImageFontConfig): void;
7862
8492
  /**
7863
- * Loads a bitmap font directly with its ID and configuration
7864
- *
7865
- * Simplified method that loads the bitmap font in one step.
8493
+ * Gets an image font by its ID
7866
8494
  *
7867
- * @param fontId - Unique font ID (0-255)
7868
- * @param config - Bitmap font configuration (dimensions + glyphs)
7869
- * @throws Error if fontId is already in use
8495
+ * @param fontId - Font ID (0-255)
8496
+ * @returns The ImageFont instance or null if not found
7870
8497
  *
7871
8498
  * @example
7872
8499
  * ```typescript
7873
- * import { createASCII8x8FontLoad } from "utsp-core";
7874
- *
7875
- * // Load the ASCII 8×8 font
7876
- * const fontLoad = createASCII8x8FontLoad(1);
7877
- * engine.loadBitmapFontById(1, fontLoad.fontConfig);
7878
- *
7879
- * // Load a custom bitmap font
7880
- * engine.loadBitmapFontById(10, {
7881
- * charWidth: 16,
7882
- * charHeight: 16,
7883
- * glyphs: new Map([
7884
- * [65, new Uint8Array([...])], // 'A'
7885
- * [66, new Uint8Array([...])], // 'B'
7886
- * ])
7887
- * });
8500
+ * const font = engine.getImageFont(1);
8501
+ * if (font) {
8502
+ * console.log(`Atlas blocks: ${font.getAtlasBlocks()}`);
8503
+ * console.log(`Max charCode: ${font.getMaxCharCode()}`);
8504
+ * }
7888
8505
  * ```
7889
8506
  */
7890
- loadBitmapFontById(fontId: number, config: BitmapFontConfig): void;
8507
+ getImageFont(fontId: number): ImageFont | null;
7891
8508
  /**
7892
- * Gets a bitmap font by its ID
8509
+ * Checks if an image font exists by ID
7893
8510
  *
7894
8511
  * @param fontId - Font ID (0-255)
7895
- * @returns The BitmapFont instance or null if not found
8512
+ * @returns true if font exists
7896
8513
  *
7897
8514
  * @example
7898
8515
  * ```typescript
7899
- * const font = engine.getBitmapFont(1);
7900
- * if (font) {
7901
- * console.log(`Font dimensions: ${font.getCharWidth()}×${font.getCharHeight()}`);
7902
- * console.log(`Glyphs: ${font.getGlyphCount()}`);
8516
+ * if (engine.hasImageFont(1)) {
8517
+ * console.log("ImageFont 1 is loaded");
7903
8518
  * }
7904
8519
  * ```
7905
8520
  */
7906
- getBitmapFont(fontId: number): BitmapFont | null;
8521
+ hasImageFont(fontId: number): boolean;
7907
8522
  /**
7908
- * Checks if a bitmap font exists
8523
+ * Checks if an image font exists by name
7909
8524
  *
7910
- * @param fontId - Font ID (0-255)
8525
+ * @param name - Font name
7911
8526
  * @returns true if font exists
7912
8527
  *
7913
8528
  * @example
7914
8529
  * ```typescript
7915
- * if (engine.hasBitmapFont(1)) {
7916
- * console.log("Font 1 is loaded");
8530
+ * if (engine.hasImageFontByName('tileset')) {
8531
+ * console.log("Tileset font is loaded");
7917
8532
  * }
7918
8533
  * ```
7919
8534
  */
7920
- hasBitmapFont(fontId: number): boolean;
8535
+ hasImageFontByName(name: string): boolean;
7921
8536
  /**
7922
- * Unloads a bitmap font from the registry
8537
+ * Unloads an image font from the registry by ID
7923
8538
  *
7924
8539
  * @param fontId - Font ID to unload (0-255)
7925
8540
  * @returns true if font was unloaded
7926
8541
  *
7927
8542
  * @example
7928
8543
  * ```typescript
7929
- * const removed = engine.unloadBitmapFont(1);
8544
+ * const removed = engine.unloadImageFont(1);
7930
8545
  * if (removed) {
7931
- * console.log("Font 1 unloaded");
8546
+ * console.log("ImageFont 1 unloaded");
7932
8547
  * }
7933
8548
  * ```
7934
8549
  */
7935
- unloadBitmapFont(fontId: number): boolean;
8550
+ unloadImageFont(fontId: number): boolean;
7936
8551
  /**
7937
- * Clears all bitmap fonts
8552
+ * Unloads an image font from the registry by name
8553
+ *
8554
+ * @param name - Font name to unload
8555
+ * @returns true if font was unloaded
7938
8556
  *
7939
8557
  * @example
7940
8558
  * ```typescript
7941
- * engine.clearBitmapFonts();
7942
- * console.log("All bitmap fonts cleared");
8559
+ * const removed = engine.unloadImageFontByName('tileset');
8560
+ * if (removed) {
8561
+ * console.log("Tileset font unloaded");
8562
+ * }
7943
8563
  * ```
7944
8564
  */
7945
- clearBitmapFonts(): void;
8565
+ unloadImageFontByName(name: string): boolean;
7946
8566
  /**
7947
- * Counts the number of loaded bitmap fonts
7948
- *
7949
- * @returns Number of bitmap fonts in memory
8567
+ * Clears all image fonts
7950
8568
  *
7951
8569
  * @example
7952
8570
  * ```typescript
7953
- * const count = engine.getBitmapFontCount();
7954
- * console.log(`${count} bitmap fonts loaded`);
8571
+ * engine.clearImageFonts();
8572
+ * console.log("All image fonts cleared");
7955
8573
  * ```
7956
8574
  */
7957
- getBitmapFontCount(): number;
8575
+ clearImageFonts(): void;
7958
8576
  /**
7959
- * Gets all loaded bitmap font IDs
8577
+ * Counts the number of loaded image fonts
7960
8578
  *
7961
- * @returns Array of fontIds (0-255)
8579
+ * @returns Number of image fonts in memory
7962
8580
  *
7963
8581
  * @example
7964
8582
  * ```typescript
7965
- * const fontIds = engine.getBitmapFontIds();
7966
- * console.log(`Loaded bitmap fonts: ${fontIds.join(", ")}`);
8583
+ * const count = engine.getImageFontCount();
8584
+ * console.log(`${count} image fonts loaded`);
7967
8585
  * ```
7968
8586
  */
7969
- getBitmapFontIds(): number[];
8587
+ getImageFontCount(): number;
7970
8588
  /**
7971
- * Loads an image font from a PNG file path
8589
+ * Gets all loaded image font IDs
7972
8590
  *
7973
- * Works identically on server (Node.js) and client (browser).
7974
- * The PNG is loaded and registered with an auto-assigned ID.
7975
- *
7976
- * @param name - Human-readable name for the font (e.g., 'tileset', 'icons')
7977
- * @param path - Path to the PNG atlas file
7978
- * @param options - Font configuration options
7979
- * @returns Promise resolving to the assigned font ID (0-255)
7980
- *
7981
- * @example
7982
- * ```typescript
7983
- * // In init() - same code works on server and client
7984
- * async init(core: Core): Promise<void> {
7985
- * await core.loadImageFont('tileset', './fonts/tileset.png', {
7986
- * glyphWidth: 16,
7987
- * glyphHeight: 16,
7988
- * atlasBlocks: 4, // 1024 chars
7989
- * });
7990
- * }
7991
- *
7992
- * // Later, use by name or ID
7993
- * const id = core.getImageFontId('tileset');
7994
- * ```
7995
- */
7996
- loadImageFont(name: string, path: string, options: ImageFontOptions): Promise<number>;
7997
- /**
7998
- * Loads multiple image fonts at once
7999
- *
8000
- * @param fonts - Object mapping font names to { path, options }
8001
- * @returns Promise resolving to object mapping names to IDs
8002
- *
8003
- * @example
8004
- * ```typescript
8005
- * async init(core: Core): Promise<void> {
8006
- * await core.loadImageFonts({
8007
- * tileset: {
8008
- * path: './fonts/tileset.png',
8009
- * options: { glyphWidth: 16, glyphHeight: 16, atlasBlocks: 4 }
8010
- * },
8011
- * icons: {
8012
- * path: './fonts/icons.png',
8013
- * options: { glyphWidth: 8, glyphHeight: 8, atlasBlocks: 1 }
8014
- * }
8015
- * });
8016
- * }
8017
- * ```
8018
- */
8019
- loadImageFonts(fonts: Record<string, {
8020
- path: string;
8021
- options: ImageFontOptions;
8022
- }>): Promise<Record<string, number>>;
8023
- /**
8024
- * Loads image data from path (isomorphic: Node.js or browser)
8025
- */
8026
- private loadImageData;
8027
- /**
8028
- * Gets the font ID for a named image font
8029
- *
8030
- * @param name - Font name
8031
- * @returns Font ID or undefined if not found
8032
- *
8033
- * @example
8034
- * ```typescript
8035
- * const id = core.getImageFontId('tileset');
8036
- * if (id !== undefined) {
8037
- * console.log(`Tileset font ID: ${id}`);
8038
- * }
8039
- * ```
8040
- */
8041
- getImageFontId(name: string): number | undefined;
8042
- /**
8043
- * Gets an image font by its name
8044
- *
8045
- * @param name - Font name
8046
- * @returns The ImageFont instance or null if not found
8047
- *
8048
- * @example
8049
- * ```typescript
8050
- * const font = core.getImageFontByName('tileset');
8051
- * if (font) {
8052
- * console.log(`Max charCode: ${font.getMaxCharCode()}`);
8053
- * }
8054
- * ```
8055
- */
8056
- getImageFontByName(name: string): ImageFont | null;
8057
- /**
8058
- * Registers a callback for image font changes
8059
- *
8060
- * Called when an image font is loaded.
8061
- *
8062
- * @param callback - Function called with the fontId
8063
- *
8064
- * @example
8065
- * ```typescript
8066
- * core.onImageFontChanged((fontId) => {
8067
- * const font = core.getImageFont(fontId);
8068
- * if (font) renderer.setImageFont(font.getImageData(), ...);
8069
- * });
8070
- * ```
8071
- */
8072
- onImageFontChanged(callback: (fontId: number) => void): void;
8073
- /**
8074
- * Gets the image font registry (low-level API)
8075
- *
8076
- * @returns The ImageFontRegistry instance
8077
- *
8078
- * @example
8079
- * ```typescript
8080
- * const registry = engine.getImageFontRegistry();
8081
- * const font = registry.getFont(1);
8082
- * ```
8083
- */
8084
- getImageFontRegistry(): ImageFontRegistry;
8085
- /**
8086
- * Loads an image font (PNG atlas) by ID (low-level API)
8087
- *
8088
- * Prefer using loadImageFont() with a name for simpler usage.
8089
- *
8090
- * @param fontId - Unique font ID (0-255)
8091
- * @param config - Image font configuration
8092
- * @throws Error if fontId is already in use
8093
- *
8094
- * @example
8095
- * ```typescript
8096
- * engine.loadImageFontById(1, {
8097
- * glyphWidth: 16,
8098
- * glyphHeight: 16,
8099
- * atlasBlocks: 4,
8100
- * imageData: pngBuffer
8101
- * });
8102
- * ```
8103
- */
8104
- loadImageFontById(fontId: number, config: ImageFontConfig): void;
8105
- /**
8106
- * Gets an image font by its ID
8107
- *
8108
- * @param fontId - Font ID (0-255)
8109
- * @returns The ImageFont instance or null if not found
8110
- *
8111
- * @example
8112
- * ```typescript
8113
- * const font = engine.getImageFont(1);
8114
- * if (font) {
8115
- * console.log(`Atlas blocks: ${font.getAtlasBlocks()}`);
8116
- * console.log(`Max charCode: ${font.getMaxCharCode()}`);
8117
- * }
8118
- * ```
8119
- */
8120
- getImageFont(fontId: number): ImageFont | null;
8121
- /**
8122
- * Checks if an image font exists by ID
8123
- *
8124
- * @param fontId - Font ID (0-255)
8125
- * @returns true if font exists
8126
- *
8127
- * @example
8128
- * ```typescript
8129
- * if (engine.hasImageFont(1)) {
8130
- * console.log("ImageFont 1 is loaded");
8131
- * }
8132
- * ```
8133
- */
8134
- hasImageFont(fontId: number): boolean;
8135
- /**
8136
- * Checks if an image font exists by name
8137
- *
8138
- * @param name - Font name
8139
- * @returns true if font exists
8140
- *
8141
- * @example
8142
- * ```typescript
8143
- * if (engine.hasImageFontByName('tileset')) {
8144
- * console.log("Tileset font is loaded");
8145
- * }
8146
- * ```
8147
- */
8148
- hasImageFontByName(name: string): boolean;
8149
- /**
8150
- * Unloads an image font from the registry by ID
8151
- *
8152
- * @param fontId - Font ID to unload (0-255)
8153
- * @returns true if font was unloaded
8154
- *
8155
- * @example
8156
- * ```typescript
8157
- * const removed = engine.unloadImageFont(1);
8158
- * if (removed) {
8159
- * console.log("ImageFont 1 unloaded");
8160
- * }
8161
- * ```
8162
- */
8163
- unloadImageFont(fontId: number): boolean;
8164
- /**
8165
- * Unloads an image font from the registry by name
8166
- *
8167
- * @param name - Font name to unload
8168
- * @returns true if font was unloaded
8169
- *
8170
- * @example
8171
- * ```typescript
8172
- * const removed = engine.unloadImageFontByName('tileset');
8173
- * if (removed) {
8174
- * console.log("Tileset font unloaded");
8175
- * }
8176
- * ```
8177
- */
8178
- unloadImageFontByName(name: string): boolean;
8179
- /**
8180
- * Clears all image fonts
8181
- *
8182
- * @example
8183
- * ```typescript
8184
- * engine.clearImageFonts();
8185
- * console.log("All image fonts cleared");
8186
- * ```
8187
- */
8188
- clearImageFonts(): void;
8189
- /**
8190
- * Counts the number of loaded image fonts
8191
- *
8192
- * @returns Number of image fonts in memory
8193
- *
8194
- * @example
8195
- * ```typescript
8196
- * const count = engine.getImageFontCount();
8197
- * console.log(`${count} image fonts loaded`);
8198
- * ```
8199
- */
8200
- getImageFontCount(): number;
8201
- /**
8202
- * Gets all loaded image font IDs
8203
- *
8204
- * @returns Array of fontIds (0-255)
8591
+ * @returns Array of fontIds (0-255)
8205
8592
  *
8206
8593
  * @example
8207
8594
  * ```typescript
@@ -8225,28 +8612,27 @@ declare class Core {
8225
8612
  }
8226
8613
 
8227
8614
  /**
8228
- * ASCII 8×8 Bitmap Font (Extended - IBM CP437)
8229
- * Complete character set including:
8615
+ * ASCII 8×8 Bitmap Font (Complete IBM CP437)
8616
+ * Complete character set (0-255) including:
8617
+ * - Control characters with graphical representations (0-31)
8230
8618
  * - ASCII printable characters (32-126)
8231
- * - Extended ASCII box drawing and blocks (128-255)
8619
+ * - Extended ASCII: accented letters, symbols (128-255)
8620
+ * - Box drawing characters (single and double lines)
8621
+ * - Block characters and shading
8622
+ * - Greek letters and mathematical symbols
8232
8623
  *
8233
8624
  * Each character is 8 pixels wide by 8 pixels tall
8234
8625
  * 1 bit per pixel, packed into 8 bytes per character
8235
- *
8236
- * Box drawing characters support:
8237
- * - Single line borders: ┌ ─ ┐ │ └ ┘ ├ ┤ ┬ ┴ ┼
8238
- * - Double line borders: ╔ ═ ╗ ║ ╚ ╝ ╠ ╣ ╦ ╩ ╬
8239
- * - Block characters: █ ▓ ▒ ░ ▀ ▄ ▌ ▐
8240
8626
  */
8241
8627
  /**
8242
8628
  * 8×8 bitmap font data
8243
- * Key: ASCII/Extended ASCII character code (32-126, 176-223)
8629
+ * Key: CP437 character code (0-255)
8244
8630
  * Value: 8 bytes representing the character bitmap
8245
8631
  */
8246
8632
  declare const ASCII_8X8_FONT: Map<number, Uint8Array>;
8247
8633
  /**
8248
8634
  * Get the bitmap data for a specific ASCII character
8249
- * @param charCode ASCII character code (32-126) or Extended ASCII (176-223)
8635
+ * @param charCode CP437 character code (0-255)
8250
8636
  * @returns 8-byte bitmap or undefined if character not found
8251
8637
  */
8252
8638
  declare function getCharBitmap(charCode: number): Uint8Array | undefined;
@@ -8258,32 +8644,9 @@ declare function getCharBitmap(charCode: number): Uint8Array | undefined;
8258
8644
  declare function hasChar(charCode: number): boolean;
8259
8645
  /**
8260
8646
  * Get all available character codes
8261
- * @returns Array of ASCII codes (32-126) and Extended ASCII (176-223)
8647
+ * @returns Array of CP437 character codes (0-255)
8262
8648
  */
8263
8649
  declare function getAllCharCodes(): number[];
8264
- /**
8265
- * Create a BitmapFontLoad packet for the complete ASCII font
8266
- * @param fontId Font identifier (0-255)
8267
- * @returns BitmapFontLoad object ready for encoding
8268
- */
8269
- declare function createASCII8x8FontLoad(fontId: number): {
8270
- loadType: number;
8271
- fontId: number;
8272
- width: number;
8273
- height: number;
8274
- cellWidth: number;
8275
- cellHeight: number;
8276
- characters: Array<{
8277
- charCode: number;
8278
- bitmap: Uint8Array;
8279
- }>;
8280
- };
8281
- /**
8282
- * Get BitmapFontConfig for the complete ASCII 8×8 font
8283
- * This is a convenience function to get the config directly
8284
- * for use with UTSPCore.loadBitmapFontById()
8285
- * @returns BitmapFontConfig ready to use
8286
- */
8287
8650
  declare function getASCII8x8FontConfig(): {
8288
8651
  charWidth: number;
8289
8652
  charHeight: number;
@@ -8610,60 +8973,114 @@ interface ColorOptions {
8610
8973
  */
8611
8974
  declare class OrderBuilder {
8612
8975
  /**
8613
- * Convert string or number to character code
8614
- * @param char - Either a string (first character used) or a number (0-65535)
8615
- * @returns Character code (0-65535)
8976
+ * Converts a string or number to a char code.
8977
+ *
8978
+ * @param char - String (first character used) or numeric char code (0-65535).
8979
+ * @returns Char code (0-65535).
8980
+ *
8616
8981
  * @example
8617
- * toCharCode('#') // → 0x23 (35)
8618
- * toCharCode(0x23) // → 0x23 (35)
8619
- * toCharCode('ABC') // → 0x41 (65, first char only)
8620
- * toCharCode(256) // → 256 (preserved for 16-bit layers)
8982
+ * OrderBuilder.toCharCode('#') // → 35
8983
+ * OrderBuilder.toCharCode(35) // → 35
8984
+ * OrderBuilder.toCharCode('ABC') // → 65 (first char only)
8985
+ * OrderBuilder.toCharCode(256) // → 256 (preserved for 16-bit layers)
8621
8986
  */
8622
8987
  static toCharCode(char: string | number): number;
8623
8988
  /**
8624
- * Remove common leading whitespace from multiline strings (dedent)
8625
- * Useful for template literals that are indented in source code
8626
- * @param text - Multiline text to dedent
8627
- * @returns Dedented text
8989
+ * Removes common leading whitespace from multiline strings (dedent).
8990
+ * Useful for template literals that are indented in source code.
8991
+ *
8992
+ * @param text - Multiline text to dedent.
8993
+ * @returns Dedented text.
8994
+ *
8628
8995
  * @example
8629
8996
  * const text = `
8630
8997
  * Hello
8631
8998
  * World
8632
8999
  * `;
8633
- * dedent(text) // → "Hello\nWorld"
9000
+ * OrderBuilder.dedent(text); // → "Hello\nWorld"
8634
9001
  */
8635
9002
  static dedent(text: string): string;
8636
9003
  /**
8637
- * 0x01 - Char: Single character at a position
8638
- * @param char - Character as string ('#') or charCode (0x23)
9004
+ * Encodes a string into CP437 character codes packed into a string.
9005
+ * This ensures that strings with Unicode characters (e.g. '', 'é') are
9006
+ * converted to their CP437 byte values (e.g. 176, 130) before being stored.
9007
+ *
9008
+ * @param text - The input string (possibly containing Unicode)
9009
+ * @returns A string where each character is a CP437 byte value (0-255)
9010
+ */
9011
+ static encodeString(text: string): string;
9012
+ /**
9013
+ * Creates a single character order at a position.
9014
+ *
9015
+ * @param x - X position (cell).
9016
+ * @param y - Y position (cell).
9017
+ * @param char - Character as string ('#') or numeric code (35).
9018
+ * @param fgColor - Foreground color (0-255).
9019
+ * @param bgColor - Background color (0-255).
9020
+ * @returns Char order.
9021
+ *
9022
+ * @example
9023
+ * OrderBuilder.char(10, 20, '#', 15, 0);
8639
9024
  */
8640
9025
  static char(x: number, y: number, char: string | number, fgColor?: number, bgColor?: number): CharOrder;
8641
9026
  /**
8642
- * 0x02 - Text: Horizontal character string
9027
+ * Creates a single-line text order.
9028
+ *
9029
+ * @param x - X position (cell).
9030
+ * @param y - Y position (cell).
9031
+ * @param text - Text to draw.
9032
+ * @param fgColor - Foreground color (0-255).
9033
+ * @param bgColor - Background color (0-255).
9034
+ * @returns Text order.
9035
+ *
9036
+ * @example
9037
+ * OrderBuilder.text(2, 4, 'Hello', 15, 0);
8643
9038
  */
8644
9039
  static text(x: number, y: number, text: string, fgColor?: number, bgColor?: number): TextOrder;
8645
9040
  /**
8646
- * 0x17 - TextMultiline: Multiple lines of text (\n for line breaks)
8647
- * Automatically removes common indentation (dedent) for template literals
9041
+ * Creates a multi-line text order (\n for line breaks).
9042
+ * Automatically dedents template literals.
9043
+ *
9044
+ * @param x - X position (cell).
9045
+ * @param y - Y position (cell).
9046
+ * @param text - Text content (can include \n).
9047
+ * @param fgColor - Foreground color (0-255).
9048
+ * @param bgColor - Background color (0-255).
9049
+ * @returns Multiline text order.
9050
+ *
8648
9051
  * @example With explicit \n
8649
- * OrderBuilder.textMultiline(10, 5, 'Hello\nWorld\n!', 15, 0)
9052
+ * OrderBuilder.textMultiline(10, 5, 'Hello\nWorld\n!', 15, 0);
8650
9053
  *
8651
9054
  * @example With template literal (auto-dedented)
8652
9055
  * OrderBuilder.textMultiline(10, 5, `
8653
9056
  * Score: ${score}
8654
9057
  * Lives: ${lives}
8655
9058
  * Level: ${level}
8656
- * `, 15, 0)
9059
+ * `, 15, 0);
8657
9060
  */
8658
9061
  static textMultiline(x: number, y: number, text: string, fgColor?: number, bgColor?: number): TextMultilineOrder;
8659
9062
  /**
8660
- * 0x03 - SubFrame: Rectangular area with uniform colors
8661
- * @param frame - Array of characters as strings or numbers
9063
+ * Creates a rectangular frame with uniform colors.
9064
+ *
9065
+ * @param x - X position (cell).
9066
+ * @param y - Y position (cell).
9067
+ * @param width - Width in cells.
9068
+ * @param height - Height in cells.
9069
+ * @param frame - Array of characters as strings or numbers.
9070
+ * @param fgColor - Foreground color (0-255).
9071
+ * @param bgColor - Background color (0-255).
9072
+ * @returns Sub-frame order.
8662
9073
  */
8663
9074
  static subFrame(x: number, y: number, width: number, height: number, frame: (string | number)[], fgColor?: number, bgColor?: number): SubFrameOrder;
8664
9075
  /**
8665
- * 0x04 - SubFrameMultiColor: Rectangular area with per-cell colors
8666
- * @param frame - Array of cells where charCode can be string or number
9076
+ * Creates a rectangular frame with per-cell colors.
9077
+ *
9078
+ * @param x - X position (cell).
9079
+ * @param y - Y position (cell).
9080
+ * @param width - Width in cells.
9081
+ * @param height - Height in cells.
9082
+ * @param frame - Array of cells where `charCode` can be string or number.
9083
+ * @returns Sub-frame order (multi-color).
8667
9084
  */
8668
9085
  static subFrameMultiColor(x: number, y: number, width: number, height: number, frame: Array<{
8669
9086
  charCode: string | number;
@@ -8671,13 +9088,19 @@ declare class OrderBuilder {
8671
9088
  fgColorCode: number;
8672
9089
  }>): SubFrameMultiColorOrder;
8673
9090
  /**
8674
- * 0x05 - FullFrame: Entire layer (256×256) with uniform colors
8675
- * @param frame - Array of characters as strings or numbers
9091
+ * Creates a full-frame fill for the entire layer (256×256).
9092
+ *
9093
+ * @param frame - Array of characters as strings or numbers.
9094
+ * @param fgColor - Foreground color (0-255).
9095
+ * @param bgColor - Background color (0-255).
9096
+ * @returns Full-frame order.
8676
9097
  */
8677
9098
  static fullFrame(frame: (string | number)[], fgColor?: number, bgColor?: number): FullFrameOrder;
8678
9099
  /**
8679
- * 0x06 - FullFrameMultiColor: Entire layer (256×256) with per-cell colors
8680
- * @param frame - Array of cells where charCode can be string or number
9100
+ * Creates a full-frame fill with per-cell colors (256×256).
9101
+ *
9102
+ * @param frame - Array of cells where `charCode` can be string or number.
9103
+ * @returns Full-frame order (multi-color).
8681
9104
  */
8682
9105
  static fullFrameMultiColor(frame: Array<{
8683
9106
  charCode: string | number;
@@ -8685,23 +9108,52 @@ declare class OrderBuilder {
8685
9108
  fgColorCode: number;
8686
9109
  }>): FullFrameMultiColorOrder;
8687
9110
  /**
8688
- * 0x07 - Sprite: Single-color sprite at a position
9111
+ * Creates a single-color sprite order at a position.
9112
+ *
9113
+ * @param x - X position (cell).
9114
+ * @param y - Y position (cell).
9115
+ * @param spriteIndex - Sprite index in the registry.
9116
+ * @param fgColor - Foreground color (0-255).
9117
+ * @param bgColor - Background color (0-255).
9118
+ * @returns Sprite order.
8689
9119
  */
8690
9120
  static sprite(x: number, y: number, spriteIndex: number, fgColor?: number, bgColor?: number): SpriteOrder;
8691
9121
  /**
8692
- * 0x08 - SpriteMultiColor: Multi-color sprite at a position
9122
+ * Creates a multi-color sprite order at a position.
9123
+ *
9124
+ * @param x - X position (cell).
9125
+ * @param y - Y position (cell).
9126
+ * @param spriteIndex - Sprite index in the registry.
9127
+ * @returns Multi-color sprite order.
8693
9128
  */
8694
9129
  static spriteMultiColor(x: number, y: number, spriteIndex: number): SpriteMultiColorOrder;
8695
9130
  /**
8696
- * 0x09 - ColorMap: Applies colors without changing characters
9131
+ * Applies colors without changing characters.
9132
+ *
9133
+ * @param x - X position (cell).
9134
+ * @param y - Y position (cell).
9135
+ * @param width - Width in cells.
9136
+ * @param height - Height in cells.
9137
+ * @param colorData - Array of fg/bg colors per cell.
9138
+ * @returns Color map order.
8697
9139
  */
8698
9140
  static colorMap(x: number, y: number, width: number, height: number, colorData: Array<{
8699
9141
  fgColorCode: number;
8700
9142
  bgColorCode: number;
8701
9143
  }>): ColorMapOrder;
8702
9144
  /**
8703
- * 0x0A - Rectangle Shape
8704
- * @param options.charCode - Character as string ('█') or charCode (0x2588)
9145
+ * Creates a rectangle shape order.
9146
+ *
9147
+ * @param x - X position (cell).
9148
+ * @param y - Y position (cell).
9149
+ * @param width - Width in cells.
9150
+ * @param height - Height in cells.
9151
+ * @param options - Shape options.
9152
+ * @param options.charCode - Character as string ('█') or numeric code (9608).
9153
+ * @param options.bgColor - Background color (0-255).
9154
+ * @param options.fgColor - Foreground color (0-255).
9155
+ * @param options.filled - Fill shape (default: true).
9156
+ * @returns Shape order.
8705
9157
  */
8706
9158
  static rectangle(x: number, y: number, width: number, height: number, options?: {
8707
9159
  charCode?: string | number;
@@ -8710,8 +9162,17 @@ declare class OrderBuilder {
8710
9162
  filled?: boolean;
8711
9163
  }): ShapeOrder;
8712
9164
  /**
8713
- * 0x0A - Circle Shape
8714
- * @param options.charCode - Character as string ('█') or charCode (0x2588)
9165
+ * Creates a circle shape order.
9166
+ *
9167
+ * @param centerX - Center X position (cell).
9168
+ * @param centerY - Center Y position (cell).
9169
+ * @param radius - Radius in cells.
9170
+ * @param options - Shape options.
9171
+ * @param options.charCode - Character as string ('█') or numeric code (9608).
9172
+ * @param options.bgColor - Background color (0-255).
9173
+ * @param options.fgColor - Foreground color (0-255).
9174
+ * @param options.filled - Fill shape (default: true).
9175
+ * @returns Shape order.
8715
9176
  */
8716
9177
  static circle(centerX: number, centerY: number, radius: number, options?: {
8717
9178
  charCode?: string | number;
@@ -8720,8 +9181,17 @@ declare class OrderBuilder {
8720
9181
  filled?: boolean;
8721
9182
  }): ShapeOrder;
8722
9183
  /**
8723
- * 0x0A - Line Shape
8724
- * @param options.charCode - Character as string ('█') or charCode (0x2588)
9184
+ * Creates a line shape order.
9185
+ *
9186
+ * @param x1 - Start X position (cell).
9187
+ * @param y1 - Start Y position (cell).
9188
+ * @param x2 - End X position (cell).
9189
+ * @param y2 - End Y position (cell).
9190
+ * @param options - Shape options.
9191
+ * @param options.charCode - Character as string ('█') or numeric code (9608).
9192
+ * @param options.bgColor - Background color (0-255).
9193
+ * @param options.fgColor - Foreground color (0-255).
9194
+ * @returns Shape order.
8725
9195
  */
8726
9196
  static line(x1: number, y1: number, x2: number, y2: number, options?: {
8727
9197
  charCode?: string | number;
@@ -8729,8 +9199,18 @@ declare class OrderBuilder {
8729
9199
  fgColor?: number;
8730
9200
  }): ShapeOrder;
8731
9201
  /**
8732
- * 0x0A - Ellipse Shape
8733
- * @param options.charCode - Character as string ('█') or charCode (0x2588)
9202
+ * Creates an ellipse shape order.
9203
+ *
9204
+ * @param centerX - Center X position (cell).
9205
+ * @param centerY - Center Y position (cell).
9206
+ * @param radiusX - Radius on X axis (cells).
9207
+ * @param radiusY - Radius on Y axis (cells).
9208
+ * @param options - Shape options.
9209
+ * @param options.charCode - Character as string ('█') or numeric code (9608).
9210
+ * @param options.bgColor - Background color (0-255).
9211
+ * @param options.fgColor - Foreground color (0-255).
9212
+ * @param options.filled - Fill shape (default: true).
9213
+ * @returns Shape order.
8734
9214
  */
8735
9215
  static ellipse(centerX: number, centerY: number, radiusX: number, radiusY: number, options?: {
8736
9216
  charCode?: string | number;
@@ -8739,8 +9219,20 @@ declare class OrderBuilder {
8739
9219
  filled?: boolean;
8740
9220
  }): ShapeOrder;
8741
9221
  /**
8742
- * 0x0A - Triangle Shape
8743
- * @param options.charCode - Character as string ('█') or charCode (0x2588)
9222
+ * Creates a triangle shape order.
9223
+ *
9224
+ * @param x1 - First point X (cell).
9225
+ * @param y1 - First point Y (cell).
9226
+ * @param x2 - Second point X (cell).
9227
+ * @param y2 - Second point Y (cell).
9228
+ * @param x3 - Third point X (cell).
9229
+ * @param y3 - Third point Y (cell).
9230
+ * @param options - Shape options.
9231
+ * @param options.charCode - Character as string ('█') or numeric code (9608).
9232
+ * @param options.bgColor - Background color (0-255).
9233
+ * @param options.fgColor - Foreground color (0-255).
9234
+ * @param options.filled - Fill shape (default: true).
9235
+ * @returns Shape order.
8744
9236
  */
8745
9237
  static triangle(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, options?: {
8746
9238
  charCode?: string | number;
@@ -8749,16 +9241,23 @@ declare class OrderBuilder {
8749
9241
  filled?: boolean;
8750
9242
  }): ShapeOrder;
8751
9243
  /**
8752
- * 0x0B - DotCloud: Same character at multiple positions
8753
- * @param char - Character as string ('#') or charCode (0x23)
9244
+ * Creates a dot cloud with the same character at multiple positions.
9245
+ *
9246
+ * @param positions - Array of positions.
9247
+ * @param char - Character as string ('#') or numeric code (35).
9248
+ * @param fgColor - Foreground color (0-255).
9249
+ * @param bgColor - Background color (0-255).
9250
+ * @returns Dot cloud order.
8754
9251
  */
8755
9252
  static dotCloud(positions: Array<{
8756
9253
  posX: number;
8757
9254
  posY: number;
8758
9255
  }>, char: string | number, fgColor?: number, bgColor?: number): DotCloudOrder;
8759
9256
  /**
8760
- * 0x0C - DotCloudMultiColor: Different characters at multiple positions
8761
- * @param dots - Array where charCode can be string or number
9257
+ * Creates a multi-color dot cloud (per-dot colors and characters).
9258
+ *
9259
+ * @param dots - Array where `charCode` can be string or number.
9260
+ * @returns Dot cloud order (multi-color).
8762
9261
  */
8763
9262
  static dotCloudMultiColor(dots: Array<{
8764
9263
  posX: number;
@@ -8768,25 +9267,41 @@ declare class OrderBuilder {
8768
9267
  fgColorCode: number;
8769
9268
  }>): DotCloudMultiColorOrder;
8770
9269
  /**
8771
- * 0x11 - Bitmask: Bitpacked presence/absence mask with uniform character
8772
- * Perfect for ore veins, destructible terrain, collision maps, fog of war
8773
- * @param mask - Flat array of booleans (row-major order: sizeX × sizeY)
8774
- * @param char - Character as string ('#') or charCode (0x23)
8775
- * @param override - true: clear absences (transparent), false: preserve existing cells
9270
+ * Creates a bitmask order with a uniform character.
9271
+ * Useful for ore veins, destructible terrain, collision maps, or fog of war.
9272
+ *
9273
+ * @param x - X position (cell).
9274
+ * @param y - Y position (cell).
9275
+ * @param width - Width in cells.
9276
+ * @param height - Height in cells.
9277
+ * @param mask - Flat array of booleans (row-major order: sizeX × sizeY).
9278
+ * @param char - Character as string ('#') or numeric code (35).
9279
+ * @param fgColor - Foreground color (0-255).
9280
+ * @param bgColor - Background color (0-255).
9281
+ * @param override - true: clear absences (transparent), false: preserve existing cells.
9282
+ * @returns Bitmask order.
9283
+ *
8776
9284
  * @example Create a 3×3 cross pattern
8777
9285
  * OrderBuilder.bitmask(10, 10, 3, 3, [
8778
9286
  * false, true, false,
8779
9287
  * true, true, true,
8780
9288
  * false, true, false
8781
- * ], '#', 15, 0, false)
9289
+ * ], '#', 15, 0, false);
8782
9290
  */
8783
9291
  static bitmask(x: number, y: number, width: number, height: number, mask: boolean[], char: string | number, fgColor?: number, bgColor?: number, override?: boolean): BitmaskOrder;
8784
9292
  /**
8785
- * 0x12 - Bitmask4: 2-bit packed mask with 3 visual variants
8786
- * @param mask - Flat array of values 0-3 (row-major order: sizeX × sizeY)
8787
- * 0 = absence, 1-3 = variant index
8788
- * @param variants - Array of up to 3 variants { char, fgColor, bgColor } for values 1, 2, 3
8789
- * @param override - true: clear absences (transparent), false: preserve existing cells
9293
+ * Creates a bitmask order with 3 visual variants (values 1..3).
9294
+ *
9295
+ * @param x - X position (cell).
9296
+ * @param y - Y position (cell).
9297
+ * @param width - Width in cells.
9298
+ * @param height - Height in cells.
9299
+ * @param mask - Flat array of values 0-3 (row-major order: sizeX × sizeY).
9300
+ * 0 = absence, 1-3 = variant index.
9301
+ * @param variants - Array of up to 3 variants { char, fgColor, bgColor } for values 1..3.
9302
+ * @param override - true: clear absences (transparent), false: preserve existing cells.
9303
+ * @returns Bitmask4 order.
9304
+ *
8790
9305
  * @example Create a 3×3 pattern with 3 variants
8791
9306
  * OrderBuilder.bitmask4(10, 10, 3, 3, [
8792
9307
  * 0, 1, 0,
@@ -8796,7 +9311,7 @@ declare class OrderBuilder {
8796
9311
  * { char: 'a', fgColor: 15, bgColor: 0 },
8797
9312
  * { char: 'b', fgColor: 14, bgColor: 0 },
8798
9313
  * { char: 'c', fgColor: 13, bgColor: 0 }
8799
- * ], false)
9314
+ * ], false);
8800
9315
  */
8801
9316
  static bitmask4(x: number, y: number, width: number, height: number, mask: number[], variants: Array<{
8802
9317
  char: string | number;
@@ -8804,11 +9319,18 @@ declare class OrderBuilder {
8804
9319
  bgColor: number;
8805
9320
  }>, override?: boolean): Bitmask4Order;
8806
9321
  /**
8807
- * 0x18 - Bitmask16: 4-bit packed mask with 15 visual variants
8808
- * @param mask - Flat array of values 0-15 (row-major order: sizeX × sizeY)
8809
- * 0 = absence, 1-15 = variant index
8810
- * @param variants - Array of up to 15 variants { char, fgColor, bgColor } for values 1-15
8811
- * @param override - true: clear absences (transparent), false: preserve existing cells
9322
+ * Creates a bitmask order with up to 15 visual variants (values 1..15).
9323
+ *
9324
+ * @param x - X position (cell).
9325
+ * @param y - Y position (cell).
9326
+ * @param width - Width in cells.
9327
+ * @param height - Height in cells.
9328
+ * @param mask - Flat array of values 0-15 (row-major order: sizeX × sizeY).
9329
+ * 0 = absence, 1-15 = variant index.
9330
+ * @param variants - Array of up to 15 variants { char, fgColor, bgColor } for values 1..15.
9331
+ * @param override - true: clear absences (transparent), false: preserve existing cells.
9332
+ * @returns Bitmask16 order.
9333
+ *
8812
9334
  * @example Create a 3×3 pattern with multiple variants
8813
9335
  * OrderBuilder.bitmask16(10, 10, 3, 3, [
8814
9336
  * 0, 1, 0,
@@ -8818,7 +9340,7 @@ declare class OrderBuilder {
8818
9340
  * { char: 'a', fgColor: 15, bgColor: 0 },
8819
9341
  * { char: 'b', fgColor: 14, bgColor: 0 },
8820
9342
  * // ... up to 15 variants
8821
- * ], false)
9343
+ * ], false);
8822
9344
  */
8823
9345
  static bitmask16(x: number, y: number, width: number, height: number, mask: number[], variants: Array<{
8824
9346
  char: string | number;
@@ -8826,21 +9348,34 @@ declare class OrderBuilder {
8826
9348
  bgColor: number;
8827
9349
  }>, override?: boolean): Bitmask16Order;
8828
9350
  /**
8829
- * 0x0D - SpriteCloud: Same single-color sprite at multiple positions
9351
+ * Creates a sprite cloud with a single-color sprite at multiple positions.
9352
+ *
9353
+ * @param spriteIndex - Sprite index in the registry.
9354
+ * @param positions - Array of positions.
9355
+ * @param fgColor - Foreground color (0-255).
9356
+ * @param bgColor - Background color (0-255).
9357
+ * @returns Sprite cloud order.
8830
9358
  */
8831
9359
  static spriteCloud(spriteIndex: number, positions: Array<{
8832
9360
  posX: number;
8833
9361
  posY: number;
8834
9362
  }>, fgColor?: number, bgColor?: number): SpriteCloudOrder;
8835
9363
  /**
8836
- * 0x0E - SpriteCloudMultiColor: Same multi-color sprite at multiple positions
9364
+ * Creates a multi-color sprite cloud at multiple positions.
9365
+ *
9366
+ * @param spriteIndex - Sprite index in the registry.
9367
+ * @param positions - Array of positions.
9368
+ * @returns Multi-color sprite cloud order.
8837
9369
  */
8838
9370
  static spriteCloudMultiColor(spriteIndex: number, positions: Array<{
8839
9371
  posX: number;
8840
9372
  posY: number;
8841
9373
  }>): SpriteCloudMultiColorOrder;
8842
9374
  /**
8843
- * 0x0F - SpriteCloudVaried: Different single-color sprites at multiple positions
9375
+ * Creates a varied sprite cloud (single-color sprites per position).
9376
+ *
9377
+ * @param sprites - Array of sprites with position and colors.
9378
+ * @returns Varied sprite cloud order.
8844
9379
  */
8845
9380
  static spriteCloudVaried(sprites: Array<{
8846
9381
  posX: number;
@@ -8850,7 +9385,10 @@ declare class OrderBuilder {
8850
9385
  fgColorCode: number;
8851
9386
  }>): SpriteCloudVariedOrder;
8852
9387
  /**
8853
- * 0x10 - SpriteCloudVariedMultiColor: Different multi-color sprites at multiple positions
9388
+ * Creates a varied sprite cloud with multi-color sprites.
9389
+ *
9390
+ * @param sprites - Array of sprites with position.
9391
+ * @returns Varied multi-color sprite cloud order.
8854
9392
  */
8855
9393
  static spriteCloudVariedMultiColor(sprites: Array<{
8856
9394
  posX: number;
@@ -8858,27 +9396,53 @@ declare class OrderBuilder {
8858
9396
  spriteIndex: number;
8859
9397
  }>): SpriteCloudVariedMultiColorOrder;
8860
9398
  /**
8861
- * 0x13 - Clear: Fills entire layer with a character
8862
- * @param char - Character as string (' ') or charCode (0x20)
9399
+ * Fills the entire layer with a character.
9400
+ *
9401
+ * @param char - Character as string (' ') or numeric code (32).
9402
+ * @param fgColor - Foreground color (0-255).
9403
+ * @param bgColor - Background color (0-255).
9404
+ * @returns Clear order.
8863
9405
  */
8864
9406
  static clear(char?: string | number, fgColor?: number, bgColor?: number): ClearOrder;
8865
9407
  /**
8866
- * 0x14 - FillChar: Fills layer with a repeating pattern
8867
- * @param pattern - Array of characters as strings or numbers
9408
+ * Fills the layer with a repeating character pattern.
9409
+ *
9410
+ * @param patternWidth - Pattern width in cells.
9411
+ * @param patternHeight - Pattern height in cells.
9412
+ * @param pattern - Array of characters as strings or numbers.
9413
+ * @param fgColor - Foreground color (0-255).
9414
+ * @param bgColor - Background color (0-255).
9415
+ * @returns Fill character order.
8868
9416
  */
8869
9417
  static fillChar(patternWidth: number, patternHeight: number, pattern: (string | number)[], fgColor?: number, bgColor?: number): FillCharOrder;
8870
9418
  /**
8871
- * 0x15 - FillSprite: Fills layer with a repeating single-color sprite
9419
+ * Fills the layer with a repeating single-color sprite.
9420
+ *
9421
+ * @param spriteIndex - Sprite index in the registry.
9422
+ * @param fgColor - Foreground color (0-255).
9423
+ * @param bgColor - Background color (0-255).
9424
+ * @returns Fill sprite order.
8872
9425
  */
8873
9426
  static fillSprite(spriteIndex: number, fgColor?: number, bgColor?: number): FillSpriteOrder;
8874
9427
  /**
8875
- * 0x16 - FillSpriteMultiColor: Fills layer with a repeating multi-color sprite
9428
+ * Fills the layer with a repeating multi-color sprite.
9429
+ *
9430
+ * @param spriteIndex - Sprite index in the registry.
9431
+ * @returns Fill multi-color sprite order.
8876
9432
  */
8877
9433
  static fillSpriteMultiColor(spriteIndex: number): FillSpriteMultiColorOrder;
8878
9434
  /**
8879
- * Helper: Create a rectangle with colored border and different interior
8880
- * @param borderOptions.charCode - Character as string ('█') or charCode (0x2588)
8881
- * @param fillOptions.charCode - Character as string ('█') or charCode (0x2588)
9435
+ * Creates a rectangle with a colored border and a different interior.
9436
+ *
9437
+ * @param x - X position (cell).
9438
+ * @param y - Y position (cell).
9439
+ * @param width - Width in cells.
9440
+ * @param height - Height in cells.
9441
+ * @param borderOptions - Border colors/char.
9442
+ * @param borderOptions.charCode - Character as string ('█') or numeric code (9608).
9443
+ * @param fillOptions - Fill colors/char.
9444
+ * @param fillOptions.charCode - Character as string ('█') or numeric code (9608).
9445
+ * @returns Array of shape orders (fill + border).
8882
9446
  */
8883
9447
  static boxWithBorder(x: number, y: number, width: number, height: number, borderOptions: ColorOptions & {
8884
9448
  charCode?: string | number;
@@ -8886,25 +9450,35 @@ declare class OrderBuilder {
8886
9450
  charCode?: string | number;
8887
9451
  }): ShapeOrder[];
8888
9452
  /**
8889
- * Helper: Create a grid of points
8890
- * @param options.charCode - Character as string ('+') or charCode (0x2b)
9453
+ * Creates a grid of points.
9454
+ *
9455
+ * @param startX - Grid start X (cell).
9456
+ * @param startY - Grid start Y (cell).
9457
+ * @param cellWidth - Cell width in cells.
9458
+ * @param cellHeight - Cell height in cells.
9459
+ * @param rows - Number of rows.
9460
+ * @param cols - Number of columns.
9461
+ * @param options - Color options.
9462
+ * @param options.charCode - Character as string ('+') or numeric code (43).
9463
+ * @returns Dot cloud order.
8891
9464
  */
8892
9465
  static grid(startX: number, startY: number, cellWidth: number, cellHeight: number, rows: number, cols: number, options?: ColorOptions): DotCloudOrder;
8893
9466
  /**
8894
- * 0x19 - Polyline: Connected line segments through multiple points
8895
- * Uses Bresenham algorithm to draw lines between consecutive points
9467
+ * Creates a polyline (connected line segments through multiple points).
9468
+ * Uses Bresenham algorithm between consecutive points.
8896
9469
  *
8897
- * @param points - Array of points to connect (minimum 2 for a line)
8898
- * @param char - Character as string ('*') or charCode (0x2A)
8899
- * @param fgColor - Foreground color (default: 15 = white)
8900
- * @param bgColor - Background color (default: 0 = black)
9470
+ * @param points - Array of points to connect (minimum 2 for a line).
9471
+ * @param char - Character as string ('*') or numeric code (42).
9472
+ * @param fgColor - Foreground color (0-255).
9473
+ * @param bgColor - Background color (0-255).
9474
+ * @returns Polyline order.
8901
9475
  *
8902
9476
  * @example Simple line
8903
9477
  * ```typescript
8904
9478
  * OrderBuilder.polyline(
8905
9479
  * [{ x: 0, y: 0 }, { x: 10, y: 5 }],
8906
9480
  * '*', 14, 0
8907
- * )
9481
+ * );
8908
9482
  * ```
8909
9483
  *
8910
9484
  * @example Path with multiple points
@@ -8917,7 +9491,7 @@ declare class OrderBuilder {
8917
9491
  * { x: 40, y: 20 }
8918
9492
  * ],
8919
9493
  * '#', 11, 0
8920
- * )
9494
+ * );
8921
9495
  * ```
8922
9496
  */
8923
9497
  static polyline(points: Array<{
@@ -8925,23 +9499,31 @@ declare class OrderBuilder {
8925
9499
  y: number;
8926
9500
  }>, char?: string | number, fgColor?: number, bgColor?: number): PolylineOrder;
8927
9501
  /**
8928
- * Helper: Create a polyline from flat coordinate array
8929
- * @param coords - Flat array of coordinates [x1, y1, x2, y2, ...]
8930
- * @param char - Character as string ('*') or charCode
9502
+ * Creates a polyline from a flat coordinate array.
9503
+ *
9504
+ * @param coords - Flat array of coordinates [x1, y1, x2, y2, ...].
9505
+ * @param char - Character as string ('*') or numeric code.
9506
+ * @param fgColor - Foreground color (0-255).
9507
+ * @param bgColor - Background color (0-255).
9508
+ * @returns Polyline order.
8931
9509
  *
8932
9510
  * @example
8933
9511
  * ```typescript
8934
9512
  * OrderBuilder.polylineFromCoords(
8935
- * [0, 0, 10, 5, 20, 0], // 3 points
9513
+ * [0, 0, 10, 5, 20, 0], // 3 points
8936
9514
  * '-', 14
8937
- * )
9515
+ * );
8938
9516
  * ```
8939
9517
  */
8940
9518
  static polylineFromCoords(coords: number[], char?: string | number, fgColor?: number, bgColor?: number): PolylineOrder;
8941
9519
  /**
8942
- * Helper: Create a closed polygon (polyline that returns to start)
8943
- * @param points - Array of points forming the polygon
8944
- * @param char - Character as string ('*') or charCode
9520
+ * Creates a closed polygon (polyline that returns to start).
9521
+ *
9522
+ * @param points - Array of points forming the polygon.
9523
+ * @param char - Character as string ('*') or numeric code.
9524
+ * @param fgColor - Foreground color (0-255).
9525
+ * @param bgColor - Background color (0-255).
9526
+ * @returns Polyline order.
8945
9527
  *
8946
9528
  * @example Triangle
8947
9529
  * ```typescript
@@ -8952,7 +9534,7 @@ declare class OrderBuilder {
8952
9534
  * { x: 30, y: 15 }
8953
9535
  * ],
8954
9536
  * '#', 12
8955
- * )
9537
+ * );
8956
9538
  * ```
8957
9539
  */
8958
9540
  static polygon(points: Array<{
@@ -9246,6 +9828,19 @@ declare enum UpdateFlags {
9246
9828
  * // → UpdateFlags |= UpdateZOrder (0x08)
9247
9829
  */
9248
9830
  UpdateZOrder = 8,
9831
+ /**
9832
+ * Bit 5: Macro layer flag
9833
+ *
9834
+ * Indicates that the layer is a macro layer (ephemeral, local effects).
9835
+ * Encoded in updateFlags for isomorphic client/server reconstruction.
9836
+ */
9837
+ IsMacroLayer = 32,
9838
+ /**
9839
+ * Bit 6: CharCode mode (0 = 8-bit, 1 = 16-bit)
9840
+ *
9841
+ * Kept here for completeness even though it is set by encoder/decoder.
9842
+ */
9843
+ CharCode16Bit = 64,
9249
9844
  /**
9250
9845
  * No changes, layer disabled
9251
9846
  * Layer ignored during rendering
@@ -9506,123 +10101,6 @@ declare class AudioOrderDecoder {
9506
10101
  private checkSize;
9507
10102
  }
9508
10103
 
9509
- /**
9510
- * AudioOrderCollector - Converts high-level audio commands to binary AudioOrders
9511
- *
9512
- * This class bridges the gap between the User's high-level audio API
9513
- * (playSound, stopSound, etc.) and the binary AudioOrder protocol.
9514
- *
9515
- * It takes SoundRegistry to resolve sound names to IDs, and produces
9516
- * AudioOrders ready for binary encoding in UpdatePacket.
9517
- *
9518
- * @example
9519
- * ```typescript
9520
- * const collector = new AudioOrderCollector(soundRegistry);
9521
- *
9522
- * // Convert User's pending commands to orders
9523
- * const audioOrders = collector.collectFromUser(user);
9524
- *
9525
- * // audioOrders can now be added to UpdatePacket
9526
- * ```
9527
- */
9528
-
9529
- /**
9530
- * Collects and converts audio commands to binary AudioOrders
9531
- */
9532
- declare class AudioOrderCollector {
9533
- private soundRegistry;
9534
- constructor(soundRegistry: SoundRegistry);
9535
- /**
9536
- * Collect all pending audio orders from a user
9537
- *
9538
- * This flushes the user's sound and config command queues,
9539
- * converts them to binary AudioOrders, and returns them.
9540
- *
9541
- * @param user - The user to collect orders from
9542
- * @returns Array of AudioOrders ready for encoding
9543
- */
9544
- collectFromUser(user: User): AnyAudioOrder[];
9545
- /**
9546
- * Convert a sound command to an AudioOrder
9547
- */
9548
- private convertSoundCommand;
9549
- /**
9550
- * Convert PlaySoundCommand to PlaySoundOrder or PlayGlobalSoundOrder
9551
- */
9552
- private convertPlayCommand;
9553
- /**
9554
- * Convert StopSoundCommand to StopSoundOrder
9555
- */
9556
- private convertStopCommand;
9557
- /**
9558
- * Convert FadeOutSoundCommand to FadeOutSoundOrder
9559
- */
9560
- private convertFadeOutCommand;
9561
- /**
9562
- * Convert PauseSoundCommand to PauseSoundOrder
9563
- */
9564
- private convertPauseCommand;
9565
- /**
9566
- * Convert ResumeSoundCommand to ResumeSoundOrder
9567
- */
9568
- private convertResumeCommand;
9569
- /**
9570
- * Convert SetSoundEffectsCommand to SetSoundEffectsOrder
9571
- */
9572
- private convertSetEffectsCommand;
9573
- /**
9574
- * Convert AudioConfigCommand to SetListenerPositionOrder or ConfigureSpatialOrder
9575
- */
9576
- private convertConfigCommand;
9577
- /**
9578
- * Resolve sound name or ID to a numeric soundId
9579
- */
9580
- private resolveSoundId;
9581
- /**
9582
- * Resolve target (instanceId, soundName, or 'all') to targetType and value
9583
- */
9584
- private resolveTarget;
9585
- /**
9586
- * Encode volume (0.0-1.0) to byte (0-255)
9587
- */
9588
- private encodeVolume;
9589
- /**
9590
- * Encode pitch (0.25x-4.0x) to byte (0-255, 128=1.0x)
9591
- * Formula: pitch = 0.25 * 2^(byte/64)
9592
- * Inverse: byte = 64 * log2(pitch / 0.25)
9593
- */
9594
- private encodePitch;
9595
- /**
9596
- * Encode fade time (seconds) to byte (1/10 seconds, 0-25.5s)
9597
- */
9598
- private encodeFadeTime;
9599
- /**
9600
- * Encode distance for spatial audio (scale: 0-25500 → 0-255)
9601
- */
9602
- private encodeDistance;
9603
- /**
9604
- * Encode rolloff factor (0.0-2.55 → 0-255)
9605
- */
9606
- private encodeRolloff;
9607
- /**
9608
- * Encode pan spread (0.0-1.0 → 0-255)
9609
- */
9610
- private encodePanSpread;
9611
- /**
9612
- * Encode position coordinate for spatial audio (clamp to 0-65535 for Uint16)
9613
- */
9614
- private encodePosition;
9615
- /**
9616
- * Encode filter frequency (100-25500 Hz) to byte (1-255, * 100 = Hz)
9617
- * 0 means disabled
9618
- */
9619
- private encodeFilterFreq;
9620
- /**
9621
- * Encode reverb wet mix (0.0-1.0) to byte (0-255)
9622
- */
9623
- private encodeReverb;
9624
- }
9625
-
9626
10104
  /**
9627
10105
  * UTSP Vibration Order Decoder
9628
10106
  *
@@ -9653,69 +10131,6 @@ declare class VibrationOrderDecoder {
9653
10131
  private decodeGamepadCancelOrder;
9654
10132
  }
9655
10133
 
9656
- /**
9657
- * VibrationOrderCollector - Converts high-level vibration commands to binary VibrationOrders
9658
- *
9659
- * This class bridges the gap between the User's high-level vibration API
9660
- * (vibrate, vibrateGamepad, etc.) and the binary VibrationOrder protocol.
9661
- *
9662
- * It produces VibrationOrders ready for binary encoding in UpdatePacket.
9663
- * Supports both mobile vibration (pattern-based) and gamepad vibration (dual-motor).
9664
- *
9665
- * @example
9666
- * ```typescript
9667
- * const collector = new VibrationOrderCollector();
9668
- *
9669
- * // Convert User's pending commands to orders
9670
- * const vibrationOrders = collector.collectFromUser(user);
9671
- *
9672
- * // vibrationOrders can now be added to UpdatePacket
9673
- * ```
9674
- */
9675
-
9676
- /**
9677
- * Collects and converts vibration commands to binary VibrationOrders
9678
- */
9679
- declare class VibrationOrderCollector {
9680
- /**
9681
- * Collect all pending vibration orders from a user
9682
- *
9683
- * This flushes the user's vibration command queues (mobile + gamepad),
9684
- * converts them to binary VibrationOrders, and returns them.
9685
- *
9686
- * @param user - The user to collect orders from
9687
- * @returns Array of VibrationOrders ready for encoding
9688
- */
9689
- collectFromUser(user: User): AnyVibrationOrder[];
9690
- /**
9691
- * Convert a mobile vibration command to a VibrationOrder
9692
- * Accepts both old format (without target) and new format (with target: 'mobile')
9693
- */
9694
- private convertMobileCommand;
9695
- /**
9696
- * Convert MobileVibrateCommand to MobileVibrateOrder
9697
- * Accepts both old format { pattern, intensity? } and new format { target: 'mobile', pattern, intensity? }
9698
- */
9699
- private convertMobileVibrateCommand;
9700
- /**
9701
- * Convert MobileCancelVibrationCommand to MobileCancelOrder
9702
- */
9703
- private convertMobileCancelCommand;
9704
- /**
9705
- * Convert a gamepad vibration command to a VibrationOrder
9706
- * Accepts both old format (without target) and new format (with target: 'gamepad')
9707
- */
9708
- private convertGamepadCommand;
9709
- /**
9710
- * Convert GamepadVibrateCommand to GamepadVibrateOrder
9711
- */
9712
- private convertGamepadVibrateCommand;
9713
- /**
9714
- * Convert GamepadCancelVibrationCommand to GamepadCancelOrder
9715
- */
9716
- private convertGamepadCancelCommand;
9717
- }
9718
-
9719
10134
  /**
9720
10135
  * UTSP Vibration Order Encoder
9721
10136
  *
@@ -9774,91 +10189,5 @@ declare class PostProcessOrderDecoder {
9774
10189
  private decodeSetCellSizeOrder;
9775
10190
  }
9776
10191
 
9777
- /**
9778
- * PostProcessOrderCollector - Converts high-level post-process commands to binary PostProcessOrders
9779
- *
9780
- * This class bridges the gap between the User's high-level post-process API
9781
- * (setPostProcess, setAmbientEffect, etc.) and the binary PostProcessOrder protocol.
9782
- *
9783
- * It converts PostProcessCommands to PostProcessOrders ready for binary encoding in UpdatePacket.
9784
- *
9785
- * @example
9786
- * ```typescript
9787
- * const collector = new PostProcessOrderCollector();
9788
- *
9789
- * // Convert User's pending commands to orders
9790
- * const postProcessOrders = collector.collectFromUser(user);
9791
- *
9792
- * // postProcessOrders can now be added to UpdatePacket
9793
- * ```
9794
- */
9795
-
9796
- /**
9797
- * Collects and converts post-process commands to binary PostProcessOrders
9798
- */
9799
- declare class PostProcessOrderCollector {
9800
- /**
9801
- * Collect all pending post-process orders from a user
9802
- *
9803
- * This flushes the user's post-process command queue,
9804
- * converts them to binary PostProcessOrders, and returns them.
9805
- *
9806
- * @param user - The user to collect orders from
9807
- * @returns Array of PostProcessOrders ready for encoding
9808
- */
9809
- collectFromUser(user: User): AnyPostProcessOrder[];
9810
- /**
9811
- * Convert an array of post-process commands to PostProcessOrders
9812
- *
9813
- * This is the core conversion logic used by both:
9814
- * - Server: collectFromUser() → encode → network
9815
- * - Local: convertCommands() → applyPostProcessOrders() (no encoding)
9816
- *
9817
- * @param commands - Array of PostProcessCommands to convert
9818
- * @returns Array of PostProcessOrders
9819
- */
9820
- convertCommands(commands: PostProcessCommand[]): AnyPostProcessOrder[];
9821
- /**
9822
- * Convert a post-process command to a PostProcessOrder
9823
- */
9824
- private convertCommand;
9825
- /**
9826
- * Convert a full set-config command to a SetConfigOrder
9827
- */
9828
- private convertSetConfig;
9829
- /**
9830
- * Create a SetScanlinesOrder with given parameters
9831
- */
9832
- private createSetScanlinesOrder;
9833
- /**
9834
- * Create a SetAmbientEffectOrder with given parameters
9835
- */
9836
- private createSetAmbientEffectOrder;
9837
- /**
9838
- * Convert pattern string to ScanlinesPatternType
9839
- */
9840
- private patternToType;
9841
- /**
9842
- * Create a SetScalingModeOrder with given scaling mode
9843
- */
9844
- private createSetScalingModeOrder;
9845
- /**
9846
- * Create a SetGridOrder with given grid configuration
9847
- */
9848
- private createSetGridOrder;
9849
- /**
9850
- * Create a SwitchPaletteOrder with given slot ID
9851
- */
9852
- private createSwitchPaletteOrder;
9853
- /**
9854
- * Create a SetCellSizeOrder with given dimensions
9855
- */
9856
- private createSetCellSizeOrder;
9857
- /**
9858
- * Parse CSS color string to RGBA components
9859
- */
9860
- private parseColor;
9861
- }
9862
-
9863
- export { ASCII_8X8_FONT, AUDIO_CONFIGURE_SPATIAL_SIZE, AUDIO_FADEOUT_SOUND_MIN_SIZE, AUDIO_PAUSE_SOUND_MIN_SIZE, AUDIO_PLAY_GLOBAL_SOUND_MIN_SIZE, AUDIO_PLAY_SOUND_MIN_SIZE, AUDIO_RESUME_SOUND_MIN_SIZE, AUDIO_SET_LISTENER_POSITION_SIZE, AUDIO_SET_SOUND_EFFECTS_MIN_SIZE, AUDIO_STOP_SOUND_MIN_SIZE, AudioOrderCollector, AudioOrderDecoder, AudioOrderType, AudioTargetType, BITMASK16_ORDER_MIN_SIZE, BITMASK4_ORDER_MIN_SIZE, BITMASK_ORDER_MIN_SIZE, BitmapFont, BitmapFontRegistry, CHAR_ORDER_SIZE, CIRCLE_SHAPE_SIZE, CLEAR_ORDER_SIZE, COLORMAP_ORDER_MIN_SIZE, COLOR_SKIP, CellBuffer, CharCodeBuffer, Core, CoreStats, DISPLAY_HEADER_SIZE, DOTCLOUD_MULTICOLOR_ORDER_MIN_SIZE, DOTCLOUD_ORDER_MIN_SIZE, Display, ELLIPSE_SHAPE_SIZE, FILLCHAR_ORDER_MIN_SIZE, FILLSPRITE_MULTICOLOR_ORDER_SIZE, FILLSPRITE_ORDER_SIZE, FULLFRAME_MULTICOLOR_ORDER_MIN_SIZE, FULLFRAME_ORDER_MIN_SIZE, FontType, GamepadVibrateFlags, ImageFont, ImageFontRegistry, InputBindingRegistry, LAYER_CELL_COUNT, LAYER_HEADER_SIZE, LAYER_SIZE, LINE_SHAPE_SIZE, Layer, LoadType, MAX_ORDERS_PER_LAYER, MacroEngine, MacroEventType, MacroOrderType, MacroRegistry, MobileVibrateFlags, OrderBuilder, OrderType, POLYLINE_ORDER_MIN_SIZE, POSTPROCESS_SET_AMBIENT_EFFECT_SIZE, POSTPROCESS_SET_CELL_SIZE_SIZE, POSTPROCESS_SET_CONFIG_MIN_SIZE, POSTPROCESS_SET_GRID_SIZE, POSTPROCESS_SET_SCALING_MODE_SIZE, POSTPROCESS_SET_SCANLINES_SIZE, POSTPROCESS_SWITCH_PALETTE_SIZE, PlaySoundFlags, PostProcessOrderCollector, PostProcessOrderDecoder, PostProcessOrderType, RECTANGLE_SHAPE_SIZE, SHAPE_ORDER_MIN_SIZE, SPRITECLOUD_MULTICOLOR_ORDER_MIN_SIZE, SPRITECLOUD_ORDER_MIN_SIZE, SPRITECLOUD_VARIED_MULTICOLOR_ORDER_MIN_SIZE, SPRITECLOUD_VARIED_ORDER_MIN_SIZE, SPRITE_MULTICOLOR_ORDER_SIZE, SPRITE_ORDER_SIZE, SUBFRAME_MULTICOLOR_ORDER_MIN_SIZE, SUBFRAME_ORDER_MIN_SIZE, ShapeType, SoundEffectsFlags, SoundRegistry, SpriteRegistry, TEXT_MULTILINE_ORDER_MIN_SIZE, TEXT_ORDER_MIN_SIZE, TRIANGLE_SHAPE_SIZE, UPDATE_PACKET_HEADER_SIZE, UpdateFlags, UpdateFlagsHelper, UpdatePacketDecoder, User, UserStats, VibrationOrderCollector, VibrationOrderDecoder, VibrationOrderEncoder, VibrationOrderType, WebFont, WebFontRegistry, charCodeByteSize, createASCII8x8FontLoad, createEmptyCompressedInputPacket, decodeCompressedInput, decodeInt8ToAxis, encodeAxisToInt8, encodeCompressedInput, getASCII8x8FontConfig, getAllCharCodes, getAtlasColumns, getAtlasDimensions, getAudioOrderTypeName, getButtonByteCount, getCharBitmap, getCompressedPacketSize, getMacroEventTypeName, getMacroOrderTypeName, getMaxCharCode, getOrderTypeName, hasChar, isValidAudioOrderType, isValidMacroEventType, isValidMacroOrderType, isValidOrderType };
9864
- export type { AnyAudioOrder, AnyLoad, AnyMacroEvent, AnyMacroOrder, AnyPostProcessOrder, AnyVibrationOrder, AtlasBlocks, AudioOrder, BitmapFontConfig, BitmapFontLoad, Bitmask16Order, Bitmask16Variant, Bitmask4Order, Bitmask4Variant, BitmaskOrder, ButtonBorderStyle, ButtonConfig, ButtonStateColors, Cell, ChangeEvent, CharCodeMode, CircleShape, ClickEvent, Color, ColorPaletteLoad, CompressedInputPacket, ConfigureSpatialOrder, CoreMode, CoreOptions, CreateInstanceConfig, CreateInstanceOrder, DisplayViewport, EffectMacroTemplate, EffectTransform, EllipseShape, FadeOutSoundOrder, GamepadCancelOrder, GamepadVibrateOrder, GamepadVibrationOrder, GlyphSize, ImageFontConfig, ImageFontLoad, ImageFontOptions, LineMacroTemplate, LineShape, MacroEntry, MacroEvent, MacroInstanceEntry, MacroLoad, MacroOrder, MacroTemplate, MacroTemplateBase, MacroType, MacroUpdateResult, MobileCancelOrder, MobileVibrateOrder, MobileVibrationOrder, MulticolorCell, MulticolorSprite, MulticolorSpriteLoad, NetworkDisplay, NetworkLayer, ParticleConfig, ParticleEmitter, ParticleMacroTemplate, PauseSoundOrder, PlayGlobalSoundOrder, PlaySoundOrder, RectangleShape, RemoveInstanceOrder, RenderCommand, RenderPassConfig, ResumeSoundOrder, RevealCellDef, RevealContent, RevealContentType, RevealCursor, RevealDirection, RevealMacroTemplate, RevealPattern, RevealPause, SelectEvent, SetAmbientEffectOrder, SetConfigOrder, SetGridOrder, SetListenerPositionOrder, SetScalingModeOrder, SetScanlinesOrder, SetSoundEffectsOrder, ShapeData, SoundEntry, SoundLoad, SpriteLoad, StopSoundOrder, SubmitEvent, SwitchPaletteOrder, TickStats, TouchPosition, TriangleShape, UIMacroTemplate, UIState, UISubtype, UnicolorSprite, UpdateInstanceOrder, UpdatePacket, UserTickStats, VibrationOrder, WebFontConfig, WebFontLoad };
10192
+ export { ASCII_8X8_FONT, AUDIO_CONFIGURE_SPATIAL_SIZE, AUDIO_FADEOUT_SOUND_MIN_SIZE, AUDIO_PAUSE_SOUND_MIN_SIZE, AUDIO_PLAY_GLOBAL_SOUND_MIN_SIZE, AUDIO_PLAY_SOUND_MIN_SIZE, AUDIO_RESUME_SOUND_MIN_SIZE, AUDIO_SET_LISTENER_POSITION_SIZE, AUDIO_SET_SOUND_EFFECTS_MIN_SIZE, AUDIO_STOP_SOUND_MIN_SIZE, AudioOrderCollector, AudioOrderDecoder, AudioOrderType, AudioTargetType, BITMASK16_ORDER_MIN_SIZE, BITMASK4_ORDER_MIN_SIZE, BITMASK_ORDER_MIN_SIZE, CHAR_ORDER_SIZE, CIRCLE_SHAPE_SIZE, CLEAR_ORDER_SIZE, COLORMAP_ORDER_MIN_SIZE, COLOR_SKIP, CellBuffer, CharCodeBuffer, Core, CoreStats, DISPLAY_HEADER_SIZE, DOTCLOUD_MULTICOLOR_ORDER_MIN_SIZE, DOTCLOUD_ORDER_MIN_SIZE, Display, ELLIPSE_SHAPE_SIZE, FILLCHAR_ORDER_MIN_SIZE, FILLSPRITE_MULTICOLOR_ORDER_SIZE, FILLSPRITE_ORDER_SIZE, FULLFRAME_MULTICOLOR_ORDER_MIN_SIZE, FULLFRAME_ORDER_MIN_SIZE, FontType, GamepadVibrateFlags, ImageFont, ImageFontRegistry, InputBindingRegistry, LAYER_CELL_COUNT, LAYER_HEADER_SIZE, LAYER_SIZE, LINE_SHAPE_SIZE, Layer, LoadType, MAX_ORDERS_PER_LAYER, MacroEngine, MacroEventType, MacroOrderType, MacroRegistry, MobileVibrateFlags, OrderBuilder, OrderType, POLYLINE_ORDER_MIN_SIZE, POSTPROCESS_SET_AMBIENT_EFFECT_SIZE, POSTPROCESS_SET_CELL_SIZE_SIZE, POSTPROCESS_SET_CONFIG_MIN_SIZE, POSTPROCESS_SET_GRID_SIZE, POSTPROCESS_SET_SCALING_MODE_SIZE, POSTPROCESS_SET_SCANLINES_SIZE, POSTPROCESS_SWITCH_PALETTE_SIZE, PlaySoundFlags, PostProcessOrderCollector, PostProcessOrderDecoder, PostProcessOrderType, RECTANGLE_SHAPE_SIZE, SHAPE_ORDER_MIN_SIZE, SPRITECLOUD_MULTICOLOR_ORDER_MIN_SIZE, SPRITECLOUD_ORDER_MIN_SIZE, SPRITECLOUD_VARIED_MULTICOLOR_ORDER_MIN_SIZE, SPRITECLOUD_VARIED_ORDER_MIN_SIZE, SPRITE_MULTICOLOR_ORDER_SIZE, SPRITE_ORDER_SIZE, SUBFRAME_MULTICOLOR_ORDER_MIN_SIZE, SUBFRAME_ORDER_MIN_SIZE, ShapeType, SoundEffectsFlags, SoundRegistry, SpriteRegistry, TEXT_MULTILINE_ORDER_MIN_SIZE, TEXT_ORDER_MIN_SIZE, TRIANGLE_SHAPE_SIZE, UPDATE_PACKET_HEADER_SIZE, UpdateFlags, UpdateFlagsHelper, UpdatePacketDecoder, User, UserStats, VibrationOrderCollector, VibrationOrderDecoder, VibrationOrderEncoder, VibrationOrderType, charCodeByteSize, createEmptyCompressedInputPacket, decodeCompressedInput, decodeInt8ToAxis, encodeAxisToInt8, encodeCompressedInput, getASCII8x8FontConfig, getAllCharCodes, getAtlasColumns, getAtlasDimensions, getAudioOrderTypeName, getButtonByteCount, getCharBitmap, getCompressedPacketSize, getMacroEventTypeName, getMacroOrderTypeName, getMaxCharCode, getOrderTypeName, hasChar, isValidAudioOrderType, isValidMacroEventType, isValidMacroOrderType, isValidOrderType };
10193
+ export type { AnyAudioOrder, AnyLoad, AnyMacroEvent, AnyMacroOrder, AnyPostProcessOrder, AnyVibrationOrder, AtlasBlocks, AudioOrder, Bitmask16Order, Bitmask16Variant, Bitmask4Order, Bitmask4Variant, BitmaskOrder, ButtonBorderStyle, ButtonConfig, ButtonStateColors, Cell, ChangeEvent, CharCodeMode, CircleShape, ClickEvent, Color, ColorPaletteLoad, CompressedInputPacket, ConfigureSpatialOrder, CoreMode, CoreOptions, CreateInstanceConfig, CreateInstanceOrder, DisplayViewport, EffectMacroTemplate, EffectTransform, EllipseShape, FadeOutSoundOrder, GamepadCancelOrder, GamepadVibrateOrder, GamepadVibrationOrder, GlyphSize, ImageFontConfig, ImageFontLoad, ImageFontOptions, LineMacroTemplate, LineShape, MacroEntry, MacroEvent, MacroInstanceEntry, MacroLoad, MacroOrder, MacroTemplate, MacroTemplateBase, MacroType, MacroUpdateResult, MobileCancelOrder, MobileVibrateOrder, MobileVibrationOrder, MulticolorCell, MulticolorSprite, MulticolorSpriteLoad, NetworkDisplay, NetworkLayer, ParticleConfig, ParticleEmitter, ParticleMacroTemplate, PauseSoundOrder, PlayGlobalSoundOrder, PlaySoundOrder, RectangleShape, RemoveInstanceOrder, RenderCommand, RenderPassConfig, ResumeSoundOrder, RevealCellDef, RevealContent, RevealContentType, RevealCursor, RevealDirection, RevealMacroTemplate, RevealPattern, RevealPause, SelectEvent, SetAmbientEffectOrder, SetConfigOrder, SetGridOrder, SetListenerPositionOrder, SetScalingModeOrder, SetScanlinesOrder, SetSoundEffectsOrder, ShapeData, SoundEntry, SoundLoad, SpriteLoad, StopSoundOrder, SubmitEvent, SwitchPaletteOrder, TickStats, TouchPosition, TriangleShape, UIMacroTemplate, UIState, UISubtype, UnicolorSprite, UpdateInstanceOrder, UpdatePacket, UserTickStats, VibrationOrder };