@utsp/core 0.5.0-nightly.20251203194806.f816057 → 0.5.0-nightly.20251204224035.7a07d4b

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as _utsp_types from '@utsp/types';
2
- import { Vector2, AxisSource, ButtonSource, InputBindingLoadPacket, AxisBinding, ButtonBinding, SoundInstanceId, AudioConfigCommand, PlaySoundCommand, StopSoundCommand, FadeOutSoundCommand, PauseSoundCommand, ResumeSoundCommand, IAudioProcessor, SoundFormat, SoundLoadType, SoundLoadPacket, SoundExternalLoadPacket, UserRenderState } from '@utsp/types';
2
+ import { Vector2, AxisSource, ButtonSource, InputBindingLoadPacket, AxisBinding, ButtonBinding, SoundInstanceId, AudioConfigCommand, PlaySoundCommand, StopSoundCommand, FadeOutSoundCommand, PauseSoundCommand, ResumeSoundCommand, SetSoundEffectsCommand, IAudioProcessor, AudioAck, SoundFormat, SoundLoadType, SoundLoadPacket, SoundExternalLoadPacket, UserRenderState } from '@utsp/types';
3
3
  export { AxisBinding, AxisSource, ButtonBinding, ButtonSource, InputBindingLoadPacket, RenderState, RenderedCell, UserRenderState, Vector2 } from '@utsp/types';
4
4
 
