@utsp/core 0.17.0-nightly.20260114213208.c9c64d9 → 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.
@@ -1,5 +1,5 @@
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, RenderState } 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, RenderState } from '@utsp/types';
3
3
  export { Vector2 } from '@utsp/types';
4
4
 
5
5
  /**
@@ -425,6 +425,46 @@ declare class OrderEncoder {
425
425
  private encodeFillSpriteMultiColorOrder;
426
426
  }
427
427
 
428
+ /**
429
+ * Internal command sink used by `Display` to enqueue network commands via `User`.
430
+ * @internal
431
+ */
432
+ interface DisplayCommandSink {
433
+ setPostProcess(displayId: number, config: PostProcessConfig | null): void;
434
+ setScanlinesEnabled(displayId: number, enabled: boolean): void;
435
+ setScanlinesOpacity(displayId: number, opacity: number): void;
436
+ setScanlinesPattern(displayId: number, pattern: 'horizontal' | 'vertical' | 'grid'): void;
437
+ setAmbientEffect(displayId: number, config: boolean | {
438
+ blur?: number;
439
+ scale?: number;
440
+ }): void;
441
+ setAmbientEffectEnabled(displayId: number, enabled: boolean): void;
442
+ setAmbientEffectBlur(displayId: number, blur: number): void;
443
+ setAmbientEffectScale(displayId: number, scale: number): void;
444
+ isAmbientEffectEnabled(displayId: number): boolean;
445
+ getAmbientEffectConfig(displayId: number): {
446
+ enabled: boolean;
447
+ blur: number;
448
+ scale: number;
449
+ } | null;
450
+ getPostProcessConfig(displayId: number): PostProcessConfig | null;
451
+ setScalingMode(displayId: number, mode: ScalingMode): void;
452
+ getScalingMode(displayId: number): ScalingMode | null;
453
+ setCellSize(displayId: number, width: number, height: number): void;
454
+ getCellSize(displayId: number): {
455
+ cellWidth: number;
456
+ cellHeight: number;
457
+ };
458
+ setGrid(displayId: number, config: boolean | GridConfig): void;
459
+ setGridEnabled(displayId: number, enabled: boolean): void;
460
+ isGridEnabled(displayId: number): boolean;
461
+ getGridConfig(displayId: number): GridConfig | null;
462
+ switchPalette(displayId: number, slotId: number): void;
463
+ getCurrentPaletteSlotId(displayId: number): number | null;
464
+ }
465
+ /**
466
+ * Render pass definition for multi-pass rendering.
467
+ */
428
468
  interface RenderPassConfig {
429
469
  id: number;
430
470
  zMin: number;
@@ -432,78 +472,326 @@ interface RenderPassConfig {
432
472
  enabled?: boolean;
433
473
  }
434
474
  /**
435
- * Represents a display (camera) in the virtual world
475
+ * Represents a display (camera) in the virtual world.
436
476
  *
437
- * ARCHITECTURE (new protocol):
438
- * - Display = camera looking into the virtual world
439
- * - LAYERS are NO LONGER in Display, they are at User level
440
- * - Display only defines WHICH PART of the world we see (origin)
477
+ * Architecture:
478
+ * - `Display` is a camera looking into the world.
479
+ * - Layers are managed at the `User` level.
480
+ * - `Display` defines viewport origin/size and display-specific settings.
441
481
  */
442
482
  declare class Display {
443
483
  private id;
444
484
  private origin;
445
485
  private size;
486
+ private commandSink?;
446
487
  private previousOrigin;
447
488
  private previousSize;
448
- private toDraw;
449
489
  private renderPasses;
490
+ /**
491
+ * Creates a new display.
492
+ *
493
+ * @param id - Display ID (0-255).
494
+ * @param sizeX - Width in cells (1-256).
495
+ * @param sizeY - Height in cells (1-256).
496
+ *
497
+ * @example
498
+ * const display = new Display(0, 80, 45);
499
+ *
500
+ * @throws Error if `id`, `sizeX`, or `sizeY` are out of bounds.
501
+ */
450
502
  constructor(id?: number, sizeX?: number, sizeY?: number);
451
503
  /**
452
- * Gets the display ID (0-255)
504
+ * Returns the display ID (0-255).
505
+ *
506
+ * @returns The display ID.
453
507
  */
454
508
  getId(): number;
455
509
  /**
456
- * Gets the origin position in the world
510
+ * Injects the command sink (set by `User`).
511
+ * @internal
512
+ */
513
+ setCommandSink(sink: DisplayCommandSink): void;
514
+ /**
515
+ * Returns the display origin in world space.
516
+ *
517
+ * @returns The current origin.
518
+ *
519
+ * @example
520
+ * const origin = display.getOrigin();
457
521
  */
458
522
  getOrigin(): Vector2;
459
523
  /**
460
- * Sets the origin position in the world
524
+ * Sets the display origin in world space.
525
+ *
526
+ * @param origin - New world position.
527
+ *
528
+ * @example
529
+ * display.setOrigin(new Vector2(10, 5));
461
530
  */
462
531
  setOrigin(origin: Vector2): void;
463
532
  /**
464
- * Moves the origin in the world
533
+ * Moves the display origin by a delta.
534
+ *
535
+ * @param deltaX - Delta X in world cells.
536
+ * @param deltaY - Delta Y in world cells.
537
+ *
538
+ * @example
539
+ * display.moveOrigin(1, 0);
465
540
  */
466
541
  moveOrigin(deltaX: number, deltaY: number): void;
467
542
  /**
468
- * Checks if display origin has changed since last tick
469
- * @internal - Used to calculate if update should be sent
543
+ * Returns `true` if the origin changed since the last tick.
544
+ *
545
+ * @returns Whether the origin has changed.
546
+ * @internal
470
547
  */
471
548
  hasOriginChanged(): boolean;
472
549
  /**
473
- * Checks if display size has changed since last tick
474
- * @internal - Used to calculate if update should be sent
550
+ * Returns `true` if the size changed since the last tick.
551
+ *
552
+ * @returns Whether the size has changed.
553
+ * @internal
475
554
  */
476
555
  hasSizeChanged(): boolean;
477
556
  /**
478
- * Checks if display has changed (origin OR size)
557
+ * Returns `true` if origin or size changed since the last tick.
558
+ *
559
+ * @returns Whether origin or size has changed.
479
560
  * @internal
480
561
  */
481
562
  hasChanged(): boolean;
482
563
  /**
483
- * Resets change tracking
484
- * @internal - Called by Core.endTick() after sending updates
564
+ * Resets change tracking to the current state.
565
+ * @internal
485
566
  */
486
567
  resetChangeTracking(): void;
487
568
  /**
488
- * Gets the display size
569
+ * Returns the display size in cells.
570
+ *
571
+ * @returns The current size in cells.
572
+ *
573
+ * @example
574
+ * const size = display.getSize();
489
575
  */
490
576
  getSize(): Vector2;
491
577
  /**
492
- * Sets the display size
578
+ * Sets the display size in cells.
579
+ *
580
+ * @param size - New size in cells (1-256).
581
+ *
582
+ * @example
583
+ * display.setSize(new Vector2(80, 45));
584
+ *
585
+ * @throws Error if width/height are out of bounds.
493
586
  */
494
587
  setSize(size: Vector2): void;
495
588
  /**
496
- * Returns the validated render passes (undefined = single pass [0,255])
589
+ * Returns the injected command sink.
590
+ * @throws Error if this display is not attached to a `User`.
591
+ */
592
+ private getSink;
593
+ /**
594
+ * Sets the post-process configuration for this display.
595
+ *
596
+ * @param config - Post-process config or `null` to disable.
597
+ *
598
+ * @example
599
+ * display.setPostProcess({
600
+ * scanlines: { enabled: true, opacity: 0.2, pattern: 'horizontal' },
601
+ * });
602
+ *
603
+ * @throws Error if the display is not attached to a `User`.
604
+ */
605
+ setPostProcess(config: PostProcessConfig | null): void;
606
+ /**
607
+ * Enables or disables scanlines for this display.
608
+ *
609
+ * @param enabled - Whether scanlines are enabled.
610
+ *
611
+ * @example
612
+ * display.setScanlinesEnabled(true);
613
+ */
614
+ setScanlinesEnabled(enabled: boolean): void;
615
+ /**
616
+ * Sets scanlines opacity for this display.
617
+ *
618
+ * @param opacity - Opacity in range [0, 1].
619
+ *
620
+ * @example
621
+ * display.setScanlinesOpacity(0.35);
622
+ */
623
+ setScanlinesOpacity(opacity: number): void;
624
+ /**
625
+ * Sets the scanlines pattern for this display.
626
+ *
627
+ * @param pattern - Pattern type.
628
+ *
629
+ * @example
630
+ * display.setScanlinesPattern('grid');
631
+ */
632
+ setScanlinesPattern(pattern: 'horizontal' | 'vertical' | 'grid'): void;
633
+ /**
634
+ * Enables or configures the ambient effect for this display.
635
+ *
636
+ * @param config - `true`/`false` or an object with `blur`/`scale`.
637
+ *
638
+ * @example
639
+ * display.setAmbientEffect({ blur: 40, scale: 1.4 });
640
+ */
641
+ setAmbientEffect(config: boolean | {
642
+ blur?: number;
643
+ scale?: number;
644
+ }): void;
645
+ /**
646
+ * Enables or disables the ambient effect for this display.
647
+ *
648
+ * @param enabled - Whether the effect is enabled.
649
+ *
650
+ * @example
651
+ * display.setAmbientEffectEnabled(false);
652
+ */
653
+ setAmbientEffectEnabled(enabled: boolean): void;
654
+ /**
655
+ * Sets ambient blur intensity for this display.
656
+ *
657
+ * @param blur - Blur amount in pixels.
658
+ *
659
+ * @example
660
+ * display.setAmbientEffectBlur(60);
661
+ */
662
+ setAmbientEffectBlur(blur: number): void;
663
+ /**
664
+ * Sets ambient effect scale for this display.
665
+ *
666
+ * @param scale - Scale factor (>= 1).
667
+ *
668
+ * @example
669
+ * display.setAmbientEffectScale(1.5);
670
+ */
671
+ setAmbientEffectScale(scale: number): void;
672
+ /**
673
+ * Returns whether the ambient effect is enabled.
674
+ *
675
+ * @returns `true` if enabled.
676
+ */
677
+ isAmbientEffectEnabled(): boolean;
678
+ /**
679
+ * Returns the current ambient effect configuration, or `null` if disabled.
680
+ *
681
+ * @returns The ambient effect config or `null`.
682
+ */
683
+ getAmbientEffectConfig(): {
684
+ enabled: boolean;
685
+ blur: number;
686
+ scale: number;
687
+ } | null;
688
+ /**
689
+ * Returns the current post-process configuration, or `null` if none.
690
+ *
691
+ * @returns The post-process config or `null`.
692
+ */
693
+ getPostProcessConfig(): PostProcessConfig | null;
694
+ /**
695
+ * Sets the pixel-perfect scaling mode for this display.
696
+ *
697
+ * @param mode - Scaling mode.
698
+ *
699
+ * @example
700
+ * display.setScalingMode('integer');
701
+ */
702
+ setScalingMode(mode: ScalingMode): void;
703
+ /**
704
+ * Returns the current scaling mode for this display, if set.
705
+ *
706
+ * @returns The scaling mode or `null`.
707
+ */
708
+ getScalingMode(): ScalingMode | null;
709
+ /**
710
+ * Sets the cell size (in pixels) for this display.
711
+ *
712
+ * @param width - Cell width in pixels.
713
+ * @param height - Cell height in pixels.
714
+ *
715
+ * @example
716
+ * display.setCellSize(8, 16);
717
+ */
718
+ setCellSize(width: number, height: number): void;
719
+ /**
720
+ * Returns the current cell size for this display.
721
+ *
722
+ * @returns The cell size in pixels.
723
+ */
724
+ getCellSize(): {
725
+ cellWidth: number;
726
+ cellHeight: number;
727
+ };
728
+ /**
729
+ * Enables or configures the debug grid overlay.
730
+ *
731
+ * @param config - `true`/`false` or a `GridConfig` object.
732
+ *
733
+ * @example
734
+ * display.setGrid({ enabled: true, color: '#00ff00', lineWidth: 2 });
735
+ */
736
+ setGrid(config: boolean | GridConfig): void;
737
+ /**
738
+ * Enables or disables the debug grid overlay.
739
+ *
740
+ * @param enabled - Whether the grid is enabled.
741
+ */
742
+ setGridEnabled(enabled: boolean): void;
743
+ /**
744
+ * Returns whether the debug grid is enabled.
745
+ *
746
+ * @returns `true` if enabled.
747
+ */
748
+ isGridEnabled(): boolean;
749
+ /**
750
+ * Returns the current grid configuration, or `null` if none.
751
+ *
752
+ * @returns The grid configuration or `null`.
753
+ */
754
+ getGridConfig(): GridConfig | null;
755
+ /**
756
+ * Switches to a preloaded palette slot for this display.
757
+ *
758
+ * @param slotId - Palette slot ID (0-255).
759
+ *
760
+ * @example
761
+ * display.switchPalette(2);
762
+ */
763
+ switchPalette(slotId: number): void;
764
+ /**
765
+ * Returns the active palette slot ID for this display, or `null`.
766
+ *
767
+ * @returns The current palette slot ID or `null`.
768
+ */
769
+ getCurrentPaletteSlotId(): number | null;
770
+ /**
771
+ * Returns the render passes configuration.
772
+ *
773
+ * @returns Array of passes or `undefined` for single pass.
497
774
  */
498
775
  getRenderPasses(): RenderPassConfig[] | undefined;
499
776
  /**
500
- * Sets the render passes configuration (0..4 passes). Applies clamping and swap.
501
- * Passing undefined resets to single pass behavior.
777
+ * Sets render passes configuration (0..4 passes).
778
+ *
779
+ * @param passes - Pass definitions or `undefined` to reset.
780
+ *
781
+ * @example
782
+ * display.setRenderPasses([
783
+ * { id: 0, zMin: 0, zMax: 127 },
784
+ * { id: 1, zMin: 128, zMax: 255 },
785
+ * ]);
786
+ *
787
+ * @throws Error if more than 4 passes are provided.
502
788
  */
503
789
  setRenderPasses(passes: RenderPassConfig[] | undefined): void;
504
790
  private normalizePass;
505
791
  /**
506
- * Returns a debug-friendly snapshot of this display (metadata only)
792
+ * Returns a debug-friendly snapshot of this display (metadata only).
793
+ *
794
+ * @returns Debug info snapshot.
507
795
  */
508
796
  getDebugInfo(): {
509
797
  id: number;
@@ -580,6 +868,13 @@ interface NetworkLayer {
580
868
  orders: AnyNetworkOrder[];
581
869
  /** Optional decoded byte size of this layer segment in the update packet */
582
870
  byteSize?: number;
871
+ /**
872
+ * Macro layer flag
873
+ * - false: standard layer
874
+ * - true: macro layer (ephemeral, local effects)
875
+ * Encoded in updateFlags bit 5
876
+ */
877
+ isMacroLayer: boolean;
583
878
  /**
584
879
  * CharCode mode for this layer
585
880
  * - false: 8-bit charCodes (0-255)
@@ -1931,140 +2226,6 @@ declare class MacroOrderEncoder {
1931
2226
  * - 16 blocks = 64×64 grid = 4096 chars (12-bit)
1932
2227
  */
1933
2228
  type AtlasBlocks = 1 | 4 | 16;
1934
- /**
1935
- * WebFont configuration
1936
- * For CSS-based fonts rendered by the browser
1937
- */
1938
- interface WebFontConfig {
1939
- fontFamily: string;
1940
- fontSize: number;
1941
- offsetX?: number;
1942
- offsetY?: number;
1943
- charSpacing?: number;
1944
- lineHeight?: number;
1945
- fontWeight?: string;
1946
- fontStyle?: string;
1947
- }
1948
- /**
1949
- * WebFont class
1950
- * Represents a CSS-based font for browser rendering
1951
- */
1952
- declare class WebFont {
1953
- private fontId;
1954
- private config;
1955
- constructor(fontId: number, config: WebFontConfig);
1956
- /**
1957
- * Get the unique font ID
1958
- */
1959
- getFontId(): number;
1960
- /**
1961
- * Get the full configuration (copy)
1962
- */
1963
- getConfig(): WebFontConfig;
1964
- /**
1965
- * Get the font family
1966
- */
1967
- getFontFamily(): string;
1968
- /**
1969
- * Get the font size in pixels
1970
- */
1971
- getFontSize(): number;
1972
- /**
1973
- * Get the horizontal offset
1974
- */
1975
- getOffsetX(): number;
1976
- /**
1977
- * Get the vertical offset
1978
- */
1979
- getOffsetY(): number;
1980
- /**
1981
- * Get the character spacing
1982
- */
1983
- getCharSpacing(): number;
1984
- /**
1985
- * Get the line height multiplier
1986
- */
1987
- getLineHeight(): number;
1988
- /**
1989
- * Get the font weight
1990
- */
1991
- getFontWeight(): string;
1992
- /**
1993
- * Get the font style
1994
- */
1995
- getFontStyle(): string;
1996
- /**
1997
- * Generate CSS declaration for this font
1998
- * @returns CSS string (e.g., "font-family: Consolas; font-size: 16px;")
1999
- */
2000
- toCSS(): string;
2001
- }
2002
- /**
2003
- * BitmapFont configuration
2004
- * For pixel-based fonts with custom glyph data
2005
- */
2006
- interface BitmapFontConfig {
2007
- charWidth: number;
2008
- charHeight: number;
2009
- cellWidth?: number;
2010
- cellHeight?: number;
2011
- glyphs: Map<number, Uint8Array>;
2012
- }
2013
- /**
2014
- * BitmapFont class
2015
- * Represents a pixel-based font with custom glyph bitmaps
2016
- * Corresponds to LoadType 0x04 (Charset) in UTSP protocol
2017
- */
2018
- declare class BitmapFont {
2019
- private fontId;
2020
- private config;
2021
- constructor(fontId: number, config: BitmapFontConfig);
2022
- /**
2023
- * Get the unique font ID
2024
- */
2025
- getFontId(): number;
2026
- /**
2027
- * Get the full configuration (deep copy)
2028
- */
2029
- getConfig(): BitmapFontConfig;
2030
- /**
2031
- * Get the glyph width in pixels (actual bitmap size)
2032
- */
2033
- getCharWidth(): number;
2034
- /**
2035
- * Get the glyph height in pixels (actual bitmap size)
2036
- */
2037
- getCharHeight(): number;
2038
- /**
2039
- * Get the target cell width in pixels (rendering size)
2040
- * Defaults to glyph width if not specified
2041
- */
2042
- getCellWidth(): number;
2043
- /**
2044
- * Get the target cell height in pixels (rendering size)
2045
- * Defaults to glyph height if not specified
2046
- */
2047
- getCellHeight(): number;
2048
- /**
2049
- * Get the bitmap data for a specific character
2050
- * @param charCode Character code (0-255)
2051
- * @returns Bitmap data or undefined if not found
2052
- */
2053
- getGlyph(charCode: number): Uint8Array | undefined;
2054
- /**
2055
- * Check if a glyph exists for a character
2056
- * @param charCode Character code (0-255)
2057
- */
2058
- hasGlyph(charCode: number): boolean;
2059
- /**
2060
- * Get the number of glyphs in this font
2061
- */
2062
- getGlyphCount(): number;
2063
- /**
2064
- * Get all character codes that have glyphs
2065
- */
2066
- getCharCodes(): number[];
2067
- }
2068
2229
  /**
2069
2230
  * ImageFont configuration
2070
2231
  * For PNG atlas-based fonts with pre-rendered glyphs
@@ -2075,7 +2236,6 @@ interface ImageFontConfig {
2075
2236
  cellWidth?: number;
2076
2237
  cellHeight?: number;
2077
2238
  atlasBlocks: AtlasBlocks;
2078
- imageData: Uint8Array;
2079
2239
  }
2080
2240
  /**
2081
2241
  * ImageFont class
@@ -2104,13 +2264,22 @@ declare class ImageFont {
2104
2264
  private config;
2105
2265
  private readonly atlasColumns;
2106
2266
  private readonly maxCharCode;
2267
+ private blocks;
2107
2268
  constructor(fontId: number, config: ImageFontConfig);
2269
+ /**
2270
+ * Add image data for a specific block
2271
+ */
2272
+ addBlock(blockIndex: number, data: Uint8Array): void;
2273
+ /**
2274
+ * Get image data for a specific block
2275
+ */
2276
+ getBlock(blockIndex: number): Uint8Array | undefined;
2108
2277
  /**
2109
2278
  * Get the unique font ID
2110
2279
  */
2111
2280
  getFontId(): number;
2112
2281
  /**
2113
- * Get the full configuration (copy with new imageData reference)
2282
+ * Get the full configuration
2114
2283
  */
2115
2284
  getConfig(): ImageFontConfig;
2116
2285
  /**
@@ -2141,10 +2310,6 @@ declare class ImageFont {
2141
2310
  * Get the maximum supported charCode
2142
2311
  */
2143
2312
  getMaxCharCode(): number;
2144
- /**
2145
- * Get the PNG image data
2146
- */
2147
- getImageData(): Uint8Array;
2148
2313
  /**
2149
2314
  * Get the atlas dimensions in pixels
2150
2315
  */
@@ -2200,11 +2365,10 @@ declare enum LoadType {
2200
2365
  ColorPalette = 1,
2201
2366
  Sprite = 2,
2202
2367
  MulticolorSprite = 3,
2203
- BitmapFont = 4,// Formerly "Charset" - pixel-based fonts (bitpacking)
2204
2368
  Sound = 5,
2205
- WebFont = 6,// CSS-based fonts for browser rendering
2206
2369
  Macro = 7,// Macro template for client-side feedback
2207
- ImageFont = 8
2370
+ ImageFont = 8,// Header for PNG atlas-based fonts (structure only)
2371
+ ImageFontBlock = 9
2208
2372
  }
2209
2373
  /**
2210
2374
  * Color definition with RGBA+E values
@@ -2222,12 +2386,12 @@ interface Color {
2222
2386
  * Loads a palette of RGBA+E colors
2223
2387
  *
2224
2388
  * When slotId is provided, the palette is loaded into a named slot for later switching.
2225
- * When slotId is undefined/absent, the palette is loaded as the main active palette.
2389
+ * When slotId is undefined/absent, the palette is loaded into the default slot (0).
2226
2390
  *
2227
2391
  * @example
2228
2392
  * ```typescript
2229
- * // Main palette (backward compatible)
2230
- * { loadType: LoadType.ColorPalette, colors: [...] }
2393
+ * // Default slot (backward compatible)
2394
+ * { loadType: LoadType.ColorPalette, colors: [...] } // → treated as slot 0
2231
2395
  *
2232
2396
  * // Palette slot for dynamic switching
2233
2397
  * { loadType: LoadType.ColorPalette, slotId: 1, colors: [...] }
@@ -2272,40 +2436,6 @@ interface MulticolorSpriteLoad {
2272
2436
  data: MulticolorCell[];
2273
2437
  }>;
2274
2438
  }
2275
- /**
2276
- * BitmapFont Load (LoadType 0x04)
2277
- * Custom character definitions (monochrome bitmaps)
2278
- * Formerly known as "Charset" - renamed to BitmapFont for clarity
2279
- */
2280
- interface BitmapFontLoad {
2281
- loadType: LoadType.BitmapFont;
2282
- fontId: number;
2283
- width: number;
2284
- height: number;
2285
- cellWidth: number;
2286
- cellHeight: number;
2287
- characters: Array<{
2288
- charCode: number;
2289
- bitmap: Uint8Array;
2290
- }>;
2291
- }
2292
- /**
2293
- * WebFont Load (LoadType 0x06)
2294
- * CSS-based font definitions for browser rendering
2295
- * Note: The default font is "Courier New" (monospace), but users can specify non-monospace fonts
2296
- */
2297
- interface WebFontLoad {
2298
- loadType: LoadType.WebFont;
2299
- fontId: number;
2300
- fontFamily: string;
2301
- fontSize: number;
2302
- offsetX?: number;
2303
- offsetY?: number;
2304
- charSpacing?: number;
2305
- lineHeight?: number;
2306
- fontWeight?: string;
2307
- fontStyle?: string;
2308
- }
2309
2439
  /**
2310
2440
  * Sound Load (LoadType 0x05)
2311
2441
  * MIDI sound data for audio playback
@@ -2320,31 +2450,31 @@ interface SoundLoad {
2320
2450
  /**
2321
2451
  * ImageFont Load (LoadType 0x08)
2322
2452
  * PNG atlas-based fonts for extended character sets (256, 1024, or 4096 chars)
2323
- *
2324
- * Atlas layout (example for 4 blocks = 1024 chars):
2325
- * ```
2326
- * ┌─────────┬─────────┐
2327
- * │ 0-255 │ 256-511 │ 32×32 grid
2328
- * ├─────────┼─────────┤ = 1024 chars
2329
- * │ 512-767 │768-1023 │
2330
- * └─────────┴─────────┘
2331
- * ```
2453
+ * Note: Protocol supports only ONE active ImageFont.
2332
2454
  */
2333
2455
  interface ImageFontLoad {
2334
2456
  loadType: LoadType.ImageFont;
2335
- fontId: number;
2336
2457
  glyphWidth: number;
2337
2458
  glyphHeight: number;
2338
2459
  cellWidth: number;
2339
2460
  cellHeight: number;
2340
2461
  atlasBlocks: AtlasBlocks;
2462
+ }
2463
+ /**
2464
+ * ImageFont Block Load (LoadType 0x09)
2465
+ * Contains one block of PNG data for the active ImageFont.
2466
+ * One block = 256 characters (16x16 grid).
2467
+ */
2468
+ interface ImageFontBlockLoad {
2469
+ loadType: LoadType.ImageFontBlock;
2470
+ blockIndex: number;
2341
2471
  imageData: Uint8Array;
2342
2472
  }
2343
2473
 
2344
2474
  /**
2345
2475
  * Union type for all load types
2346
2476
  */
2347
- type AnyLoad = ColorPaletteLoad | SpriteLoad | MulticolorSpriteLoad | BitmapFontLoad | SoundLoad | WebFontLoad | MacroLoad | ImageFontLoad;
2477
+ type AnyLoad = ColorPaletteLoad | SpriteLoad | MulticolorSpriteLoad | SoundLoad | MacroLoad | ImageFontLoad | ImageFontBlockLoad;
2348
2478
 
2349
2479
  /**
2350
2480
  * Encoder for UTSP Load packets
@@ -2357,7 +2487,7 @@ declare class LoadEncoder {
2357
2487
  encode(load: AnyLoad): Uint8Array;
2358
2488
  /**
2359
2489
  * Encode ColorPaletteLoad (0x01)
2360
- * Structure (main palette): LoadType(1) + HasSlot(1=0x00) + PaletteSize(1) + [ColorId(1) + R(1) + G(1) + B(1) + A(1) + E(1)]*N
2490
+ * Structure (default slot): LoadType(1) + HasSlot(1=0x00) + PaletteSize(1) + [ColorId(1) + R(1) + G(1) + B(1) + A(1) + E(1)]*N
2361
2491
  * Structure (slot palette): LoadType(1) + HasSlot(1=0xFF) + SlotId(1) + PaletteSize(1) + [ColorId(1) + R(1) + G(1) + B(1) + A(1) + E(1)]*N
2362
2492
  */
2363
2493
  private encodeColorPalette;
@@ -2371,29 +2501,23 @@ declare class LoadEncoder {
2371
2501
  * Structure: LoadType(1) + SpriteCount(1) + [SpriteId(1) + SizeX(1) + SizeY(1) + Data(SizeX*SizeY*3)]*N
2372
2502
  */
2373
2503
  private encodeMulticolorSprite;
2374
- /**
2375
- * Encode BitmapFontLoad (0x04)
2376
- * Formerly "CharsetLoad" - renamed to BitmapFont
2377
- * Structure: LoadType(1) + FontId(1) + Width(1) + Height(1) + CellWidth(1) + CellHeight(1) + CharCount(1) + [CharCode(1) + Bitmap(ceil(W*H/8))]*N
2378
- */
2379
- private encodeBitmapFont;
2380
2504
  /**
2381
2505
  * Encode SoundLoad (0x05)
2382
2506
  * Structure: LoadType(1) + SoundCount(1) + [SoundId(1) + DataSize(2) + MidiData(DataSize)]*N
2383
2507
  */
2384
2508
  private encodeSound;
2385
- /**
2386
- * Encode WebFontLoad (0x06)
2387
- * NEW: CSS-based font definitions for browser rendering
2388
- * Structure: LoadType(1) + FontId(1) + Flags(1) + FontFamily(string) + FontSize(2) + [Optional fields based on flags]
2389
- */
2390
- private encodeWebFont;
2391
2509
  /**
2392
2510
  * Encode ImageFontLoad (0x08)
2393
- * PNG atlas-based font for extended character sets
2394
- * Structure: LoadType(1) + FontId(1) + GlyphWidth(1) + GlyphHeight(1) + CellWidth(1) + CellHeight(1) + AtlasBlocks(1) + ImageDataSize(4) + ImageData(N)
2511
+ * Header for PNG atlas-based fonts (structure only)
2512
+ * Structure: LoadType(1) + GlyphWidth(1) + GlyphHeight(1) + CellWidth(1) + CellHeight(1) + AtlasBlocks(1)
2395
2513
  */
2396
2514
  private encodeImageFont;
2515
+ /**
2516
+ * Encode ImageFontBlockLoad (0x09)
2517
+ * Data block for PNG atlas-based fonts
2518
+ * Structure: LoadType(1) + BlockIndex(1) + DataLength(4) + Data
2519
+ */
2520
+ private encodeImageFontBlock;
2397
2521
  }
2398
2522
 
2399
2523
  /**
@@ -2795,7 +2919,7 @@ declare class LoadDecoder {
2795
2919
  decode(data: Uint8Array, offset?: number): LoadDecodeResult;
2796
2920
  /**
2797
2921
  * Decode ColorPaletteLoad (0x01)
2798
- * Structure (main palette): LoadType(1) + HasSlot(1=0x00) + PaletteSize(1) + [ColorId(1) + R(1) + G(1) + B(1) + A(1) + E(1)]*N
2922
+ * Structure (default slot): LoadType(1) + HasSlot(1=0x00) + PaletteSize(1) + [ColorId(1) + R(1) + G(1) + B(1) + A(1) + E(1)]*N
2799
2923
  * Structure (slot palette): LoadType(1) + HasSlot(1=0xFF) + SlotId(1) + PaletteSize(1) + [ColorId(1) + R(1) + G(1) + B(1) + A(1) + E(1)]*N
2800
2924
  */
2801
2925
  private decodeColorPalette;
@@ -2807,11 +2931,6 @@ declare class LoadDecoder {
2807
2931
  * Decode MulticolorSpriteLoad (0x03)
2808
2932
  */
2809
2933
  private decodeMulticolorSprite;
2810
- /**
2811
- * Decode BitmapFontLoad (0x04)
2812
- * Formerly "CharsetLoad" - renamed to BitmapFont
2813
- */
2814
- private decodeBitmapFont;
2815
2934
  /**
2816
2935
  * Decode SoundLoad (0x05)
2817
2936
  */
@@ -2820,11 +2939,6 @@ declare class LoadDecoder {
2820
2939
  * Helper to check if buffer has enough bytes remaining
2821
2940
  */
2822
2941
  private checkSize;
2823
- /**
2824
- * Decode WebFontLoad (0x06)
2825
- * NEW: CSS-based font definitions for browser rendering
2826
- */
2827
- private decodeWebFont;
2828
2942
  /**
2829
2943
  * Decode MacroLoad (0x07)
2830
2944
  */
@@ -2834,6 +2948,12 @@ declare class LoadDecoder {
2834
2948
  * PNG atlas-based font for extended character sets
2835
2949
  */
2836
2950
  private decodeImageFont;
2951
+ /**
2952
+ * Decode ImageFontBlockLoad (0x09)
2953
+ * Data block for PNG atlas-based fonts
2954
+ * Structure: LoadType(1) + BlockIndex(1) + DataLength(4) + Data
2955
+ */
2956
+ private decodeImageFontBlock;
2837
2957
  }
2838
2958
 
2839
2959
  /**
@@ -2905,8 +3025,8 @@ declare class MacroEventDecoder {
2905
3025
 
2906
3026
  /**
2907
3027
  * CharCode mode for layers
2908
- * - '8bit': Uses Uint8Array, limited to 256 characters (ASCII/CP437), optimized bandwidth
2909
- * - '16bit': Uses Uint16Array, supports 65536 characters (Unicode BMP), universal
3028
+ * - '8bit': 256 char codes (CP437 default)
3029
+ * - '16bit': 65536 char codes (256 atlas blocks × 256 chars)
2910
3030
  */
2911
3031
  type CharCodeMode = '8bit' | '16bit';
2912
3032
  interface Cell {
@@ -2915,19 +3035,16 @@ interface Cell {
2915
3035
  bgColorCode: number;
2916
3036
  }
2917
3037
  /**
2918
- * Optimized buffer for cells with TypedArray
2919
- * Separate arrays for charCodes and colors for optimal memory layout
3038
+ * Optimized buffer for cells
2920
3039
  *
2921
3040
  * CharCode storage depends on mode:
2922
- * - 8-bit mode: Uint8Array (1 byte per charCode) - network optimized
2923
- * - 16-bit mode: Uint16Array (2 bytes per charCode) - full Unicode BMP
3041
+ * - 8-bit mode: 256 char codes
3042
+ * - 16-bit mode: 65536 char codes (atlas indices)
2924
3043
  *
2925
3044
  * Colors are always 8-bit (256 palette colors)
2926
3045
  *
2927
3046
  * Performance:
2928
3047
  * - clear(): ~5-10μs (vs 826μs with object array)
2929
- * - Better cache locality
2930
- * - Less GC pressure
2931
3048
  */
2932
3049
  declare class CellBuffer {
2933
3050
  private charCodes;
@@ -3039,7 +3156,7 @@ declare class CellBuffer {
3039
3156
  /**
3040
3157
  * Optimized buffer to store only charcodes (unicolor sprites)
3041
3158
  * Simple structure: [char0, char1, char2, ...]
3042
- * Always uses 16-bit charCodes to support full Unicode BMP
3159
+ * Always uses 16-bit charCodes to support atlas indices (0-65535)
3043
3160
  *
3044
3161
  * Performance:
3045
3162
  * - Less memory than CellBuffer (2 bytes vs 4 bytes per cell)
@@ -3415,14 +3532,21 @@ declare class ImageFontRegistry {
3415
3532
  */
3416
3533
  private allocateId;
3417
3534
  /**
3418
- * Register a new ImageFont with auto-assigned ID
3535
+ * Register a new ImageFont structure (no data)
3536
+ * Use addBlock() to add image data
3419
3537
  * @param name Human-readable name for the font
3420
3538
  * @param options Font options (glyph size, atlas blocks)
3421
- * @param imageData PNG image data
3422
3539
  * @returns The assigned font ID (0-255)
3423
3540
  * @throws Error if name already exists
3424
3541
  */
3425
- registerFont(name: string, options: ImageFontOptions, imageData: Uint8Array): number;
3542
+ registerFont(name: string, options: ImageFontOptions): number;
3543
+ /**
3544
+ * Add a data block to an existing font
3545
+ * @param fontId The font ID
3546
+ * @param blockIndex Block index (0-15)
3547
+ * @param data PNG image data
3548
+ */
3549
+ addBlock(fontId: number, blockIndex: number, data: Uint8Array): void;
3426
3550
  /**
3427
3551
  * Load a new ImageFont into the registry with specific ID (low-level API)
3428
3552
  * @param fontId Unique font identifier (0-255)
@@ -4317,85 +4441,276 @@ declare class UserStats {
4317
4441
  private _userName;
4318
4442
  constructor(userId: string, userName: string);
4319
4443
  /**
4320
- * Enables or disables statistics collection
4444
+ * Enables or disables statistics collection.
4445
+ *
4446
+ * @param enabled - Whether to collect stats.
4447
+ *
4448
+ * @example
4449
+ * ```typescript
4450
+ * user.getStats().setEnabled(true);
4451
+ * ```
4321
4452
  */
4322
4453
  setEnabled(enabled: boolean): void;
4454
+ /**
4455
+ * Returns whether statistics collection is enabled.
4456
+ *
4457
+ * @returns true if enabled.
4458
+ */
4323
4459
  isEnabled(): boolean;
4324
- /** User ID */
4460
+ /**
4461
+ * Returns the user ID.
4462
+ *
4463
+ * @returns User ID.
4464
+ *
4465
+ * @example
4466
+ * ```typescript
4467
+ * const id = user.getStats().userId;
4468
+ * ```
4469
+ */
4325
4470
  get userId(): string;
4326
- /** User name */
4471
+ /**
4472
+ * Returns the user name.
4473
+ *
4474
+ * @returns User name.
4475
+ *
4476
+ * @example
4477
+ * ```typescript
4478
+ * const name = user.getStats().userName;
4479
+ * ```
4480
+ */
4327
4481
  get userName(): string;
4328
- /** Current tick number */
4482
+ /**
4483
+ * Returns the current tick number.
4484
+ *
4485
+ * @returns Tick number.
4486
+ *
4487
+ * @example
4488
+ * ```typescript
4489
+ * const tick = user.getStats().tick;
4490
+ * ```
4491
+ */
4329
4492
  get tick(): number;
4330
- /** Current tick timestamp */
4493
+ /**
4494
+ * Returns the current tick timestamp.
4495
+ *
4496
+ * @returns Timestamp in ms.
4497
+ *
4498
+ * @example
4499
+ * ```typescript
4500
+ * const ts = user.getStats().timestamp;
4501
+ * ```
4502
+ */
4331
4503
  get timestamp(): number;
4332
- /** Number of displays */
4504
+ /**
4505
+ * Returns the number of displays.
4506
+ *
4507
+ * @returns Display count.
4508
+ *
4509
+ * @example
4510
+ * ```typescript
4511
+ * const count = user.getStats().displayCount;
4512
+ * ```
4513
+ */
4333
4514
  get displayCount(): number;
4334
- /** Total display surface area (width × height) */
4515
+ /**
4516
+ * Returns the total display surface area (width × height).
4517
+ *
4518
+ * @returns Total display area.
4519
+ *
4520
+ * @example
4521
+ * ```typescript
4522
+ * const area = user.getStats().totalDisplayArea;
4523
+ * ```
4524
+ */
4335
4525
  get totalDisplayArea(): number;
4336
- /** Total number of layers */
4526
+ /**
4527
+ * Returns the total number of layers.
4528
+ *
4529
+ * @returns Total layer count.
4530
+ *
4531
+ * @example
4532
+ * ```typescript
4533
+ * const total = user.getStats().totalLayers;
4534
+ * ```
4535
+ */
4337
4536
  get totalLayers(): number;
4338
- /** Visible layers in displays */
4537
+ /**
4538
+ * Returns the number of visible layers in displays.
4539
+ *
4540
+ * @returns Visible layer count.
4541
+ *
4542
+ * @example
4543
+ * ```typescript
4544
+ * const visible = user.getStats().visibleLayers;
4545
+ * ```
4546
+ */
4339
4547
  get visibleLayers(): number;
4340
- /** Static layers */
4548
+ /**
4549
+ * Returns the number of reliable layers.
4550
+ *
4551
+ * @returns Reliable layer count.
4552
+ *
4553
+ * @example
4554
+ * ```typescript
4555
+ * const reliable = user.getStats().staticLayers;
4556
+ * ```
4557
+ */
4341
4558
  get staticLayers(): number;
4342
- /** Dynamic layers */
4559
+ /**
4560
+ * Returns the number of volatile layers.
4561
+ *
4562
+ * @returns Volatile layer count.
4563
+ *
4564
+ * @example
4565
+ * ```typescript
4566
+ * const volatile = user.getStats().dynamicLayers;
4567
+ * ```
4568
+ */
4343
4569
  get dynamicLayers(): number;
4344
- /** Total orders for this user */
4570
+ /**
4571
+ * Returns the total number of orders for this user.
4572
+ *
4573
+ * @returns Total order count.
4574
+ *
4575
+ * @example
4576
+ * ```typescript
4577
+ * const orders = user.getStats().totalOrders;
4578
+ * ```
4579
+ */
4345
4580
  get totalOrders(): number;
4346
- /** Orders par layer ID */
4581
+ /**
4582
+ * Returns order counts per layer ID.
4583
+ *
4584
+ * @returns Map of layerId → order count.
4585
+ *
4586
+ * @example
4587
+ * ```typescript
4588
+ * const byLayer = user.getStats().ordersByLayer;
4589
+ * const uiOrders = byLayer.get(2) ?? 0;
4590
+ * ```
4591
+ */
4347
4592
  get ordersByLayer(): Map<number, number>;
4348
- /** Taille du packet statique (octets) */
4593
+ /**
4594
+ * Returns the static packet size in bytes.
4595
+ *
4596
+ * @returns Static packet size.
4597
+ *
4598
+ * @example
4599
+ * ```typescript
4600
+ * const size = user.getStats().staticPacketSize;
4601
+ * ```
4602
+ */
4349
4603
  get staticPacketSize(): number;
4350
- /** Taille du packet dynamique (octets) */
4604
+ /**
4605
+ * Returns the dynamic packet size in bytes.
4606
+ *
4607
+ * @returns Dynamic packet size.
4608
+ *
4609
+ * @example
4610
+ * ```typescript
4611
+ * const size = user.getStats().dynamicPacketSize;
4612
+ * ```
4613
+ */
4351
4614
  get dynamicPacketSize(): number;
4352
- /** Taille totale des packets (static + dynamic) */
4615
+ /**
4616
+ * Returns the total packet size (static + dynamic) in bytes.
4617
+ *
4618
+ * @returns Total packet size.
4619
+ *
4620
+ * @example
4621
+ * ```typescript
4622
+ * const total = user.getStats().totalPacketSize;
4623
+ * ```
4624
+ */
4353
4625
  get totalPacketSize(): number;
4354
- /** Estimated size after gzip compression (25% of original size) */
4626
+ /**
4627
+ * Returns the estimated compressed size (25% of original).
4628
+ *
4629
+ * @returns Estimated compressed size.
4630
+ *
4631
+ * @example
4632
+ * ```typescript
4633
+ * const compressed = user.getStats().compressedPacketSize;
4634
+ * ```
4635
+ */
4355
4636
  get compressedPacketSize(): number;
4356
- /** If user sent input this tick */
4637
+ /**
4638
+ * Returns whether the user sent input this tick.
4639
+ *
4640
+ * @returns true if input was sent.
4641
+ *
4642
+ * @example
4643
+ * ```typescript
4644
+ * if (user.getStats().hasInput) {
4645
+ * console.log('Input received this tick');
4646
+ * }
4647
+ * ```
4648
+ */
4357
4649
  get hasInput(): boolean;
4358
- /** Number of bound axes */
4650
+ /**
4651
+ * Returns the number of bound axes.
4652
+ *
4653
+ * @returns Axis count.
4654
+ *
4655
+ * @example
4656
+ * ```typescript
4657
+ * const axes = user.getStats().axisCount;
4658
+ * ```
4659
+ */
4359
4660
  get axisCount(): number;
4360
- /** Number of bound buttons */
4661
+ /**
4662
+ * Returns the number of bound buttons.
4663
+ *
4664
+ * @returns Button count.
4665
+ *
4666
+ * @example
4667
+ * ```typescript
4668
+ * const buttons = user.getStats().buttonCount;
4669
+ * ```
4670
+ */
4361
4671
  get buttonCount(): number;
4362
4672
  /**
4673
+ * Starts collection for a new tick.
4363
4674
  * @internal
4364
- * Starts collection for a new tick
4365
4675
  */
4366
4676
  startTick(tickNumber: number): void;
4367
4677
  /**
4678
+ * Records display information.
4368
4679
  * @internal
4369
- * Records display information
4370
4680
  */
4371
4681
  recordDisplays(displayCount: number, totalArea: number): void;
4372
4682
  /**
4683
+ * Records layer information.
4373
4684
  * @internal
4374
- * Enregistre les informations des layers
4375
4685
  */
4376
4686
  recordLayers(total: number, visible: number, staticCount: number, dynamicCount: number): void;
4377
4687
  /**
4688
+ * Records order count for a layer.
4378
4689
  * @internal
4379
- * Enregistre les orders d'un layer
4380
4690
  */
4381
4691
  recordLayerOrders(layerId: number, orderCount: number): void;
4382
4692
  /**
4693
+ * Records network packet sizes.
4383
4694
  * @internal
4384
- * Records network packet sizes
4385
4695
  */
4386
4696
  recordPacketSizes(staticSize: number, dynamicSize: number): void;
4387
4697
  /**
4698
+ * Records input information.
4388
4699
  * @internal
4389
- * Records input information
4390
4700
  */
4391
4701
  recordInput(hasInput: boolean, axisCount: number, buttonCount: number): void;
4392
4702
  /**
4703
+ * Finalizes current tick stats.
4393
4704
  * @internal
4394
- * Finalizes current tick stats
4395
4705
  */
4396
4706
  endTick(): void;
4397
4707
  /**
4398
- * Resets statistics
4708
+ * Resets statistics.
4709
+ *
4710
+ * @example
4711
+ * ```typescript
4712
+ * user.getStats().reset();
4713
+ * ```
4399
4714
  */
4400
4715
  reset(): void;
4401
4716
  }
@@ -4457,6 +4772,10 @@ declare class User<TData = Record<string, any>> {
4457
4772
  private currentTickBytesSent;
4458
4773
  private currentTickBytesReceived;
4459
4774
  private availableViewports;
4775
+ /**
4776
+ * Display command sink (used by Display to enqueue network commands)
4777
+ */
4778
+ private readonly displayCommandSink;
4460
4779
  /**
4461
4780
  * Application-specific data storage
4462
4781
  * Use this to store game state, player data, or any custom information
@@ -4468,11 +4787,28 @@ declare class User<TData = Record<string, any>> {
4468
4787
  * @internal
4469
4788
  */
4470
4789
  setSpriteRegistry(registry: SpriteRegistry): void;
4790
+ /**
4791
+ * Returns all displays for this user.
4792
+ *
4793
+ * @returns Array of displays.
4794
+ *
4795
+ * @example
4796
+ * ```typescript
4797
+ * const displays = user.getDisplays();
4798
+ * const mainDisplay = displays[0];
4799
+ * ```
4800
+ */
4471
4801
  getDisplays(): Display[];
4472
4802
  /**
4473
4803
  * Adds a display to the user
4474
4804
  *
4475
4805
  * @param display - The display to add
4806
+ *
4807
+ * @example
4808
+ * ```typescript
4809
+ * const display = new Display(0, 80, 25);
4810
+ * user.addDisplay(display);
4811
+ * ```
4476
4812
  */
4477
4813
  addDisplay(display: Display): void;
4478
4814
  /**
@@ -4480,10 +4816,21 @@ declare class User<TData = Record<string, any>> {
4480
4816
  *
4481
4817
  * @param display - The display to remove
4482
4818
  * @returns true if display was removed, false otherwise
4819
+ *
4820
+ * @example
4821
+ * ```typescript
4822
+ * const ok = user.removeDisplay(display);
4823
+ * if (!ok) console.warn('Display not found');
4824
+ * ```
4483
4825
  */
4484
4826
  removeDisplay(display: Display): boolean;
4485
4827
  /**
4486
4828
  * Removes all displays from the user
4829
+ *
4830
+ * @example
4831
+ * ```typescript
4832
+ * user.clearDisplays();
4833
+ * ```
4487
4834
  */
4488
4835
  clearDisplays(): void;
4489
4836
  /**
@@ -4525,6 +4872,12 @@ declare class User<TData = Record<string, any>> {
4525
4872
  * Gets all available viewports (in pixels)
4526
4873
  *
4527
4874
  * @returns Map of displayId → viewport size
4875
+ *
4876
+ * @example
4877
+ * ```typescript
4878
+ * const viewports = user.getAllDisplayViewports();
4879
+ * const display0 = viewports.get(0);
4880
+ * ```
4528
4881
  */
4529
4882
  getAllDisplayViewports(): Map<number, {
4530
4883
  pixelWidth: number;
@@ -4558,12 +4911,29 @@ declare class User<TData = Record<string, any>> {
4558
4911
  cols: number;
4559
4912
  rows: number;
4560
4913
  } | null;
4914
+ /**
4915
+ * Returns all layers for this user.
4916
+ *
4917
+ * @returns Array of layers.
4918
+ *
4919
+ * @example
4920
+ * ```typescript
4921
+ * const layers = user.getLayers();
4922
+ * const uiLayer = layers.find((l) => l.getName() === 'ui');
4923
+ * ```
4924
+ */
4561
4925
  getLayers(): Layer[];
4562
4926
  /**
4563
4927
  * Gets a layer by its ID
4564
4928
  *
4565
4929
  * @param layerId - The layer ID to find
4566
4930
  * @returns The layer, or undefined if not found
4931
+ *
4932
+ * @example
4933
+ * ```typescript
4934
+ * const layer = user.getLayerById(2);
4935
+ * if (layer) layer.setZOrder(10);
4936
+ * ```
4567
4937
  */
4568
4938
  getLayerById(layerId: number): Layer | undefined;
4569
4939
  /**
@@ -4572,6 +4942,12 @@ declare class User<TData = Record<string, any>> {
4572
4942
  *
4573
4943
  * @param layer - The layer to add
4574
4944
  * @param name - Optional name for macro system (used in createInstance)
4945
+ *
4946
+ * @example
4947
+ * ```typescript
4948
+ * const layer = new Layer(new Vector2(0, 0), 0, 80, 25);
4949
+ * user.addLayer(layer, 'game');
4950
+ * ```
4575
4951
  */
4576
4952
  addLayer(layer: Layer, name?: string): void;
4577
4953
  /**
@@ -4579,10 +4955,20 @@ declare class User<TData = Record<string, any>> {
4579
4955
  *
4580
4956
  * @param layer - The layer to remove
4581
4957
  * @returns true if layer was removed, false otherwise
4958
+ *
4959
+ * @example
4960
+ * ```typescript
4961
+ * user.removeLayer(layer);
4962
+ * ```
4582
4963
  */
4583
4964
  removeLayer(layer: Layer): boolean;
4584
4965
  /**
4585
4966
  * Removes all layers from the user
4967
+ *
4968
+ * @example
4969
+ * ```typescript
4970
+ * user.clearLayers();
4971
+ * ```
4586
4972
  */
4587
4973
  clearLayers(): void;
4588
4974
  /**
@@ -5134,11 +5520,27 @@ declare class User<TData = Record<string, any>> {
5134
5520
  /**
5135
5521
  * Gets total bytes sent to this user (server-side)
5136
5522
  * Excludes bridge messages.
5523
+ *
5524
+ * @returns Total bytes sent.
5525
+ *
5526
+ * @example
5527
+ * ```typescript
5528
+ * const total = user.getTotalBytesSent();
5529
+ * console.log(`Sent: ${total} bytes`);
5530
+ * ```
5137
5531
  */
5138
5532
  getTotalBytesSent(): number;
5139
5533
  /**
5140
5534
  * Gets total bytes received by this user (client-side)
5141
5535
  * Excludes bridge messages.
5536
+ *
5537
+ * @returns Total bytes received.
5538
+ *
5539
+ * @example
5540
+ * ```typescript
5541
+ * const total = user.getTotalBytesReceived();
5542
+ * console.log(`Received: ${total} bytes`);
5543
+ * ```
5142
5544
  */
5143
5545
  getTotalBytesReceived(): number;
5144
5546
  /**
@@ -5153,12 +5555,22 @@ declare class User<TData = Record<string, any>> {
5153
5555
  recordBytesReceived(bytes: number): void;
5154
5556
  /**
5155
5557
  * Resets byte counters (useful for periodic stats)
5558
+ *
5559
+ * @example
5560
+ * ```typescript
5561
+ * user.resetByteCounters();
5562
+ * ```
5156
5563
  */
5157
5564
  resetByteCounters(): void;
5158
5565
  /**
5159
5566
  * Sets the tick rate for bytes-per-second calculation
5160
5567
  * Call this when the runtime tick rate changes
5161
5568
  * @param tickRate - The tick rate in ticks per second
5569
+ *
5570
+ * @example
5571
+ * ```typescript
5572
+ * user.setBytesTickRate(60);
5573
+ * ```
5162
5574
  */
5163
5575
  setBytesTickRate(tickRate: number): void;
5164
5576
  /**
@@ -5170,11 +5582,21 @@ declare class User<TData = Record<string, any>> {
5170
5582
  /**
5171
5583
  * Gets bytes sent per second (sliding window over last second)
5172
5584
  * @returns Bytes sent per second
5173
- */
5174
- getBytesSentPerSecond(): number;
5175
- /**
5585
+ *
5586
+ * @example
5587
+ * ```typescript
5588
+ * const sentPerSec = user.getBytesSentPerSecond();
5589
+ * ```
5590
+ */
5591
+ getBytesSentPerSecond(): number;
5592
+ /**
5176
5593
  * Gets bytes received per second (sliding window over last second)
5177
5594
  * @returns Bytes received per second
5595
+ *
5596
+ * @example
5597
+ * ```typescript
5598
+ * const recvPerSec = user.getBytesReceivedPerSecond();
5599
+ * ```
5178
5600
  */
5179
5601
  getBytesReceivedPerSecond(): number;
5180
5602
  /**
@@ -5182,6 +5604,11 @@ declare class User<TData = Record<string, any>> {
5182
5604
  *
5183
5605
  * @param name - Axis name
5184
5606
  * @returns bindingId or null if not found
5607
+ *
5608
+ * @example
5609
+ * ```typescript
5610
+ * const id = user.getAxisBindingId('MoveHorizontal');
5611
+ * ```
5185
5612
  */
5186
5613
  getAxisBindingId(name: string): number | null;
5187
5614
  /**
@@ -5189,6 +5616,11 @@ declare class User<TData = Record<string, any>> {
5189
5616
  *
5190
5617
  * @param name - Button name
5191
5618
  * @returns bindingId or null if not found
5619
+ *
5620
+ * @example
5621
+ * ```typescript
5622
+ * const id = user.getButtonBindingId('Jump');
5623
+ * ```
5192
5624
  */
5193
5625
  getButtonBindingId(name: string): number | null;
5194
5626
  /**
@@ -5818,6 +6250,13 @@ declare class User<TData = Record<string, any>> {
5818
6250
  *
5819
6251
  * @param soundId - The sound ID to check
5820
6252
  * @returns true if the sound is loaded
6253
+ *
6254
+ * @example
6255
+ * ```typescript
6256
+ * if (user.isSoundLoaded(3)) {
6257
+ * console.log('Sound 3 is ready');
6258
+ * }
6259
+ * ```
5821
6260
  */
5822
6261
  isSoundLoaded(soundId: number): boolean;
5823
6262
  /**
@@ -5825,12 +6264,24 @@ declare class User<TData = Record<string, any>> {
5825
6264
  *
5826
6265
  * @param soundId - The sound ID to check
5827
6266
  * @returns Error message if failed, undefined otherwise
6267
+ *
6268
+ * @example
6269
+ * ```typescript
6270
+ * const error = user.getSoundLoadError(3);
6271
+ * if (error) console.warn(error);
6272
+ * ```
5828
6273
  */
5829
6274
  getSoundLoadError(soundId: number): string | undefined;
5830
6275
  /**
5831
6276
  * Get all loaded sounds on the client
5832
6277
  *
5833
6278
  * @returns Map of soundId to load info
6279
+ *
6280
+ * @example
6281
+ * ```typescript
6282
+ * const loaded = user.getLoadedSounds();
6283
+ * console.log(`Loaded: ${loaded.size}`);
6284
+ * ```
5834
6285
  */
5835
6286
  getLoadedSounds(): ReadonlyMap<number, {
5836
6287
  name: string;
@@ -5840,6 +6291,12 @@ declare class User<TData = Record<string, any>> {
5840
6291
  * Get all sound load errors
5841
6292
  *
5842
6293
  * @returns Map of soundId to error info
6294
+ *
6295
+ * @example
6296
+ * ```typescript
6297
+ * const errors = user.getSoundLoadErrors();
6298
+ * errors.forEach((info, id) => console.warn(id, info.error));
6299
+ * ```
5843
6300
  */
5844
6301
  getSoundLoadErrors(): ReadonlyMap<number, {
5845
6302
  name: string;
@@ -5851,12 +6308,25 @@ declare class User<TData = Record<string, any>> {
5851
6308
  *
5852
6309
  * @param instanceId - The instance ID to check
5853
6310
  * @returns true if the instance is playing
6311
+ *
6312
+ * @example
6313
+ * ```typescript
6314
+ * if (user.isSoundPlaying(musicId)) {
6315
+ * console.log('Music is playing');
6316
+ * }
6317
+ * ```
5854
6318
  */
5855
6319
  isSoundPlaying(instanceId: SoundInstanceId): boolean;
5856
6320
  /**
5857
6321
  * Get all currently playing sounds on the client
5858
6322
  *
5859
6323
  * @returns Map of instanceId to playback info
6324
+ *
6325
+ * @example
6326
+ * ```typescript
6327
+ * const playing = user.getPlayingSounds();
6328
+ * playing.forEach((info, id) => console.log(id, info.soundId));
6329
+ * ```
5860
6330
  */
5861
6331
  getPlayingSounds(): ReadonlyMap<SoundInstanceId, {
5862
6332
  soundId: number;
@@ -5864,6 +6334,13 @@ declare class User<TData = Record<string, any>> {
5864
6334
  }>;
5865
6335
  /**
5866
6336
  * Get the number of sounds currently playing on the client
6337
+ *
6338
+ * @returns Count of active sound instances.
6339
+ *
6340
+ * @example
6341
+ * ```typescript
6342
+ * const count = user.getPlayingSoundCount();
6343
+ * ```
5867
6344
  */
5868
6345
  getPlayingSoundCount(): number;
5869
6346
  /**
@@ -5989,6 +6466,12 @@ declare class User<TData = Record<string, any>> {
5989
6466
  *
5990
6467
  * @param instanceName - Instance name
5991
6468
  * @param eventType - Event type to remove (optional, removes all if not specified)
6469
+ *
6470
+ * @example
6471
+ * ```typescript
6472
+ * user.offMacroEvent('btn-play', 'click');
6473
+ * user.offMacroEvent('btn-play'); // remove all handlers for instance
6474
+ * ```
5992
6475
  */
5993
6476
  offMacroEvent(instanceName: string, eventType?: string): void;
5994
6477
  /**
@@ -6038,6 +6521,11 @@ declare class User<TData = Record<string, any>> {
6038
6521
  *
6039
6522
  * @param name - Layer name (used in createInstance)
6040
6523
  * @param layer - The layer object
6524
+ *
6525
+ * @example
6526
+ * ```typescript
6527
+ * user.registerLayerName('ui', uiLayer);
6528
+ * ```
6041
6529
  */
6042
6530
  registerLayerName(name: string, layer: Layer): void;
6043
6531
  /**
@@ -6054,6 +6542,12 @@ declare class User<TData = Record<string, any>> {
6054
6542
  * Should be called once per tick (tick-based updates)
6055
6543
  *
6056
6544
  * @returns Update result with events and sounds to play
6545
+ *
6546
+ * @example
6547
+ * ```typescript
6548
+ * const result = user.updateMacros();
6549
+ * user.processMacroEvents(result);
6550
+ * ```
6057
6551
  */
6058
6552
  updateMacros(): MacroUpdateResult;
6059
6553
  /**
@@ -6061,6 +6555,12 @@ declare class User<TData = Record<string, any>> {
6061
6555
  * Dispatches events to registered handlers (used in standalone mode)
6062
6556
  *
6063
6557
  * @param result - The result from updateMacros()
6558
+ *
6559
+ * @example
6560
+ * ```typescript
6561
+ * const result = user.updateMacros();
6562
+ * user.processMacroEvents(result);
6563
+ * ```
6064
6564
  */
6065
6565
  processMacroEvents(result: MacroUpdateResult): void;
6066
6566
  /**
@@ -6070,6 +6570,11 @@ declare class User<TData = Record<string, any>> {
6070
6570
  * @param displayX - Mouse X position in display cells (local to display)
6071
6571
  * @param displayY - Mouse Y position in display cells (local to display)
6072
6572
  * @param isDown - Whether the mouse button is pressed
6573
+ *
6574
+ * @example
6575
+ * ```typescript
6576
+ * user.updateMacroMouse(mouseX, mouseY, mouseDown);
6577
+ * ```
6073
6578
  */
6074
6579
  updateMacroMouse(displayX: number, displayY: number, isDown: boolean): void;
6075
6580
  /**
@@ -6078,12 +6583,24 @@ declare class User<TData = Record<string, any>> {
6078
6583
  * by subtracting the display's origin.
6079
6584
  *
6080
6585
  * @returns Map of layerId → render orders (in display coordinates)
6586
+ *
6587
+ * @example
6588
+ * ```typescript
6589
+ * const ordersByLayer = user.getMacroRenderOrders();
6590
+ * const uiOrders = ordersByLayer.get(uiLayerId) ?? [];
6591
+ * ```
6081
6592
  */
6082
6593
  getMacroRenderOrders(): Map<number, AnyNetworkOrder[]>;
6083
6594
  /**
6084
6595
  * Get the effect offset (for screen shake, etc.)
6085
6596
  *
6086
6597
  * @returns Current offset from effect macros
6598
+ *
6599
+ * @example
6600
+ * ```typescript
6601
+ * const offset = user.getMacroEffectOffset();
6602
+ * camera.setShake(offset.x, offset.y);
6603
+ * ```
6087
6604
  */
6088
6605
  getMacroEffectOffset(): {
6089
6606
  x: number;
@@ -6096,14 +6613,29 @@ declare class User<TData = Record<string, any>> {
6096
6613
  getMacroEngine(): MacroEngine;
6097
6614
  /**
6098
6615
  * Move focus to next focusable macro element
6616
+ *
6617
+ * @example
6618
+ * ```typescript
6619
+ * user.macroFocusNext();
6620
+ * ```
6099
6621
  */
6100
6622
  macroFocusNext(): void;
6101
6623
  /**
6102
6624
  * Move focus to previous focusable macro element
6625
+ *
6626
+ * @example
6627
+ * ```typescript
6628
+ * user.macroFocusPrevious();
6629
+ * ```
6103
6630
  */
6104
6631
  macroFocusPrevious(): void;
6105
6632
  /**
6106
6633
  * Activate the currently focused macro element
6634
+ *
6635
+ * @example
6636
+ * ```typescript
6637
+ * user.macroActivateFocused();
6638
+ * ```
6107
6639
  */
6108
6640
  macroActivateFocused(): void;
6109
6641
  /**
@@ -6130,7 +6662,7 @@ declare class User<TData = Record<string, any>> {
6130
6662
  * user.setPostProcess(0, null);
6131
6663
  * ```
6132
6664
  */
6133
- setPostProcess(displayId: number, config: PostProcessConfig | null): void;
6665
+ private setPostProcess;
6134
6666
  /**
6135
6667
  * Enable or disable scanlines effect with default/current settings for a specific display
6136
6668
  *
@@ -6143,7 +6675,7 @@ declare class User<TData = Record<string, any>> {
6143
6675
  * user.setScanlinesEnabled(0, false); // Disable on display 0
6144
6676
  * ```
6145
6677
  */
6146
- setScanlinesEnabled(displayId: number, enabled: boolean): void;
6678
+ private setScanlinesEnabled;
6147
6679
  /**
6148
6680
  * Set scanlines opacity (0-1) for a specific display
6149
6681
  *
@@ -6158,14 +6690,14 @@ declare class User<TData = Record<string, any>> {
6158
6690
  * user.setScanlinesOpacity(0, 0.5); // Strong effect on display 0
6159
6691
  * ```
6160
6692
  */
6161
- setScanlinesOpacity(displayId: number, opacity: number): void;
6693
+ private setScanlinesOpacity;
6162
6694
  /**
6163
6695
  * Set scanlines pattern for a specific display
6164
6696
  *
6165
6697
  * @param displayId - Display ID (0-255)
6166
6698
  * @param pattern - Pattern type: 'horizontal', 'vertical', or 'grid'
6167
6699
  */
6168
- setScanlinesPattern(displayId: number, pattern: 'horizontal' | 'vertical' | 'grid'): void;
6700
+ private setScanlinesPattern;
6169
6701
  /**
6170
6702
  * Enable or configure ambient effect for a specific display
6171
6703
  *
@@ -6189,10 +6721,7 @@ declare class User<TData = Record<string, any>> {
6189
6721
  * user.setAmbientEffect(1, { blur: 50, scale: 1.5 });
6190
6722
  * ```
6191
6723
  */
6192
- setAmbientEffect(displayId: number, config: boolean | {
6193
- blur?: number;
6194
- scale?: number;
6195
- }): void;
6724
+ private setAmbientEffect;
6196
6725
  /**
6197
6726
  * Enable or disable ambient effect for a specific display
6198
6727
  *
@@ -6205,7 +6734,7 @@ declare class User<TData = Record<string, any>> {
6205
6734
  * user.setAmbientEffectEnabled(0, false); // Disable on display 0
6206
6735
  * ```
6207
6736
  */
6208
- setAmbientEffectEnabled(displayId: number, enabled: boolean): void;
6737
+ private setAmbientEffectEnabled;
6209
6738
  /**
6210
6739
  * Set ambient effect blur intensity for a specific display
6211
6740
  *
@@ -6218,7 +6747,7 @@ declare class User<TData = Record<string, any>> {
6218
6747
  * user.setAmbientEffectBlur(0, 15); // Less blur on display 0
6219
6748
  * ```
6220
6749
  */
6221
- setAmbientEffectBlur(displayId: number, blur: number): void;
6750
+ private setAmbientEffectBlur;
6222
6751
  /**
6223
6752
  * Set ambient effect scale factor for a specific display
6224
6753
  *
@@ -6231,23 +6760,19 @@ declare class User<TData = Record<string, any>> {
6231
6760
  * user.setAmbientEffectScale(0, 1.1); // Smaller glow area on display 0
6232
6761
  * ```
6233
6762
  */
6234
- setAmbientEffectScale(displayId: number, scale: number): void;
6763
+ private setAmbientEffectScale;
6235
6764
  /**
6236
6765
  * Check if ambient effect is currently enabled
6237
6766
  */
6238
- isAmbientEffectEnabled(): boolean;
6767
+ private isAmbientEffectEnabled;
6239
6768
  /**
6240
6769
  * Get current ambient effect configuration
6241
6770
  */
6242
- getAmbientEffectConfig(): {
6243
- enabled: boolean;
6244
- blur: number;
6245
- scale: number;
6246
- } | null;
6771
+ private getAmbientEffectConfig;
6247
6772
  /**
6248
6773
  * Get current post-process configuration
6249
6774
  */
6250
- getPostProcessConfig(): PostProcessConfig | null;
6775
+ private getPostProcessConfig;
6251
6776
  /**
6252
6777
  * Check if there are pending post-process commands
6253
6778
  * @internal
@@ -6287,7 +6812,7 @@ declare class User<TData = Record<string, any>> {
6287
6812
  * user.setScalingMode(0, 'none');
6288
6813
  * ```
6289
6814
  */
6290
- setScalingMode(displayId: number, mode: ScalingMode): void;
6815
+ private setScalingMode;
6291
6816
  /**
6292
6817
  * Get current scaling mode for a display
6293
6818
  *
@@ -6295,7 +6820,7 @@ declare class User<TData = Record<string, any>> {
6295
6820
  * @param displayId - Display ID (0-255)
6296
6821
  * @returns Current scaling mode or null if not set
6297
6822
  */
6298
- getScalingMode(displayId: number): ScalingMode | null;
6823
+ private getScalingMode;
6299
6824
  /** Current cell size configuration per display (Map<displayId, {width, height}>) */
6300
6825
  private currentCellSizes;
6301
6826
  /**
@@ -6323,17 +6848,14 @@ declare class User<TData = Record<string, any>> {
6323
6848
  * user.setCellSize(1, 16, 16);
6324
6849
  * ```
6325
6850
  */
6326
- setCellSize(displayId: number, width: number, height: number): void;
6851
+ private setCellSize;
6327
6852
  /**
6328
6853
  * Get current cell size for a display
6329
6854
  *
6330
6855
  * @param displayId - Display ID (0-255)
6331
6856
  * @returns Object with cellWidth and cellHeight in pixels, or default 8x8 if not set
6332
6857
  */
6333
- getCellSize(displayId: number): {
6334
- cellWidth: number;
6335
- cellHeight: number;
6336
- };
6858
+ private getCellSize;
6337
6859
  /** Current grid configuration per display (Map<displayId, GridConfig>) */
6338
6860
  private currentGridConfigs;
6339
6861
  /**
@@ -6361,7 +6883,7 @@ declare class User<TData = Record<string, any>> {
6361
6883
  * user.setGrid(0, { enabled: true, color: '#ff0000', lineWidth: 2 });
6362
6884
  * ```
6363
6885
  */
6364
- setGrid(displayId: number, config: boolean | GridConfig): void;
6886
+ private setGrid;
6365
6887
  /**
6366
6888
  * Enable or disable the grid for a specific display
6367
6889
  *
@@ -6374,19 +6896,19 @@ declare class User<TData = Record<string, any>> {
6374
6896
  * user.setGridEnabled(0, false); // Hide grid on display 0
6375
6897
  * ```
6376
6898
  */
6377
- setGridEnabled(displayId: number, enabled: boolean): void;
6899
+ private setGridEnabled;
6378
6900
  /**
6379
6901
  * Check if grid is currently enabled for a display
6380
6902
  *
6381
6903
  * @param displayId - Display ID (0-255)
6382
6904
  */
6383
- isGridEnabled(displayId: number): boolean;
6905
+ private isGridEnabled;
6384
6906
  /**
6385
6907
  * Get current grid configuration for a display
6386
6908
  *
6387
6909
  * @param displayId - Display ID (0-255)
6388
6910
  */
6389
- getGridConfig(displayId: number): GridConfig | null;
6911
+ private getGridConfig;
6390
6912
  /** Currently active palette slot ID per display (Map<displayId, slotId>) */
6391
6913
  private currentPaletteSlotIds;
6392
6914
  /**
@@ -6423,14 +6945,14 @@ declare class User<TData = Record<string, any>> {
6423
6945
  * user.switchPalette(1, nightPalette); // Player 2 display
6424
6946
  * ```
6425
6947
  */
6426
- switchPalette(displayId: number, slotId: number): void;
6948
+ private switchPalette;
6427
6949
  /**
6428
6950
  * Get the currently active palette slot ID for a display
6429
6951
  *
6430
6952
  * @param displayId - Display ID (0-255)
6431
6953
  * @returns The active slot ID, or null if no palette has been switched yet
6432
6954
  */
6433
- getCurrentPaletteSlotId(displayId: number): number | null;
6955
+ private getCurrentPaletteSlotId;
6434
6956
  /**
6435
6957
  * Send data through the bridge channel to the client application
6436
6958
  *
@@ -6578,7 +7100,7 @@ declare class CoreStats {
6578
7100
  /** Details of all layers processed this tick */
6579
7101
  get layerDetails(): Array<{
6580
7102
  layerId: number;
6581
- isStatic: boolean;
7103
+ mustBeReliable: boolean;
6582
7104
  orderCount: number;
6583
7105
  updateFlags: number;
6584
7106
  }> | undefined;
@@ -6613,7 +7135,7 @@ declare class CoreStats {
6613
7135
  /**
6614
7136
  * Records individual layer information
6615
7137
  */
6616
- recordLayerInfo(layerId: number, isStatic: boolean, orderCount: number, updateFlags: number): void;
7138
+ recordLayerInfo(layerId: number, mustBeReliable: boolean, orderCount: number, updateFlags: number): void;
6617
7139
  /**
6618
7140
  * Records rendered cell statistics
6619
7141
  */
@@ -6637,119 +7159,6 @@ declare class CoreStats {
6637
7159
  reset(): void;
6638
7160
  }
6639
7161
 
6640
- /**
6641
- * WebFontRegistry - Registry for CSS-based fonts
6642
- */
6643
-
6644
- /**
6645
- * Registry for managing WebFont instances
6646
- * Each font is identified by a unique fontId (0-255)
6647
- */
6648
- declare class WebFontRegistry {
6649
- private fonts;
6650
- /**
6651
- * Load a new WebFont into the registry
6652
- * @param fontId Unique font identifier (0-255)
6653
- * @param config WebFont configuration
6654
- * @throws Error if font ID already exists
6655
- */
6656
- loadFont(fontId: number, config: WebFontConfig): void;
6657
- /**
6658
- * Get a WebFont by ID
6659
- * @param fontId Font identifier
6660
- * @returns WebFont instance or undefined if not found
6661
- */
6662
- getFont(fontId: number): WebFont | undefined;
6663
- /**
6664
- * Check if a font exists in the registry
6665
- * @param fontId Font identifier
6666
- * @returns true if font exists, false otherwise
6667
- */
6668
- hasFont(fontId: number): boolean;
6669
- /**
6670
- * Remove a WebFont from the registry
6671
- * @param fontId Font identifier
6672
- * @returns true if font was removed, false if not found
6673
- */
6674
- unloadFont(fontId: number): boolean;
6675
- /**
6676
- * Remove all fonts from the registry
6677
- */
6678
- clearFonts(): void;
6679
- /**
6680
- * Get all font IDs in the registry
6681
- * @returns Array of font IDs, sorted in ascending order
6682
- */
6683
- getFontIds(): number[];
6684
- /**
6685
- * Get all WebFont instances in the registry
6686
- * @returns Array of WebFont instances, sorted by font ID
6687
- */
6688
- getAllFonts(): WebFont[];
6689
- /**
6690
- * Get the number of fonts in the registry
6691
- * @returns Number of fonts
6692
- */
6693
- getFontCount(): number;
6694
- }
6695
-
6696
- /**
6697
- * BitmapFontRegistry - Registry for pixel-based bitmap fonts
6698
- */
6699
-
6700
- /**
6701
- * Registry for managing BitmapFont instances
6702
- * Each font is identified by a unique fontId (0-255)
6703
- * BitmapFonts correspond to LoadType 0x04 (Charset) in UTSP protocol
6704
- */
6705
- declare class BitmapFontRegistry {
6706
- private fonts;
6707
- /**
6708
- * Load a new BitmapFont into the registry
6709
- * @param fontId Unique font identifier (0-255)
6710
- * @param config BitmapFont configuration
6711
- * @throws Error if font ID already exists
6712
- */
6713
- loadFont(fontId: number, config: BitmapFontConfig): void;
6714
- /**
6715
- * Get a BitmapFont by ID
6716
- * @param fontId Font identifier
6717
- * @returns BitmapFont instance or undefined if not found
6718
- */
6719
- getFont(fontId: number): BitmapFont | undefined;
6720
- /**
6721
- * Check if a font exists in the registry
6722
- * @param fontId Font identifier
6723
- * @returns true if font exists, false otherwise
6724
- */
6725
- hasFont(fontId: number): boolean;
6726
- /**
6727
- * Remove a BitmapFont from the registry
6728
- * @param fontId Font identifier
6729
- * @returns true if font was removed, false if not found
6730
- */
6731
- unloadFont(fontId: number): boolean;
6732
- /**
6733
- * Remove all fonts from the registry
6734
- */
6735
- clearFonts(): void;
6736
- /**
6737
- * Get all font IDs in the registry
6738
- * @returns Array of font IDs, sorted in ascending order
6739
- */
6740
- getFontIds(): number[];
6741
- /**
6742
- * Get all BitmapFont instances in the registry
6743
- * @returns Array of BitmapFont instances, sorted by font ID
6744
- */
6745
- getAllFonts(): BitmapFont[];
6746
- /**
6747
- * Get the number of fonts in the registry
6748
- * @returns Number of fonts
6749
- */
6750
- getFontCount(): number;
6751
- }
6752
-
6753
7162
  /**
6754
7163
  * SoundRegistry - Server-side registry for audio assets
6755
7164
  *
@@ -6901,152 +7310,359 @@ declare class SoundRegistry {
6901
7310
  }
6902
7311
 
6903
7312
  /**
6904
- * Engine execution context type
7313
+ * AudioOrderCollector - Converts high-level audio commands to binary AudioOrders
7314
+ *
7315
+ * This class bridges the gap between the User's high-level audio API
7316
+ * (playSound, stopSound, etc.) and the binary AudioOrder protocol.
7317
+ *
7318
+ * It takes SoundRegistry to resolve sound names to IDs, and produces
7319
+ * AudioOrders ready for binary encoding in UpdatePacket.
7320
+ *
7321
+ * @example
7322
+ * ```typescript
7323
+ * const collector = new AudioOrderCollector(soundRegistry);
7324
+ *
7325
+ * // Convert User's pending commands to orders
7326
+ * const audioOrders = collector.collectFromUser(user);
7327
+ *
7328
+ * // audioOrders can now be added to UpdatePacket
7329
+ * ```
6905
7330
  */
6906
- type CoreMode = 'server' | 'client' | 'standalone';
7331
+
6907
7332
  /**
6908
- * UTSP engine configuration options
7333
+ * Collects and converts audio commands to binary AudioOrders
6909
7334
  */
6910
- interface CoreOptions {
7335
+ declare class AudioOrderCollector {
7336
+ private soundRegistry;
7337
+ constructor(soundRegistry: SoundRegistry);
6911
7338
  /**
6912
- * Execution mode: "server", "client" or "standalone"
6913
- *
6914
- * - "server": Server-side engine
6915
- * → Marks layers as dirty (change tracking)
6916
- * → Does NOT rasterize (CPU savings, client-side rasterization)
6917
- * → Manages multiple users (limited by maxUsers)
6918
- *
6919
- * - "client": Client-side engine
6920
- * → Does NOT mark as dirty (no tracking needed)
6921
- * → Rasterizes immediately (local rendering for display)
6922
- * → Manages ONE local user only (fixed limit)
7339
+ * Collect all pending audio orders from a user
6923
7340
  *
6924
- * - "standalone": Standalone engine (preview, tests, debug)
6925
- * Marks as dirty AND rasterizes
6926
- * → Manages multiple users
6927
- * → Useful for getRenderState(), tests, simulations
7341
+ * This flushes the user's sound and config command queues,
7342
+ * converts them to binary AudioOrders, and returns them.
6928
7343
  *
6929
- * @default "server"
7344
+ * @param user - The user to collect orders from
7345
+ * @returns Array of AudioOrders ready for encoding
6930
7346
  */
6931
- mode?: CoreMode;
7347
+ collectFromUser(user: User): AnyAudioOrder[];
6932
7348
  /**
6933
- * Maximum number of users allowed (server mode only)
6934
- *
6935
- * In client mode, this option is ignored (fixed limit of 1 user)
6936
- *
6937
- * @default 64
7349
+ * Convert a sound command to an AudioOrder
6938
7350
  */
6939
- maxUsers?: number;
7351
+ private convertSoundCommand;
6940
7352
  /**
6941
- * Enable strict validations (useful in development)
6942
- *
6943
- * @default false
7353
+ * Convert PlaySoundCommand to PlaySoundOrder or PlayGlobalSoundOrder
6944
7354
  */
6945
- strictMode?: boolean;
6946
- }
6947
- /**
6948
- * Core - UTSP data management engine
6949
- *
6950
- * Passive API: no loop, no network, no callbacks.
6951
- * Parent package (utsp-server, utsp-client) controls execution flow.
6952
- *
6953
- * Responsibilities:
6954
- * - Store and manage users
6955
- * - Provide data manipulation methods
6956
- * - Pure and predictable API
6957
- *
6958
- * What the core does NOT do:
6959
- * - No tick loop (server/client manages it)
6960
- * - No network (server/client manages it)
6961
- * - No callbacks/events (core is a passive slave)
6962
- */
6963
- declare class Core {
6964
- private users;
6965
- private readonly mode;
6966
- private readonly maxUsers;
6967
- private readonly strictMode;
6968
- private currentTick;
6969
- private encoder;
6970
- private displayRasterizer;
6971
- private colorPalette;
6972
- private static readonly ANSI_VGA_COLORS;
6973
- private stats;
6974
- private spriteRegistry;
6975
- private webFontRegistry;
6976
- private bitmapFontRegistry;
6977
- private imageFontRegistry;
6978
- private soundRegistry;
6979
- private audioOrderCollector;
6980
- private vibrationOrderCollector;
6981
- private postProcessOrderCollector;
6982
- private activeWebFontId;
6983
- private _renderCallCount;
6984
- private paletteSlots;
6985
- private onPaletteChangedCallback?;
6986
- private onBitmapFontChangedCallback?;
6987
- private onImageFontChangedCallback?;
7355
+ private convertPlayCommand;
6988
7356
  /**
6989
- * Creates a new UTSP engine instance
6990
- *
6991
- * @param options - Configuration options
6992
- *
6993
- * @example
6994
- * ```typescript
6995
- * // Server with 100 max users
6996
- * const engine = new Core({
6997
- * mode: "server",
6998
- * maxUsers: 100
6999
- * });
7000
- *
7001
- * // Simple client
7002
- * const engine = new Core({
7003
- * mode: "client"
7004
- * });
7005
- *
7006
- * // Default mode (server)
7007
- * const engine = new Core();
7008
- * ```
7357
+ * Convert StopSoundCommand to StopSoundOrder
7009
7358
  */
7010
- constructor(options?: CoreOptions);
7359
+ private convertStopCommand;
7011
7360
  /**
7012
- * Initialize default color palette (15 reserved UI colors + free colors)
7013
- * @private
7361
+ * Convert FadeOutSoundCommand to FadeOutSoundOrder
7014
7362
  */
7015
- private initializeDefaultPalette;
7363
+ private convertFadeOutCommand;
7016
7364
  /**
7017
- * Returns current execution mode
7018
- *
7019
- * @returns "server", "client" or "standalone"
7365
+ * Convert PauseSoundCommand to PauseSoundOrder
7020
7366
  */
7021
- getMode(): CoreMode;
7367
+ private convertPauseCommand;
7022
7368
  /**
7023
- * Returns maximum allowed users
7024
- *
7025
- * @returns Max number of users
7369
+ * Convert ResumeSoundCommand to ResumeSoundOrder
7026
7370
  */
7027
- getMaxUsers(): number;
7371
+ private convertResumeCommand;
7028
7372
  /**
7029
- * Indicates if strict mode is enabled
7373
+ * Convert SetSoundEffectsCommand to SetSoundEffectsOrder
7374
+ */
7375
+ private convertSetEffectsCommand;
7376
+ /**
7377
+ * Convert AudioConfigCommand to SetListenerPositionOrder or ConfigureSpatialOrder
7378
+ */
7379
+ private convertConfigCommand;
7380
+ /**
7381
+ * Resolve sound name or ID to a numeric soundId
7382
+ */
7383
+ private resolveSoundId;
7384
+ /**
7385
+ * Resolve target (instanceId, soundName, or 'all') to targetType and value
7386
+ */
7387
+ private resolveTarget;
7388
+ /**
7389
+ * Encode volume (0.0-1.0) to byte (0-255)
7390
+ */
7391
+ private encodeVolume;
7392
+ /**
7393
+ * Encode pitch (0.25x-4.0x) to byte (0-255, 128=1.0x)
7394
+ * Formula: pitch = 0.25 * 2^(byte/64)
7395
+ * Inverse: byte = 64 * log2(pitch / 0.25)
7396
+ */
7397
+ private encodePitch;
7398
+ /**
7399
+ * Encode fade time (seconds) to byte (1/10 seconds, 0-25.5s)
7400
+ */
7401
+ private encodeFadeTime;
7402
+ /**
7403
+ * Encode distance for spatial audio (scale: 0-25500 → 0-255)
7404
+ */
7405
+ private encodeDistance;
7406
+ /**
7407
+ * Encode rolloff factor (0.0-2.55 → 0-255)
7408
+ */
7409
+ private encodeRolloff;
7410
+ /**
7411
+ * Encode pan spread (0.0-1.0 → 0-255)
7412
+ */
7413
+ private encodePanSpread;
7414
+ /**
7415
+ * Encode position coordinate for spatial audio (clamp to 0-65535 for Uint16)
7416
+ */
7417
+ private encodePosition;
7418
+ /**
7419
+ * Encode filter frequency (100-25500 Hz) to byte (1-255, * 100 = Hz)
7420
+ * 0 means disabled
7421
+ */
7422
+ private encodeFilterFreq;
7423
+ /**
7424
+ * Encode reverb wet mix (0.0-1.0) to byte (0-255)
7425
+ */
7426
+ private encodeReverb;
7427
+ }
7428
+
7429
+ /**
7430
+ * VibrationOrderCollector - Converts high-level vibration commands to binary VibrationOrders
7431
+ *
7432
+ * This class bridges the gap between the User's high-level vibration API
7433
+ * (vibrate, vibrateGamepad, etc.) and the binary VibrationOrder protocol.
7434
+ *
7435
+ * It produces VibrationOrders ready for binary encoding in UpdatePacket.
7436
+ * Supports both mobile vibration (pattern-based) and gamepad vibration (dual-motor).
7437
+ *
7438
+ * @example
7439
+ * ```typescript
7440
+ * const collector = new VibrationOrderCollector();
7441
+ *
7442
+ * // Convert User's pending commands to orders
7443
+ * const vibrationOrders = collector.collectFromUser(user);
7444
+ *
7445
+ * // vibrationOrders can now be added to UpdatePacket
7446
+ * ```
7447
+ */
7448
+
7449
+ /**
7450
+ * Collects and converts vibration commands to binary VibrationOrders
7451
+ */
7452
+ declare class VibrationOrderCollector {
7453
+ /**
7454
+ * Collect all pending vibration orders from a user
7455
+ *
7456
+ * This flushes the user's vibration command queues (mobile + gamepad),
7457
+ * converts them to binary VibrationOrders, and returns them.
7458
+ *
7459
+ * @param user - The user to collect orders from
7460
+ * @returns Array of VibrationOrders ready for encoding
7461
+ */
7462
+ collectFromUser(user: User): AnyVibrationOrder[];
7463
+ /**
7464
+ * Convert a mobile vibration command to a VibrationOrder
7465
+ * Accepts both old format (without target) and new format (with target: 'mobile')
7466
+ */
7467
+ private convertMobileCommand;
7468
+ /**
7469
+ * Convert MobileVibrateCommand to MobileVibrateOrder
7470
+ * Accepts both old format { pattern, intensity? } and new format { target: 'mobile', pattern, intensity? }
7471
+ */
7472
+ private convertMobileVibrateCommand;
7473
+ /**
7474
+ * Convert MobileCancelVibrationCommand to MobileCancelOrder
7475
+ */
7476
+ private convertMobileCancelCommand;
7477
+ /**
7478
+ * Convert a gamepad vibration command to a VibrationOrder
7479
+ * Accepts both old format (without target) and new format (with target: 'gamepad')
7480
+ */
7481
+ private convertGamepadCommand;
7482
+ /**
7483
+ * Convert GamepadVibrateCommand to GamepadVibrateOrder
7484
+ */
7485
+ private convertGamepadVibrateCommand;
7486
+ /**
7487
+ * Convert GamepadCancelVibrationCommand to GamepadCancelOrder
7488
+ */
7489
+ private convertGamepadCancelCommand;
7490
+ }
7491
+
7492
+ /**
7493
+ * PostProcessOrderCollector - Converts high-level post-process commands to binary PostProcessOrders
7494
+ *
7495
+ * This class bridges the gap between the User's high-level post-process API
7496
+ * (setPostProcess, setAmbientEffect, etc.) and the binary PostProcessOrder protocol.
7497
+ *
7498
+ * It converts PostProcessCommands to PostProcessOrders ready for binary encoding in UpdatePacket.
7499
+ *
7500
+ * @example
7501
+ * ```typescript
7502
+ * const collector = new PostProcessOrderCollector();
7503
+ *
7504
+ * // Convert User's pending commands to orders
7505
+ * const postProcessOrders = collector.collectFromUser(user);
7506
+ *
7507
+ * // postProcessOrders can now be added to UpdatePacket
7508
+ * ```
7509
+ */
7510
+
7511
+ /**
7512
+ * Collects and converts post-process commands to binary PostProcessOrders
7513
+ */
7514
+ declare class PostProcessOrderCollector {
7515
+ /**
7516
+ * Collect all pending post-process orders from a user
7517
+ *
7518
+ * This flushes the user's post-process command queue,
7519
+ * converts them to binary PostProcessOrders, and returns them.
7520
+ *
7521
+ * @param user - The user to collect orders from
7522
+ * @returns Array of PostProcessOrders ready for encoding
7523
+ */
7524
+ collectFromUser(user: User): AnyPostProcessOrder[];
7525
+ /**
7526
+ * Convert an array of post-process commands to PostProcessOrders
7527
+ *
7528
+ * This is the core conversion logic used by both:
7529
+ * - Server: collectFromUser() → encode → network
7530
+ * - Local: convertCommands() → applyPostProcessOrders() (no encoding)
7030
7531
  *
7031
- * @returns true if strict mode is enabled
7532
+ * @param commands - Array of PostProcessCommands to convert
7533
+ * @returns Array of PostProcessOrders
7534
+ */
7535
+ convertCommands(commands: PostProcessCommand[]): AnyPostProcessOrder[];
7536
+ /**
7537
+ * Convert a post-process command to a PostProcessOrder
7538
+ */
7539
+ private convertCommand;
7540
+ /**
7541
+ * Convert a full set-config command to a SetConfigOrder
7542
+ */
7543
+ private convertSetConfig;
7544
+ /**
7545
+ * Create a SetScanlinesOrder with given parameters
7546
+ */
7547
+ private createSetScanlinesOrder;
7548
+ /**
7549
+ * Create a SetAmbientEffectOrder with given parameters
7550
+ */
7551
+ private createSetAmbientEffectOrder;
7552
+ /**
7553
+ * Convert pattern string to ScanlinesPatternType
7554
+ */
7555
+ private patternToType;
7556
+ /**
7557
+ * Create a SetScalingModeOrder with given scaling mode
7558
+ */
7559
+ private createSetScalingModeOrder;
7560
+ /**
7561
+ * Create a SetGridOrder with given grid configuration
7562
+ */
7563
+ private createSetGridOrder;
7564
+ /**
7565
+ * Create a SwitchPaletteOrder with given slot ID
7566
+ */
7567
+ private createSwitchPaletteOrder;
7568
+ /**
7569
+ * Create a SetCellSizeOrder with given dimensions
7032
7570
  */
7033
- isStrictMode(): boolean;
7571
+ private createSetCellSizeOrder;
7572
+ /**
7573
+ * Parse CSS color string to RGBA components
7574
+ */
7575
+ private parseColor;
7576
+ }
7577
+
7578
+ /**
7579
+ * Engine execution context type
7580
+ */
7581
+ type CoreMode = 'server' | 'client' | 'standalone';
7582
+ /**
7583
+ * UTSP engine configuration options
7584
+ */
7585
+ interface CoreOptions {
7586
+ /**
7587
+ * Execution mode: "server", "client" or "standalone"
7588
+ */
7589
+ mode?: CoreMode;
7590
+ /**
7591
+ * Maximum number of users allowed (server mode only)
7592
+ * Default: 100
7593
+ */
7594
+ maxUsers?: number;
7595
+ }
7596
+ declare class Core {
7597
+ static readonly ANSI_VGA_COLORS: {
7598
+ colorId: number;
7599
+ r: number;
7600
+ g: number;
7601
+ b: number;
7602
+ a: number;
7603
+ e: number;
7604
+ }[];
7605
+ readonly mode: CoreMode;
7606
+ readonly maxUsers: number;
7607
+ strictMode: boolean;
7608
+ currentTick: number;
7609
+ readonly stats: CoreStats;
7610
+ readonly spriteRegistry: SpriteRegistry;
7611
+ readonly imageFontRegistry: ImageFontRegistry;
7612
+ readonly soundRegistry: SoundRegistry;
7613
+ readonly audioOrderCollector: AudioOrderCollector;
7614
+ readonly vibrationOrderCollector: VibrationOrderCollector;
7615
+ readonly postProcessOrderCollector: PostProcessOrderCollector;
7616
+ readonly encoder: UpdatePacketEncoder;
7617
+ private readonly users;
7618
+ private readonly colorPalette;
7619
+ private readonly paletteSlots;
7620
+ private readonly displayRasterizer;
7621
+ private _renderCallCount;
7622
+ private onPaletteChangedCallback?;
7623
+ private onFontAllocatedCallback?;
7624
+ private onFontBlockAddedCallback?;
7625
+ /** @deprecated Use onFontAllocated/onFontBlockAdded */
7626
+ private onImageFontChangedCallback?;
7627
+ constructor(options?: CoreOptions);
7628
+ private initializeDefaultPalette;
7034
7629
  /**
7035
7630
  * Checks if core is in server mode
7036
7631
  *
7037
7632
  * @returns true if server mode
7633
+ *
7634
+ * @example
7635
+ * ```typescript
7636
+ * if (engine.isServer()) {
7637
+ * // Server-specific logic
7638
+ * }
7639
+ * ```
7038
7640
  */
7039
7641
  isServer(): boolean;
7040
7642
  /**
7041
7643
  * Checks if core is in client mode
7042
7644
  *
7043
7645
  * @returns true if client mode
7646
+ *
7647
+ * @example
7648
+ * ```typescript
7649
+ * if (engine.isClient()) {
7650
+ * // Client-specific logic
7651
+ * }
7652
+ * ```
7044
7653
  */
7045
7654
  isClient(): boolean;
7046
7655
  /**
7047
7656
  * Checks if core is in standalone mode
7048
7657
  *
7049
7658
  * @returns true if standalone mode
7659
+ *
7660
+ * @example
7661
+ * ```typescript
7662
+ * if (engine.isStandalone()) {
7663
+ * // Local preview or tests
7664
+ * }
7665
+ * ```
7050
7666
  */
7051
7667
  isStandalone(): boolean;
7052
7668
  /**
@@ -7182,7 +7798,7 @@ declare class Core {
7182
7798
  /**
7183
7799
  * Register a callback to be notified when palette changes
7184
7800
  *
7185
- * Use this to update the renderer when palette is modified via loadPalette() or setColor().
7801
+ * Use this to update the renderer when palette is modified via setColor() or resetPalette().
7186
7802
  *
7187
7803
  * @param callback - Function called with the new palette
7188
7804
  *
@@ -7201,22 +7817,6 @@ declare class Core {
7201
7817
  a: number;
7202
7818
  e: number;
7203
7819
  }>) => void): void;
7204
- /**
7205
- * Register a callback to be notified when a bitmap font is loaded.
7206
- *
7207
- * Use this to update the renderer when a font is loaded via loadBitmapFontById().
7208
- *
7209
- * @param callback - Function called with the fontId
7210
- *
7211
- * @example
7212
- * ```typescript
7213
- * core.onBitmapFontChanged((fontId) => {
7214
- * const font = core.getBitmapFont(fontId);
7215
- * if (font) renderer.uploadFontToGPU(font);
7216
- * });
7217
- * ```
7218
- */
7219
- onBitmapFontChanged(callback: (fontId: number) => void): void;
7220
7820
  /**
7221
7821
  * Gets a color from the palette
7222
7822
  *
@@ -7239,38 +7839,6 @@ declare class Core {
7239
7839
  a: number;
7240
7840
  e: number;
7241
7841
  } | null;
7242
- /**
7243
- * Loads a complete color palette
7244
- *
7245
- * Replaces existing colors for the specified IDs.
7246
- *
7247
- * 🎨 RESERVED COLORS (automatically forced):
7248
- * - ColorIDs 240-254: Standard UI palette (will be overridden even if provided)
7249
- * - ColorID 255: Skip/transparent color (will be overridden even if provided)
7250
- * - ColorIDs 0-239: Free for application use
7251
- *
7252
- * @param colors - Array of colors to load (any ColorIDs 0-255)
7253
- *
7254
- * @example
7255
- * ```typescript
7256
- * engine.loadPalette([
7257
- * { colorId: 0, r: 255, g: 0, b: 0, a: 255, e: 0 }, // ✅ Custom color (free range)
7258
- * { colorId: 1, r: 255, g: 255, b: 255, a: 255, e: 0 }, // ✅ Custom white
7259
- * { colorId: 2, r: 255, g: 0, b: 0, a: 255, e: 0 }, // ✅ Custom red
7260
- * { colorId: 3, r: 0, g: 255, b: 255, a: 255, e: 255 }, // ✅ Bright cyan
7261
- * { colorId: 250, r: 255, g: 0, b: 0, a: 255, e: 0 }, // ⚠️ Will be ignored (reserved)
7262
- * ]);
7263
- * // ColorIDs 240-254 and 255 will be forced to standard values
7264
- * ```
7265
- */
7266
- loadPalette(colors: Array<{
7267
- colorId: number;
7268
- r: number;
7269
- g: number;
7270
- b: number;
7271
- a: number;
7272
- e?: number;
7273
- }>): void;
7274
7842
  /**
7275
7843
  * Gets the entire color palette
7276
7844
  *
@@ -7303,7 +7871,7 @@ declare class Core {
7303
7871
  /**
7304
7872
  * Load a palette into a slot for later switching
7305
7873
  *
7306
- * Palettes are stored in the Core and can be switched per-user at runtime.
7874
+ * Palettes are stored in the Core and can be switched per-display at runtime.
7307
7875
  * This allows preloading multiple palettes (e.g., day/night themes)
7308
7876
  * and switching between them without re-sending the palette data.
7309
7877
  *
@@ -7316,8 +7884,9 @@ declare class Core {
7316
7884
  * core.loadPaletteToSlot(0, dayColors);
7317
7885
  * core.loadPaletteToSlot(1, nightColors);
7318
7886
  *
7319
- * // Later, switch user to night palette
7320
- * user.switchPalette(1);
7887
+ * // Later, switch display to night palette
7888
+ * const display = user.getDisplays()[0];
7889
+ * display.switchPalette(1);
7321
7890
  * ```
7322
7891
  */
7323
7892
  loadPaletteToSlot(slotId: number, colors: Array<{
@@ -7354,16 +7923,33 @@ declare class Core {
7354
7923
  *
7355
7924
  * @param slotId - Slot ID (0-255)
7356
7925
  * @returns true if the slot has a palette loaded
7926
+ *
7927
+ * @example
7928
+ * ```typescript
7929
+ * if (core.hasPaletteSlot(1)) {
7930
+ * console.log('Slot 1 is ready');
7931
+ * }
7932
+ * ```
7357
7933
  */
7358
7934
  hasPaletteSlot(slotId: number): boolean;
7359
7935
  /**
7360
7936
  * Clear a palette slot
7361
7937
  *
7362
7938
  * @param slotId - Slot ID (0-255)
7939
+ *
7940
+ * @example
7941
+ * ```typescript
7942
+ * core.clearPaletteSlot(1);
7943
+ * ```
7363
7944
  */
7364
7945
  clearPaletteSlot(slotId: number): void;
7365
7946
  /**
7366
7947
  * Clear all palette slots
7948
+ *
7949
+ * @example
7950
+ * ```typescript
7951
+ * core.clearAllPaletteSlots();
7952
+ * ```
7367
7953
  */
7368
7954
  clearAllPaletteSlots(): void;
7369
7955
  /**
@@ -7618,11 +8204,9 @@ declare class Core {
7618
8204
  *
7619
8205
  * This method automatically decodes the binary buffer and applies
7620
8206
  * the asset to the Core according to its LoadType:
7621
- * - ColorPalette → loadPalette()
8207
+ * - ColorPalette → loadPaletteToSlot()
7622
8208
  * - Sprite → loadUnicolorSprites()
7623
8209
  * - MulticolorSprite → loadMulticolorSprites()
7624
- * - BitmapFont → loadBitmapFontById()
7625
- * - WebFont → loadWebFontById()
7626
8210
  * - Sound → (TODO: implement audio system)
7627
8211
  *
7628
8212
  * @param buffer - Encoded binary buffer received via WebSocket
@@ -7637,23 +8221,6 @@ declare class Core {
7637
8221
  * ```
7638
8222
  */
7639
8223
  applyLoadPacket(buffer: Uint8Array): boolean;
7640
- /**
7641
- * Generates a LoadPacket for the current color palette (SERVER-SIDE)
7642
- *
7643
- * Encodes the complete palette in binary format ready to send to clients.
7644
- *
7645
- * @returns Encoded binary buffer (or null if palette empty)
7646
- *
7647
- * @example
7648
- * ```typescript
7649
- * // Server side
7650
- * const palettePacket = core.generatePaletteLoadPacket();
7651
- * if (palettePacket) {
7652
- * websocket.emit('load', palettePacket);
7653
- * }
7654
- * ```
7655
- */
7656
- generatePaletteLoadPacket(): Uint8Array | null;
7657
8224
  /**
7658
8225
  * Generates a LoadPacket for a specific palette slot (SERVER-SIDE)
7659
8226
  *
@@ -7717,39 +8284,7 @@ declare class Core {
7717
8284
  */
7718
8285
  generateMulticolorSpritesLoadPacket(): Uint8Array | null;
7719
8286
  /**
7720
- * Generates LoadPackets for all web fonts (SERVER-SIDE)
7721
- *
7722
- * Returns an array of buffers (one font = one packet)
7723
- *
7724
- * @returns Array of encoded buffers (or empty array if no fonts)
7725
- *
7726
- * @example
7727
- * ```typescript
7728
- * const fontPackets = core.generateWebFontsLoadPackets();
7729
- * fontPackets.forEach(packet => {
7730
- * websocket.emit('load', packet);
7731
- * });
7732
- * ```
7733
- */
7734
- generateWebFontsLoadPackets(): Uint8Array[];
7735
- /**
7736
- * Generates LoadPackets for all bitmap fonts (SERVER-SIDE)
7737
- *
7738
- * Returns an array of buffers (one font = one packet)
7739
- *
7740
- * @returns Array of encoded buffers (or empty array if no fonts)
7741
- *
7742
- * @example
7743
- * ```typescript
7744
- * const fontPackets = core.generateBitmapFontsLoadPackets();
7745
- * fontPackets.forEach(packet => {
7746
- * websocket.emit('load', packet);
7747
- * });
7748
- * ```
7749
- */
7750
- generateBitmapFontsLoadPackets(): Uint8Array[];
7751
- /**
7752
- * Generates ALL LoadPackets (palette + sprites + fonts) (SERVER-SIDE)
8287
+ * Generates ALL LoadPackets (palette slots + sprites + fonts) (SERVER-SIDE)
7753
8288
  *
7754
8289
  * Useful when a client initially connects to send them
7755
8290
  * all assets at once.
@@ -7948,6 +8483,26 @@ declare class Core {
7948
8483
  * ```
7949
8484
  */
7950
8485
  loadMulticolorSprites(loadData: MulticolorSpriteLoad): void;
8486
+ /**
8487
+ * Load Font structure (allocate font)
8488
+ * Defines the font dimensions and allocates the atlas in memory (empty)
8489
+ *
8490
+ * @param glyphWidth Width of each glyph source in pixels
8491
+ * @param glyphHeight Height of each glyph source in pixels
8492
+ * @param atlasBlocks Number of 256-char blocks (1, 4, or 16)
8493
+ * @param cellWidth Target rendering width
8494
+ * @param cellHeight Target rendering height
8495
+ */
8496
+ loadFont(glyphWidth: number, glyphHeight: number, atlasBlocks: AtlasBlocks, cellWidth: number, cellHeight: number): void;
8497
+ /**
8498
+ * Load Font data block
8499
+ * Uploads a PNG chunk (256 chars) to the previously allocated font atlas
8500
+ *
8501
+ * @param blockIndex Index of the block (0-15)
8502
+ * @param pathOrData Path to the PNG file (string) or raw data (Uint8Array)
8503
+ */
8504
+ loadFontBlock(blockIndex: number, path: string): Promise<void>;
8505
+ loadFontBlock(blockIndex: number, data: Uint8Array): void;
7951
8506
  /**
7952
8507
  * Unloads a unicolor sprite from memory
7953
8508
  *
@@ -8137,9 +8692,9 @@ declare class Core {
8137
8692
  */
8138
8693
  private detectSoundFormat;
8139
8694
  /**
8140
- * Loads sound data from path (isomorphic: Node.js or browser)
8695
+ * Loads resource data from path (isomorphic: Node.js or browser)
8141
8696
  */
8142
- private loadSoundData;
8697
+ private readResource;
8143
8698
  /**
8144
8699
  * Registers a sound with embedded data (File mode) - Low-level API
8145
8700
  *
@@ -8213,345 +8768,37 @@ declare class Core {
8213
8768
  */
8214
8769
  generateSoundLoadPackets(): Array<_utsp_types.SoundLoadPacket | _utsp_types.SoundExternalLoadPacket>;
8215
8770
  /**
8216
- * Loads the default web font (Courier New, 16px, monospace)
8217
- *
8218
- * This font is loaded automatically during engine initialization.
8219
- * It uses fontId 0 (reserved for the default font).
8220
- *
8221
- * @private
8222
- */
8223
- private loadDefaultWebFont;
8224
- /**
8225
- * Loads a web font into the registry
8771
+ * Loads an image font from a PNG file path
8226
8772
  *
8227
- * Web fonts use the CSS system for rendering (fontFamily, fontSize, etc.)
8228
- * FontID 0 is reserved for the default font.
8773
+ * Works identically on server (Node.js) and client (browser).
8774
+ * The PNG is loaded and registered with an auto-assigned ID.
8229
8775
  *
8230
- * @param font - WebFont instance to load
8231
- * @throws Error if fontId is already in use
8776
+ * @param name - Human-readable name for the font (e.g., 'tileset', 'icons')
8777
+ * @param path - Path to the PNG atlas file
8778
+ * @param options - Font configuration options
8779
+ * @returns Promise resolving to the assigned font ID (0-255)
8232
8780
  *
8233
8781
  * @example
8234
8782
  * ```typescript
8235
- * const customFont = new WebFont(1, {
8236
- * fontFamily: "Arial",
8237
- * fontSize: 20,
8238
- * fontWeight: "bold"
8239
- * });
8240
- * engine.loadWebFont(customFont);
8783
+ * // In init() - same code works on server and client
8784
+ * async init(core: Core): Promise<void> {
8785
+ * await core.loadImageFont('tileset', './fonts/tileset.png', {
8786
+ * glyphWidth: 16,
8787
+ * glyphHeight: 16,
8788
+ * atlasBlocks: 4, // 1024 chars
8789
+ * });
8790
+ * }
8791
+ *
8792
+ * // Later, use by name or ID
8793
+ * const id = core.getImageFontId('tileset');
8241
8794
  * ```
8242
8795
  */
8243
- loadWebFont(font: WebFont): void;
8796
+ loadImageFont(name: string, path: string, options: ImageFontOptions): Promise<number>;
8244
8797
  /**
8245
- * Gets a web font by its ID
8798
+ * Loads multiple image fonts at once
8246
8799
  *
8247
- * @param fontId - Font ID (0-255)
8248
- * @returns The WebFont instance or null if not found
8249
- *
8250
- * @example
8251
- * ```typescript
8252
- * const font = engine.getWebFont(1);
8253
- * if (font) {
8254
- * console.log(font.toCSS());
8255
- * }
8256
- * ```
8257
- */
8258
- getWebFont(fontId: number): WebFont | null;
8259
- /**
8260
- * Checks if a web font exists
8261
- *
8262
- * @param fontId - Font ID (0-255)
8263
- * @returns true if font exists
8264
- *
8265
- * @example
8266
- * ```typescript
8267
- * if (engine.hasWebFont(1)) {
8268
- * console.log("Font 1 is loaded");
8269
- * }
8270
- * ```
8271
- */
8272
- hasWebFont(fontId: number): boolean;
8273
- /**
8274
- * Unloads a web font from the registry
8275
- *
8276
- * Note: Cannot unload the default font (fontId 0)
8277
- *
8278
- * @param fontId - Font ID to unload (1-255)
8279
- * @returns true if font was unloaded
8280
- * @throws Error if attempting to unload default font (fontId 0)
8281
- *
8282
- * @example
8283
- * ```typescript
8284
- * const removed = engine.unloadWebFont(1);
8285
- * if (removed) {
8286
- * console.log("Font 1 unloaded");
8287
- * }
8288
- * ```
8289
- */
8290
- unloadWebFont(fontId: number): boolean;
8291
- /**
8292
- * Clears all web fonts (except default font)
8293
- *
8294
- * @example
8295
- * ```typescript
8296
- * engine.clearWebFonts();
8297
- * console.log("All custom web fonts cleared");
8298
- * ```
8299
- */
8300
- clearWebFonts(): void;
8301
- /**
8302
- * Sets the active web font
8303
- *
8304
- * The active font is used by default for character rendering.
8305
- *
8306
- * @param fontId - Font ID to activate (0-255)
8307
- * @throws Error if font doesn't exist
8308
- *
8309
- * @example
8310
- * ```typescript
8311
- * engine.setActiveWebFont(1);
8312
- * console.log(`Active font: ${engine.getActiveWebFontId()}`);
8313
- * ```
8314
- */
8315
- setActiveWebFont(fontId: number): void;
8316
- /**
8317
- * Gets the active web font ID
8318
- *
8319
- * @returns Active font ID (0-255)
8320
- *
8321
- * @example
8322
- * ```typescript
8323
- * const activeFontId = engine.getActiveWebFontId();
8324
- * console.log(`Current font: ${activeFontId}`);
8325
- * ```
8326
- */
8327
- getActiveWebFontId(): number;
8328
- /**
8329
- * Gets the active web font
8330
- *
8331
- * @returns The active WebFont instance
8332
- *
8333
- * @example
8334
- * ```typescript
8335
- * const activeFont = engine.getActiveWebFont();
8336
- * console.log(activeFont.toCSS());
8337
- * ```
8338
- */
8339
- getActiveWebFont(): WebFont;
8340
- /**
8341
- * Counts the number of loaded web fonts
8342
- *
8343
- * @returns Number of web fonts in memory
8344
- *
8345
- * @example
8346
- * ```typescript
8347
- * const count = engine.getWebFontCount();
8348
- * console.log(`${count} web fonts loaded`);
8349
- * ```
8350
- */
8351
- getWebFontCount(): number;
8352
- /**
8353
- * Gets all loaded web font IDs
8354
- *
8355
- * @returns Array of fontIds (0-255)
8356
- *
8357
- * @example
8358
- * ```typescript
8359
- * const fontIds = engine.getWebFontIds();
8360
- * console.log(`Loaded fonts: ${fontIds.join(", ")}`);
8361
- * ```
8362
- */
8363
- getWebFontIds(): number[];
8364
- /**
8365
- * Gets the web font registry
8366
- *
8367
- * @returns WebFontRegistry instance
8368
- *
8369
- * @example
8370
- * ```typescript
8371
- * const registry = engine.getWebFontRegistry();
8372
- * console.log(`Total fonts: ${registry.getFontCount()}`);
8373
- * ```
8374
- */
8375
- getWebFontRegistry(): WebFontRegistry;
8376
- /**
8377
- * Gets the bitmap font registry
8378
- *
8379
- * @returns BitmapFontRegistry instance
8380
- *
8381
- * @example
8382
- * ```typescript
8383
- * const registry = engine.getBitmapFontRegistry();
8384
- * console.log(`Total fonts: ${registry.getFontCount()}`);
8385
- * ```
8386
- */
8387
- getBitmapFontRegistry(): BitmapFontRegistry;
8388
- /**
8389
- * Loads a web font directly with its ID and configuration
8390
- *
8391
- * Simplified method that creates and loads the font in one step.
8392
- *
8393
- * @param fontId - Unique font ID (0-255, 0 reserved for default font)
8394
- * @param config - Web font configuration
8395
- * @throws Error if fontId is already in use
8396
- *
8397
- * @example
8398
- * ```typescript
8399
- * // Load a custom font
8400
- * engine.loadWebFontById(1, {
8401
- * fontFamily: "Arial",
8402
- * fontSize: 20,
8403
- * fontWeight: "bold"
8404
- * });
8405
- *
8406
- * // Load a monospace font
8407
- * engine.loadWebFontById(2, {
8408
- * fontFamily: "Consolas",
8409
- * fontSize: 16,
8410
- * charSpacing: 2
8411
- * });
8412
- * ```
8413
- */
8414
- loadWebFontById(fontId: number, config: WebFontConfig): void;
8415
- /**
8416
- * Loads a bitmap font directly with its ID and configuration
8417
- *
8418
- * Simplified method that loads the bitmap font in one step.
8419
- *
8420
- * @param fontId - Unique font ID (0-255)
8421
- * @param config - Bitmap font configuration (dimensions + glyphs)
8422
- * @throws Error if fontId is already in use
8423
- *
8424
- * @example
8425
- * ```typescript
8426
- * import { createASCII8x8FontLoad } from "utsp-core";
8427
- *
8428
- * // Load the ASCII 8×8 font
8429
- * const fontLoad = createASCII8x8FontLoad(1);
8430
- * engine.loadBitmapFontById(1, fontLoad.fontConfig);
8431
- *
8432
- * // Load a custom bitmap font
8433
- * engine.loadBitmapFontById(10, {
8434
- * charWidth: 16,
8435
- * charHeight: 16,
8436
- * glyphs: new Map([
8437
- * [65, new Uint8Array([...])], // 'A'
8438
- * [66, new Uint8Array([...])], // 'B'
8439
- * ])
8440
- * });
8441
- * ```
8442
- */
8443
- loadBitmapFontById(fontId: number, config: BitmapFontConfig): void;
8444
- /**
8445
- * Gets a bitmap font by its ID
8446
- *
8447
- * @param fontId - Font ID (0-255)
8448
- * @returns The BitmapFont instance or null if not found
8449
- *
8450
- * @example
8451
- * ```typescript
8452
- * const font = engine.getBitmapFont(1);
8453
- * if (font) {
8454
- * console.log(`Font dimensions: ${font.getCharWidth()}×${font.getCharHeight()}`);
8455
- * console.log(`Glyphs: ${font.getGlyphCount()}`);
8456
- * }
8457
- * ```
8458
- */
8459
- getBitmapFont(fontId: number): BitmapFont | null;
8460
- /**
8461
- * Checks if a bitmap font exists
8462
- *
8463
- * @param fontId - Font ID (0-255)
8464
- * @returns true if font exists
8465
- *
8466
- * @example
8467
- * ```typescript
8468
- * if (engine.hasBitmapFont(1)) {
8469
- * console.log("Font 1 is loaded");
8470
- * }
8471
- * ```
8472
- */
8473
- hasBitmapFont(fontId: number): boolean;
8474
- /**
8475
- * Unloads a bitmap font from the registry
8476
- *
8477
- * @param fontId - Font ID to unload (0-255)
8478
- * @returns true if font was unloaded
8479
- *
8480
- * @example
8481
- * ```typescript
8482
- * const removed = engine.unloadBitmapFont(1);
8483
- * if (removed) {
8484
- * console.log("Font 1 unloaded");
8485
- * }
8486
- * ```
8487
- */
8488
- unloadBitmapFont(fontId: number): boolean;
8489
- /**
8490
- * Clears all bitmap fonts
8491
- *
8492
- * @example
8493
- * ```typescript
8494
- * engine.clearBitmapFonts();
8495
- * console.log("All bitmap fonts cleared");
8496
- * ```
8497
- */
8498
- clearBitmapFonts(): void;
8499
- /**
8500
- * Counts the number of loaded bitmap fonts
8501
- *
8502
- * @returns Number of bitmap fonts in memory
8503
- *
8504
- * @example
8505
- * ```typescript
8506
- * const count = engine.getBitmapFontCount();
8507
- * console.log(`${count} bitmap fonts loaded`);
8508
- * ```
8509
- */
8510
- getBitmapFontCount(): number;
8511
- /**
8512
- * Gets all loaded bitmap font IDs
8513
- *
8514
- * @returns Array of fontIds (0-255)
8515
- *
8516
- * @example
8517
- * ```typescript
8518
- * const fontIds = engine.getBitmapFontIds();
8519
- * console.log(`Loaded bitmap fonts: ${fontIds.join(", ")}`);
8520
- * ```
8521
- */
8522
- getBitmapFontIds(): number[];
8523
- /**
8524
- * Loads an image font from a PNG file path
8525
- *
8526
- * Works identically on server (Node.js) and client (browser).
8527
- * The PNG is loaded and registered with an auto-assigned ID.
8528
- *
8529
- * @param name - Human-readable name for the font (e.g., 'tileset', 'icons')
8530
- * @param path - Path to the PNG atlas file
8531
- * @param options - Font configuration options
8532
- * @returns Promise resolving to the assigned font ID (0-255)
8533
- *
8534
- * @example
8535
- * ```typescript
8536
- * // In init() - same code works on server and client
8537
- * async init(core: Core): Promise<void> {
8538
- * await core.loadImageFont('tileset', './fonts/tileset.png', {
8539
- * glyphWidth: 16,
8540
- * glyphHeight: 16,
8541
- * atlasBlocks: 4, // 1024 chars
8542
- * });
8543
- * }
8544
- *
8545
- * // Later, use by name or ID
8546
- * const id = core.getImageFontId('tileset');
8547
- * ```
8548
- */
8549
- loadImageFont(name: string, path: string, options: ImageFontOptions): Promise<number>;
8550
- /**
8551
- * Loads multiple image fonts at once
8552
- *
8553
- * @param fonts - Object mapping font names to { path, options }
8554
- * @returns Promise resolving to object mapping names to IDs
8800
+ * @param fonts - Object mapping font names to { path, options }
8801
+ * @returns Promise resolving to object mapping names to IDs
8555
8802
  *
8556
8803
  * @example
8557
8804
  * ```typescript
@@ -8613,12 +8860,25 @@ declare class Core {
8613
8860
  * Called when an image font is loaded.
8614
8861
  *
8615
8862
  * @param callback - Function called with the fontId
8863
+ /**
8864
+ * Register a callback for when a font structure is allocated
8865
+ * (Does not imply data is ready, just dimensions)
8866
+ */
8867
+ onFontAllocated(callback: () => void): void;
8868
+ /**
8869
+ * Register a callback for when a font data block is added
8870
+ */
8871
+ onFontBlockAdded(callback: (blockIndex: number) => void): void;
8872
+ /**
8873
+ * Register a callback for when an image font is changed (loaded or updated)
8874
+ * DEPRECATED: Use onFontAllocated/onFontBlockAdded for granular updates
8875
+ *
8876
+ * @param callback Function to call when an image font changes
8616
8877
  *
8617
8878
  * @example
8618
8879
  * ```typescript
8619
8880
  * core.onImageFontChanged((fontId) => {
8620
- * const font = core.getImageFont(fontId);
8621
- * if (font) renderer.setImageFont(font.getImageData(), ...);
8881
+ * // Legacy support
8622
8882
  * });
8623
8883
  * ```
8624
8884
  */
@@ -8778,34 +9038,46 @@ declare class Core {
8778
9038
  }
8779
9039
 
8780
9040
  /**
8781
- * Layer configuration options
9041
+ * Layer configuration options.
8782
9042
  */
8783
9043
  interface LayerOptions {
8784
- /** Optional layer name for tooling/debug */
9044
+ /** Optional layer name for tooling/debug. */
8785
9045
  name?: string;
8786
9046
  /**
8787
9047
  * CharCode mode for this layer (immutable after creation)
8788
- * - '8bit': Uses Uint8Array, limited to 256 characters (ASCII/CP437), optimized bandwidth
8789
- * - '16bit': Uses Uint16Array, supports 65536 characters (Unicode BMP), universal
9048
+ * - '8bit': 256 char codes (CP437 default)
9049
+ * - '16bit': 65536 char codes (256 atlas blocks × 256 chars)
8790
9050
  * @default '8bit'
8791
9051
  */
8792
9052
  charCodeMode?: CharCodeMode;
8793
9053
  /**
8794
- * Static layer (sent only once to client)
9054
+ * If true, the layer is sent on the reliable channel.
9055
+ * @default false
9056
+ */
9057
+ mustBeReliable?: boolean;
9058
+ /**
9059
+ * If true, the layer is considered a macro layer (ephemeral, local effects).
8795
9060
  * @default false
8796
9061
  */
8797
- isStatic?: boolean;
9062
+ isMacroLayer?: boolean;
8798
9063
  }
9064
+ /**
9065
+ * Represents a renderable layer in world space.
9066
+ *
9067
+ * Layers store rendering orders and metadata (position, z-order, size)
9068
+ * and can be composed by displays at the `User` level.
9069
+ */
8799
9070
  declare class Layer {
8800
9071
  private id;
8801
9072
  private name?;
9073
+ private isMacroLayer;
8802
9074
  private origin;
8803
9075
  private orders;
8804
9076
  private zOrder;
8805
9077
  private data;
8806
9078
  private width;
8807
9079
  private height;
8808
- private isStatic;
9080
+ private mustBeReliable;
8809
9081
  private spriteRegistry?;
8810
9082
  private mode;
8811
9083
  private charCodeMode;
@@ -8816,99 +9088,137 @@ declare class Layer {
8816
9088
  private needsCommit;
8817
9089
  private static rasterizer;
8818
9090
  /**
8819
- * Creates a new Layer
9091
+ * Creates a new layer.
8820
9092
  *
8821
- * @param origin - Layer origin in world space
8822
- * @param zOrder - Z-order for layer stacking (higher = on top)
8823
- * @param width - Layer width in cells (1-256)
8824
- * @param height - Layer height in cells (1-256)
8825
- * @param options - Layer options (charCodeMode, isStatic)
9093
+ * @param origin - Layer origin in world space.
9094
+ * @param zOrder - Z-order for stacking (higher = on top).
9095
+ * @param width - Layer width in cells (1-256).
9096
+ * @param height - Layer height in cells (1-256).
9097
+ * @param options - Layer options.
9098
+ *
9099
+ * Options:
9100
+ * - `name`: Optional name for tooling/debug.
9101
+ * - `charCodeMode`: `'8bit'` (default) or `'16bit'`.
9102
+ * - `mustBeReliable`: `true` to use reliable channel, `false` for volatile.
9103
+ * - `isMacroLayer`: `true` for macro effects, `false` for standard layers.
8826
9104
  *
8827
9105
  * @example
8828
- * // 8-bit layer (default) - optimized for ASCII/CP437 text
9106
+ * // 8-bit layer (default) - CP437 (block 0) only
8829
9107
  * const gameLayer = new Layer(new Vector2(0, 0), 0, 80, 25);
8830
9108
  *
8831
- * // 16-bit layer - full Unicode support (emoji, CJK, symbols)
8832
- * const unicodeLayer = new Layer(new Vector2(0, 0), 10, 40, 10, { charCodeMode: '16bit' });
9109
+ * @example
9110
+ * // 16-bit layer - atlas blocks beyond CP437
9111
+ * const atlasLayer = new Layer(new Vector2(0, 0), 10, 40, 10, { charCodeMode: '16bit' });
9112
+ *
9113
+ * @throws Error if width/height are out of bounds.
8833
9114
  */
8834
9115
  constructor(origin: Vector2, zOrder: number, width: number, height: number, options?: LayerOptions | boolean);
8835
9116
  /**
8836
- * Gets the layer's charCode mode (immutable)
8837
- * @returns '8bit' or '16bit'
9117
+ * Returns whether the layer is a macro layer.
9118
+ */
9119
+ getIsMacroLayer(): boolean;
9120
+ /**
9121
+ * Returns the layer's charCode mode (immutable).
9122
+ *
9123
+ * @returns `'8bit'` or `'16bit'`.
8838
9124
  */
8839
9125
  getCharCodeMode(): CharCodeMode;
8840
9126
  /**
8841
- * Configures the layer's execution mode (called by User)
9127
+ * Configures the layer's execution mode.
8842
9128
  * @internal
8843
9129
  */
8844
9130
  setMode(mode: CoreMode): void;
8845
9131
  /**
8846
- * Injects the SpriteRegistry into the layer (called by Core)
9132
+ * Injects the SpriteRegistry into the layer.
8847
9133
  * @internal
8848
9134
  */
8849
9135
  setSpriteRegistry(registry: SpriteRegistry): void;
9136
+ /**
9137
+ * Returns all orders currently stored in this layer.
9138
+ *
9139
+ * @returns The order list.
9140
+ */
8850
9141
  getOrders(): AnyNetworkOrder[];
8851
9142
  /**
8852
- * Adds orders to the layer (incremental mode)
8853
- * Re-rasterizes all orders to ensure consistent state
9143
+ * Adds orders to the layer (incremental mode).
9144
+ * Re-rasterizes all orders to ensure consistent state.
9145
+ *
9146
+ * @param orders - Orders to append.
9147
+ *
9148
+ * @example
9149
+ * layer.addOrders([orderA, orderB]);
8854
9150
  */
8855
9151
  addOrders(orders: AnyNetworkOrder[]): void;
8856
9152
  /**
8857
- * Adds temporary orders that are rasterized but not stored
8858
- * Used for macro-generated content (particles, UI) that is regenerated each frame
9153
+ * Adds temporary orders that are rasterized but not stored.
9154
+ * Used for macro-generated content (particles/UI) regenerated each frame.
9155
+ *
9156
+ * @param orders - Orders to rasterize temporarily.
8859
9157
  */
8860
9158
  addTemporaryOrders(orders: AnyNetworkOrder[]): void;
8861
9159
  /**
8862
- * Replaces all orders in the layer (reset mode)
8863
- * Automatically rasterizes all orders
9160
+ * Replaces all orders in the layer (reset mode).
9161
+ * Automatically rasterizes all orders.
9162
+ *
9163
+ * @param orders - New orders to set.
8864
9164
  */
8865
9165
  setOrders(orders: AnyNetworkOrder[]): void;
8866
9166
  /**
8867
- * Clears all orders and cleans the buffer
9167
+ * Clears all orders and resets the buffer.
8868
9168
  */
8869
9169
  clearOrders(): void;
8870
- getOrigin(): Vector2;
8871
9170
  /**
8872
- * Updates the layer's origin and rasterizes if necessary
9171
+ * Returns the layer origin in world space.
8873
9172
  *
8874
- * In client mode, this method automatically rasterizes the layer
8875
- * to reflect the new position.
9173
+ * @returns The current origin.
9174
+ */
9175
+ getOrigin(): Vector2;
9176
+ /**
9177
+ * Updates the layer's origin.
8876
9178
  *
8877
- * @param origin - New layer origin
9179
+ * @param origin - New layer origin.
8878
9180
  */
8879
9181
  setOrigin(origin: Vector2): void;
9182
+ /**
9183
+ * Returns the layer's z-order.
9184
+ *
9185
+ * @returns Z-order value.
9186
+ */
8880
9187
  getZOrder(): number;
8881
9188
  /**
8882
- * Updates the layer's z-order
9189
+ * Updates the layer's z-order.
8883
9190
  *
8884
- * @param zOrder - New z-order
9191
+ * @param zOrder - New z-order.
8885
9192
  */
8886
9193
  setZOrder(zOrder: number): void;
8887
9194
  /**
8888
- * Gets the layer's unique ID
8889
- *
8890
- * Used for client-side reconstruction when applying UpdatePackets.
8891
- * The ID allows associating a NetworkLayer with its corresponding Layer.
9195
+ * Returns the layer's unique ID.
8892
9196
  *
8893
- * @returns Layer ID (0-65535)
9197
+ * @returns Layer ID (0-65535).
8894
9198
  */
8895
9199
  getId(): number;
8896
9200
  /**
8897
- * Gets the layer's optional name (debug/metadata only)
9201
+ * Returns the layer's optional name (debug/metadata only).
9202
+ *
9203
+ * @returns Name or `undefined`.
8898
9204
  */
8899
9205
  getName(): string | undefined;
8900
9206
  /**
8901
- * Sets the layer's optional name (debug/metadata only)
9207
+ * Sets the layer's optional name (debug/metadata only).
9208
+ *
9209
+ * @param name - New name or `undefined` to clear.
8902
9210
  */
8903
9211
  setName(name: string | undefined): void;
8904
9212
  /**
8905
- * Returns a debug-friendly snapshot of this layer (metadata only)
9213
+ * Returns a debug-friendly snapshot of this layer (metadata only).
9214
+ *
9215
+ * @returns Debug info snapshot.
8906
9216
  */
8907
9217
  getDebugInfo(): {
8908
9218
  id: number;
8909
9219
  name?: string;
8910
9220
  z: number;
8911
- isStatic: boolean;
9221
+ mustBeReliable: boolean;
8912
9222
  charCodeMode: CharCodeMode;
8913
9223
  width: number;
8914
9224
  height: number;
@@ -8922,58 +9232,74 @@ declare class Layer {
8922
9232
  ordersCount: number;
8923
9233
  };
8924
9234
  /**
8925
- * Sets the layer's unique ID
8926
- *
8927
- * @internal - Used by User.applyUpdate() during reconstruction
8928
- * @param id - Unique layer ID (0-65535)
9235
+ * Sets the layer's unique ID.
9236
+ * @internal
9237
+ * @param id - Unique layer ID (0-65535).
9238
+ */
9239
+ private setIdInternal;
9240
+ /**
9241
+ * Returns the internal cell buffer.
9242
+ * @returns The `CellBuffer` instance.
9243
+ * @internal
8929
9244
  */
8930
- setId(id: number): void;
8931
9245
  getData(): CellBuffer;
9246
+ /**
9247
+ * Returns the layer width in cells.
9248
+ * @returns Width in cells.
9249
+ */
8932
9250
  getWidth(): number;
9251
+ /**
9252
+ * Returns the layer height in cells.
9253
+ * @returns Height in cells.
9254
+ */
8933
9255
  getHeight(): number;
8934
- getCellAt(x: number, y: number): Cell | null;
8935
9256
  /**
8936
- * Marks this layer as static or dynamic
8937
- *
8938
- * Static layer: Sent only once to client via reliable channel,
8939
- * but continues to be rasterized client-side every frame.
8940
- * Used for UI elements, backgrounds, elements that never change.
9257
+ * Returns the cell at the given coordinates.
8941
9258
  *
8942
- * Dynamic layer: Sent every tick via volatile channel.
8943
- * Used for animated elements, players, projectiles, etc.
9259
+ * @param x - X coordinate (0..width-1).
9260
+ * @param y - Y coordinate (0..height-1).
9261
+ * @returns The cell or `null` if out of bounds.
9262
+ */
9263
+ getCellAt(x: number, y: number): Cell | null;
9264
+ /**
9265
+ * Marks this layer as reliable or volatile for network transport.
8944
9266
  *
8945
- * @param isStatic - true for static, false for dynamic
9267
+ * @param mustBeReliable - `true` for reliable channel, `false` for volatile.
8946
9268
  */
8947
- setStatic(isStatic: boolean): void;
9269
+ setMustBeReliable(mustBeReliable: boolean): void;
8948
9270
  /**
8949
- * Checks if this layer is static
9271
+ * Returns whether this layer must be sent reliably.
9272
+ *
9273
+ * @returns `true` if reliable.
8950
9274
  */
8951
- getStatic(): boolean;
9275
+ getMustBeReliable(): boolean;
8952
9276
  /**
8953
- * Enables or disables the layer
8954
- * A disabled layer will not be rendered by DisplayRasterizer
9277
+ * Enables or disables the layer.
9278
+ * A disabled layer will not be rendered by the display rasterizer.
8955
9279
  *
8956
- * @param enabled - true to enable, false to disable
9280
+ * @param enabled - `true` to enable, `false` to disable.
8957
9281
  */
8958
9282
  setEnabled(enabled: boolean): void;
8959
9283
  /**
8960
- * Checks if layer is enabled
9284
+ * Returns whether the layer is enabled.
9285
+ *
9286
+ * @returns `true` if enabled.
8961
9287
  */
8962
9288
  isEnabled(): boolean;
8963
9289
  /**
8964
- * Checks if layer origin changed since last tick
8965
- * @internal - Used to calculate UpdateFlags
9290
+ * Returns `true` if the origin changed since the last tick.
9291
+ * @internal
8966
9292
  */
8967
9293
  hasOriginChanged(): boolean;
8968
9294
  /**
8969
- * Checks if layer z-order changed since last tick
8970
- * @internal - Used to calculate UpdateFlags
9295
+ * Returns `true` if the z-order changed since the last tick.
9296
+ * @internal
8971
9297
  */
8972
9298
  hasZOrderChanged(): boolean;
8973
9299
  /**
8974
- * Calculates UpdateFlags based on layer state and changes
8975
- * @internal - Used by Core.endTick()
8976
- * @returns Bitpacked flags (0x00 to 0x0F)
9300
+ * Calculates UpdateFlags based on layer state and changes.
9301
+ * @internal
9302
+ * @returns Bitpacked flags (0x00 to 0x0F).
8977
9303
  *
8978
9304
  * Flag structure:
8979
9305
  * - Bit 0 (0x01): Layer Enabled (1=active, 0=disabled)
@@ -8983,35 +9309,33 @@ declare class Layer {
8983
9309
  */
8984
9310
  calculateUpdateFlags(): number;
8985
9311
  /**
8986
- * Resets change tracking after sending a tick
8987
- * @internal - Used by Core.endTick()
9312
+ * Resets change tracking after sending a tick.
9313
+ * @internal
8988
9314
  */
8989
9315
  resetChangeTracking(): void;
8990
9316
  /**
8991
- * Marks the layer as needing to be sent on next tick
9317
+ * Marks the layer as needing to be sent on the next tick.
8992
9318
  *
8993
9319
  * Used to optimize bandwidth by sending only modified layers.
8994
9320
  *
8995
9321
  * @example
8996
- * ```typescript
8997
9322
  * layer.addOrders([...]);
8998
- * layer.commit(); // Layer will be sent on next tick
8999
- * ```
9323
+ * layer.commit();
9000
9324
  */
9001
9325
  commit(): void;
9002
9326
  /**
9003
- * Returns a breakdown of order types for debugging
9327
+ * Returns a breakdown of order types for debugging.
9004
9328
  * @internal
9005
9329
  */
9006
9330
  private getOrdersBreakdown;
9007
9331
  /**
9008
- * Checks if layer needs to be sent
9009
- * @internal - Used by Core.endTick()
9332
+ * Returns `true` if the layer needs to be sent.
9333
+ * @internal
9010
9334
  */
9011
9335
  getNeedsCommit(): boolean;
9012
9336
  /**
9013
- * Resets commit flag after sending
9014
- * @internal - Used by Core.endTick()
9337
+ * Resets the commit flag after sending.
9338
+ * @internal
9015
9339
  */
9016
9340
  resetCommit(): void;
9017
9341
  }
@@ -9068,7 +9392,7 @@ declare class DisplayRasterizer {
9068
9392
  private static charCache;
9069
9393
  /**
9070
9394
  * Gets the cached character for a charCode, creating it lazily if needed
9071
- * Supports full 16-bit range (0-65535) for extended Unicode
9395
+ * Supports full 16-bit range (0-65535) for atlas indices
9072
9396
  */
9073
9397
  private static getChar;
9074
9398
  /**
@@ -9090,7 +9414,7 @@ declare class DisplayRasterizer {
9090
9414
  constructor(engine: Core);
9091
9415
  /**
9092
9416
  * Rebuilds the RGB cache from the engine palette
9093
- * Call after palette modification (loadPalette, setColor)
9417
+ * Call after palette modification (setColor, resetPalette)
9094
9418
  */
9095
9419
  rebuildColorCache(): void;
9096
9420
  /**
@@ -9184,60 +9508,114 @@ interface ColorOptions {
9184
9508
  */
9185
9509
  declare class OrderBuilder {
9186
9510
  /**
9187
- * Convert string or number to character code
9188
- * @param char - Either a string (first character used) or a number (0-65535)
9189
- * @returns Character code (0-65535)
9511
+ * Converts a string or number to a char code.
9512
+ *
9513
+ * @param char - String (first character used) or numeric char code (0-65535).
9514
+ * @returns Char code (0-65535).
9515
+ *
9190
9516
  * @example
9191
- * toCharCode('#') // → 0x23 (35)
9192
- * toCharCode(0x23) // → 0x23 (35)
9193
- * toCharCode('ABC') // → 0x41 (65, first char only)
9194
- * toCharCode(256) // → 256 (preserved for 16-bit layers)
9517
+ * OrderBuilder.toCharCode('#') // → 35
9518
+ * OrderBuilder.toCharCode(35) // → 35
9519
+ * OrderBuilder.toCharCode('ABC') // → 65 (first char only)
9520
+ * OrderBuilder.toCharCode(256) // → 256 (preserved for 16-bit layers)
9195
9521
  */
9196
9522
  static toCharCode(char: string | number): number;
9197
9523
  /**
9198
- * Remove common leading whitespace from multiline strings (dedent)
9199
- * Useful for template literals that are indented in source code
9200
- * @param text - Multiline text to dedent
9201
- * @returns Dedented text
9524
+ * Removes common leading whitespace from multiline strings (dedent).
9525
+ * Useful for template literals that are indented in source code.
9526
+ *
9527
+ * @param text - Multiline text to dedent.
9528
+ * @returns Dedented text.
9529
+ *
9202
9530
  * @example
9203
9531
  * const text = `
9204
9532
  * Hello
9205
9533
  * World
9206
9534
  * `;
9207
- * dedent(text) // → "Hello\nWorld"
9535
+ * OrderBuilder.dedent(text); // → "Hello\nWorld"
9208
9536
  */
9209
9537
  static dedent(text: string): string;
9210
9538
  /**
9211
- * 0x01 - Char: Single character at a position
9212
- * @param char - Character as string ('#') or charCode (0x23)
9539
+ * Encodes a string into CP437 character codes packed into a string.
9540
+ * This ensures that strings with Unicode characters (e.g. '', 'é') are
9541
+ * converted to their CP437 byte values (e.g. 176, 130) before being stored.
9542
+ *
9543
+ * @param text - The input string (possibly containing Unicode)
9544
+ * @returns A string where each character is a CP437 byte value (0-255)
9545
+ */
9546
+ static encodeString(text: string): string;
9547
+ /**
9548
+ * Creates a single character order at a position.
9549
+ *
9550
+ * @param x - X position (cell).
9551
+ * @param y - Y position (cell).
9552
+ * @param char - Character as string ('#') or numeric code (35).
9553
+ * @param fgColor - Foreground color (0-255).
9554
+ * @param bgColor - Background color (0-255).
9555
+ * @returns Char order.
9556
+ *
9557
+ * @example
9558
+ * OrderBuilder.char(10, 20, '#', 15, 0);
9213
9559
  */
9214
9560
  static char(x: number, y: number, char: string | number, fgColor?: number, bgColor?: number): CharOrder;
9215
9561
  /**
9216
- * 0x02 - Text: Horizontal character string
9562
+ * Creates a single-line text order.
9563
+ *
9564
+ * @param x - X position (cell).
9565
+ * @param y - Y position (cell).
9566
+ * @param text - Text to draw.
9567
+ * @param fgColor - Foreground color (0-255).
9568
+ * @param bgColor - Background color (0-255).
9569
+ * @returns Text order.
9570
+ *
9571
+ * @example
9572
+ * OrderBuilder.text(2, 4, 'Hello', 15, 0);
9217
9573
  */
9218
9574
  static text(x: number, y: number, text: string, fgColor?: number, bgColor?: number): TextOrder;
9219
9575
  /**
9220
- * 0x17 - TextMultiline: Multiple lines of text (\n for line breaks)
9221
- * Automatically removes common indentation (dedent) for template literals
9576
+ * Creates a multi-line text order (\n for line breaks).
9577
+ * Automatically dedents template literals.
9578
+ *
9579
+ * @param x - X position (cell).
9580
+ * @param y - Y position (cell).
9581
+ * @param text - Text content (can include \n).
9582
+ * @param fgColor - Foreground color (0-255).
9583
+ * @param bgColor - Background color (0-255).
9584
+ * @returns Multiline text order.
9585
+ *
9222
9586
  * @example With explicit \n
9223
- * OrderBuilder.textMultiline(10, 5, 'Hello\nWorld\n!', 15, 0)
9587
+ * OrderBuilder.textMultiline(10, 5, 'Hello\nWorld\n!', 15, 0);
9224
9588
  *
9225
9589
  * @example With template literal (auto-dedented)
9226
9590
  * OrderBuilder.textMultiline(10, 5, `
9227
9591
  * Score: ${score}
9228
9592
  * Lives: ${lives}
9229
9593
  * Level: ${level}
9230
- * `, 15, 0)
9594
+ * `, 15, 0);
9231
9595
  */
9232
9596
  static textMultiline(x: number, y: number, text: string, fgColor?: number, bgColor?: number): TextMultilineOrder;
9233
9597
  /**
9234
- * 0x03 - SubFrame: Rectangular area with uniform colors
9235
- * @param frame - Array of characters as strings or numbers
9598
+ * Creates a rectangular frame with uniform colors.
9599
+ *
9600
+ * @param x - X position (cell).
9601
+ * @param y - Y position (cell).
9602
+ * @param width - Width in cells.
9603
+ * @param height - Height in cells.
9604
+ * @param frame - Array of characters as strings or numbers.
9605
+ * @param fgColor - Foreground color (0-255).
9606
+ * @param bgColor - Background color (0-255).
9607
+ * @returns Sub-frame order.
9236
9608
  */
9237
9609
  static subFrame(x: number, y: number, width: number, height: number, frame: (string | number)[], fgColor?: number, bgColor?: number): SubFrameOrder;
9238
9610
  /**
9239
- * 0x04 - SubFrameMultiColor: Rectangular area with per-cell colors
9240
- * @param frame - Array of cells where charCode can be string or number
9611
+ * Creates a rectangular frame with per-cell colors.
9612
+ *
9613
+ * @param x - X position (cell).
9614
+ * @param y - Y position (cell).
9615
+ * @param width - Width in cells.
9616
+ * @param height - Height in cells.
9617
+ * @param frame - Array of cells where `charCode` can be string or number.
9618
+ * @returns Sub-frame order (multi-color).
9241
9619
  */
9242
9620
  static subFrameMultiColor(x: number, y: number, width: number, height: number, frame: Array<{
9243
9621
  charCode: string | number;
@@ -9245,13 +9623,19 @@ declare class OrderBuilder {
9245
9623
  fgColorCode: number;
9246
9624
  }>): SubFrameMultiColorOrder;
9247
9625
  /**
9248
- * 0x05 - FullFrame: Entire layer (256×256) with uniform colors
9249
- * @param frame - Array of characters as strings or numbers
9626
+ * Creates a full-frame fill for the entire layer (256×256).
9627
+ *
9628
+ * @param frame - Array of characters as strings or numbers.
9629
+ * @param fgColor - Foreground color (0-255).
9630
+ * @param bgColor - Background color (0-255).
9631
+ * @returns Full-frame order.
9250
9632
  */
9251
9633
  static fullFrame(frame: (string | number)[], fgColor?: number, bgColor?: number): FullFrameOrder;
9252
9634
  /**
9253
- * 0x06 - FullFrameMultiColor: Entire layer (256×256) with per-cell colors
9254
- * @param frame - Array of cells where charCode can be string or number
9635
+ * Creates a full-frame fill with per-cell colors (256×256).
9636
+ *
9637
+ * @param frame - Array of cells where `charCode` can be string or number.
9638
+ * @returns Full-frame order (multi-color).
9255
9639
  */
9256
9640
  static fullFrameMultiColor(frame: Array<{
9257
9641
  charCode: string | number;
@@ -9259,23 +9643,52 @@ declare class OrderBuilder {
9259
9643
  fgColorCode: number;
9260
9644
  }>): FullFrameMultiColorOrder;
9261
9645
  /**
9262
- * 0x07 - Sprite: Single-color sprite at a position
9646
+ * Creates a single-color sprite order at a position.
9647
+ *
9648
+ * @param x - X position (cell).
9649
+ * @param y - Y position (cell).
9650
+ * @param spriteIndex - Sprite index in the registry.
9651
+ * @param fgColor - Foreground color (0-255).
9652
+ * @param bgColor - Background color (0-255).
9653
+ * @returns Sprite order.
9263
9654
  */
9264
9655
  static sprite(x: number, y: number, spriteIndex: number, fgColor?: number, bgColor?: number): SpriteOrder;
9265
9656
  /**
9266
- * 0x08 - SpriteMultiColor: Multi-color sprite at a position
9657
+ * Creates a multi-color sprite order at a position.
9658
+ *
9659
+ * @param x - X position (cell).
9660
+ * @param y - Y position (cell).
9661
+ * @param spriteIndex - Sprite index in the registry.
9662
+ * @returns Multi-color sprite order.
9267
9663
  */
9268
9664
  static spriteMultiColor(x: number, y: number, spriteIndex: number): SpriteMultiColorOrder;
9269
9665
  /**
9270
- * 0x09 - ColorMap: Applies colors without changing characters
9666
+ * Applies colors without changing characters.
9667
+ *
9668
+ * @param x - X position (cell).
9669
+ * @param y - Y position (cell).
9670
+ * @param width - Width in cells.
9671
+ * @param height - Height in cells.
9672
+ * @param colorData - Array of fg/bg colors per cell.
9673
+ * @returns Color map order.
9271
9674
  */
9272
9675
  static colorMap(x: number, y: number, width: number, height: number, colorData: Array<{
9273
9676
  fgColorCode: number;
9274
9677
  bgColorCode: number;
9275
9678
  }>): ColorMapOrder;
9276
9679
  /**
9277
- * 0x0A - Rectangle Shape
9278
- * @param options.charCode - Character as string ('█') or charCode (0x2588)
9680
+ * Creates a rectangle shape order.
9681
+ *
9682
+ * @param x - X position (cell).
9683
+ * @param y - Y position (cell).
9684
+ * @param width - Width in cells.
9685
+ * @param height - Height in cells.
9686
+ * @param options - Shape options.
9687
+ * @param options.charCode - Character as string ('█') or numeric code (9608).
9688
+ * @param options.bgColor - Background color (0-255).
9689
+ * @param options.fgColor - Foreground color (0-255).
9690
+ * @param options.filled - Fill shape (default: true).
9691
+ * @returns Shape order.
9279
9692
  */
9280
9693
  static rectangle(x: number, y: number, width: number, height: number, options?: {
9281
9694
  charCode?: string | number;
@@ -9284,8 +9697,17 @@ declare class OrderBuilder {
9284
9697
  filled?: boolean;
9285
9698
  }): ShapeOrder;
9286
9699
  /**
9287
- * 0x0A - Circle Shape
9288
- * @param options.charCode - Character as string ('█') or charCode (0x2588)
9700
+ * Creates a circle shape order.
9701
+ *
9702
+ * @param centerX - Center X position (cell).
9703
+ * @param centerY - Center Y position (cell).
9704
+ * @param radius - Radius in cells.
9705
+ * @param options - Shape options.
9706
+ * @param options.charCode - Character as string ('█') or numeric code (9608).
9707
+ * @param options.bgColor - Background color (0-255).
9708
+ * @param options.fgColor - Foreground color (0-255).
9709
+ * @param options.filled - Fill shape (default: true).
9710
+ * @returns Shape order.
9289
9711
  */
9290
9712
  static circle(centerX: number, centerY: number, radius: number, options?: {
9291
9713
  charCode?: string | number;
@@ -9294,8 +9716,17 @@ declare class OrderBuilder {
9294
9716
  filled?: boolean;
9295
9717
  }): ShapeOrder;
9296
9718
  /**
9297
- * 0x0A - Line Shape
9298
- * @param options.charCode - Character as string ('█') or charCode (0x2588)
9719
+ * Creates a line shape order.
9720
+ *
9721
+ * @param x1 - Start X position (cell).
9722
+ * @param y1 - Start Y position (cell).
9723
+ * @param x2 - End X position (cell).
9724
+ * @param y2 - End Y position (cell).
9725
+ * @param options - Shape options.
9726
+ * @param options.charCode - Character as string ('█') or numeric code (9608).
9727
+ * @param options.bgColor - Background color (0-255).
9728
+ * @param options.fgColor - Foreground color (0-255).
9729
+ * @returns Shape order.
9299
9730
  */
9300
9731
  static line(x1: number, y1: number, x2: number, y2: number, options?: {
9301
9732
  charCode?: string | number;
@@ -9303,8 +9734,18 @@ declare class OrderBuilder {
9303
9734
  fgColor?: number;
9304
9735
  }): ShapeOrder;
9305
9736
  /**
9306
- * 0x0A - Ellipse Shape
9307
- * @param options.charCode - Character as string ('█') or charCode (0x2588)
9737
+ * Creates an ellipse shape order.
9738
+ *
9739
+ * @param centerX - Center X position (cell).
9740
+ * @param centerY - Center Y position (cell).
9741
+ * @param radiusX - Radius on X axis (cells).
9742
+ * @param radiusY - Radius on Y axis (cells).
9743
+ * @param options - Shape options.
9744
+ * @param options.charCode - Character as string ('█') or numeric code (9608).
9745
+ * @param options.bgColor - Background color (0-255).
9746
+ * @param options.fgColor - Foreground color (0-255).
9747
+ * @param options.filled - Fill shape (default: true).
9748
+ * @returns Shape order.
9308
9749
  */
9309
9750
  static ellipse(centerX: number, centerY: number, radiusX: number, radiusY: number, options?: {
9310
9751
  charCode?: string | number;
@@ -9313,8 +9754,20 @@ declare class OrderBuilder {
9313
9754
  filled?: boolean;
9314
9755
  }): ShapeOrder;
9315
9756
  /**
9316
- * 0x0A - Triangle Shape
9317
- * @param options.charCode - Character as string ('█') or charCode (0x2588)
9757
+ * Creates a triangle shape order.
9758
+ *
9759
+ * @param x1 - First point X (cell).
9760
+ * @param y1 - First point Y (cell).
9761
+ * @param x2 - Second point X (cell).
9762
+ * @param y2 - Second point Y (cell).
9763
+ * @param x3 - Third point X (cell).
9764
+ * @param y3 - Third point Y (cell).
9765
+ * @param options - Shape options.
9766
+ * @param options.charCode - Character as string ('█') or numeric code (9608).
9767
+ * @param options.bgColor - Background color (0-255).
9768
+ * @param options.fgColor - Foreground color (0-255).
9769
+ * @param options.filled - Fill shape (default: true).
9770
+ * @returns Shape order.
9318
9771
  */
9319
9772
  static triangle(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, options?: {
9320
9773
  charCode?: string | number;
@@ -9323,16 +9776,23 @@ declare class OrderBuilder {
9323
9776
  filled?: boolean;
9324
9777
  }): ShapeOrder;
9325
9778
  /**
9326
- * 0x0B - DotCloud: Same character at multiple positions
9327
- * @param char - Character as string ('#') or charCode (0x23)
9779
+ * Creates a dot cloud with the same character at multiple positions.
9780
+ *
9781
+ * @param positions - Array of positions.
9782
+ * @param char - Character as string ('#') or numeric code (35).
9783
+ * @param fgColor - Foreground color (0-255).
9784
+ * @param bgColor - Background color (0-255).
9785
+ * @returns Dot cloud order.
9328
9786
  */
9329
9787
  static dotCloud(positions: Array<{
9330
9788
  posX: number;
9331
9789
  posY: number;
9332
9790
  }>, char: string | number, fgColor?: number, bgColor?: number): DotCloudOrder;
9333
9791
  /**
9334
- * 0x0C - DotCloudMultiColor: Different characters at multiple positions
9335
- * @param dots - Array where charCode can be string or number
9792
+ * Creates a multi-color dot cloud (per-dot colors and characters).
9793
+ *
9794
+ * @param dots - Array where `charCode` can be string or number.
9795
+ * @returns Dot cloud order (multi-color).
9336
9796
  */
9337
9797
  static dotCloudMultiColor(dots: Array<{
9338
9798
  posX: number;
@@ -9342,25 +9802,41 @@ declare class OrderBuilder {
9342
9802
  fgColorCode: number;
9343
9803
  }>): DotCloudMultiColorOrder;
9344
9804
  /**
9345
- * 0x11 - Bitmask: Bitpacked presence/absence mask with uniform character
9346
- * Perfect for ore veins, destructible terrain, collision maps, fog of war
9347
- * @param mask - Flat array of booleans (row-major order: sizeX × sizeY)
9348
- * @param char - Character as string ('#') or charCode (0x23)
9349
- * @param override - true: clear absences (transparent), false: preserve existing cells
9805
+ * Creates a bitmask order with a uniform character.
9806
+ * Useful for ore veins, destructible terrain, collision maps, or fog of war.
9807
+ *
9808
+ * @param x - X position (cell).
9809
+ * @param y - Y position (cell).
9810
+ * @param width - Width in cells.
9811
+ * @param height - Height in cells.
9812
+ * @param mask - Flat array of booleans (row-major order: sizeX × sizeY).
9813
+ * @param char - Character as string ('#') or numeric code (35).
9814
+ * @param fgColor - Foreground color (0-255).
9815
+ * @param bgColor - Background color (0-255).
9816
+ * @param override - true: clear absences (transparent), false: preserve existing cells.
9817
+ * @returns Bitmask order.
9818
+ *
9350
9819
  * @example Create a 3×3 cross pattern
9351
9820
  * OrderBuilder.bitmask(10, 10, 3, 3, [
9352
9821
  * false, true, false,
9353
9822
  * true, true, true,
9354
9823
  * false, true, false
9355
- * ], '#', 15, 0, false)
9824
+ * ], '#', 15, 0, false);
9356
9825
  */
9357
9826
  static bitmask(x: number, y: number, width: number, height: number, mask: boolean[], char: string | number, fgColor?: number, bgColor?: number, override?: boolean): BitmaskOrder;
9358
9827
  /**
9359
- * 0x12 - Bitmask4: 2-bit packed mask with 3 visual variants
9360
- * @param mask - Flat array of values 0-3 (row-major order: sizeX × sizeY)
9361
- * 0 = absence, 1-3 = variant index
9362
- * @param variants - Array of up to 3 variants { char, fgColor, bgColor } for values 1, 2, 3
9363
- * @param override - true: clear absences (transparent), false: preserve existing cells
9828
+ * Creates a bitmask order with 3 visual variants (values 1..3).
9829
+ *
9830
+ * @param x - X position (cell).
9831
+ * @param y - Y position (cell).
9832
+ * @param width - Width in cells.
9833
+ * @param height - Height in cells.
9834
+ * @param mask - Flat array of values 0-3 (row-major order: sizeX × sizeY).
9835
+ * 0 = absence, 1-3 = variant index.
9836
+ * @param variants - Array of up to 3 variants { char, fgColor, bgColor } for values 1..3.
9837
+ * @param override - true: clear absences (transparent), false: preserve existing cells.
9838
+ * @returns Bitmask4 order.
9839
+ *
9364
9840
  * @example Create a 3×3 pattern with 3 variants
9365
9841
  * OrderBuilder.bitmask4(10, 10, 3, 3, [
9366
9842
  * 0, 1, 0,
@@ -9370,7 +9846,7 @@ declare class OrderBuilder {
9370
9846
  * { char: 'a', fgColor: 15, bgColor: 0 },
9371
9847
  * { char: 'b', fgColor: 14, bgColor: 0 },
9372
9848
  * { char: 'c', fgColor: 13, bgColor: 0 }
9373
- * ], false)
9849
+ * ], false);
9374
9850
  */
9375
9851
  static bitmask4(x: number, y: number, width: number, height: number, mask: number[], variants: Array<{
9376
9852
  char: string | number;
@@ -9378,11 +9854,18 @@ declare class OrderBuilder {
9378
9854
  bgColor: number;
9379
9855
  }>, override?: boolean): Bitmask4Order;
9380
9856
  /**
9381
- * 0x18 - Bitmask16: 4-bit packed mask with 15 visual variants
9382
- * @param mask - Flat array of values 0-15 (row-major order: sizeX × sizeY)
9383
- * 0 = absence, 1-15 = variant index
9384
- * @param variants - Array of up to 15 variants { char, fgColor, bgColor } for values 1-15
9385
- * @param override - true: clear absences (transparent), false: preserve existing cells
9857
+ * Creates a bitmask order with up to 15 visual variants (values 1..15).
9858
+ *
9859
+ * @param x - X position (cell).
9860
+ * @param y - Y position (cell).
9861
+ * @param width - Width in cells.
9862
+ * @param height - Height in cells.
9863
+ * @param mask - Flat array of values 0-15 (row-major order: sizeX × sizeY).
9864
+ * 0 = absence, 1-15 = variant index.
9865
+ * @param variants - Array of up to 15 variants { char, fgColor, bgColor } for values 1..15.
9866
+ * @param override - true: clear absences (transparent), false: preserve existing cells.
9867
+ * @returns Bitmask16 order.
9868
+ *
9386
9869
  * @example Create a 3×3 pattern with multiple variants
9387
9870
  * OrderBuilder.bitmask16(10, 10, 3, 3, [
9388
9871
  * 0, 1, 0,
@@ -9392,7 +9875,7 @@ declare class OrderBuilder {
9392
9875
  * { char: 'a', fgColor: 15, bgColor: 0 },
9393
9876
  * { char: 'b', fgColor: 14, bgColor: 0 },
9394
9877
  * // ... up to 15 variants
9395
- * ], false)
9878
+ * ], false);
9396
9879
  */
9397
9880
  static bitmask16(x: number, y: number, width: number, height: number, mask: number[], variants: Array<{
9398
9881
  char: string | number;
@@ -9400,21 +9883,34 @@ declare class OrderBuilder {
9400
9883
  bgColor: number;
9401
9884
  }>, override?: boolean): Bitmask16Order;
9402
9885
  /**
9403
- * 0x0D - SpriteCloud: Same single-color sprite at multiple positions
9886
+ * Creates a sprite cloud with a single-color sprite at multiple positions.
9887
+ *
9888
+ * @param spriteIndex - Sprite index in the registry.
9889
+ * @param positions - Array of positions.
9890
+ * @param fgColor - Foreground color (0-255).
9891
+ * @param bgColor - Background color (0-255).
9892
+ * @returns Sprite cloud order.
9404
9893
  */
9405
9894
  static spriteCloud(spriteIndex: number, positions: Array<{
9406
9895
  posX: number;
9407
9896
  posY: number;
9408
9897
  }>, fgColor?: number, bgColor?: number): SpriteCloudOrder;
9409
9898
  /**
9410
- * 0x0E - SpriteCloudMultiColor: Same multi-color sprite at multiple positions
9899
+ * Creates a multi-color sprite cloud at multiple positions.
9900
+ *
9901
+ * @param spriteIndex - Sprite index in the registry.
9902
+ * @param positions - Array of positions.
9903
+ * @returns Multi-color sprite cloud order.
9411
9904
  */
9412
9905
  static spriteCloudMultiColor(spriteIndex: number, positions: Array<{
9413
9906
  posX: number;
9414
9907
  posY: number;
9415
9908
  }>): SpriteCloudMultiColorOrder;
9416
9909
  /**
9417
- * 0x0F - SpriteCloudVaried: Different single-color sprites at multiple positions
9910
+ * Creates a varied sprite cloud (single-color sprites per position).
9911
+ *
9912
+ * @param sprites - Array of sprites with position and colors.
9913
+ * @returns Varied sprite cloud order.
9418
9914
  */
9419
9915
  static spriteCloudVaried(sprites: Array<{
9420
9916
  posX: number;
@@ -9424,7 +9920,10 @@ declare class OrderBuilder {
9424
9920
  fgColorCode: number;
9425
9921
  }>): SpriteCloudVariedOrder;
9426
9922
  /**
9427
- * 0x10 - SpriteCloudVariedMultiColor: Different multi-color sprites at multiple positions
9923
+ * Creates a varied sprite cloud with multi-color sprites.
9924
+ *
9925
+ * @param sprites - Array of sprites with position.
9926
+ * @returns Varied multi-color sprite cloud order.
9428
9927
  */
9429
9928
  static spriteCloudVariedMultiColor(sprites: Array<{
9430
9929
  posX: number;
@@ -9432,27 +9931,53 @@ declare class OrderBuilder {
9432
9931
  spriteIndex: number;
9433
9932
  }>): SpriteCloudVariedMultiColorOrder;
9434
9933
  /**
9435
- * 0x13 - Clear: Fills entire layer with a character
9436
- * @param char - Character as string (' ') or charCode (0x20)
9934
+ * Fills the entire layer with a character.
9935
+ *
9936
+ * @param char - Character as string (' ') or numeric code (32).
9937
+ * @param fgColor - Foreground color (0-255).
9938
+ * @param bgColor - Background color (0-255).
9939
+ * @returns Clear order.
9437
9940
  */
9438
9941
  static clear(char?: string | number, fgColor?: number, bgColor?: number): ClearOrder;
9439
9942
  /**
9440
- * 0x14 - FillChar: Fills layer with a repeating pattern
9441
- * @param pattern - Array of characters as strings or numbers
9943
+ * Fills the layer with a repeating character pattern.
9944
+ *
9945
+ * @param patternWidth - Pattern width in cells.
9946
+ * @param patternHeight - Pattern height in cells.
9947
+ * @param pattern - Array of characters as strings or numbers.
9948
+ * @param fgColor - Foreground color (0-255).
9949
+ * @param bgColor - Background color (0-255).
9950
+ * @returns Fill character order.
9442
9951
  */
9443
9952
  static fillChar(patternWidth: number, patternHeight: number, pattern: (string | number)[], fgColor?: number, bgColor?: number): FillCharOrder;
9444
9953
  /**
9445
- * 0x15 - FillSprite: Fills layer with a repeating single-color sprite
9954
+ * Fills the layer with a repeating single-color sprite.
9955
+ *
9956
+ * @param spriteIndex - Sprite index in the registry.
9957
+ * @param fgColor - Foreground color (0-255).
9958
+ * @param bgColor - Background color (0-255).
9959
+ * @returns Fill sprite order.
9446
9960
  */
9447
9961
  static fillSprite(spriteIndex: number, fgColor?: number, bgColor?: number): FillSpriteOrder;
9448
9962
  /**
9449
- * 0x16 - FillSpriteMultiColor: Fills layer with a repeating multi-color sprite
9963
+ * Fills the layer with a repeating multi-color sprite.
9964
+ *
9965
+ * @param spriteIndex - Sprite index in the registry.
9966
+ * @returns Fill multi-color sprite order.
9450
9967
  */
9451
9968
  static fillSpriteMultiColor(spriteIndex: number): FillSpriteMultiColorOrder;
9452
9969
  /**
9453
- * Helper: Create a rectangle with colored border and different interior
9454
- * @param borderOptions.charCode - Character as string ('█') or charCode (0x2588)
9455
- * @param fillOptions.charCode - Character as string ('█') or charCode (0x2588)
9970
+ * Creates a rectangle with a colored border and a different interior.
9971
+ *
9972
+ * @param x - X position (cell).
9973
+ * @param y - Y position (cell).
9974
+ * @param width - Width in cells.
9975
+ * @param height - Height in cells.
9976
+ * @param borderOptions - Border colors/char.
9977
+ * @param borderOptions.charCode - Character as string ('█') or numeric code (9608).
9978
+ * @param fillOptions - Fill colors/char.
9979
+ * @param fillOptions.charCode - Character as string ('█') or numeric code (9608).
9980
+ * @returns Array of shape orders (fill + border).
9456
9981
  */
9457
9982
  static boxWithBorder(x: number, y: number, width: number, height: number, borderOptions: ColorOptions & {
9458
9983
  charCode?: string | number;
@@ -9460,25 +9985,35 @@ declare class OrderBuilder {
9460
9985
  charCode?: string | number;
9461
9986
  }): ShapeOrder[];
9462
9987
  /**
9463
- * Helper: Create a grid of points
9464
- * @param options.charCode - Character as string ('+') or charCode (0x2b)
9988
+ * Creates a grid of points.
9989
+ *
9990
+ * @param startX - Grid start X (cell).
9991
+ * @param startY - Grid start Y (cell).
9992
+ * @param cellWidth - Cell width in cells.
9993
+ * @param cellHeight - Cell height in cells.
9994
+ * @param rows - Number of rows.
9995
+ * @param cols - Number of columns.
9996
+ * @param options - Color options.
9997
+ * @param options.charCode - Character as string ('+') or numeric code (43).
9998
+ * @returns Dot cloud order.
9465
9999
  */
9466
10000
  static grid(startX: number, startY: number, cellWidth: number, cellHeight: number, rows: number, cols: number, options?: ColorOptions): DotCloudOrder;
9467
10001
  /**
9468
- * 0x19 - Polyline: Connected line segments through multiple points
9469
- * Uses Bresenham algorithm to draw lines between consecutive points
10002
+ * Creates a polyline (connected line segments through multiple points).
10003
+ * Uses Bresenham algorithm between consecutive points.
9470
10004
  *
9471
- * @param points - Array of points to connect (minimum 2 for a line)
9472
- * @param char - Character as string ('*') or charCode (0x2A)
9473
- * @param fgColor - Foreground color (default: 15 = white)
9474
- * @param bgColor - Background color (default: 0 = black)
10005
+ * @param points - Array of points to connect (minimum 2 for a line).
10006
+ * @param char - Character as string ('*') or numeric code (42).
10007
+ * @param fgColor - Foreground color (0-255).
10008
+ * @param bgColor - Background color (0-255).
10009
+ * @returns Polyline order.
9475
10010
  *
9476
10011
  * @example Simple line
9477
10012
  * ```typescript
9478
10013
  * OrderBuilder.polyline(
9479
10014
  * [{ x: 0, y: 0 }, { x: 10, y: 5 }],
9480
10015
  * '*', 14, 0
9481
- * )
10016
+ * );
9482
10017
  * ```
9483
10018
  *
9484
10019
  * @example Path with multiple points
@@ -9491,7 +10026,7 @@ declare class OrderBuilder {
9491
10026
  * { x: 40, y: 20 }
9492
10027
  * ],
9493
10028
  * '#', 11, 0
9494
- * )
10029
+ * );
9495
10030
  * ```
9496
10031
  */
9497
10032
  static polyline(points: Array<{
@@ -9499,23 +10034,31 @@ declare class OrderBuilder {
9499
10034
  y: number;
9500
10035
  }>, char?: string | number, fgColor?: number, bgColor?: number): PolylineOrder;
9501
10036
  /**
9502
- * Helper: Create a polyline from flat coordinate array
9503
- * @param coords - Flat array of coordinates [x1, y1, x2, y2, ...]
9504
- * @param char - Character as string ('*') or charCode
10037
+ * Creates a polyline from a flat coordinate array.
10038
+ *
10039
+ * @param coords - Flat array of coordinates [x1, y1, x2, y2, ...].
10040
+ * @param char - Character as string ('*') or numeric code.
10041
+ * @param fgColor - Foreground color (0-255).
10042
+ * @param bgColor - Background color (0-255).
10043
+ * @returns Polyline order.
9505
10044
  *
9506
10045
  * @example
9507
10046
  * ```typescript
9508
10047
  * OrderBuilder.polylineFromCoords(
9509
- * [0, 0, 10, 5, 20, 0], // 3 points
10048
+ * [0, 0, 10, 5, 20, 0], // 3 points
9510
10049
  * '-', 14
9511
- * )
10050
+ * );
9512
10051
  * ```
9513
10052
  */
9514
10053
  static polylineFromCoords(coords: number[], char?: string | number, fgColor?: number, bgColor?: number): PolylineOrder;
9515
10054
  /**
9516
- * Helper: Create a closed polygon (polyline that returns to start)
9517
- * @param points - Array of points forming the polygon
9518
- * @param char - Character as string ('*') or charCode
10055
+ * Creates a closed polygon (polyline that returns to start).
10056
+ *
10057
+ * @param points - Array of points forming the polygon.
10058
+ * @param char - Character as string ('*') or numeric code.
10059
+ * @param fgColor - Foreground color (0-255).
10060
+ * @param bgColor - Background color (0-255).
10061
+ * @returns Polyline order.
9519
10062
  *
9520
10063
  * @example Triangle
9521
10064
  * ```typescript
@@ -9526,7 +10069,7 @@ declare class OrderBuilder {
9526
10069
  * { x: 30, y: 15 }
9527
10070
  * ],
9528
10071
  * '#', 12
9529
- * )
10072
+ * );
9530
10073
  * ```
9531
10074
  */
9532
10075
  static polygon(points: Array<{