5
5
  /**
@@ -148,6 +148,356 @@ declare class BitmapFont {
148
148
  getCharCodes(): number[];
149
149
  }
150
150
 
151
+ /**
152
+ * UTSP Audio Order Types Enumeration
153
+ *
154
+ * Audio orders are separate from render orders and have their own type space.
155
+ * They are included in the UpdatePacket but processed by the AudioProcessor,
156
+ * not the Rasterizer.
157
+ *
158
+ * This separation ensures:
159
+ * - Clear distinction between visual and audio orders
160
+ * - Independent type numbering (0x01 audio ≠ 0x01 render)
161
+ * - Extensibility without conflicts
162
+ *
163
+ * @example
164
+ * ```typescript
165
+ * import { AudioOrderType } from '@utsp/core';
166
+ *
167
+ * const order = { type: AudioOrderType.PlaySound, soundId: 0, volume: 200 };
168
+ * ```
169
+ */
170
+ declare enum AudioOrderType {
171
+ /**
172
+ * 0x01 - PlaySound: Play a sound with optional spatial position
173
+ *
174
+ * Parameters: soundId, instanceId, flags, volume?, pitch?, fadeIn?, posX?, posY?
175
+ */
176
+ PlaySound = 1,
177
+ /**
178
+ * 0x02 - PlayGlobalSound: Play a non-positional (global) sound
179
+ *
180
+ * Parameters: soundId, instanceId, flags, volume?, pitch?, fadeIn?
181
+ */
182
+ PlayGlobalSound = 2,
183
+ /**
184
+ * 0x03 - StopSound: Stop a sound immediately
185
+ *
186
+ * Parameters: targetType, target (instanceId, soundId, or 'all')
187
+ */
188
+ StopSound = 3,
189
+ /**
190
+ * 0x04 - FadeOutSound: Fade out and stop a sound
191
+ *
192
+ * Parameters: targetType, target, duration
193
+ */
194
+ FadeOutSound = 4,
195
+ /**
196
+ * 0x05 - PauseSound: Pause a playing sound
197
+ *
198
+ * Parameters: targetType, target
199
+ */
200
+ PauseSound = 5,
201
+ /**
202
+ * 0x06 - ResumeSound: Resume a paused sound
203
+ *
204
+ * Parameters: targetType, target
205
+ */
206
+ ResumeSound = 6,
207
+ /**
208
+ * 0x07 - SetListenerPosition: Set the listener position for spatial audio
209
+ *
210
+ * Parameters: x, y (16-bit each)
211
+ */
212
+ SetListenerPosition = 7,
213
+ /**
214
+ * 0x08 - ConfigureSpatial: Configure spatial audio parameters
215
+ *
216
+ * Parameters: maxDistance, referenceDistance, rolloffFactor, panSpread
217
+ */
218
+ ConfigureSpatial = 8,
219
+ /**
220
+ * 0x09 - SetSoundEffects: Set audio effects on a playing sound
221
+ *
222
+ * Parameters: instanceId, flags, lowpass?, highpass?, reverb?
223
+ */
224
+ SetSoundEffects = 9
225
+ }
226
+ /**
227
+ * Target type for stop/pause/resume/fadeout commands
228
+ */
229
+ declare enum AudioTargetType {
230
+ /** Target a specific instance by ID */
231
+ InstanceId = 0,
232
+ /** Target all instances of a sound by soundId */
233
+ SoundId = 1,
234
+ /** Target all sounds */
235
+ All = 2
236
+ }
237
+ /**
238
+ * Type guard to check if a number is a valid AudioOrderType
239
+ */
240
+ declare function isValidAudioOrderType(type: number): type is AudioOrderType;
241
+ /**
242
+ * Get human-readable name for an AudioOrderType
243
+ */
244
+ declare function getAudioOrderTypeName(type: AudioOrderType | number): string;
245
+
246
+ /**
247
+ * UTSP Audio Orders
248
+ *
249
+ * Binary-encoded audio commands included in UpdatePacket.
250
+ * Processed by AudioProcessor on client, synchronized with render orders.
251
+ *
252
+ * Each order has a specific binary structure optimized for network transmission.
253
+ */
254
+
255
+ /**
256
+ * Base interface for all audio orders
257
+ */
258
+ interface AudioOrder {
259
+ /** Audio order type identifier */
260
+ type: AudioOrderType;
261
+ }
262
+ /**
263
+ * Flags for PlaySound/PlayGlobalSound orders
264
+ * Packed into a single byte to minimize bandwidth
265
+ */
266
+ declare enum PlaySoundFlags {
267
+ /** Sound should loop */
268
+ Loop = 1,
269
+ /** Volume is specified (otherwise default 100%) */
270
+ HasVolume = 2,
271
+ /** Pitch is specified (otherwise default 1.0x) */
272
+ HasPitch = 4,
273
+ /** FadeIn duration is specified (otherwise instant) */
274
+ HasFadeIn = 8,
275
+ /** Position is specified (only for PlaySound, not PlayGlobalSound) */
276
+ HasPosition = 16,
277
+ /** Low-pass filter is specified */
278
+ HasLowpass = 32,
279
+ /** High-pass filter is specified */
280
+ HasHighpass = 64,
281
+ /** Reverb mix is specified */
282
+ HasReverb = 128
283
+ }
284
+ /**
285
+ * 0x01 - PlaySound: Play a sound with optional spatial position
286
+ *
287
+ * Binary structure (variable size, 4-15 bytes):
288
+ * - type: 1 byte (0x01)
289
+ * - soundId: 1 byte (0-255)
290
+ * - instanceId: 2 bytes (big-endian, unique ID for this playback)
291
+ * - flags: 1 byte (PlaySoundFlags bitfield)
292
+ * - volume?: 1 byte (0-255, maps to 0.0-1.0) - if HasVolume
293
+ * - pitch?: 1 byte (0-255, maps to 0.25x-4.0x, 128=1.0x) - if HasPitch
294
+ * - fadeIn?: 1 byte (0-255, duration in 1/10 seconds, 0=instant) - if HasFadeIn
295
+ * - posX?: 2 bytes (big-endian, 0-65535) - if HasPosition
296
+ * - posY?: 2 bytes (big-endian, 0-65535) - if HasPosition
297
+ * - lowpass?: 1 byte (0-255, * 100 = Hz cutoff) - if HasLowpass
298
+ * - highpass?: 1 byte (0-255, * 100 = Hz cutoff) - if HasHighpass
299
+ * - reverb?: 1 byte (0-255, / 255 = wet mix 0.0-1.0) - if HasReverb
300
+ */
301
+ interface PlaySoundOrder extends AudioOrder {
302
+ type: AudioOrderType.PlaySound;
303
+ /** Sound ID (0-255) */
304
+ soundId: number;
305
+ /** Unique instance ID for this playback */
306
+ instanceId: number;
307
+ /** Flags bitfield */
308
+ flags: number;
309
+ /** Volume (0-255, maps to 0.0-1.0). Present if HasVolume flag set */
310
+ volume?: number;
311
+ /** Pitch (0-255, 128=1.0x). Present if HasPitch flag set */
312
+ pitch?: number;
313
+ /** Fade in duration in 1/10 seconds. Present if HasFadeIn flag set */
314
+ fadeIn?: number;
315
+ /** X position (0-65535). Present if HasPosition flag set */
316
+ posX?: number;
317
+ /** Y position (0-65535). Present if HasPosition flag set */
318
+ posY?: number;
319
+ /** Low-pass filter cutoff (0-255, * 100 = Hz). Present if HasLowpass flag set */
320
+ lowpass?: number;
321
+ /** High-pass filter cutoff (0-255, * 100 = Hz). Present if HasHighpass flag set */
322
+ highpass?: number;
323
+ /** Reverb wet mix (0-255, / 255 = 0.0-1.0). Present if HasReverb flag set */
324
+ reverb?: number;
325
+ }
326
+ /**
327
+ * 0x02 - PlayGlobalSound: Play a non-positional sound
328
+ *
329
+ * Binary structure (variable size, 4-10 bytes):
330
+ * - type: 1 byte (0x02)
331
+ * - soundId: 1 byte (0-255)
332
+ * - instanceId: 2 bytes (big-endian)
333
+ * - flags: 1 byte (PlaySoundFlags, but HasPosition is ignored)
334
+ * - volume?: 1 byte - if HasVolume
335
+ * - pitch?: 1 byte - if HasPitch
336
+ * - fadeIn?: 1 byte - if HasFadeIn
337
+ * - lowpass?: 1 byte - if HasLowpass
338
+ * - highpass?: 1 byte - if HasHighpass
339
+ * - reverb?: 1 byte - if HasReverb
340
+ */
341
+ interface PlayGlobalSoundOrder extends AudioOrder {
342
+ type: AudioOrderType.PlayGlobalSound;
343
+ /** Sound ID (0-255) */
344
+ soundId: number;
345
+ /** Unique instance ID for this playback */
346
+ instanceId: number;
347
+ /** Flags bitfield (HasPosition ignored) */
348
+ flags: number;
349
+ /** Volume (0-255). Present if HasVolume flag set */
350
+ volume?: number;
351
+ /** Pitch (0-255, 128=1.0x). Present if HasPitch flag set */
352
+ pitch?: number;
353
+ /** Fade in duration in 1/10 seconds. Present if HasFadeIn flag set */
354
+ fadeIn?: number;
355
+ /** Low-pass filter cutoff (0-255, * 100 = Hz). Present if HasLowpass flag set */
356
+ lowpass?: number;
357
+ /** High-pass filter cutoff (0-255, * 100 = Hz). Present if HasHighpass flag set */
358
+ highpass?: number;
359
+ /** Reverb wet mix (0-255, / 255 = 0.0-1.0). Present if HasReverb flag set */
360
+ reverb?: number;
361
+ }
362
+ /**
363
+ * 0x03 - StopSound: Stop a sound immediately
364
+ *
365
+ * Binary structure (3-4 bytes):
366
+ * - type: 1 byte (0x03)
367
+ * - targetType: 1 byte (AudioTargetType)
368
+ * - target: 1-2 bytes (instanceId=2B, soundId=1B, all=0B)
369
+ */
370
+ interface StopSoundOrder extends AudioOrder {
371
+ type: AudioOrderType.StopSound;
372
+ /** Type of target */
373
+ targetType: AudioTargetType;
374
+ /** Target value (instanceId, soundId, or undefined for 'all') */
375
+ target?: number;
376
+ }
377
+ /**
378
+ * 0x04 - FadeOutSound: Fade out and stop a sound
379
+ *
380
+ * Binary structure (4-5 bytes):
381
+ * - type: 1 byte (0x04)
382
+ * - targetType: 1 byte
383
+ * - duration: 1 byte (1/10 seconds, 0-25.5s)
384
+ * - target: 1-2 bytes
385
+ */
386
+ interface FadeOutSoundOrder extends AudioOrder {
387
+ type: AudioOrderType.FadeOutSound;
388
+ /** Type of target */
389
+ targetType: AudioTargetType;
390
+ /** Fade duration in 1/10 seconds (0-255 = 0-25.5 seconds) */
391
+ duration: number;
392
+ /** Target value */
393
+ target?: number;
394
+ }
395
+ /**
396
+ * 0x05 - PauseSound: Pause a playing sound
397
+ *
398
+ * Binary structure (2-4 bytes):
399
+ * - type: 1 byte (0x05)
400
+ * - targetType: 1 byte
401
+ * - target: 0-2 bytes
402
+ */
403
+ interface PauseSoundOrder extends AudioOrder {
404
+ type: AudioOrderType.PauseSound;
405
+ /** Type of target */
406
+ targetType: AudioTargetType;
407
+ /** Target value */
408
+ target?: number;
409
+ }
410
+ /**
411
+ * 0x06 - ResumeSound: Resume a paused sound
412
+ *
413
+ * Binary structure (2-4 bytes):
414
+ * - type: 1 byte (0x06)
415
+ * - targetType: 1 byte
416
+ * - target: 0-2 bytes
417
+ */
418
+ interface ResumeSoundOrder extends AudioOrder {
419
+ type: AudioOrderType.ResumeSound;
420
+ /** Type of target */
421
+ targetType: AudioTargetType;
422
+ /** Target value */
423
+ target?: number;
424
+ }
425
+ /**
426
+ * 0x07 - SetListenerPosition: Set listener position for spatial audio
427
+ *
428
+ * Binary structure (5 bytes):
429
+ * - type: 1 byte (0x07)
430
+ * - x: 2 bytes (big-endian, 0-65535)
431
+ * - y: 2 bytes (big-endian, 0-65535)
432
+ */
433
+ interface SetListenerPositionOrder extends AudioOrder {
434
+ type: AudioOrderType.SetListenerPosition;
435
+ /** X position (0-65535) */
436
+ x: number;
437
+ /** Y position (0-65535) */
438
+ y: number;
439
+ }
440
+ /**
441
+ * 0x08 - ConfigureSpatial: Configure spatial audio parameters
442
+ *
443
+ * Binary structure (5 bytes):
444
+ * - type: 1 byte (0x08)
445
+ * - maxDistance: 1 byte (0-255, scaled appropriately)
446
+ * - referenceDistance: 1 byte (0-255)
447
+ * - rolloffFactor: 1 byte (0-255, maps to 0.0-2.55)
448
+ * - panSpread: 1 byte (0-255, maps to 0.0-1.0)
449
+ */
450
+ interface ConfigureSpatialOrder extends AudioOrder {
451
+ type: AudioOrderType.ConfigureSpatial;
452
+ /** Maximum audible distance (encoded, 0-255) */
453
+ maxDistance: number;
454
+ /** Reference distance for full volume (encoded, 0-255) */
455
+ referenceDistance: number;
456
+ /** Rolloff factor (0-255, maps to 0.0-2.55) */
457
+ rolloffFactor: number;
458
+ /** Pan spread factor (0-255, maps to 0.0-1.0) */
459
+ panSpread: number;
460
+ }
461
+ /**
462
+ * Flags for SetSoundEffects order
463
+ */
464
+ declare enum SoundEffectsFlags {
465
+ /** Low-pass filter is specified */
466
+ HasLowpass = 1,
467
+ /** High-pass filter is specified */
468
+ HasHighpass = 2,
469
+ /** Reverb mix is specified */
470
+ HasReverb = 4
471
+ }
472
+ /**
473
+ * 0x09 - SetSoundEffects: Update audio effects on a playing sound
474
+ *
475
+ * Binary structure (variable size, 4-7 bytes):
476
+ * - type: 1 byte (0x09)
477
+ * - instanceId: 2 bytes (big-endian)
478
+ * - flags: 1 byte (SoundEffectsFlags bitfield)
479
+ * - lowpass?: 1 byte (0-255, * 100 = Hz cutoff) - if HasLowpass
480
+ * - highpass?: 1 byte (0-255, * 100 = Hz cutoff) - if HasHighpass
481
+ * - reverb?: 1 byte (0-255, / 255 = wet mix 0.0-1.0) - if HasReverb
482
+ */
483
+ interface SetSoundEffectsOrder extends AudioOrder {
484
+ type: AudioOrderType.SetSoundEffects;
485
+ /** Target instance ID */
486
+ instanceId: number;
487
+ /** Flags bitfield */
488
+ flags: number;
489
+ /** Low-pass filter cutoff (0-255, * 100 = Hz). Present if HasLowpass flag set */
490
+ lowpass?: number;
491
+ /** High-pass filter cutoff (0-255, * 100 = Hz). Present if HasHighpass flag set */
492
+ highpass?: number;
493
+ /** Reverb wet mix (0-255, / 255 = 0.0-1.0). Present if HasReverb flag set */
494
+ reverb?: number;
495
+ }
496
+ /**
497
+ * Union of all audio order types
498
+ */
499
+ type AnyAudioOrder = PlaySoundOrder | PlayGlobalSoundOrder | StopSoundOrder | FadeOutSoundOrder | PauseSoundOrder | ResumeSoundOrder | SetListenerPositionOrder | ConfigureSpatialOrder | SetSoundEffectsOrder;
500
+
151
501
  /**
152
502
  * Network representation of a display
153
503
  * Layers are NO LONGER under displays - they are at User level
@@ -557,12 +907,20 @@ interface NetworkLayer {
557
907
 
558
908
  /**
559
909
  * Update packet according to the new UTSP protocol
560
- * Layers are at the User level, not under displays
910
+ *
911
+ * Structure:
912
+ * - Tick (8 bytes): Frame counter for synchronization
913
+ * - Displays: Viewport definitions
914
+ * - Layers: Render orders for visual output
915
+ * - Audio Orders: Audio commands synchronized with the frame
916
+ *
917
+ * Audio orders are in the same packet as render orders to ensure
918
+ * perfect frame-level synchronization between visuals and sound.
561
919
  */
562
920
  interface UpdatePacket {
563
921
  /** Tick counter (8 bytes) */
564
922
  tick: number;
565
- /** Number of displays (2 bytes) */
923
+ /** Number of displays (1 byte) */
566
924
  displayCount: number;
567
925
  /** List of displays with their origins */
568
926
  displays: NetworkDisplay[];
@@ -570,6 +928,10 @@ interface UpdatePacket {
570
928
  layerCount: number;
571
929
  /** List of layers (shared across all displays) */
572
930
  layers: NetworkLayer[];
931
+ /** Number of audio orders (1 byte) */
932
+ audioOrderCount: number;
933
+ /** List of audio orders (synchronized with this frame) */
934
+ audioOrders: AnyAudioOrder[];
573
935
  }
574
936
 
575
937
  /**
@@ -1580,6 +1942,9 @@ declare class User<TData = Record<string, any>> {
1580
1942
  private lastListenerY;
1581
1943
  private pendingSendSounds;
1582
1944
  private audioProcessor?;
1945
+ private loadedSounds;
1946
+ private soundLoadErrors;
1947
+ private playingSounds;
1583
1948
  /**
1584
1949
  * Application-specific data storage
1585
1950
  * Use this to store game state, player data, or any custom information
@@ -2243,6 +2608,9 @@ declare class User<TData = Record<string, any>> {
2243
2608
  *
2244
2609
  * // Spatial audio (x/y position 0-65535)
2245
2610
  * user.playSound('explosion', { x: 10000, y: 32768 });
2611
+ *
2612
+ * // With audio effects
2613
+ * user.playSound('voice', { lowpass: 2000, reverb: 0.3 });
2246
2614
  * ```
2247
2615
  */
2248
2616
  playSound(sound: string | number, options?: {
@@ -2252,6 +2620,12 @@ declare class User<TData = Record<string, any>> {
2252
2620
  fadeIn?: number;
2253
2621
  x?: number;
2254
2622
  y?: number;
2623
+ /** Low-pass filter cutoff in Hz (100-25500, 0 = disabled) */
2624
+ lowpass?: number;
2625
+ /** High-pass filter cutoff in Hz (100-25500, 0 = disabled) */
2626
+ highpass?: number;
2627
+ /** Reverb wet/dry mix (0.0-1.0, 0 = disabled) */
2628
+ reverb?: number;
2255
2629
  }): SoundInstanceId;
2256
2630
  /**
2257
2631
  * Stop a sound immediately by instance ID or name
@@ -2365,6 +2739,34 @@ declare class User<TData = Record<string, any>> {
2365
2739
  * ```
2366
2740
  */
2367
2741
  resumeAllSounds(): void;
2742
+ /**
2743
+ * Set audio effects on a playing sound instance
2744
+ *
2745
+ * This allows updating filters and reverb on a sound that's already playing.
2746
+ * Pass 0 to disable a specific effect, or omit it to leave unchanged.
2747
+ *
2748
+ * @param instanceId - The instance ID returned by playSound()
2749
+ * @param options - Effects to set
2750
+ *
2751
+ * @example
2752
+ * ```typescript
2753
+ * const musicId = user.playSound('music', { loop: true });
2754
+ *
2755
+ * // Later, add effects when entering a cave
2756
+ * user.setSoundEffects(musicId, { lowpass: 1500, reverb: 0.5 });
2757
+ *
2758
+ * // Remove effects when leaving the cave
2759
+ * user.setSoundEffects(musicId, { lowpass: 0, reverb: 0 });
2760
+ * ```
2761
+ */
2762
+ setSoundEffects(instanceId: SoundInstanceId, options: {
2763
+ /** Low-pass filter cutoff in Hz (100-25500, 0 = disabled) */
2764
+ lowpass?: number;
2765
+ /** High-pass filter cutoff in Hz (100-25500, 0 = disabled) */
2766
+ highpass?: number;
2767
+ /** Reverb wet/dry mix (0.0-1.0, 0 = disabled) */
2768
+ reverb?: number;
2769
+ }): void;
2368
2770
  /**
2369
2771
  * Set the listener position for spatial audio
2370
2772
  *
@@ -2430,7 +2832,7 @@ declare class User<TData = Record<string, any>> {
2430
2832
  * @returns Array of sound commands to send
2431
2833
  * @internal
2432
2834
  */
2433
- flushSoundCommands(): Array<PlaySoundCommand | StopSoundCommand | FadeOutSoundCommand | PauseSoundCommand | ResumeSoundCommand>;
2835
+ flushSoundCommands(): Array<PlaySoundCommand | StopSoundCommand | FadeOutSoundCommand | PauseSoundCommand | ResumeSoundCommand | SetSoundEffectsCommand>;
2434
2836
  /**
2435
2837
  * Check if there are pending sound commands
2436
2838
  *
@@ -2509,7 +2911,7 @@ declare class User<TData = Record<string, any>> {
2509
2911
  * @param commands - Array of sound commands
2510
2912
  * @internal
2511
2913
  */
2512
- applyAudioCommands(commands: Array<PlaySoundCommand | StopSoundCommand | FadeOutSoundCommand | PauseSoundCommand | ResumeSoundCommand>): void;
2914
+ applyAudioCommands(commands: Array<PlaySoundCommand | StopSoundCommand | FadeOutSoundCommand | PauseSoundCommand | ResumeSoundCommand | SetSoundEffectsCommand>): void;
2513
2915
  /**
2514
2916
  * Apply audio configuration commands (listener position, spatial config)
2515
2917
  *
@@ -2523,6 +2925,88 @@ declare class User<TData = Record<string, any>> {
2523
2925
  * @internal
2524
2926
  */
2525
2927
  applyAudioConfigCommands(commands: AudioConfigCommand[]): void;
2928
+ /**
2929
+ * Apply audio orders from an UpdatePacket (BINARY PROTOCOL)
2930
+ *
2931
+ * This method processes decoded audio orders from the binary UpdatePacket.
2932
+ * Audio orders use soundId (number) rather than sound names for efficiency.
2933
+ *
2934
+ * Order types:
2935
+ * - PlaySound/PlayGlobalSound: Play a sound
2936
+ * - StopSound: Stop a sound
2937
+ * - FadeOutSound: Fade out and stop
2938
+ * - PauseSound: Pause playback
2939
+ * - ResumeSound: Resume playback
2940
+ * - SetListenerPosition: Set listener for spatial audio
2941
+ * - ConfigureSpatial: Configure spatial audio parameters
2942
+ *
2943
+ * @param orders - Array of decoded audio orders from UpdatePacket
2944
+ * @internal
2945
+ */
2946
+ applyAudioOrders(orders: AnyAudioOrder[]): void;
2947
+ /**
2948
+ * Handle an audio ACK from the client
2949
+ *
2950
+ * Called by ServerRuntime when receiving 'audio-ack' messages.
2951
+ * Updates internal tracking of the client's audio state.
2952
+ *
2953
+ * @param ack - The audio acknowledgment
2954
+ * @internal
2955
+ */
2956
+ handleAudioAck(ack: AudioAck): void;
2957
+ /**
2958
+ * Check if a sound is loaded on the client
2959
+ *
2960
+ * @param soundId - The sound ID to check
2961
+ * @returns true if the sound is loaded
2962
+ */
2963
+ isSoundLoaded(soundId: number): boolean;
2964
+ /**
2965
+ * Check if a sound failed to load on the client
2966
+ *
2967
+ * @param soundId - The sound ID to check
2968
+ * @returns Error message if failed, undefined otherwise
2969
+ */
2970
+ getSoundLoadError(soundId: number): string | undefined;
2971
+ /**
2972
+ * Get all loaded sounds on the client
2973
+ *
2974
+ * @returns Map of soundId to load info
2975
+ */
2976
+ getLoadedSounds(): ReadonlyMap<number, {
2977
+ name: string;
2978
+ loadedAt: number;
2979
+ }>;
2980
+ /**
2981
+ * Get all sound load errors
2982
+ *
2983
+ * @returns Map of soundId to error info
2984
+ */
2985
+ getSoundLoadErrors(): ReadonlyMap<number, {
2986
+ name: string;
2987
+ error: string;
2988
+ at: number;
2989
+ }>;
2990
+ /**
2991
+ * Check if a sound instance is currently playing on the client
2992
+ *
2993
+ * @param instanceId - The instance ID to check
2994
+ * @returns true if the instance is playing
2995
+ */
2996
+ isSoundPlaying(instanceId: SoundInstanceId): boolean;
2997
+ /**
2998
+ * Get all currently playing sounds on the client
2999
+ *
3000
+ * @returns Map of instanceId to playback info
3001
+ */
3002
+ getPlayingSounds(): ReadonlyMap<SoundInstanceId, {
3003
+ soundId: number;
3004
+ startedAt: number;
3005
+ }>;
3006
+ /**
3007
+ * Get the number of sounds currently playing on the client
3008
+ */
3009
+ getPlayingSoundCount(): number;
2526
3010
  }
2527
3011
 
2528
3012
  /**
@@ -2998,6 +3482,7 @@ declare class Core {
2998
3482
  private webFontRegistry;
2999
3483
  private bitmapFontRegistry;
3000
3484
  private soundRegistry;
3485
+ private audioOrderCollector;
3001
3486
  private activeWebFontId;
3002
3487
  private _renderCallCount;
3003
3488
  private onPaletteChangedCallback?;
@@ -5094,6 +5579,15 @@ declare const FILLSPRITE_ORDER_SIZE = 4;
5094
5579
  declare const FILLSPRITE_MULTICOLOR_ORDER_SIZE = 2;
5095
5580
  declare const TRIGGERSOUND_ORDER_SIZE = 5;
5096
5581
  declare const TRIGGERGLOBALSOUND_ORDER_SIZE = 3;
5582
+ declare const AUDIO_PLAY_SOUND_MIN_SIZE = 5;
5583
+ declare const AUDIO_PLAY_GLOBAL_SOUND_MIN_SIZE = 5;
5584
+ declare const AUDIO_STOP_SOUND_MIN_SIZE = 2;
5585
+ declare const AUDIO_FADEOUT_SOUND_MIN_SIZE = 3;
5586
+ declare const AUDIO_PAUSE_SOUND_MIN_SIZE = 2;
5587
+ declare const AUDIO_RESUME_SOUND_MIN_SIZE = 2;
5588
+ declare const AUDIO_SET_LISTENER_POSITION_SIZE = 5;
5589
+ declare const AUDIO_CONFIGURE_SPATIAL_SIZE = 5;
5590
+ declare const AUDIO_SET_SOUND_EFFECTS_MIN_SIZE = 4;
5097
5591
 
5098
5592
  /**
5099
5593
  * UTSP Order Types Enumeration
@@ -5398,6 +5892,7 @@ declare namespace UpdateFlagsHelper {
5398
5892
  declare class UpdatePacketDecoder {
5399
5893
  private displayDecoder;
5400
5894
  private layerDecoder;
5895
+ private audioOrderDecoder;
5401
5896
  constructor();
5402
5897
  /**
5403
5898
  * Decodes an UpdatePacket from binary buffer
@@ -5408,8 +5903,10 @@ declare class UpdatePacketDecoder {
5408
5903
  * - Displays: variable (DisplayId + OriginX + OriginY + SizeX + SizeY = 7 bytes each)
5409
5904
  * - LayerCount: 2 bytes (big-endian, 16-bit unsigned integer)
5410
5905
  * - Layers: variable (encoded layers)
5906
+ * - AudioOrderCount: 1 byte (max 255 audio orders)
5907
+ * - AudioOrders: variable (encoded audio orders)
5411
5908
  *
5412
- * Minimum packet size: 11 bytes (Tick + DisplayCount + LayerCount)
5909
+ * Minimum packet size: 12 bytes (Tick + DisplayCount + LayerCount + AudioOrderCount)
5413
5910
  */
5414
5911
  decode(data: Uint8Array, offset?: number): UpdatePacket;
5415
5912
  /**
@@ -5418,16 +5915,254 @@ declare class UpdatePacketDecoder {
5418
5915
  */
5419
5916
  isValid(data: Uint8Array, offset?: number): boolean;
5420
5917
  /**
5421
- * Decodes only the tick and counts without decoding the displays/layers
5918
+ * Decodes only the tick and counts without decoding the displays/layers/audio
5422
5919
  * Useful for quick inspection of packet metadata
5423
5920
  */
5424
5921
  decodeHeader(data: Uint8Array, offset?: number): {
5425
5922
  tick: number;
5426
5923
  displayCount: number;
5427
5924
  layerCount: number;
5925
+ audioOrderCount?: number;
5428
5926
  };
5429
5927
  private checkSize;
5430
5928
  }
5431
5929
 
5432
- export { ASCII_8X8_FONT, BITMASK16_ORDER_MIN_SIZE, BITMASK4_ORDER_MIN_SIZE, BITMASK_ORDER_MIN_SIZE, BitmapFont, BitmapFontRegistry, CHAR_ORDER_SIZE, CIRCLE_SHAPE_SIZE, CLEAR_ORDER_SIZE, COLORMAP_ORDER_MIN_SIZE, COLOR_SKIP, CellBuffer, CharCodeBuffer, Core, CoreStats, DISPLAY_HEADER_SIZE, DOTCLOUD_MULTICOLOR_ORDER_MIN_SIZE, DOTCLOUD_ORDER_MIN_SIZE, Display, ELLIPSE_SHAPE_SIZE, FILLCHAR_ORDER_MIN_SIZE, FILLSPRITE_MULTICOLOR_ORDER_SIZE, FILLSPRITE_ORDER_SIZE, FULLFRAME_MULTICOLOR_ORDER_MIN_SIZE, FULLFRAME_ORDER_MIN_SIZE, FontType, InputBindingRegistry, LAYER_CELL_COUNT, LAYER_HEADER_SIZE, LAYER_SIZE, LINE_SHAPE_SIZE, Layer, LoadType, OrderBuilder, OrderType, RECTANGLE_SHAPE_SIZE, SHAPE_ORDER_MIN_SIZE, SPRITECLOUD_MULTICOLOR_ORDER_MIN_SIZE, SPRITECLOUD_ORDER_MIN_SIZE, SPRITECLOUD_VARIED_MULTICOLOR_ORDER_MIN_SIZE, SPRITECLOUD_VARIED_ORDER_MIN_SIZE, SPRITE_MULTICOLOR_ORDER_SIZE, SPRITE_ORDER_SIZE, SUBFRAME_MULTICOLOR_ORDER_MIN_SIZE, SUBFRAME_ORDER_MIN_SIZE, ShapeType, SoundRegistry, SpriteRegistry, TEXT_MULTILINE_ORDER_MIN_SIZE, TEXT_ORDER_MIN_SIZE, TRIANGLE_SHAPE_SIZE, TRIGGERGLOBALSOUND_ORDER_SIZE, TRIGGERSOUND_ORDER_SIZE, UPDATE_PACKET_HEADER_SIZE, UpdateFlags, UpdateFlagsHelper, UpdatePacketDecoder, User, UserStats, WebFont, WebFontRegistry, createASCII8x8FontLoad, createEmptyCompressedInputPacket, decodeCompressedInput, decodeInt8ToAxis, encodeAxisToInt8, encodeCompressedInput, getASCII8x8FontConfig, getAllCharCodes, getButtonByteCount, getCharBitmap, getCompressedPacketSize, getOrderTypeName, hasChar, isValidOrderType };
5433
- export type { AnyLoad, BitmapFontConfig, BitmapFontLoad, Bitmask16Order, Bitmask16Variant, Bitmask4Order, Bitmask4Variant, BitmaskOrder, Cell, CircleShape, Color, ColorPaletteLoad, CompressedInputPacket, CoreMode, CoreOptions, EllipseShape, LineShape, MulticolorCell, MulticolorSprite, MulticolorSpriteLoad, NetworkDisplay, NetworkLayer, RectangleShape, ShapeData, SoundEntry, SoundLoad, SpriteLoad, TickStats, TriangleShape, UnicolorSprite, UpdatePacket, UserTickStats, WebFontConfig, WebFontLoad };
5930
+ /**
5931
+ * BufferCompat - Node.js AND browser compatible abstraction
5932
+ *
5933
+ * Replaces Buffer (Node.js only) with Uint8Array + DataView
5934
+ * which are standard APIs available everywhere.
5935
+ */
5936
+ /**
5937
+ * Cross-platform compatible class for manipulating binary data
5938
+ * Uses Uint8Array (standard) instead of Buffer (Node.js only)
5939
+ */
5940
+ declare class BufferCompat {
5941
+ private data;
5942
+ private view;
5943
+ constructor(size: number);
5944
+ /**
5945
+ * Creates a BufferCompat from an existing Uint8Array
5946
+ */
5947
+ static from(array: Uint8Array): BufferCompat;
5948
+ /**
5949
+ * Allocates an uninitialized buffer (equivalent to Buffer.allocUnsafe)
5950
+ */
5951
+ static allocUnsafe(size: number): BufferCompat;
5952
+ /**
5953
+ * Returns the buffer length
5954
+ */
5955
+ get length(): number;
5956
+ /**
5957
+ * Returns the underlying Uint8Array
5958
+ */
5959
+ toUint8Array(): Uint8Array;
5960
+ readUInt8(offset: number): number;
5961
+ readInt8(offset: number): number;
5962
+ readUInt16BE(offset: number): number;
5963
+ readInt16BE(offset: number): number;
5964
+ readUInt16LE(offset: number): number;
5965
+ readInt16LE(offset: number): number;
5966
+ readUInt32BE(offset: number): number;
5967
+ readInt32BE(offset: number): number;
5968
+ readUInt32LE(offset: number): number;
5969
+ readInt32LE(offset: number): number;
5970
+ readBigUInt64BE(offset: number): bigint;
5971
+ readBigInt64BE(offset: number): bigint;
5972
+ readBigUInt64LE(offset: number): bigint;
5973
+ readBigInt64LE(offset: number): bigint;
5974
+ writeUInt8(value: number, offset: number): void;
5975
+ writeInt8(value: number, offset: number): void;
5976
+ writeUInt16BE(value: number, offset: number): void;
5977
+ writeInt16BE(value: number, offset: number): void;
5978
+ writeUInt16LE(value: number, offset: number): void;
5979
+ writeInt16LE(value: number, offset: number): void;
5980
+ writeUInt32BE(value: number, offset: number): void;
5981
+ writeInt32BE(value: number, offset: number): void;
5982
+ writeUInt32LE(value: number, offset: number): void;
5983
+ writeInt32LE(value: number, offset: number): void;
5984
+ writeBigUInt64BE(value: bigint, offset: number): void;
5985
+ writeBigInt64BE(value: bigint, offset: number): void;
5986
+ writeBigUInt64LE(value: bigint, offset: number): void;
5987
+ writeBigInt64LE(value: bigint, offset: number): void;
5988
+ /**
5989
+ * Copies data from this buffer to another
5990
+ * @param target Destination buffer
5991
+ * @param targetStart Starting position in destination buffer
5992
+ * @param sourceStart Starting position in this buffer (optional)
5993
+ * @param sourceEnd Ending position in this buffer (optional)
5994
+ */
5995
+ copy(target: BufferCompat, targetStart?: number, sourceStart?: number, sourceEnd?: number): number;
5996
+ /**
5997
+ * Returns a portion of the buffer
5998
+ */
5999
+ slice(start?: number, end?: number): BufferCompat;
6000
+ /**
6001
+ * Returns a view on a portion of the buffer (without copying)
6002
+ */
6003
+ subarray(start?: number, end?: number): BufferCompat;
6004
+ /**
6005
+ * Converts to Node.js Buffer (if available) or returns the Uint8Array
6006
+ */
6007
+ toBuffer(): Buffer | Uint8Array;
6008
+ /**
6009
+ * Creates a BufferCompat from a Node.js Buffer or Uint8Array
6010
+ */
6011
+ static fromNodeBuffer(buffer: Buffer | Uint8Array): BufferCompat;
6012
+ }
6013
+
6014
+ /**
6015
+ * UTSP Audio Order Decoder
6016
+ *
6017
+ * Decodes audio orders from binary format received in UpdatePacket.
6018
+ * Audio orders are processed by AudioProcessor on client, not Rasterizer.
6019
+ */
6020
+
6021
+ /**
6022
+ * Result of decoding an audio order from a buffer
6023
+ */
6024
+ interface AudioDecodeResult<T = AnyAudioOrder> {
6025
+ order: T;
6026
+ bytesRead: number;
6027
+ }
6028
+ /**
6029
+ * Decoder for UTSP audio orders
6030
+ * Converts binary buffers to audio order interfaces
6031
+ */
6032
+ declare class AudioOrderDecoder {
6033
+ /**
6034
+ * Main entry point - decodes any audio order type from binary buffer
6035
+ * Returns the decoded order and the number of bytes consumed
6036
+ */
6037
+ decode(buffer: BufferCompat, offset?: number): AudioDecodeResult;
6038
+ private decodePlaySoundOrder;
6039
+ private decodePlayGlobalSoundOrder;
6040
+ private decodeStopSoundOrder;
6041
+ private decodeFadeOutSoundOrder;
6042
+ private decodePauseSoundOrder;
6043
+ private decodeResumeSoundOrder;
6044
+ private decodeSetListenerPositionOrder;
6045
+ private decodeConfigureSpatialOrder;
6046
+ private decodeSetSoundEffectsOrder;
6047
+ private checkSize;
6048
+ }
6049
+
6050
+ /**
6051
+ * AudioOrderCollector - Converts high-level audio commands to binary AudioOrders
6052
+ *
6053
+ * This class bridges the gap between the User's high-level audio API
6054
+ * (playSound, stopSound, etc.) and the binary AudioOrder protocol.
6055
+ *
6056
+ * It takes SoundRegistry to resolve sound names to IDs, and produces
6057
+ * AudioOrders ready for binary encoding in UpdatePacket.
6058
+ *
6059
+ * @example
6060
+ * ```typescript
6061
+ * const collector = new AudioOrderCollector(soundRegistry);
6062
+ *
6063
+ * // Convert User's pending commands to orders
6064
+ * const audioOrders = collector.collectFromUser(user);
6065
+ *
6066
+ * // audioOrders can now be added to UpdatePacket
6067
+ * ```
6068
+ */
6069
+
6070
+ /**
6071
+ * Collects and converts audio commands to binary AudioOrders
6072
+ */
6073
+ declare class AudioOrderCollector {
6074
+ private soundRegistry;
6075
+ constructor(soundRegistry: SoundRegistry);
6076
+ /**
6077
+ * Collect all pending audio orders from a user
6078
+ *
6079
+ * This flushes the user's sound and config command queues,
6080
+ * converts them to binary AudioOrders, and returns them.
6081
+ *
6082
+ * @param user - The user to collect orders from
6083
+ * @returns Array of AudioOrders ready for encoding
6084
+ */
6085
+ collectFromUser(user: User): AnyAudioOrder[];
6086
+ /**
6087
+ * Convert a sound command to an AudioOrder
6088
+ */
6089
+ private convertSoundCommand;
6090
+ /**
6091
+ * Convert PlaySoundCommand to PlaySoundOrder or PlayGlobalSoundOrder
6092
+ */
6093
+ private convertPlayCommand;
6094
+ /**
6095
+ * Convert StopSoundCommand to StopSoundOrder
6096
+ */
6097
+ private convertStopCommand;
6098
+ /**
6099
+ * Convert FadeOutSoundCommand to FadeOutSoundOrder
6100
+ */
6101
+ private convertFadeOutCommand;
6102
+ /**
6103
+ * Convert PauseSoundCommand to PauseSoundOrder
6104
+ */
6105
+ private convertPauseCommand;
6106
+ /**
6107
+ * Convert ResumeSoundCommand to ResumeSoundOrder
6108
+ */
6109
+ private convertResumeCommand;
6110
+ /**
6111
+ * Convert SetSoundEffectsCommand to SetSoundEffectsOrder
6112
+ */
6113
+ private convertSetEffectsCommand;
6114
+ /**
6115
+ * Convert AudioConfigCommand to SetListenerPositionOrder or ConfigureSpatialOrder
6116
+ */
6117
+ private convertConfigCommand;
6118
+ /**
6119
+ * Resolve sound name or ID to a numeric soundId
6120
+ */
6121
+ private resolveSoundId;
6122
+ /**
6123
+ * Resolve target (instanceId, soundName, or 'all') to targetType and value
6124
+ */
6125
+ private resolveTarget;
6126
+ /**
6127
+ * Encode volume (0.0-1.0) to byte (0-255)
6128
+ */
6129
+ private encodeVolume;
6130
+ /**
6131
+ * Encode pitch (0.25x-4.0x) to byte (0-255, 128=1.0x)
6132
+ * Formula: pitch = 0.25 * 2^(byte/64)
6133
+ * Inverse: byte = 64 * log2(pitch / 0.25)
6134
+ */
6135
+ private encodePitch;
6136
+ /**
6137
+ * Encode fade time (seconds) to byte (1/10 seconds, 0-25.5s)
6138
+ */
6139
+ private encodeFadeTime;
6140
+ /**
6141
+ * Encode distance for spatial audio (scale: 0-25500 → 0-255)
6142
+ */
6143
+ private encodeDistance;
6144
+ /**
6145
+ * Encode rolloff factor (0.0-2.55 → 0-255)
6146
+ */
6147
+ private encodeRolloff;
6148
+ /**
6149
+ * Encode pan spread (0.0-1.0 → 0-255)
6150
+ */
6151
+ private encodePanSpread;
6152
+ /**
6153
+ * Encode position coordinate for spatial audio (clamp to 0-65535 for Uint16)
6154
+ */
6155
+ private encodePosition;
6156
+ /**
6157
+ * Encode filter frequency (100-25500 Hz) to byte (1-255, * 100 = Hz)
6158
+ * 0 means disabled
6159
+ */
6160
+ private encodeFilterFreq;
6161
+ /**
6162
+ * Encode reverb wet mix (0.0-1.0) to byte (0-255)
6163
+ */
6164
+ private encodeReverb;
6165
+ }
6166
+
6167
+ export { ASCII_8X8_FONT, AUDIO_CONFIGURE_SPATIAL_SIZE, AUDIO_FADEOUT_SOUND_MIN_SIZE, AUDIO_PAUSE_SOUND_MIN_SIZE, AUDIO_PLAY_GLOBAL_SOUND_MIN_SIZE, AUDIO_PLAY_SOUND_MIN_SIZE, AUDIO_RESUME_SOUND_MIN_SIZE, AUDIO_SET_LISTENER_POSITION_SIZE, AUDIO_SET_SOUND_EFFECTS_MIN_SIZE, AUDIO_STOP_SOUND_MIN_SIZE, AudioOrderCollector, AudioOrderDecoder, AudioOrderType, AudioTargetType, BITMASK16_ORDER_MIN_SIZE, BITMASK4_ORDER_MIN_SIZE, BITMASK_ORDER_MIN_SIZE, BitmapFont, BitmapFontRegistry, CHAR_ORDER_SIZE, CIRCLE_SHAPE_SIZE, CLEAR_ORDER_SIZE, COLORMAP_ORDER_MIN_SIZE, COLOR_SKIP, CellBuffer, CharCodeBuffer, Core, CoreStats, DISPLAY_HEADER_SIZE, DOTCLOUD_MULTICOLOR_ORDER_MIN_SIZE, DOTCLOUD_ORDER_MIN_SIZE, Display, ELLIPSE_SHAPE_SIZE, FILLCHAR_ORDER_MIN_SIZE, FILLSPRITE_MULTICOLOR_ORDER_SIZE, FILLSPRITE_ORDER_SIZE, FULLFRAME_MULTICOLOR_ORDER_MIN_SIZE, FULLFRAME_ORDER_MIN_SIZE, FontType, InputBindingRegistry, LAYER_CELL_COUNT, LAYER_HEADER_SIZE, LAYER_SIZE, LINE_SHAPE_SIZE, Layer, LoadType, OrderBuilder, OrderType, PlaySoundFlags, RECTANGLE_SHAPE_SIZE, SHAPE_ORDER_MIN_SIZE, SPRITECLOUD_MULTICOLOR_ORDER_MIN_SIZE, SPRITECLOUD_ORDER_MIN_SIZE, SPRITECLOUD_VARIED_MULTICOLOR_ORDER_MIN_SIZE, SPRITECLOUD_VARIED_ORDER_MIN_SIZE, SPRITE_MULTICOLOR_ORDER_SIZE, SPRITE_ORDER_SIZE, SUBFRAME_MULTICOLOR_ORDER_MIN_SIZE, SUBFRAME_ORDER_MIN_SIZE, ShapeType, SoundEffectsFlags, SoundRegistry, SpriteRegistry, TEXT_MULTILINE_ORDER_MIN_SIZE, TEXT_ORDER_MIN_SIZE, TRIANGLE_SHAPE_SIZE, TRIGGERGLOBALSOUND_ORDER_SIZE, TRIGGERSOUND_ORDER_SIZE, UPDATE_PACKET_HEADER_SIZE, UpdateFlags, UpdateFlagsHelper, UpdatePacketDecoder, User, UserStats, WebFont, WebFontRegistry, createASCII8x8FontLoad, createEmptyCompressedInputPacket, decodeCompressedInput, decodeInt8ToAxis, encodeAxisToInt8, encodeCompressedInput, getASCII8x8FontConfig, getAllCharCodes, getAudioOrderTypeName, getButtonByteCount, getCharBitmap, getCompressedPacketSize, getOrderTypeName, hasChar, isValidAudioOrderType, isValidOrderType };
6168
+ export type { AnyAudioOrder, AnyLoad, AudioOrder, BitmapFontConfig, BitmapFontLoad, Bitmask16Order, Bitmask16Variant, Bitmask4Order, Bitmask4Variant, BitmaskOrder, Cell, CircleShape, Color, ColorPaletteLoad, CompressedInputPacket, ConfigureSpatialOrder, CoreMode, CoreOptions, EllipseShape, FadeOutSoundOrder, LineShape, MulticolorCell, MulticolorSprite, MulticolorSpriteLoad, NetworkDisplay, NetworkLayer, PauseSoundOrder, PlayGlobalSoundOrder, PlaySoundOrder, RectangleShape, ResumeSoundOrder, SetListenerPositionOrder, SetSoundEffectsOrder, ShapeData, SoundEntry, SoundLoad, SpriteLoad, StopSoundOrder, TickStats, TriangleShape, UnicolorSprite, UpdatePacket, UserTickStats, WebFontConfig, WebFontLoad };