@primitiv/core 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.txt +190 -0
- package/README.md +9 -0
- package/dist/index.cjs +4 -0
- package/dist/index.d.ts +2421 -0
- package/dist/index.mjs +4 -0
- package/package.json +64 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,2421 @@
|
|
|
1
|
+
import { Vector2, Order, PostProcessConfig, ScalingMode, RenderPassConfig, AmbientEffectConfig, GridConfig, ScanlinesConfig, AxisSource, ButtonSource, InputBindingLoadPacket, AxisBinding, ButtonBinding, TouchZoneBinding, MacroTemplate, MacroDefine, MacroOrder, MacroCreateOrder, MacroFeedback, BridgeMessage, CompressedInputPacket, AudioAck, SoundInstanceId, SoundFormat, SoundLoadType, SoundLoadPacket, SoundExternalLoadPacket, IResourceLoader, RenderPassState, CharOrder, TextOrder, TextMultilineOrder, SubFrameOrder, SubFrameMultiOrder, FullFrameOrder, FullFrameMultiOrder, SpriteOrder, SpriteMultiOrder, ColorMapCell, ShapeOrder, PolylineOrder, DotCloudOrder, DotCloudMultiOrder, SpriteCloudOrder, SpriteCloudMultiOrder, SpriteCloudVariedOrder, SpriteCloudVariedMultiOrder, BitmaskOrder, Bitmask4Order, Bitmask16Order, FillOrder, FillCharOrder, FillSpriteOrder, FillSpriteMultiOrder, AudioOrder, VibrationOrder } from '@primitiv/types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Primitiv Core - Grid Primitive
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Optimized 2D buffer using a single Uint32Array for performance.
|
|
8
|
+
*
|
|
9
|
+
* Storage Format (32-bit Packed Integer):
|
|
10
|
+
* - Bits 0-15 (16 bits): CharCode (0-65535)
|
|
11
|
+
* - Bits 16-23 (8 bits): Foreground Color (0-255)
|
|
12
|
+
* - Bits 24-31 (8 bits): Background Color (0-255)
|
|
13
|
+
*
|
|
14
|
+
* Example:
|
|
15
|
+
* [ BG (8) | FG (8) | CHAR (16) ]
|
|
16
|
+
*
|
|
17
|
+
* This allows:
|
|
18
|
+
* - Atomic reads/writes (1 ops vs 3)
|
|
19
|
+
* - Fast comparison (dirty checks)
|
|
20
|
+
* - Zero-allocation updates
|
|
21
|
+
*/
|
|
22
|
+
declare class Grid {
|
|
23
|
+
readonly width: number;
|
|
24
|
+
readonly height: number;
|
|
25
|
+
readonly size: number;
|
|
26
|
+
readonly data: Uint32Array;
|
|
27
|
+
constructor(width: number, height: number);
|
|
28
|
+
/**
|
|
29
|
+
* Clear the grid with empty cells (BG: COLOR_SKIP, FG: COLOR_SKIP, Char: 0)
|
|
30
|
+
*/
|
|
31
|
+
clear(): void;
|
|
32
|
+
/**
|
|
33
|
+
* Fill the entire grid with a specific char/color
|
|
34
|
+
*/
|
|
35
|
+
fill(charCode: number, fg: number, bg: number): void;
|
|
36
|
+
/**
|
|
37
|
+
* Set a cell with bounds checking (Safe version for rasterization)
|
|
38
|
+
*/
|
|
39
|
+
setSafe(x: number, y: number, charCode: number, fg: number, bg: number): void;
|
|
40
|
+
/**
|
|
41
|
+
* Set a single cell (Atomic)
|
|
42
|
+
* @param index Array index (y * width + x)
|
|
43
|
+
* @param charCode 16-bit char code
|
|
44
|
+
* @param fg 8-bit foreground color
|
|
45
|
+
* @param bg 8-bit background color
|
|
46
|
+
*/
|
|
47
|
+
set(index: number, charCode: number, fg: number, bg: number): void;
|
|
48
|
+
/**
|
|
49
|
+
* Set a single cell using packed value
|
|
50
|
+
*/
|
|
51
|
+
setPacked(index: number, value: number): void;
|
|
52
|
+
/**
|
|
53
|
+
* Get packed cell value
|
|
54
|
+
*/
|
|
55
|
+
get(index: number): number;
|
|
56
|
+
/**
|
|
57
|
+
* Unpack a cell at index into components
|
|
58
|
+
* Useful for rendering or debugging
|
|
59
|
+
*/
|
|
60
|
+
unpack(index: number): {
|
|
61
|
+
char: number;
|
|
62
|
+
fg: number;
|
|
63
|
+
bg: number;
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Create a clone of this grid
|
|
67
|
+
*/
|
|
68
|
+
clone(): Grid;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Static helpers for cell bitwise operations without object overhead.
|
|
73
|
+
*/
|
|
74
|
+
declare class CellStruct {
|
|
75
|
+
/**
|
|
76
|
+
* Pack components into a 32-bit integer
|
|
77
|
+
*/
|
|
78
|
+
static pack(char: number, fg: number, bg: number): number;
|
|
79
|
+
/**
|
|
80
|
+
* Extract CharCode (Bits 0-15)
|
|
81
|
+
*/
|
|
82
|
+
static getChar(cell: number): number;
|
|
83
|
+
/**
|
|
84
|
+
* Extract Foreground Color (Bits 16-23)
|
|
85
|
+
*/
|
|
86
|
+
static getFg(cell: number): number;
|
|
87
|
+
/**
|
|
88
|
+
* Extract Background Color (Bits 24-31)
|
|
89
|
+
*/
|
|
90
|
+
static getBg(cell: number): number;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Structure of Sprite objects in Primitives
|
|
95
|
+
*/
|
|
96
|
+
/**
|
|
97
|
+
* Unicolor sprite - Stores only charcodes.
|
|
98
|
+
* Colors (fg/bg) are defined at render time via SpriteOrder.
|
|
99
|
+
*/
|
|
100
|
+
interface UnicolorSprite {
|
|
101
|
+
id: number;
|
|
102
|
+
width: number;
|
|
103
|
+
height: number;
|
|
104
|
+
data: Uint16Array;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Multicolor sprite - Stores charcodes + fg/bg colors.
|
|
108
|
+
* Each cell contains its own complete set of attributes.
|
|
109
|
+
* The data buffer format must match the Grid (packed 32-bit: BG|FG|Char).
|
|
110
|
+
*/
|
|
111
|
+
interface MulticolorSprite {
|
|
112
|
+
id: number;
|
|
113
|
+
width: number;
|
|
114
|
+
height: number;
|
|
115
|
+
data: Uint32Array;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Definition for creating a Unicolor Sprite (friendly format)
|
|
119
|
+
*/
|
|
120
|
+
interface UnicolorSpriteDefinition {
|
|
121
|
+
spriteId: number;
|
|
122
|
+
width: number;
|
|
123
|
+
height: number;
|
|
124
|
+
data: string | string[] | number[];
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Definition for creating a Multicolor Sprite (friendly format)
|
|
128
|
+
* Not implementing fully yet as we need to define the Cell input format
|
|
129
|
+
*/
|
|
130
|
+
interface MulticolorSpriteDefinition {
|
|
131
|
+
spriteId: number;
|
|
132
|
+
width: number;
|
|
133
|
+
height: number;
|
|
134
|
+
data: any[];
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* SpriteRegistry
|
|
139
|
+
* Central registry to manage unicolor and multicolor sprites.
|
|
140
|
+
* Adapted for Primitiv Core V6 (Uint32Array / Uint16Array based).
|
|
141
|
+
*/
|
|
142
|
+
declare class SpriteRegistry {
|
|
143
|
+
private unicolorSprites;
|
|
144
|
+
private multicolorSprites;
|
|
145
|
+
/**
|
|
146
|
+
* Loads unicolor sprites from public definitions
|
|
147
|
+
* Supports strings, string arrays, and numbers
|
|
148
|
+
*/
|
|
149
|
+
loadUnicolorSprites(definitions: UnicolorSpriteDefinition[]): void;
|
|
150
|
+
/**
|
|
151
|
+
* Loads multicolor sprites from public definitions
|
|
152
|
+
*/
|
|
153
|
+
loadMulticolorSprites(definitions: MulticolorSpriteDefinition[]): void;
|
|
154
|
+
getUnicolorSprite(id: number): UnicolorSprite | undefined;
|
|
155
|
+
getMulticolorSprite(id: number): MulticolorSprite | undefined;
|
|
156
|
+
hasUnicolorSprite(id: number): boolean;
|
|
157
|
+
hasMulticolorSprite(id: number): boolean;
|
|
158
|
+
clearAll(): void;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
type CharCodeMode = '8bit' | '16bit';
|
|
162
|
+
/**
|
|
163
|
+
* Layer configuration options.
|
|
164
|
+
*/
|
|
165
|
+
interface LayerOptions {
|
|
166
|
+
/** Optional layer name for tooling/debug. */
|
|
167
|
+
name?: string;
|
|
168
|
+
/**
|
|
169
|
+
* CharCode mode for this layer (immutable after creation)
|
|
170
|
+
* - '8bit': 256 char codes (CP437 default)
|
|
171
|
+
* - '16bit': 65536 char codes (256 atlas blocks × 256 chars)
|
|
172
|
+
* @default '8bit'
|
|
173
|
+
*/
|
|
174
|
+
charCodeMode?: CharCodeMode;
|
|
175
|
+
/**
|
|
176
|
+
* If true, the layer is sent on the reliable channel.
|
|
177
|
+
* @default false
|
|
178
|
+
*/
|
|
179
|
+
mustBeReliable?: boolean;
|
|
180
|
+
/**
|
|
181
|
+
* If true, the layer is considered a macro layer (ephemeral, local effects).
|
|
182
|
+
* @default false
|
|
183
|
+
*/
|
|
184
|
+
isMacroLayer?: boolean;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Layer State
|
|
188
|
+
* Represents a renderable surface in the world.
|
|
189
|
+
* Wraps a Grid with positioning and composition properties.
|
|
190
|
+
*/
|
|
191
|
+
declare class Layer {
|
|
192
|
+
id: number;
|
|
193
|
+
grid: Grid;
|
|
194
|
+
x: number;
|
|
195
|
+
y: number;
|
|
196
|
+
private origin;
|
|
197
|
+
zIndex: number;
|
|
198
|
+
visible: boolean;
|
|
199
|
+
private name?;
|
|
200
|
+
private isMacroLayer;
|
|
201
|
+
private width;
|
|
202
|
+
private height;
|
|
203
|
+
private mustBeReliable;
|
|
204
|
+
private spriteRegistry?;
|
|
205
|
+
readonly charCodeMode: CharCodeMode;
|
|
206
|
+
/** Pre-computed flag: true when charCodeMode is '16bit' (avoids string comparison per tick) */
|
|
207
|
+
readonly is16bit: boolean;
|
|
208
|
+
private pendingOrders;
|
|
209
|
+
private ordersUpdatedThisTick;
|
|
210
|
+
private enabled;
|
|
211
|
+
private needsCommit;
|
|
212
|
+
private static rasterizer;
|
|
213
|
+
/**
|
|
214
|
+
* Creates a new layer.
|
|
215
|
+
*
|
|
216
|
+
* @param origin - Layer origin in world space.
|
|
217
|
+
* @param zOrder - Z-order for stacking (higher = on top).
|
|
218
|
+
* @param width - Layer width in cells (1-256).
|
|
219
|
+
* @param height - Layer height in cells (1-256).
|
|
220
|
+
* @param options - Layer options.
|
|
221
|
+
*/
|
|
222
|
+
constructor(origin: Vector2, zOrder: number, width: number, height: number, options?: LayerOptions | boolean);
|
|
223
|
+
/**
|
|
224
|
+
* Explicitly set the layer ID.
|
|
225
|
+
* Needed because the constructor no longer takes an ID.
|
|
226
|
+
*/
|
|
227
|
+
setId(id: number): void;
|
|
228
|
+
/**
|
|
229
|
+
* Injects the SpriteRegistry into the layer.
|
|
230
|
+
* Required for sprite-dependent orders (Sprite, SpriteCloud, FillSprite, etc.)
|
|
231
|
+
* @internal
|
|
232
|
+
*/
|
|
233
|
+
setSpriteRegistry(registry: SpriteRegistry): void;
|
|
234
|
+
/**
|
|
235
|
+
* Resize the layer (clears content)
|
|
236
|
+
*/
|
|
237
|
+
resize(width: number, height: number): void;
|
|
238
|
+
getMustBeReliable(): boolean;
|
|
239
|
+
getName(): string | undefined;
|
|
240
|
+
getIsMacroLayer(): boolean;
|
|
241
|
+
getWidth(): number;
|
|
242
|
+
getHeight(): number;
|
|
243
|
+
getOrigin(): Vector2;
|
|
244
|
+
/**
|
|
245
|
+
* Sets the layer origin in world space.
|
|
246
|
+
* Marks the layer as needing commit so the new position is transmitted.
|
|
247
|
+
*/
|
|
248
|
+
setOrigin(origin: Vector2): void;
|
|
249
|
+
/**
|
|
250
|
+
* Sets the layer name (debug/metadata).
|
|
251
|
+
* Trims whitespace; empty string clears the name.
|
|
252
|
+
*/
|
|
253
|
+
setName(name: string | undefined): void;
|
|
254
|
+
/**
|
|
255
|
+
* Enables or disables the layer.
|
|
256
|
+
* The enabled state is transmitted over the network so the client
|
|
257
|
+
* hides/shows the layer accordingly.
|
|
258
|
+
*/
|
|
259
|
+
setEnabled(enabled: boolean): void;
|
|
260
|
+
/**
|
|
261
|
+
* Sets the z-index (stacking order).
|
|
262
|
+
* Marks the layer as needing commit so the new z-index is transmitted.
|
|
263
|
+
*/
|
|
264
|
+
setZIndex(zIndex: number): void;
|
|
265
|
+
/**
|
|
266
|
+
* Marks this layer as reliable or volatile for network transport.
|
|
267
|
+
*/
|
|
268
|
+
setMustBeReliable(reliable: boolean): void;
|
|
269
|
+
/**
|
|
270
|
+
* Returns the cell at the given coordinates (unpacked).
|
|
271
|
+
*
|
|
272
|
+
* @param x - X coordinate (0..width-1).
|
|
273
|
+
* @param y - Y coordinate (0..height-1).
|
|
274
|
+
* @returns The unpacked cell `{ char, fg, bg }` or `null` if out of bounds.
|
|
275
|
+
*/
|
|
276
|
+
getCellAt(x: number, y: number): {
|
|
277
|
+
char: number;
|
|
278
|
+
fg: number;
|
|
279
|
+
bg: number;
|
|
280
|
+
} | null;
|
|
281
|
+
/**
|
|
282
|
+
* UTSP Parity: Set orders for this layer.
|
|
283
|
+
* Stores orders for serialization AND rasterizes into the grid.
|
|
284
|
+
*/
|
|
285
|
+
setOrders(orders: Order[]): void;
|
|
286
|
+
/**
|
|
287
|
+
* Get pending orders (for serialization by TickPacketEncoder).
|
|
288
|
+
*/
|
|
289
|
+
getPendingOrders(): Order[];
|
|
290
|
+
/**
|
|
291
|
+
* Clear pending orders after serialization.
|
|
292
|
+
* Called by Engine.endTick() after encoding.
|
|
293
|
+
*/
|
|
294
|
+
clearPendingOrders(): void;
|
|
295
|
+
/**
|
|
296
|
+
* Returns true if setOrders() was called this tick (even with empty array).
|
|
297
|
+
* Used by TickPacketEncoder to determine FLAG_HAS_ORDERS.
|
|
298
|
+
*/
|
|
299
|
+
getOrdersUpdatedThisTick(): boolean;
|
|
300
|
+
/**
|
|
301
|
+
* Marks the layer as needing to be sent to clients.
|
|
302
|
+
*
|
|
303
|
+
* **Note:** You typically do NOT need to call this method.
|
|
304
|
+
* All setters (`setOrders()`, `setOrigin()`, `setEnabled()`, `setZIndex()`)
|
|
305
|
+
* already mark the layer for commit automatically.
|
|
306
|
+
*
|
|
307
|
+
* This method is only useful for:
|
|
308
|
+
* - Force resync: sending a layer's current state even if unchanged this tick
|
|
309
|
+
* - Internal use after direct grid manipulation (not recommended)
|
|
310
|
+
*/
|
|
311
|
+
commit(): void;
|
|
312
|
+
getNeedsCommit(): boolean;
|
|
313
|
+
/**
|
|
314
|
+
* Clear the commit flag after endTick processing.
|
|
315
|
+
*/
|
|
316
|
+
clearCommit(): void;
|
|
317
|
+
isEnabled(): boolean;
|
|
318
|
+
/**
|
|
319
|
+
* Returns a debug-friendly snapshot of this layer (metadata only).
|
|
320
|
+
*/
|
|
321
|
+
getDebugInfo(): {
|
|
322
|
+
id: number;
|
|
323
|
+
name?: string;
|
|
324
|
+
zIndex: number;
|
|
325
|
+
origin: {
|
|
326
|
+
x: number;
|
|
327
|
+
y: number;
|
|
328
|
+
};
|
|
329
|
+
width: number;
|
|
330
|
+
height: number;
|
|
331
|
+
visible: boolean;
|
|
332
|
+
enabled: boolean;
|
|
333
|
+
mustBeReliable: boolean;
|
|
334
|
+
isMacroLayer: boolean;
|
|
335
|
+
charCodeMode: CharCodeMode;
|
|
336
|
+
needsCommit: boolean;
|
|
337
|
+
ordersCount: number;
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Display State
|
|
343
|
+
* Represents a Viewport (Camera) into the world.
|
|
344
|
+
* Does NOT contain logic, only state.
|
|
345
|
+
*/
|
|
346
|
+
declare class Display {
|
|
347
|
+
readonly id: number;
|
|
348
|
+
x: number;
|
|
349
|
+
y: number;
|
|
350
|
+
width: number;
|
|
351
|
+
height: number;
|
|
352
|
+
cellWidth: number;
|
|
353
|
+
cellHeight: number;
|
|
354
|
+
pixelWidth: number;
|
|
355
|
+
pixelHeight: number;
|
|
356
|
+
postProcess: PostProcessConfig;
|
|
357
|
+
scalingMode: ScalingMode;
|
|
358
|
+
activePaletteSlot: number;
|
|
359
|
+
renderPasses: RenderPassConfig[] | undefined;
|
|
360
|
+
constructor(id: number, width: number, height: number);
|
|
361
|
+
/**
|
|
362
|
+
* Move the camera to a specific position
|
|
363
|
+
*/
|
|
364
|
+
teleport(x: number, y: number): void;
|
|
365
|
+
/**
|
|
366
|
+
* Resize the viewport (cell dimensions).
|
|
367
|
+
*/
|
|
368
|
+
resize(width: number, height: number): void;
|
|
369
|
+
/**
|
|
370
|
+
* Resize the viewport using a Vector2 (cell dimensions).
|
|
371
|
+
* Alias for `resize(size.x, size.y)`.
|
|
372
|
+
*/
|
|
373
|
+
setSize(size: Vector2): void;
|
|
374
|
+
/**
|
|
375
|
+
* Store the client's pixel viewport dimensions.
|
|
376
|
+
* Called by the runtime when the client reports its screen size.
|
|
377
|
+
* @internal
|
|
378
|
+
*/
|
|
379
|
+
setPixelViewport(pixelWidth: number, pixelHeight: number): void;
|
|
380
|
+
/**
|
|
381
|
+
* Calculate the maximum number of cells that fit in the client's pixel viewport
|
|
382
|
+
* for the given cell size. Uses the stored pixelWidth/pixelHeight.
|
|
383
|
+
*
|
|
384
|
+
* @param cellW - Cell width in pixels (defaults to this.cellWidth).
|
|
385
|
+
* @param cellH - Cell height in pixels (defaults to this.cellHeight).
|
|
386
|
+
* @returns `{ cols, rows }` clamped to [1, 256], or `null` if no pixel viewport is known.
|
|
387
|
+
*/
|
|
388
|
+
calculateMaxCells(cellW?: number, cellH?: number): {
|
|
389
|
+
cols: number;
|
|
390
|
+
rows: number;
|
|
391
|
+
} | null;
|
|
392
|
+
/**
|
|
393
|
+
* Set cell pixel dimensions.
|
|
394
|
+
* Clamped to [1, 255]. Affects canvas resolution and Responsive grid calculation.
|
|
395
|
+
*/
|
|
396
|
+
setCellSize(width: number, height: number): void;
|
|
397
|
+
/**
|
|
398
|
+
* Get cell pixel dimensions.
|
|
399
|
+
*/
|
|
400
|
+
getCellSize(): {
|
|
401
|
+
cellWidth: number;
|
|
402
|
+
cellHeight: number;
|
|
403
|
+
};
|
|
404
|
+
/**
|
|
405
|
+
* Set scaling mode.
|
|
406
|
+
*/
|
|
407
|
+
setScalingMode(mode: ScalingMode): void;
|
|
408
|
+
/**
|
|
409
|
+
* Set ambient (CRT/Blur) effects.
|
|
410
|
+
*/
|
|
411
|
+
setAmbientEffect(config: boolean | Partial<AmbientEffectConfig>): void;
|
|
412
|
+
/**
|
|
413
|
+
* Set grid overlay (debug cell delimitation).
|
|
414
|
+
*/
|
|
415
|
+
setGrid(config: boolean | Partial<GridConfig>): void;
|
|
416
|
+
/**
|
|
417
|
+
* Move the camera by a delta (relative movement).
|
|
418
|
+
*
|
|
419
|
+
* @param deltaX - Delta X in world cells.
|
|
420
|
+
* @param deltaY - Delta Y in world cells.
|
|
421
|
+
*/
|
|
422
|
+
moveOrigin(deltaX: number, deltaY: number): void;
|
|
423
|
+
/**
|
|
424
|
+
* Set scanlines configuration.
|
|
425
|
+
* Pass `true` to enable with defaults, `false` to disable,
|
|
426
|
+
* or a partial config to merge.
|
|
427
|
+
*/
|
|
428
|
+
setScanlines(config: boolean | Partial<ScanlinesConfig>): void;
|
|
429
|
+
/**
|
|
430
|
+
* Enable or disable scanlines.
|
|
431
|
+
*/
|
|
432
|
+
setScanlinesEnabled(enabled: boolean): void;
|
|
433
|
+
/**
|
|
434
|
+
* Set scanlines opacity (0..1).
|
|
435
|
+
*/
|
|
436
|
+
setScanlinesOpacity(opacity: number): void;
|
|
437
|
+
/**
|
|
438
|
+
* Enable or disable the grid overlay.
|
|
439
|
+
*/
|
|
440
|
+
setGridEnabled(enabled: boolean): void;
|
|
441
|
+
/**
|
|
442
|
+
* Enable or disable the ambient effect.
|
|
443
|
+
*/
|
|
444
|
+
setAmbientEffectEnabled(enabled: boolean): void;
|
|
445
|
+
/**
|
|
446
|
+
* Set post-processing effects.
|
|
447
|
+
*/
|
|
448
|
+
setPostProcess(config: PostProcessConfig | null): void;
|
|
449
|
+
/**
|
|
450
|
+
* Set origin (top-left of viewport).
|
|
451
|
+
*/
|
|
452
|
+
setOrigin(origin: Vector2): void;
|
|
453
|
+
/**
|
|
454
|
+
* Get origin (top-left of viewport).
|
|
455
|
+
* Backward-compatible helper.
|
|
456
|
+
*/
|
|
457
|
+
getOrigin(): Vector2;
|
|
458
|
+
/**
|
|
459
|
+
* Get viewport size.
|
|
460
|
+
* Backward-compatible helper.
|
|
461
|
+
*/
|
|
462
|
+
getSize(): {
|
|
463
|
+
x: number;
|
|
464
|
+
y: number;
|
|
465
|
+
width: number;
|
|
466
|
+
height: number;
|
|
467
|
+
};
|
|
468
|
+
/**
|
|
469
|
+
* Switch palette slot.
|
|
470
|
+
*/
|
|
471
|
+
switchPalette(slotId: number): void;
|
|
472
|
+
/**
|
|
473
|
+
* Set render passes for multi-pass compositing (max 4).
|
|
474
|
+
* Each pass filters layers by Z-range.
|
|
475
|
+
* Pass `undefined` or empty array to reset to the default single pass.
|
|
476
|
+
*/
|
|
477
|
+
setRenderPasses(passes: RenderPassConfig[] | undefined): void;
|
|
478
|
+
/**
|
|
479
|
+
* Get the current render pass configuration.
|
|
480
|
+
*/
|
|
481
|
+
getRenderPasses(): RenderPassConfig[] | undefined;
|
|
482
|
+
private normalizePass;
|
|
483
|
+
/**
|
|
484
|
+
* Returns a debug-friendly snapshot of this display (metadata only).
|
|
485
|
+
*/
|
|
486
|
+
getDebugInfo(): {
|
|
487
|
+
id: number;
|
|
488
|
+
origin: {
|
|
489
|
+
x: number;
|
|
490
|
+
y: number;
|
|
491
|
+
};
|
|
492
|
+
size: {
|
|
493
|
+
width: number;
|
|
494
|
+
height: number;
|
|
495
|
+
};
|
|
496
|
+
pixelViewport: {
|
|
497
|
+
pixelWidth: number;
|
|
498
|
+
pixelHeight: number;
|
|
499
|
+
};
|
|
500
|
+
cellSize: {
|
|
501
|
+
cellWidth: number;
|
|
502
|
+
cellHeight: number;
|
|
503
|
+
};
|
|
504
|
+
scalingMode: ScalingMode;
|
|
505
|
+
activePaletteSlot: number;
|
|
506
|
+
postProcess: PostProcessConfig;
|
|
507
|
+
renderPasses?: RenderPassConfig[];
|
|
508
|
+
};
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
/**
|
|
512
|
+
* InputBindingRegistry - Registry for logical axes and buttons.
|
|
513
|
+
*
|
|
514
|
+
* This registry is shared between client and server to ensure consistent input decoding.
|
|
515
|
+
* The server defines the bindings and sends them to the client via a JSON LoadPacket.
|
|
516
|
+
* Both sides use this registry to evaluate raw source values into logical actions.
|
|
517
|
+
*/
|
|
518
|
+
declare class InputBindingRegistry {
|
|
519
|
+
private axes;
|
|
520
|
+
private buttons;
|
|
521
|
+
private touchZones;
|
|
522
|
+
private axisNameToId;
|
|
523
|
+
private buttonNameToId;
|
|
524
|
+
private touchZoneNameToId;
|
|
525
|
+
private version;
|
|
526
|
+
private _axesSortedCache;
|
|
527
|
+
private _buttonsSortedCache;
|
|
528
|
+
private _touchZonesSortedCache;
|
|
529
|
+
defineAxis(bindingId: number, name: string, sources?: AxisSource[], min?: number, max?: number, defaultValue?: number): void;
|
|
530
|
+
defineButton(bindingId: number, name: string, sources?: ButtonSource[], defaultValue?: boolean): void;
|
|
531
|
+
defineTouchZone(zoneId: number, name: string, x: number, y: number, width: number, height: number): void;
|
|
532
|
+
/**
|
|
533
|
+
* Evaluates an axis by summing all its sources.
|
|
534
|
+
*
|
|
535
|
+
* @param bindingId - Axis binding ID
|
|
536
|
+
* @param sourceValues - Map of raw source values (sourceId -> value)
|
|
537
|
+
* @returns Final axis value (clamped)
|
|
538
|
+
*/
|
|
539
|
+
evaluateAxis(bindingId: number, sourceValues: Map<number, number>): number;
|
|
540
|
+
/**
|
|
541
|
+
* Evaluates a button with OR logic (pressed if any source is pressed).
|
|
542
|
+
*/
|
|
543
|
+
evaluateButton(bindingId: number, sourceValues: Map<number, boolean>): boolean;
|
|
544
|
+
toLoadPacket(): InputBindingLoadPacket;
|
|
545
|
+
/**
|
|
546
|
+
* Rebuild this registry from a previously serialised `InputBindingLoadPacket`.
|
|
547
|
+
*
|
|
548
|
+
* Clears any existing bindings first, then re-registers every axis,
|
|
549
|
+
* button, and touch zone contained in the packet.
|
|
550
|
+
*/
|
|
551
|
+
loadFromPacket(packet: InputBindingLoadPacket): void;
|
|
552
|
+
getAllAxes(): AxisBinding[];
|
|
553
|
+
getAllButtons(): ButtonBinding[];
|
|
554
|
+
getAllTouchZones(): TouchZoneBinding[];
|
|
555
|
+
getAxisCount(): number;
|
|
556
|
+
getButtonCount(): number;
|
|
557
|
+
getAxisId(name: string): number | null;
|
|
558
|
+
getButtonId(name: string): number | null;
|
|
559
|
+
clear(): void;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
interface MacroInstanceState {
|
|
563
|
+
instanceId: number;
|
|
564
|
+
templateId: number;
|
|
565
|
+
layerId: number;
|
|
566
|
+
x: number;
|
|
567
|
+
y: number;
|
|
568
|
+
zIndex: number;
|
|
569
|
+
params: Record<string, unknown>;
|
|
570
|
+
state: 'running' | 'paused';
|
|
571
|
+
}
|
|
572
|
+
interface CreateInstanceConfig {
|
|
573
|
+
/** Template name (resolved to templateId internally) */
|
|
574
|
+
macro: string;
|
|
575
|
+
/** Target layer ID */
|
|
576
|
+
layer: number;
|
|
577
|
+
/** Position in cell coordinates on the layer */
|
|
578
|
+
x: number;
|
|
579
|
+
y: number;
|
|
580
|
+
/** Z-index within the macro layer (for multi-instance ordering) */
|
|
581
|
+
zIndex?: number;
|
|
582
|
+
/** Instance name (for later reference by name) */
|
|
583
|
+
name?: string;
|
|
584
|
+
/** Runtime parameters (merged with template defaults) */
|
|
585
|
+
params?: Record<string, unknown>;
|
|
586
|
+
}
|
|
587
|
+
declare class MacroRegistry {
|
|
588
|
+
private templates;
|
|
589
|
+
private templateNameToId;
|
|
590
|
+
private nextTemplateId;
|
|
591
|
+
private instances;
|
|
592
|
+
private instanceNameToId;
|
|
593
|
+
private nextInstanceId;
|
|
594
|
+
private pendingDefines;
|
|
595
|
+
private pendingOrders;
|
|
596
|
+
private feedbackHandlers;
|
|
597
|
+
registerTemplate(name: string, template: MacroTemplate): number;
|
|
598
|
+
getTemplate(idOrName: number | string): MacroTemplate | undefined;
|
|
599
|
+
getTemplateId(name: string): number | undefined;
|
|
600
|
+
createInstance(config: CreateInstanceConfig): number;
|
|
601
|
+
updateInstance(nameOrId: number | string, params: Record<string, unknown>): void;
|
|
602
|
+
removeInstance(nameOrId: number | string): void;
|
|
603
|
+
pauseInstance(nameOrId: number | string): void;
|
|
604
|
+
resumeInstance(nameOrId: number | string): void;
|
|
605
|
+
getPendingDefines(): MacroDefine[];
|
|
606
|
+
getPendingOrders(): MacroOrder[];
|
|
607
|
+
clearPendingDefines(): void;
|
|
608
|
+
clearPendingOrders(): void;
|
|
609
|
+
getAllDefines(): MacroDefine[];
|
|
610
|
+
getActiveInstanceOrders(): MacroCreateOrder[];
|
|
611
|
+
onEvent(nameOrId: number | string, event: string, handler: (data?: unknown) => void): void;
|
|
612
|
+
handleFeedback(feedback: MacroFeedback): void;
|
|
613
|
+
private resolveInstanceId;
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
/**
|
|
617
|
+
* User
|
|
618
|
+
* Represents a user connected to the Primitiv Engine.
|
|
619
|
+
* Owns a set of Layers and Displays (Viewports).
|
|
620
|
+
* Holds the current input state (axes, buttons, mouse).
|
|
621
|
+
* Collects imperative commands (Audio, Vibration) for the current tick.
|
|
622
|
+
*
|
|
623
|
+
* @typeParam TData - Custom per-user data state.
|
|
624
|
+
*/
|
|
625
|
+
declare class User<TData = any> {
|
|
626
|
+
readonly id: string;
|
|
627
|
+
readonly name: string;
|
|
628
|
+
/** Custom persistent state for this user */
|
|
629
|
+
data: TData;
|
|
630
|
+
/**
|
|
631
|
+
* Incoming bridge messages from the remote peer (client or server).
|
|
632
|
+
*
|
|
633
|
+
* Populated between ticks by the runtime. Read during `updateUser()` to
|
|
634
|
+
* process messages synchronised with the game tick. The runtime clears the
|
|
635
|
+
* inbox automatically after `updateUser()` completes.
|
|
636
|
+
*/
|
|
637
|
+
bridgeInbox: BridgeMessage[];
|
|
638
|
+
private _loadedSounds;
|
|
639
|
+
private _soundLoadErrors;
|
|
640
|
+
private _playingSounds;
|
|
641
|
+
/**
|
|
642
|
+
* Whether this user's browser tab is hidden.
|
|
643
|
+
* Set by the runtime when a visibility-change message is received.
|
|
644
|
+
* Used by RuntimeServer to skip sending updates to inactive clients.
|
|
645
|
+
*/
|
|
646
|
+
isTabHidden: boolean;
|
|
647
|
+
private layers;
|
|
648
|
+
private displays;
|
|
649
|
+
private nextLayerId;
|
|
650
|
+
private _layersCache;
|
|
651
|
+
private _displaysCache;
|
|
652
|
+
private spriteRegistry?;
|
|
653
|
+
private macroRegistry;
|
|
654
|
+
private commandQueue;
|
|
655
|
+
private _commandQueueSwap;
|
|
656
|
+
private nextSoundInstanceId;
|
|
657
|
+
private axes;
|
|
658
|
+
private buttons;
|
|
659
|
+
private justPressed;
|
|
660
|
+
private justReleased;
|
|
661
|
+
mouseX: number;
|
|
662
|
+
mouseY: number;
|
|
663
|
+
activeDisplay: number;
|
|
664
|
+
mouseOver: boolean;
|
|
665
|
+
constructor(id: string, name: string);
|
|
666
|
+
/**
|
|
667
|
+
* Inject the sprite registry into this user.
|
|
668
|
+
* Called by the runtime after creation so layers can rasterize sprites.
|
|
669
|
+
* @internal
|
|
670
|
+
*/
|
|
671
|
+
setSpriteRegistry(registry: SpriteRegistry): void;
|
|
672
|
+
/**
|
|
673
|
+
* Alias for createLayer for better readability in application code.
|
|
674
|
+
* Auto-assigns a unique numeric ID to the layer (like UTSP).
|
|
675
|
+
*/
|
|
676
|
+
addLayer(layer: Layer, _id?: string): void;
|
|
677
|
+
/**
|
|
678
|
+
* Alias for createDisplay for better readability.
|
|
679
|
+
*/
|
|
680
|
+
addDisplay(display: Display): void;
|
|
681
|
+
/**
|
|
682
|
+
* Returns a summary of mouse position info relative to the local display.
|
|
683
|
+
*/
|
|
684
|
+
getMouseDisplayInfo(): {
|
|
685
|
+
localX: number;
|
|
686
|
+
localY: number;
|
|
687
|
+
displayId: number;
|
|
688
|
+
} | null;
|
|
689
|
+
/**
|
|
690
|
+
* Backward-compatible alias for touch display info.
|
|
691
|
+
* Uses unified pointer state (mouse/touch) tracked on the active display.
|
|
692
|
+
*/
|
|
693
|
+
getTouchDisplayInfo(displayId?: number): {
|
|
694
|
+
localX: number;
|
|
695
|
+
localY: number;
|
|
696
|
+
displayId: number;
|
|
697
|
+
} | null;
|
|
698
|
+
/**
|
|
699
|
+
* Get viewport info for a display, including pixel dimensions
|
|
700
|
+
* reported by the client.
|
|
701
|
+
*/
|
|
702
|
+
getDisplayViewport(displayId: number): {
|
|
703
|
+
id: number;
|
|
704
|
+
x: number;
|
|
705
|
+
y: number;
|
|
706
|
+
width: number;
|
|
707
|
+
height: number;
|
|
708
|
+
pixelWidth: number;
|
|
709
|
+
pixelHeight: number;
|
|
710
|
+
origin: {
|
|
711
|
+
x: number;
|
|
712
|
+
y: number;
|
|
713
|
+
};
|
|
714
|
+
size: {
|
|
715
|
+
x: number;
|
|
716
|
+
y: number;
|
|
717
|
+
width: number;
|
|
718
|
+
height: number;
|
|
719
|
+
};
|
|
720
|
+
} | null;
|
|
721
|
+
/**
|
|
722
|
+
* Calculate the maximum number of cells that fit in the client's pixel viewport
|
|
723
|
+
* for the given cell size. Delegates to Display.calculateMaxCells().
|
|
724
|
+
*
|
|
725
|
+
* @param displayId - Display ID.
|
|
726
|
+
* @param cellW - Cell width in pixels.
|
|
727
|
+
* @param cellH - Cell height in pixels.
|
|
728
|
+
*/
|
|
729
|
+
calculateMaxCells(displayId: number, cellW: number, cellH: number): {
|
|
730
|
+
cols: number;
|
|
731
|
+
rows: number;
|
|
732
|
+
} | null;
|
|
733
|
+
private inputRegistry;
|
|
734
|
+
/**
|
|
735
|
+
* Get binding registry for application specific input definitions.
|
|
736
|
+
*/
|
|
737
|
+
getInputBindingRegistry(): InputBindingRegistry;
|
|
738
|
+
/**
|
|
739
|
+
* Updates the user state from a binary input packet.
|
|
740
|
+
* This is called on the server when receiving a packet,
|
|
741
|
+
* or on the client after hardware sampling.
|
|
742
|
+
*/
|
|
743
|
+
applyInput(packet: CompressedInputPacket, registry: InputBindingRegistry): void;
|
|
744
|
+
/**
|
|
745
|
+
* Clears one-frame transitions and command queues.
|
|
746
|
+
* Should be called at the end of the engine update.
|
|
747
|
+
*/
|
|
748
|
+
poll(): void;
|
|
749
|
+
/**
|
|
750
|
+
* Play a sound for this user.
|
|
751
|
+
* Queues an AudioOrder for the next network update.
|
|
752
|
+
*/
|
|
753
|
+
playSound(sound: string | number, options?: {
|
|
754
|
+
volume?: number;
|
|
755
|
+
pitch?: number;
|
|
756
|
+
loop?: boolean;
|
|
757
|
+
fadeIn?: number;
|
|
758
|
+
x?: number;
|
|
759
|
+
y?: number;
|
|
760
|
+
lowpass?: number;
|
|
761
|
+
highpass?: number;
|
|
762
|
+
reverb?: number;
|
|
763
|
+
}): number;
|
|
764
|
+
/**
|
|
765
|
+
* Stop a sound immediately by instance ID or name.
|
|
766
|
+
*/
|
|
767
|
+
stopSound(target: number | string): void;
|
|
768
|
+
/**
|
|
769
|
+
* Stop all sounds immediately.
|
|
770
|
+
*/
|
|
771
|
+
stopAllSounds(): void;
|
|
772
|
+
/**
|
|
773
|
+
* Fade out a sound over a duration (seconds).
|
|
774
|
+
*/
|
|
775
|
+
fadeOutSound(target: number | string, duration: number): void;
|
|
776
|
+
/**
|
|
777
|
+
* Fade out all sounds over a duration (seconds).
|
|
778
|
+
*/
|
|
779
|
+
fadeOutAllSounds(duration: number): void;
|
|
780
|
+
/**
|
|
781
|
+
* Pause a specific sound instance.
|
|
782
|
+
*/
|
|
783
|
+
pauseSound(target: number | string): void;
|
|
784
|
+
/**
|
|
785
|
+
* Pause all sounds.
|
|
786
|
+
*/
|
|
787
|
+
pauseAllSounds(): void;
|
|
788
|
+
/**
|
|
789
|
+
* Resume a specific sound instance.
|
|
790
|
+
*/
|
|
791
|
+
resumeSound(target: number | string): void;
|
|
792
|
+
/**
|
|
793
|
+
* Resume all sounds.
|
|
794
|
+
*/
|
|
795
|
+
resumeAllSounds(): void;
|
|
796
|
+
/**
|
|
797
|
+
* Set audio effects (lowpass, highpass, reverb) on a playing sound instance.
|
|
798
|
+
*/
|
|
799
|
+
setSoundEffects(instanceId: number, options: {
|
|
800
|
+
lowpass?: number;
|
|
801
|
+
highpass?: number;
|
|
802
|
+
reverb?: number;
|
|
803
|
+
pitch?: number;
|
|
804
|
+
volume?: number;
|
|
805
|
+
}): void;
|
|
806
|
+
/**
|
|
807
|
+
* Set the listener position for 2D spatial audio.
|
|
808
|
+
*/
|
|
809
|
+
setListenerPosition(x: number, y: number): void;
|
|
810
|
+
/**
|
|
811
|
+
* Configure spatial audio parameters.
|
|
812
|
+
*/
|
|
813
|
+
configureSpatialAudio(config: {
|
|
814
|
+
maxDistance?: number;
|
|
815
|
+
referenceDistance?: number;
|
|
816
|
+
rolloffFactor?: number;
|
|
817
|
+
panSpread?: number;
|
|
818
|
+
}): void;
|
|
819
|
+
/**
|
|
820
|
+
* Signal that all registered sounds should be sent to this user's client.
|
|
821
|
+
* In standalone mode, this triggers loading sounds into the AudioEngine's SoundBank.
|
|
822
|
+
*/
|
|
823
|
+
sendSounds(): void;
|
|
824
|
+
/** @internal */
|
|
825
|
+
_pendingSendSounds: boolean;
|
|
826
|
+
/**
|
|
827
|
+
* Trigger a vibration on the user's device (mobile).
|
|
828
|
+
*/
|
|
829
|
+
vibrate(pattern: number | number[]): void;
|
|
830
|
+
/**
|
|
831
|
+
* Trigger a dual-rumble vibration on the user's gamepad.
|
|
832
|
+
*
|
|
833
|
+
* @param options Vibration parameters (duration, motors, gamepad index).
|
|
834
|
+
*
|
|
835
|
+
* @example
|
|
836
|
+
* ```ts
|
|
837
|
+
* // Heavy hit on first gamepad
|
|
838
|
+
* user.vibrateGamepad({ duration: 200, strongMagnitude: 1.0, weakMagnitude: 0.3 });
|
|
839
|
+
*
|
|
840
|
+
* // Light buzz on second gamepad
|
|
841
|
+
* user.vibrateGamepad({ duration: 100, strongMagnitude: 0, weakMagnitude: 0.8, gamepadIndex: 1 });
|
|
842
|
+
* ```
|
|
843
|
+
*/
|
|
844
|
+
vibrateGamepad(options: {
|
|
845
|
+
duration: number;
|
|
846
|
+
strongMagnitude?: number;
|
|
847
|
+
weakMagnitude?: number;
|
|
848
|
+
startDelay?: number;
|
|
849
|
+
gamepadIndex?: number;
|
|
850
|
+
}): void;
|
|
851
|
+
/**
|
|
852
|
+
* Update post-processing effects for a specific display.
|
|
853
|
+
*/
|
|
854
|
+
setPostProcess(displayId: number, config: PostProcessConfig | null): void;
|
|
855
|
+
setAmbientEffect(displayId: number, config: boolean | Partial<AmbientEffectConfig>): void;
|
|
856
|
+
setGrid(displayId: number, config: boolean | Partial<GridConfig>): void;
|
|
857
|
+
setScalingMode(displayId: number, mode: ScalingMode): void;
|
|
858
|
+
switchPalette(displayId: number, slotId: number): void;
|
|
859
|
+
setOrigin(displayId: number, origin: Vector2): void;
|
|
860
|
+
/**
|
|
861
|
+
* Returns and clears the current command queue.
|
|
862
|
+
* Internal use for synchronization.
|
|
863
|
+
*/
|
|
864
|
+
flushCommands(): Order[];
|
|
865
|
+
getAxis(name: string): number;
|
|
866
|
+
getButton(name: string): boolean;
|
|
867
|
+
isJustPressed(name: string): boolean;
|
|
868
|
+
isJustReleased(name: string): boolean;
|
|
869
|
+
createLayer(id: number, width: number, height: number): Layer;
|
|
870
|
+
getLayer(id: number): Layer | undefined;
|
|
871
|
+
removeLayer(id: number): boolean;
|
|
872
|
+
getLayers(): Layer[];
|
|
873
|
+
createDisplay(id: number, width: number, height: number): Display;
|
|
874
|
+
getDisplay(id: number): Display | undefined;
|
|
875
|
+
removeDisplay(id: number): boolean;
|
|
876
|
+
getDisplays(): Display[];
|
|
877
|
+
defineButton(bindingId: number, name: string, sources: ButtonSource[], defaultValue?: boolean): void;
|
|
878
|
+
defineAxis(bindingId: number, name: string, sources: AxisSource[], min?: number, max?: number, defaultValue?: number): void;
|
|
879
|
+
/**
|
|
880
|
+
* Process an audio acknowledgment from this user's client.
|
|
881
|
+
*
|
|
882
|
+
* Called automatically by the runtime when the client reports audio events.
|
|
883
|
+
* Updates internal tracking maps so the application can query state at any
|
|
884
|
+
* time via `isSoundLoaded()`, `isSoundPlaying()`, etc.
|
|
885
|
+
*
|
|
886
|
+
* @internal
|
|
887
|
+
*/
|
|
888
|
+
handleAudioAck(ack: AudioAck): void;
|
|
889
|
+
/** Check whether a sound (by soundId) is loaded on this user's client. */
|
|
890
|
+
isSoundLoaded(soundId: number): boolean;
|
|
891
|
+
/** Get all loaded sounds for this user. */
|
|
892
|
+
getLoadedSounds(): ReadonlyMap<number, {
|
|
893
|
+
name: string;
|
|
894
|
+
loadedAt: number;
|
|
895
|
+
}>;
|
|
896
|
+
/** Get the load error for a specific sound, if any. */
|
|
897
|
+
getSoundLoadError(soundId: number): string | undefined;
|
|
898
|
+
/** Get all sound load errors for this user. */
|
|
899
|
+
getSoundLoadErrors(): ReadonlyMap<number, {
|
|
900
|
+
name: string;
|
|
901
|
+
error: string;
|
|
902
|
+
at: number;
|
|
903
|
+
}>;
|
|
904
|
+
/** Check whether a sound instance is currently playing on this user's client. */
|
|
905
|
+
isSoundPlaying(instanceId: SoundInstanceId): boolean;
|
|
906
|
+
/** Get all currently playing sound instances for this user. */
|
|
907
|
+
getPlayingSounds(): ReadonlyMap<SoundInstanceId, {
|
|
908
|
+
soundId: number;
|
|
909
|
+
startedAt: number;
|
|
910
|
+
}>;
|
|
911
|
+
/** Get the number of sound instances currently playing on this user's client. */
|
|
912
|
+
getPlayingSoundCount(): number;
|
|
913
|
+
/** Injected by Engine.createUser() */
|
|
914
|
+
setMacroRegistry(registry: MacroRegistry): void;
|
|
915
|
+
/** Get the macro registry (used by encoder to gather pending orders/defines). */
|
|
916
|
+
getMacroRegistry(): MacroRegistry | null;
|
|
917
|
+
/**
|
|
918
|
+
* Load a macro template. Call during initUser().
|
|
919
|
+
* Returns the templateId for reference.
|
|
920
|
+
*/
|
|
921
|
+
loadMacro(name: string, template: MacroTemplate): number;
|
|
922
|
+
/** Create a macro instance on a macro layer. */
|
|
923
|
+
createMacroInstance(config: {
|
|
924
|
+
macro: string;
|
|
925
|
+
layer: number;
|
|
926
|
+
x: number;
|
|
927
|
+
y: number;
|
|
928
|
+
zIndex?: number;
|
|
929
|
+
name?: string;
|
|
930
|
+
params?: Record<string, unknown>;
|
|
931
|
+
}): number;
|
|
932
|
+
updateMacroInstance(nameOrId: number | string, params: Record<string, unknown>): void;
|
|
933
|
+
removeMacroInstance(nameOrId: number | string): void;
|
|
934
|
+
pauseMacroInstance(nameOrId: number | string): void;
|
|
935
|
+
resumeMacroInstance(nameOrId: number | string): void;
|
|
936
|
+
/** Register a handler for macro feedback from the client. */
|
|
937
|
+
onMacroEvent(nameOrId: number | string, event: string, handler: (data?: unknown) => void): void;
|
|
938
|
+
/** Handle macro feedback received from ClientCallback. */
|
|
939
|
+
handleMacroFeedback(feedback: MacroFeedback): void;
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
/**
|
|
943
|
+
* UserUpdateBuilder
|
|
944
|
+
*
|
|
945
|
+
* Serializes UserSession state and commands into a binary update packet.
|
|
946
|
+
* Currently focuses on imperative commands (Audio, Vibration).
|
|
947
|
+
*/
|
|
948
|
+
declare class UserUpdateBuilder {
|
|
949
|
+
private buffer;
|
|
950
|
+
private view;
|
|
951
|
+
private offset;
|
|
952
|
+
private textEncoder;
|
|
953
|
+
constructor(initialSize?: number);
|
|
954
|
+
/**
|
|
955
|
+
* Serializes the session's pending commands into a binary payload.
|
|
956
|
+
* Note: This does not yet serialize the Grid/Layer state, only the command queue.
|
|
957
|
+
*/
|
|
958
|
+
serialize(session: User): Uint8Array;
|
|
959
|
+
private writeOrder;
|
|
960
|
+
private writeAudioOrder;
|
|
961
|
+
private writeVibrationOrder;
|
|
962
|
+
private writePostProcessOrder;
|
|
963
|
+
private ensureCapacity;
|
|
964
|
+
private writeUint8;
|
|
965
|
+
private writeUint16;
|
|
966
|
+
private writeInt16;
|
|
967
|
+
private writeString;
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
/**
|
|
971
|
+
* UserUpdateParser
|
|
972
|
+
*
|
|
973
|
+
* Deserializes binary update packets into User state and commands.
|
|
974
|
+
* Currently focuses on imperative commands (Audio, Vibration).
|
|
975
|
+
*/
|
|
976
|
+
declare class UserUpdateParser {
|
|
977
|
+
private textDecoder;
|
|
978
|
+
/**
|
|
979
|
+
* Parses a binary update payload into a list of Orders.
|
|
980
|
+
*/
|
|
981
|
+
parse(payload: Uint8Array): Order[];
|
|
982
|
+
private parseOrder;
|
|
983
|
+
private parseAudioOrder;
|
|
984
|
+
private parseVibrationOrder;
|
|
985
|
+
private parsePostProcessOrder;
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
/**
|
|
989
|
+
* Encodes a CompressedInputPacket into a self-describing binary buffer.
|
|
990
|
+
*
|
|
991
|
+
* Binary layout:
|
|
992
|
+
* [axisCount(1), buttonCount(1),
|
|
993
|
+
* axes(N × (bindingId:uint16 + value:int8) = 3 bytes each),
|
|
994
|
+
* buttonBindingIds(M × uint16), buttonValues(ceil(M/8) bytes bitpacked),
|
|
995
|
+
* displayId(1), mouseX(1), mouseY(1), flags(1),
|
|
996
|
+
* textInputs(variable), viewports(variable), touches(variable)]
|
|
997
|
+
*
|
|
998
|
+
* The 2-byte header (axisCount, buttonCount) makes the format self-describing
|
|
999
|
+
* so the decoder does not need an external registry to know the field counts.
|
|
1000
|
+
* BindingIds are preserved to ensure correct input mapping after decode.
|
|
1001
|
+
*/
|
|
1002
|
+
declare function encodeCompressedInput(packet: CompressedInputPacket): Uint8Array;
|
|
1003
|
+
/**
|
|
1004
|
+
* Decodes a self-describing binary buffer into a CompressedInputPacket.
|
|
1005
|
+
*
|
|
1006
|
+
* Axis and button counts are read from the 2-byte header, so no external
|
|
1007
|
+
* registry is needed to parse the packet. BindingIds are preserved from
|
|
1008
|
+
* the encoded data to ensure correct input mapping.
|
|
1009
|
+
*/
|
|
1010
|
+
declare function decodeCompressedInput(buffer: Uint8Array, _registry?: InputBindingRegistry): CompressedInputPacket;
|
|
1011
|
+
|
|
1012
|
+
/**
|
|
1013
|
+
* Font system for Primitiv Core
|
|
1014
|
+
* Supports BitmapFont (pixel-based) and ImageFont (PNG atlas-based)
|
|
1015
|
+
*/
|
|
1016
|
+
/**
|
|
1017
|
+
* Font type enumeration
|
|
1018
|
+
*/
|
|
1019
|
+
declare enum FontType {
|
|
1020
|
+
Bitmap = "bitmap",
|
|
1021
|
+
Image = "image"
|
|
1022
|
+
}
|
|
1023
|
+
/**
|
|
1024
|
+
* Number of 256-char blocks in an atlas
|
|
1025
|
+
* Must be a power of two from 1 to 256.
|
|
1026
|
+
* - 1 block = 256 chars (128×128 @ 8px)
|
|
1027
|
+
* - 2 blocks = 512 chars (256×128 @ 8px)
|
|
1028
|
+
* - 4 blocks = 1024 chars (256×256 @ 8px)
|
|
1029
|
+
* - 256 blocks = 65536 chars (2048×2048 @ 8px)
|
|
1030
|
+
*/
|
|
1031
|
+
type AtlasBlocks = 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128 | 256;
|
|
1032
|
+
/**
|
|
1033
|
+
* Glyph size in pixels (uniform within an atlas)
|
|
1034
|
+
*/
|
|
1035
|
+
type GlyphSize = 8 | 16 | 32;
|
|
1036
|
+
/**
|
|
1037
|
+
* Atlas grid layout computed from block count.
|
|
1038
|
+
* The atlas may be rectangular (cols ≠ rows).
|
|
1039
|
+
*/
|
|
1040
|
+
interface AtlasLayout {
|
|
1041
|
+
/** Number of character columns (blocksPerRow × 16) */
|
|
1042
|
+
cols: number;
|
|
1043
|
+
/** Number of character rows (blocksPerCol × 16) */
|
|
1044
|
+
rows: number;
|
|
1045
|
+
/** Number of blocks per row */
|
|
1046
|
+
blocksPerRow: number;
|
|
1047
|
+
/** Number of block rows */
|
|
1048
|
+
blocksPerCol: number;
|
|
1049
|
+
}
|
|
1050
|
+
/**
|
|
1051
|
+
* Return the smallest power of two ≥ n (n must be > 0).
|
|
1052
|
+
*/
|
|
1053
|
+
declare function nextPow2(n: number): number;
|
|
1054
|
+
/**
|
|
1055
|
+
* Compute the atlas grid layout for a given block count.
|
|
1056
|
+
* Both blocksPerRow and blocksPerCol are powers of two.
|
|
1057
|
+
*/
|
|
1058
|
+
declare function getAtlasLayout(blocks: number): AtlasLayout;
|
|
1059
|
+
/**
|
|
1060
|
+
* Get the number of columns in an atlas grid
|
|
1061
|
+
* @param blocks Number of atlas blocks (1, 4, or 16)
|
|
1062
|
+
* @returns Number of columns (16, 32, or 64)
|
|
1063
|
+
*/
|
|
1064
|
+
declare function getAtlasColumns(blocks: AtlasBlocks): number;
|
|
1065
|
+
/**
|
|
1066
|
+
* Get the number of rows in an atlas grid
|
|
1067
|
+
* @param blocks Number of atlas blocks
|
|
1068
|
+
* @returns Number of rows
|
|
1069
|
+
*/
|
|
1070
|
+
declare function getAtlasRows(blocks: AtlasBlocks): number;
|
|
1071
|
+
/**
|
|
1072
|
+
* Get the maximum character code for an atlas configuration
|
|
1073
|
+
* @param blocks Number of atlas blocks
|
|
1074
|
+
* @returns Maximum charCode (blocks * 256 - 1)
|
|
1075
|
+
*/
|
|
1076
|
+
declare function getMaxCharCode(blocks: AtlasBlocks): number;
|
|
1077
|
+
/**
|
|
1078
|
+
* Get atlas texture dimensions in pixels.
|
|
1079
|
+
* Each block occupies 16 × nextPow2(glyphWidth) by 16 × nextPow2(glyphHeight),
|
|
1080
|
+
* so the overall atlas is always PoT.
|
|
1081
|
+
*
|
|
1082
|
+
* @param blocks Number of atlas blocks
|
|
1083
|
+
* @param glyphWidth Width of each glyph in pixels
|
|
1084
|
+
* @param glyphHeight Height of each glyph in pixels (defaults to glyphWidth)
|
|
1085
|
+
* @returns Atlas dimensions { width, height }
|
|
1086
|
+
*/
|
|
1087
|
+
declare function getAtlasDimensions(blocks: AtlasBlocks, glyphWidth: number, glyphHeight?: number): {
|
|
1088
|
+
width: number;
|
|
1089
|
+
height: number;
|
|
1090
|
+
};
|
|
1091
|
+
/**
|
|
1092
|
+
* Options for loading an ImageFont
|
|
1093
|
+
*/
|
|
1094
|
+
interface ImageFontOptions {
|
|
1095
|
+
/** Width of each glyph in pixels (8, 16, or 32) */
|
|
1096
|
+
glyphWidth: number;
|
|
1097
|
+
/** Height of each glyph in pixels (8, 16, or 32) */
|
|
1098
|
+
glyphHeight: number;
|
|
1099
|
+
/** Target cell width for rendering (default: glyphWidth) */
|
|
1100
|
+
cellWidth?: number;
|
|
1101
|
+
/** Target cell height for rendering (default: glyphHeight) */
|
|
1102
|
+
cellHeight?: number;
|
|
1103
|
+
/** Number of 256-char blocks (power of two, 1-256) */
|
|
1104
|
+
atlasBlocks?: AtlasBlocks;
|
|
1105
|
+
}
|
|
1106
|
+
/**
|
|
1107
|
+
* ImageFont configuration
|
|
1108
|
+
* For PNG atlas-based fonts with pre-rendered glyphs
|
|
1109
|
+
*/
|
|
1110
|
+
interface ImageFontConfig {
|
|
1111
|
+
glyphWidth: number;
|
|
1112
|
+
glyphHeight: number;
|
|
1113
|
+
cellWidth?: number;
|
|
1114
|
+
cellHeight?: number;
|
|
1115
|
+
atlasBlocks: AtlasBlocks;
|
|
1116
|
+
}
|
|
1117
|
+
/**
|
|
1118
|
+
* ImageFont class
|
|
1119
|
+
* Represents a PNG atlas-based font for extended character sets
|
|
1120
|
+
*/
|
|
1121
|
+
declare class ImageFont {
|
|
1122
|
+
private fontId;
|
|
1123
|
+
private config;
|
|
1124
|
+
private readonly atlasColumns;
|
|
1125
|
+
private readonly atlasRows;
|
|
1126
|
+
private readonly maxCharCode;
|
|
1127
|
+
private blocks;
|
|
1128
|
+
constructor(fontId: number, config: ImageFontConfig);
|
|
1129
|
+
/**
|
|
1130
|
+
* Add image data for a specific block
|
|
1131
|
+
*/
|
|
1132
|
+
addBlock(blockIndex: number, data: Uint8Array): void;
|
|
1133
|
+
/**
|
|
1134
|
+
* Get image data for a specific block
|
|
1135
|
+
*/
|
|
1136
|
+
getBlock(blockIndex: number): Uint8Array | undefined;
|
|
1137
|
+
/**
|
|
1138
|
+
* Get the unique font ID
|
|
1139
|
+
*/
|
|
1140
|
+
getFontId(): number;
|
|
1141
|
+
/**
|
|
1142
|
+
* Get the full configuration
|
|
1143
|
+
*/
|
|
1144
|
+
getConfig(): ImageFontConfig;
|
|
1145
|
+
/**
|
|
1146
|
+
* Get the glyph width in pixels
|
|
1147
|
+
*/
|
|
1148
|
+
getGlyphWidth(): number;
|
|
1149
|
+
/**
|
|
1150
|
+
* Get the glyph height in pixels
|
|
1151
|
+
*/
|
|
1152
|
+
getGlyphHeight(): number;
|
|
1153
|
+
/**
|
|
1154
|
+
* Get the target cell width in pixels (rendering size)
|
|
1155
|
+
*/
|
|
1156
|
+
getCellWidth(): number;
|
|
1157
|
+
/**
|
|
1158
|
+
* Get the target cell height in pixels (rendering size)
|
|
1159
|
+
*/
|
|
1160
|
+
getCellHeight(): number;
|
|
1161
|
+
/**
|
|
1162
|
+
* Get the number of atlas blocks
|
|
1163
|
+
*/
|
|
1164
|
+
getAtlasBlocks(): AtlasBlocks;
|
|
1165
|
+
/**
|
|
1166
|
+
* Get the number of columns in the atlas grid
|
|
1167
|
+
*/
|
|
1168
|
+
getAtlasColumns(): number;
|
|
1169
|
+
/**
|
|
1170
|
+
* Get the maximum supported charCode
|
|
1171
|
+
*/
|
|
1172
|
+
getMaxCharCode(): number;
|
|
1173
|
+
/**
|
|
1174
|
+
* Get the number of rows in the atlas grid
|
|
1175
|
+
*/
|
|
1176
|
+
getAtlasRows(): number;
|
|
1177
|
+
/**
|
|
1178
|
+
* Get the atlas dimensions in pixels.
|
|
1179
|
+
* Uses effective (next-PoT) glyph size for PoT texture dimensions.
|
|
1180
|
+
*/
|
|
1181
|
+
getAtlasDimensions(): {
|
|
1182
|
+
width: number;
|
|
1183
|
+
height: number;
|
|
1184
|
+
};
|
|
1185
|
+
/**
|
|
1186
|
+
* Get UV coordinates for a character code.
|
|
1187
|
+
*
|
|
1188
|
+
* Glyphs are tightly packed within each block (no per-glyph padding).
|
|
1189
|
+
* Blocks are positioned at PoT boundaries in the atlas.
|
|
1190
|
+
* UV coordinates sample only the real glyph area.
|
|
1191
|
+
*
|
|
1192
|
+
* @param charCode Character code (0 to maxCharCode)
|
|
1193
|
+
* @returns UV coordinates { u1, v1, u2, v2 } or null if out of range
|
|
1194
|
+
*/
|
|
1195
|
+
getCharUV(charCode: number): {
|
|
1196
|
+
u1: number;
|
|
1197
|
+
v1: number;
|
|
1198
|
+
u2: number;
|
|
1199
|
+
v2: number;
|
|
1200
|
+
} | null;
|
|
1201
|
+
/**
|
|
1202
|
+
* Check if a charCode is valid for this atlas
|
|
1203
|
+
*/
|
|
1204
|
+
isValidCharCode(charCode: number): boolean;
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
/**
|
|
1208
|
+
* Registry for managing ImageFont instances
|
|
1209
|
+
* Each font is identified by a unique fontId (0-255) and a human-readable name
|
|
1210
|
+
*/
|
|
1211
|
+
declare class ImageFontRegistry {
|
|
1212
|
+
private fonts;
|
|
1213
|
+
private nameToId;
|
|
1214
|
+
private nextId;
|
|
1215
|
+
private allocateId;
|
|
1216
|
+
/**
|
|
1217
|
+
* Register a new ImageFont structure (no data)
|
|
1218
|
+
*/
|
|
1219
|
+
registerFont(name: string, options: ImageFontOptions): number;
|
|
1220
|
+
/**
|
|
1221
|
+
* Unregister a font by name
|
|
1222
|
+
*/
|
|
1223
|
+
unregisterFont(name: string): void;
|
|
1224
|
+
/**
|
|
1225
|
+
* Check if a font exists by name
|
|
1226
|
+
*/
|
|
1227
|
+
hasFont(name: string): boolean;
|
|
1228
|
+
/**
|
|
1229
|
+
* Add a data block to an existing font
|
|
1230
|
+
*/
|
|
1231
|
+
addBlock(fontId: number, blockIndex: number, data: Uint8Array): void;
|
|
1232
|
+
getFont(fontId: number): ImageFont | undefined;
|
|
1233
|
+
getFontByName(name: string): ImageFont | undefined;
|
|
1234
|
+
getFontId(name: string): number | undefined;
|
|
1235
|
+
/**
|
|
1236
|
+
* Get all registered fonts
|
|
1237
|
+
*/
|
|
1238
|
+
getAllFonts(): ImageFont[];
|
|
1239
|
+
/**
|
|
1240
|
+
* Get the human-readable name of a font by its ID
|
|
1241
|
+
*/
|
|
1242
|
+
getFontName(fontId: number): string | undefined;
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1245
|
+
/**
|
|
1246
|
+
* Internal representation of a registered sound
|
|
1247
|
+
*/
|
|
1248
|
+
interface SoundEntry {
|
|
1249
|
+
soundId: number;
|
|
1250
|
+
name: string;
|
|
1251
|
+
loadType: SoundLoadType;
|
|
1252
|
+
format: SoundFormat;
|
|
1253
|
+
data?: Uint8Array;
|
|
1254
|
+
url?: string;
|
|
1255
|
+
size?: number;
|
|
1256
|
+
checksum?: string;
|
|
1257
|
+
}
|
|
1258
|
+
/**
|
|
1259
|
+
* SoundRegistry - Manages sound definitions on the server
|
|
1260
|
+
*/
|
|
1261
|
+
declare class SoundRegistry {
|
|
1262
|
+
private sounds;
|
|
1263
|
+
private nameToId;
|
|
1264
|
+
private nextId;
|
|
1265
|
+
/**
|
|
1266
|
+
* Register a sound with embedded data (File mode)
|
|
1267
|
+
*/
|
|
1268
|
+
registerFile(name: string, format: SoundFormat, data: Uint8Array): number;
|
|
1269
|
+
/**
|
|
1270
|
+
* Register an external sound (FileExternal mode)
|
|
1271
|
+
*/
|
|
1272
|
+
registerExternal(name: string, format: SoundFormat, url: string, size?: number, checksum?: string): number;
|
|
1273
|
+
get(idOrName: number | string): SoundEntry | undefined;
|
|
1274
|
+
has(idOrName: number | string): boolean;
|
|
1275
|
+
/**
|
|
1276
|
+
* Generate load packets for all registered sounds
|
|
1277
|
+
*/
|
|
1278
|
+
toLoadPackets(): Array<SoundLoadPacket | SoundExternalLoadPacket>;
|
|
1279
|
+
private allocateId;
|
|
1280
|
+
private addEntry;
|
|
1281
|
+
}
|
|
1282
|
+
|
|
1283
|
+
interface TickPackets {
|
|
1284
|
+
reliable: Uint8Array;
|
|
1285
|
+
volatile: Uint8Array;
|
|
1286
|
+
}
|
|
1287
|
+
declare class TickPacketEncoder {
|
|
1288
|
+
/**
|
|
1289
|
+
* Encode a user's tick state into reliable + volatile packets.
|
|
1290
|
+
*/
|
|
1291
|
+
static encode(user: User): TickPackets;
|
|
1292
|
+
/**
|
|
1293
|
+
* Encode the complete user state into a single packet (for LoadBundle).
|
|
1294
|
+
*
|
|
1295
|
+
* Unlike encode(), this includes ALL layers regardless of mustBeReliable
|
|
1296
|
+
* and ignores the needsCommit flag - every layer is encoded.
|
|
1297
|
+
* This is used to send the full initial state during the handshake.
|
|
1298
|
+
*/
|
|
1299
|
+
static encodeFull(user: User, palettes?: Map<number, any[]>): Uint8Array;
|
|
1300
|
+
private static encodePacket;
|
|
1301
|
+
private static encodeAudioOrder;
|
|
1302
|
+
private static encodeSoundTarget;
|
|
1303
|
+
private static encodeVibrationOrder;
|
|
1304
|
+
private static encodeMacroDefine;
|
|
1305
|
+
private static encodeMacroOrder;
|
|
1306
|
+
/**
|
|
1307
|
+
* Encode PostProcessConfig into the binary stream.
|
|
1308
|
+
*
|
|
1309
|
+
* Format:
|
|
1310
|
+
* flags: u8 (bit0=ambientEffect, bit1=scanlines, bit2=grid)
|
|
1311
|
+
* If bit0: enabled(1) blur(1) scale×10(1) opacity×100(1)
|
|
1312
|
+
* If bit1: enabled(1) opacity×100(1) pattern(1) spacing(1) thickness(1) colorR(1) colorG(1) colorB(1)
|
|
1313
|
+
* If bit2: enabled(1) lineWidth×10(1) colorLen(1) color(utf8)
|
|
1314
|
+
*/
|
|
1315
|
+
private static encodePostProcess;
|
|
1316
|
+
}
|
|
1317
|
+
|
|
1318
|
+
/**
|
|
1319
|
+
* EngineStats - Lightweight tick-level metrics for the Primitiv Engine.
|
|
1320
|
+
*
|
|
1321
|
+
* Tracks per-tick encoding cost (time, bytes, layer/cell/order counts)
|
|
1322
|
+
* using a fixed-size ring buffer. Provides rolling averages and
|
|
1323
|
+
* instantaneous snapshots with zero allocation in the hot path.
|
|
1324
|
+
*/
|
|
1325
|
+
/** Snapshot of engine metrics at query time. */
|
|
1326
|
+
interface EngineStatsSnapshot {
|
|
1327
|
+
/** Total ticks encoded since engine start. */
|
|
1328
|
+
totalTicks: number;
|
|
1329
|
+
/** Duration of the last endTick() call (ms). */
|
|
1330
|
+
lastTickDurationMs: number;
|
|
1331
|
+
/** Rolling average of endTick() duration over the window (ms). */
|
|
1332
|
+
avgTickDurationMs: number;
|
|
1333
|
+
/** Peak endTick() duration within the window (ms). */
|
|
1334
|
+
peakTickDurationMs: number;
|
|
1335
|
+
/** Bytes produced by the last endTick() (reliable + volatile). */
|
|
1336
|
+
lastTickBytes: number;
|
|
1337
|
+
/** Rolling average bytes per tick. */
|
|
1338
|
+
avgTickBytes: number;
|
|
1339
|
+
/** Number of layers encoded in the last tick. */
|
|
1340
|
+
lastLayerCount: number;
|
|
1341
|
+
/** Number of draw orders encoded in the last tick. */
|
|
1342
|
+
lastOrderCount: number;
|
|
1343
|
+
/** Number of display cells composited in the last tick. */
|
|
1344
|
+
lastCellCount: number;
|
|
1345
|
+
/** Number of displays encoded in the last tick. */
|
|
1346
|
+
lastDisplayCount: number;
|
|
1347
|
+
}
|
|
1348
|
+
/**
|
|
1349
|
+
* Collects per-tick metrics in a fixed-size ring buffer.
|
|
1350
|
+
*
|
|
1351
|
+
* Usage (called by Engine.endTick internals):
|
|
1352
|
+
* stats.beginTick();
|
|
1353
|
+
* // … encode …
|
|
1354
|
+
* stats.endTick({ bytes, layers, orders, cells, displays });
|
|
1355
|
+
*/
|
|
1356
|
+
declare class EngineStats {
|
|
1357
|
+
private readonly samples;
|
|
1358
|
+
private head;
|
|
1359
|
+
private count;
|
|
1360
|
+
private readonly windowSize;
|
|
1361
|
+
/** Monotonically increasing tick counter. */
|
|
1362
|
+
totalTicks: number;
|
|
1363
|
+
private _t0;
|
|
1364
|
+
constructor(windowSize?: number);
|
|
1365
|
+
/** Call immediately before encoding begins. */
|
|
1366
|
+
beginTick(): void;
|
|
1367
|
+
/** Call immediately after encoding finishes with the tick's counters. */
|
|
1368
|
+
endTick(counters: {
|
|
1369
|
+
bytes: number;
|
|
1370
|
+
layers: number;
|
|
1371
|
+
orders: number;
|
|
1372
|
+
cells: number;
|
|
1373
|
+
displays: number;
|
|
1374
|
+
}): void;
|
|
1375
|
+
/** Return a snapshot of current metrics. Zero-alloc for the ring scan. */
|
|
1376
|
+
getSnapshot(): EngineStatsSnapshot;
|
|
1377
|
+
/** Reset all samples and counters. */
|
|
1378
|
+
reset(): void;
|
|
1379
|
+
}
|
|
1380
|
+
|
|
1381
|
+
type EngineMode = 'server' | 'client' | 'standalone';
|
|
1382
|
+
interface EngineOptions {
|
|
1383
|
+
mode: EngineMode;
|
|
1384
|
+
}
|
|
1385
|
+
/**
|
|
1386
|
+
* Engine
|
|
1387
|
+
* The central game engine that orchestrates the world.
|
|
1388
|
+
* Unified Architecture: Operates as Server or Client based on mode.
|
|
1389
|
+
*/
|
|
1390
|
+
declare class Engine {
|
|
1391
|
+
static readonly VGA_COLORS: {
|
|
1392
|
+
colorId: number;
|
|
1393
|
+
r: number;
|
|
1394
|
+
g: number;
|
|
1395
|
+
b: number;
|
|
1396
|
+
a: number;
|
|
1397
|
+
}[];
|
|
1398
|
+
static readonly SYSTEM_COLORS: {
|
|
1399
|
+
colorId: number;
|
|
1400
|
+
r: number;
|
|
1401
|
+
g: number;
|
|
1402
|
+
b: number;
|
|
1403
|
+
a: number;
|
|
1404
|
+
}[];
|
|
1405
|
+
readonly mode: EngineMode;
|
|
1406
|
+
readonly sessions: Map<string, User>;
|
|
1407
|
+
readonly spriteRegistry: SpriteRegistry;
|
|
1408
|
+
readonly fontRegistry: ImageFontRegistry;
|
|
1409
|
+
readonly soundRegistry: SoundRegistry;
|
|
1410
|
+
readonly inputBindings: InputBindingRegistry;
|
|
1411
|
+
readonly macroRegistry: MacroRegistry;
|
|
1412
|
+
/** Per-tick performance metrics. */
|
|
1413
|
+
readonly stats: EngineStats;
|
|
1414
|
+
/**
|
|
1415
|
+
* Get the sprite registry instance.
|
|
1416
|
+
*/
|
|
1417
|
+
getSpriteRegistry(): SpriteRegistry;
|
|
1418
|
+
private resourceLoader;
|
|
1419
|
+
private onFontAllocatedCallback;
|
|
1420
|
+
private onFontBlockAddedCallback;
|
|
1421
|
+
constructor(options: EngineOptions);
|
|
1422
|
+
/**
|
|
1423
|
+
* Set the resource loader implementation.
|
|
1424
|
+
* Must be called by the runtime before any loadSound() / loadSounds() call.
|
|
1425
|
+
*
|
|
1426
|
+
* - ClientRuntime injects FetchResourceLoader (browser)
|
|
1427
|
+
* - RuntimeServer injects NodeResourceLoader (Node.js)
|
|
1428
|
+
*/
|
|
1429
|
+
setResourceLoader(loader: IResourceLoader): void;
|
|
1430
|
+
/**
|
|
1431
|
+
* Create and register a new User session.
|
|
1432
|
+
*
|
|
1433
|
+
* @param clientId - Numeric client ID (will be converted to string internally)
|
|
1434
|
+
* @param name - Optional display name (defaults to "Player {clientId}")
|
|
1435
|
+
* @returns The newly created User
|
|
1436
|
+
*/
|
|
1437
|
+
createUser(clientId: number, name?: string): User;
|
|
1438
|
+
/**
|
|
1439
|
+
* Remove a User session by numeric client ID.
|
|
1440
|
+
*
|
|
1441
|
+
* @param clientId - Numeric client ID
|
|
1442
|
+
* @returns true if the user was found and removed
|
|
1443
|
+
*/
|
|
1444
|
+
removeUser(clientId: number): boolean;
|
|
1445
|
+
/**
|
|
1446
|
+
* Get a User session by numeric client ID.
|
|
1447
|
+
*
|
|
1448
|
+
* @param clientId - Numeric client ID
|
|
1449
|
+
* @returns The User if found, undefined otherwise
|
|
1450
|
+
*/
|
|
1451
|
+
getUser(clientId: number): User | undefined;
|
|
1452
|
+
/**
|
|
1453
|
+
* Encode a user's current tick state into binary packets.
|
|
1454
|
+
*
|
|
1455
|
+
* Produces two packets:
|
|
1456
|
+
* - `reliable`: layers with mustBeReliable=true + audio/vibration commands
|
|
1457
|
+
* - `volatile`: layers with mustBeReliable=false (no commands)
|
|
1458
|
+
*
|
|
1459
|
+
* After encoding, clears pending orders and commit flags on dirty layers.
|
|
1460
|
+
* The caller is responsible for transporting these packets (loopback or network).
|
|
1461
|
+
*/
|
|
1462
|
+
endTick(user: User): TickPackets;
|
|
1463
|
+
/**
|
|
1464
|
+
* Get a snapshot of engine performance metrics.
|
|
1465
|
+
*
|
|
1466
|
+
* Returns rolling averages over the last ~120 ticks:
|
|
1467
|
+
* tick duration, bytes produced, layer/order/cell counts.
|
|
1468
|
+
*/
|
|
1469
|
+
getEngineStats(): EngineStatsSnapshot;
|
|
1470
|
+
/**
|
|
1471
|
+
* Encode the complete initial state of a user into a single packet (for LoadBundle).
|
|
1472
|
+
*
|
|
1473
|
+
* Unlike endTick(), this includes ALL layers regardless of mustBeReliable flag
|
|
1474
|
+
* and does NOT require layers to be committed. Used during the handshake to send
|
|
1475
|
+
* the full initial state (displays, layers, commands) to the client before simulation.
|
|
1476
|
+
*
|
|
1477
|
+
* Does NOT clear pending orders or commit flags - the caller (RuntimeServer)
|
|
1478
|
+
* manages post-encoding cleanup separately.
|
|
1479
|
+
*/
|
|
1480
|
+
encodeInitialState(user: User): Uint8Array;
|
|
1481
|
+
/**
|
|
1482
|
+
* Register a callback fired when font structure is (re)allocated.
|
|
1483
|
+
* The runtime uses this to call renderer.setImageFontStructure().
|
|
1484
|
+
*/
|
|
1485
|
+
onFontAllocated(cb: () => void): void;
|
|
1486
|
+
/**
|
|
1487
|
+
* Register a callback fired when a font block is added.
|
|
1488
|
+
* The runtime uses this to call renderer.setImageFontBlock().
|
|
1489
|
+
*/
|
|
1490
|
+
onFontBlockAdded(cb: (blockIndex: number) => void): void;
|
|
1491
|
+
/**
|
|
1492
|
+
* Configure the font / atlas structure.
|
|
1493
|
+
*
|
|
1494
|
+
* @param glyphWidth Width of each glyph in the atlas PNG (px)
|
|
1495
|
+
* @param glyphHeight Height of each glyph in the atlas PNG (px)
|
|
1496
|
+
* @param atlasBlocks Number of 256-char blocks (power of two, 1-256)
|
|
1497
|
+
* @param cellWidth Rendering cell width (px) - may be larger than glyph for padding
|
|
1498
|
+
* @param cellHeight Rendering cell height (px)
|
|
1499
|
+
*/
|
|
1500
|
+
loadFont(glyphWidth: number, glyphHeight: number, atlasBlocks: AtlasBlocks, cellWidth: number, cellHeight: number): void;
|
|
1501
|
+
/**
|
|
1502
|
+
* Load a font block from a resource path (PNG image).
|
|
1503
|
+
* Can also accept raw Uint8Array data directly.
|
|
1504
|
+
*
|
|
1505
|
+
* @param blockIndex Block index (0-based). Block 0 is the base ASCII set.
|
|
1506
|
+
* @param pathOrData Path to a PNG file, or raw PNG bytes
|
|
1507
|
+
*/
|
|
1508
|
+
loadFontBlock(blockIndex: number, pathOrData: string | Uint8Array): Promise<void>;
|
|
1509
|
+
/**
|
|
1510
|
+
* Load multiple font blocks in parallel.
|
|
1511
|
+
* @param blocks Record of blockIndex -> path/URL
|
|
1512
|
+
*/
|
|
1513
|
+
loadFontBlocks(blocks: Record<number, string>): Promise<void>;
|
|
1514
|
+
/**
|
|
1515
|
+
* Get the current font configuration (fontId 0).
|
|
1516
|
+
* Returns undefined if no font is allocated.
|
|
1517
|
+
*/
|
|
1518
|
+
getFontConfig(): ImageFontConfig | undefined;
|
|
1519
|
+
/**
|
|
1520
|
+
* Get block data for a specific block index.
|
|
1521
|
+
*/
|
|
1522
|
+
getFontBlock(blockIndex: number): Uint8Array | undefined;
|
|
1523
|
+
private palettes;
|
|
1524
|
+
/**
|
|
1525
|
+
* Detect sound format from file path extension.
|
|
1526
|
+
*/
|
|
1527
|
+
private detectSoundFormat;
|
|
1528
|
+
/**
|
|
1529
|
+
* Load a sound from a file path and register it.
|
|
1530
|
+
* Returns the assigned sound ID (0-255).
|
|
1531
|
+
*
|
|
1532
|
+
* Works isomorphically:
|
|
1533
|
+
* - Browser: fetches via HTTP
|
|
1534
|
+
* - Node.js: reads from filesystem
|
|
1535
|
+
*/
|
|
1536
|
+
loadSound(name: string, path: string): Promise<number>;
|
|
1537
|
+
/**
|
|
1538
|
+
* Load multiple sounds in parallel.
|
|
1539
|
+
* @param sounds Record of name -> path pairs
|
|
1540
|
+
* @returns Record of name -> soundId
|
|
1541
|
+
*/
|
|
1542
|
+
loadSounds(sounds: Record<string, string>): Promise<Record<string, number>>;
|
|
1543
|
+
/**
|
|
1544
|
+
* Initialize the default palette (slot 0).
|
|
1545
|
+
*
|
|
1546
|
+
* Matches UTSP Core.initializeDefaultPalette():
|
|
1547
|
+
* - 0-15: VGA base colors
|
|
1548
|
+
* - 16-239: Undefined -> transparent (r:0, g:0, b:0, a:0)
|
|
1549
|
+
* - 240-254: System reserved colors (cannot be overridden)
|
|
1550
|
+
* - 255: COLOR_SKIP -> transparent (r:0, g:0, b:0, a:0)
|
|
1551
|
+
*/
|
|
1552
|
+
private initializeDefaultPalette;
|
|
1553
|
+
/**
|
|
1554
|
+
* Load a palette into a specific slot.
|
|
1555
|
+
*
|
|
1556
|
+
* Matches UTSP Core.loadPaletteToSlot():
|
|
1557
|
+
* - Accepts user-defined colors for indices 0-239
|
|
1558
|
+
* - Forces system reserved colors 240-254 (cannot be overridden)
|
|
1559
|
+
* - Forces color 255 as transparent (COLOR_SKIP)
|
|
1560
|
+
* - Undefined slots default to transparent (r:0, g:0, b:0, a:0)
|
|
1561
|
+
*/
|
|
1562
|
+
loadPaletteToSlot(slot: number, palette: any[]): void;
|
|
1563
|
+
/**
|
|
1564
|
+
* Get a palette from a specific slot.
|
|
1565
|
+
*/
|
|
1566
|
+
getPalette(slot: number): any[] | undefined;
|
|
1567
|
+
}
|
|
1568
|
+
|
|
1569
|
+
/**
|
|
1570
|
+
* DisplayCompositor
|
|
1571
|
+
*
|
|
1572
|
+
* Merges multiple Layers into a single Display buffer.
|
|
1573
|
+
* Optimized for Primitiv V6 (Uint32Array).
|
|
1574
|
+
*
|
|
1575
|
+
* Supports multi-pass rendering: each pass filters layers by Z-range,
|
|
1576
|
+
* then passes are composited bottom-up (lowest pass first).
|
|
1577
|
+
*
|
|
1578
|
+
* Cached scratch buffers (opaqueMask, passGrids, sortScratch) are reused
|
|
1579
|
+
* across frames to avoid per-frame heap allocations.
|
|
1580
|
+
*/
|
|
1581
|
+
declare class DisplayCompositor {
|
|
1582
|
+
/** Reusable opaque-mask buffer (resized as needed). */
|
|
1583
|
+
private _opaqueMask;
|
|
1584
|
+
/** Per-pass cached grids for multi-pass compositing. */
|
|
1585
|
+
private _passGrids;
|
|
1586
|
+
/** Per-pass opaque-mask buffers. */
|
|
1587
|
+
private _passOpaqueMasks;
|
|
1588
|
+
/** Scratch array for sorting layers without allocating. */
|
|
1589
|
+
private _sortScratch;
|
|
1590
|
+
/** Last composite pass output (cached for retrieval). */
|
|
1591
|
+
private _lastPasses;
|
|
1592
|
+
/** Ensure the opaque mask is large enough, then zero it. */
|
|
1593
|
+
private ensureMask;
|
|
1594
|
+
/** Ensure per-pass grid buffers are allocated and correctly sized. */
|
|
1595
|
+
private ensurePassGrids;
|
|
1596
|
+
/**
|
|
1597
|
+
* Composites layers onto a target Display grid.
|
|
1598
|
+
*
|
|
1599
|
+
* When the display has no render passes defined, uses a single default
|
|
1600
|
+
* pass that accepts Z 0-255.
|
|
1601
|
+
*
|
|
1602
|
+
* With render passes:
|
|
1603
|
+
* 1. Each pass composites only the layers whose zIndex falls in [zMin, zMax].
|
|
1604
|
+
* 2. Passes are composited bottom-up (pass 0 first), each pass's opaque pixels
|
|
1605
|
+
* overwrite the previous ones.
|
|
1606
|
+
* 3. Per-pass grid data is preserved for renderers that support multi-pass.
|
|
1607
|
+
*
|
|
1608
|
+
* @returns Per-pass render states when multi-pass is active, undefined otherwise.
|
|
1609
|
+
*/
|
|
1610
|
+
composite(display: Display, layers: Layer[], target: Grid): RenderPassState[] | undefined;
|
|
1611
|
+
/** Retrieve the last composite passes result (for callers who can't use the return value). */
|
|
1612
|
+
getLastPasses(): RenderPassState[] | undefined;
|
|
1613
|
+
private compositeSinglePass;
|
|
1614
|
+
private compositeMultiPass;
|
|
1615
|
+
/**
|
|
1616
|
+
* Overlay pass data onto target.
|
|
1617
|
+
* Foreground passes overwrite background passes:
|
|
1618
|
+
* - Opaque BG: fully replaces target cell
|
|
1619
|
+
* - Transparent BG with char/fg: char and fg overwrite target (foreground wins)
|
|
1620
|
+
*/
|
|
1621
|
+
private overlayPass;
|
|
1622
|
+
private compositeLayer;
|
|
1623
|
+
}
|
|
1624
|
+
|
|
1625
|
+
/**
|
|
1626
|
+
* LayerRasterizer
|
|
1627
|
+
*
|
|
1628
|
+
* Responsible for translating drawing orders into a Grid's packed data.
|
|
1629
|
+
* Optimized for Primitiv V6 (Uint32Array).
|
|
1630
|
+
*/
|
|
1631
|
+
declare class LayerRasterizer {
|
|
1632
|
+
/**
|
|
1633
|
+
* Rasterize a set of orders onto a target grid.
|
|
1634
|
+
* Note: Does NOT clear the grid; assume it's pre-cleared if needed.
|
|
1635
|
+
*/
|
|
1636
|
+
rasterize(grid: Grid, orders: Order[], spriteRegistry?: SpriteRegistry): void;
|
|
1637
|
+
private executeOrder;
|
|
1638
|
+
private drawChar;
|
|
1639
|
+
private drawText;
|
|
1640
|
+
private drawTextMultiline;
|
|
1641
|
+
private drawSubFrame;
|
|
1642
|
+
private drawSubFrameMulti;
|
|
1643
|
+
private drawFullFrame;
|
|
1644
|
+
private drawFullFrameMulti;
|
|
1645
|
+
private drawColorMap;
|
|
1646
|
+
private drawFill;
|
|
1647
|
+
private drawFillChar;
|
|
1648
|
+
private drawFillSprite;
|
|
1649
|
+
private drawFillSpriteMulti;
|
|
1650
|
+
private drawSprite;
|
|
1651
|
+
private drawSpriteMulti;
|
|
1652
|
+
private drawDotCloud;
|
|
1653
|
+
private drawDotCloudMulti;
|
|
1654
|
+
private drawSpriteCloud;
|
|
1655
|
+
private drawSpriteCloudMulti;
|
|
1656
|
+
private drawSpriteCloudVaried;
|
|
1657
|
+
private drawSpriteCloudVariedMulti;
|
|
1658
|
+
private drawBitmask;
|
|
1659
|
+
private drawBitmask4;
|
|
1660
|
+
private drawBitmask16;
|
|
1661
|
+
private drawPolyline;
|
|
1662
|
+
private drawLineBresenham;
|
|
1663
|
+
private drawShape;
|
|
1664
|
+
private drawRectangle;
|
|
1665
|
+
private drawCircle;
|
|
1666
|
+
private drawEllipse;
|
|
1667
|
+
private drawTriangle;
|
|
1668
|
+
}
|
|
1669
|
+
|
|
1670
|
+
/**
|
|
1671
|
+
* OrderBuilder - Fluent API for generating draw orders
|
|
1672
|
+
*/
|
|
1673
|
+
declare class OrderBuilder {
|
|
1674
|
+
private orders;
|
|
1675
|
+
/**
|
|
1676
|
+
* Convert string or number to char code
|
|
1677
|
+
*/
|
|
1678
|
+
static toCharCode(char: string | number): number;
|
|
1679
|
+
/**
|
|
1680
|
+
* Dedent template literals
|
|
1681
|
+
*/
|
|
1682
|
+
static dedent(text: string): string;
|
|
1683
|
+
/**
|
|
1684
|
+
* Encodes a string into CP437 character codes packed into a string.
|
|
1685
|
+
*/
|
|
1686
|
+
static encodeString(text: string): string;
|
|
1687
|
+
/**
|
|
1688
|
+
* Get the accumulated orders
|
|
1689
|
+
*/
|
|
1690
|
+
getOrders(): Order[];
|
|
1691
|
+
/**
|
|
1692
|
+
* Clear orders
|
|
1693
|
+
*/
|
|
1694
|
+
clear(): this;
|
|
1695
|
+
/**
|
|
1696
|
+
* Draw a single character
|
|
1697
|
+
*/
|
|
1698
|
+
char(x: number, y: number, char: string | number, fg?: number, bg?: number): this;
|
|
1699
|
+
static char(x: number, y: number, char: string | number, fg?: number, bg?: number): CharOrder;
|
|
1700
|
+
/**
|
|
1701
|
+
* Draw a single line of text
|
|
1702
|
+
*/
|
|
1703
|
+
text(x: number, y: number, text: string, fg?: number, bg?: number): this;
|
|
1704
|
+
static text(x: number, y: number, text: string, fg?: number, bg?: number): TextOrder;
|
|
1705
|
+
/**
|
|
1706
|
+
* Draw multiple lines of text
|
|
1707
|
+
*/
|
|
1708
|
+
textMultiline(x: number, y: number, text: string, fg?: number, bg?: number): this;
|
|
1709
|
+
static textMultiline(x: number, y: number, text: string, fg?: number, bg?: number): TextMultilineOrder;
|
|
1710
|
+
/**
|
|
1711
|
+
* Draw a sub-frame (region of characters)
|
|
1712
|
+
*/
|
|
1713
|
+
subFrame(x: number, y: number, width: number, height: number, frame: (string | number)[], fg?: number, bg?: number): this;
|
|
1714
|
+
static subFrame(x: number, y: number, width: number, height: number, frame: (string | number)[], fg?: number, bg?: number): SubFrameOrder;
|
|
1715
|
+
/**
|
|
1716
|
+
* Draw a sub-frame with individual cell colors
|
|
1717
|
+
*/
|
|
1718
|
+
subFrameMulti(x: number, y: number, width: number, height: number, frame: {
|
|
1719
|
+
char: string | number;
|
|
1720
|
+
fg: number;
|
|
1721
|
+
bg: number;
|
|
1722
|
+
}[]): this;
|
|
1723
|
+
static subFrameMulti(x: number, y: number, width: number, height: number, frame: {
|
|
1724
|
+
char?: string | number;
|
|
1725
|
+
charCode?: string | number;
|
|
1726
|
+
fg?: number;
|
|
1727
|
+
fgColor?: number;
|
|
1728
|
+
fgColorCode?: number;
|
|
1729
|
+
bg?: number;
|
|
1730
|
+
bgColor?: number;
|
|
1731
|
+
bgColorCode?: number;
|
|
1732
|
+
}[]): SubFrameMultiOrder;
|
|
1733
|
+
/**
|
|
1734
|
+
* Draw a full frame (entire grid of characters)
|
|
1735
|
+
*/
|
|
1736
|
+
fullFrame(frame: (string | number)[], fg?: number, bg?: number): this;
|
|
1737
|
+
static fullFrame(frame: (string | number)[], fg?: number, bg?: number): FullFrameOrder;
|
|
1738
|
+
/**
|
|
1739
|
+
* Draw a full frame with individual cell colors
|
|
1740
|
+
*/
|
|
1741
|
+
fullFrameMulti(frame: {
|
|
1742
|
+
char?: string | number;
|
|
1743
|
+
charCode?: string | number;
|
|
1744
|
+
fg?: number;
|
|
1745
|
+
fgColor?: number;
|
|
1746
|
+
fgColorCode?: number;
|
|
1747
|
+
bg?: number;
|
|
1748
|
+
bgColor?: number;
|
|
1749
|
+
bgColorCode?: number;
|
|
1750
|
+
}[]): this;
|
|
1751
|
+
static fullFrameMulti(frame: {
|
|
1752
|
+
char?: string | number;
|
|
1753
|
+
charCode?: string | number;
|
|
1754
|
+
fg?: number;
|
|
1755
|
+
fgColor?: number;
|
|
1756
|
+
fgColorCode?: number;
|
|
1757
|
+
bg?: number;
|
|
1758
|
+
bgColor?: number;
|
|
1759
|
+
bgColorCode?: number;
|
|
1760
|
+
}[]): FullFrameMultiOrder;
|
|
1761
|
+
/**
|
|
1762
|
+
* Draw a unicolor sprite
|
|
1763
|
+
*/
|
|
1764
|
+
sprite(x: number, y: number, spriteId: number, fg?: number, bg?: number): this;
|
|
1765
|
+
static sprite(x: number, y: number, spriteId: number, fg?: number, bg?: number): SpriteOrder;
|
|
1766
|
+
/**
|
|
1767
|
+
* Draw a multicolor sprite
|
|
1768
|
+
*/
|
|
1769
|
+
spriteMulti(x: number, y: number, spriteId: number): this;
|
|
1770
|
+
static spriteMulti(x: number, y: number, spriteId: number): SpriteMultiOrder;
|
|
1771
|
+
/**
|
|
1772
|
+
* Draw a color map (region of colors)
|
|
1773
|
+
*/
|
|
1774
|
+
colorMap(x: number, y: number, width: number, height: number, data: ColorMapCell[]): this;
|
|
1775
|
+
/**
|
|
1776
|
+
* Draw a rectangle
|
|
1777
|
+
*/
|
|
1778
|
+
rect(x: number, y: number, width: number, height: number, char?: string | number, fg?: number, bg?: number, filled?: boolean): this;
|
|
1779
|
+
static rect(x: number, y: number, width: number, height: number, char?: string | number, fg?: number, bg?: number, filled?: boolean): ShapeOrder;
|
|
1780
|
+
/**
|
|
1781
|
+
* Draw a circle
|
|
1782
|
+
*/
|
|
1783
|
+
circle(x: number, y: number, radius: number, char: string | number, fg?: number, bg?: number, filled?: boolean): this;
|
|
1784
|
+
static circle(x: number, y: number, radius: number, charOrOptions?: string | number | {
|
|
1785
|
+
charCode?: string | number;
|
|
1786
|
+
fgColor?: number;
|
|
1787
|
+
bgColor?: number;
|
|
1788
|
+
filled?: boolean;
|
|
1789
|
+
}, fg?: number, bg?: number, filled?: boolean): ShapeOrder;
|
|
1790
|
+
/**
|
|
1791
|
+
* Draw a line
|
|
1792
|
+
*/
|
|
1793
|
+
line(x1: number, y1: number, x2: number, y2: number, charOrOptions: string | number | {
|
|
1794
|
+
charCode?: string | number;
|
|
1795
|
+
fgColor?: number;
|
|
1796
|
+
bgColor?: number;
|
|
1797
|
+
}, fg?: number, bg?: number): this;
|
|
1798
|
+
static line(x1: number, y1: number, x2: number, y2: number, charOrOptions: string | number | {
|
|
1799
|
+
charCode?: string | number;
|
|
1800
|
+
fgColor?: number;
|
|
1801
|
+
bgColor?: number;
|
|
1802
|
+
}, fg?: number, bg?: number): ShapeOrder;
|
|
1803
|
+
/**
|
|
1804
|
+
* Draw a triangle
|
|
1805
|
+
*/
|
|
1806
|
+
triangle(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, char: string | number, fg?: number, bg?: number, filled?: boolean): this;
|
|
1807
|
+
static triangle(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, charOrOptions?: string | number | {
|
|
1808
|
+
charCode?: string | number;
|
|
1809
|
+
fgColor?: number;
|
|
1810
|
+
bgColor?: number;
|
|
1811
|
+
filled?: boolean;
|
|
1812
|
+
}, fg?: number, bg?: number, filled?: boolean): ShapeOrder;
|
|
1813
|
+
/**
|
|
1814
|
+
* Draw an ellipse
|
|
1815
|
+
*/
|
|
1816
|
+
ellipse(x: number, y: number, radiusX: number, radiusY: number, char: string | number, fg?: number, bg?: number, filled?: boolean): this;
|
|
1817
|
+
static ellipse(x: number, y: number, radiusX: number, radiusY: number, charOrOptions?: string | number | {
|
|
1818
|
+
charCode?: string | number;
|
|
1819
|
+
fgColor?: number;
|
|
1820
|
+
bgColor?: number;
|
|
1821
|
+
filled?: boolean;
|
|
1822
|
+
}, fg?: number, bg?: number, filled?: boolean): ShapeOrder;
|
|
1823
|
+
/**
|
|
1824
|
+
* Draw a polyline
|
|
1825
|
+
*/
|
|
1826
|
+
polyline(points: {
|
|
1827
|
+
x: number;
|
|
1828
|
+
y: number;
|
|
1829
|
+
}[], char: string | number, fg?: number, bg?: number): this;
|
|
1830
|
+
static polyline(points: {
|
|
1831
|
+
x: number;
|
|
1832
|
+
y: number;
|
|
1833
|
+
}[], char: string | number, fg?: number, bg?: number): PolylineOrder;
|
|
1834
|
+
/**
|
|
1835
|
+
* Draw a closed polygon (polyline that connects back to start)
|
|
1836
|
+
*/
|
|
1837
|
+
polygon(points: {
|
|
1838
|
+
x: number;
|
|
1839
|
+
y: number;
|
|
1840
|
+
}[], char: string | number, fg?: number, bg?: number): this;
|
|
1841
|
+
static polygon(points: {
|
|
1842
|
+
x: number;
|
|
1843
|
+
y: number;
|
|
1844
|
+
}[], char: string | number, fg?: number, bg?: number): PolylineOrder;
|
|
1845
|
+
/**
|
|
1846
|
+
* Draw a cloud of dots with a single character and color
|
|
1847
|
+
*/
|
|
1848
|
+
dotCloud(positions: {
|
|
1849
|
+
x: number;
|
|
1850
|
+
y: number;
|
|
1851
|
+
}[], char: string | number, fg?: number, bg?: number): this;
|
|
1852
|
+
static dotCloud(positions: {
|
|
1853
|
+
x?: number;
|
|
1854
|
+
y?: number;
|
|
1855
|
+
posX?: number;
|
|
1856
|
+
posY?: number;
|
|
1857
|
+
}[], char: string | number, fg?: number, bg?: number): DotCloudOrder;
|
|
1858
|
+
/**
|
|
1859
|
+
* Draw a cloud of dots with individual characters and colors
|
|
1860
|
+
*/
|
|
1861
|
+
dotCloudMulti(dots: {
|
|
1862
|
+
x: number;
|
|
1863
|
+
y: number;
|
|
1864
|
+
char: string | number;
|
|
1865
|
+
fg: number;
|
|
1866
|
+
bg: number;
|
|
1867
|
+
}[]): this;
|
|
1868
|
+
static dotCloudMulti(dots: {
|
|
1869
|
+
x?: number;
|
|
1870
|
+
y?: number;
|
|
1871
|
+
posX?: number;
|
|
1872
|
+
posY?: number;
|
|
1873
|
+
char?: string | number;
|
|
1874
|
+
charCode?: string | number;
|
|
1875
|
+
fg?: number;
|
|
1876
|
+
fgColor?: number;
|
|
1877
|
+
fgColorCode?: number;
|
|
1878
|
+
bg?: number;
|
|
1879
|
+
bgColor?: number;
|
|
1880
|
+
bgColorCode?: number;
|
|
1881
|
+
}[]): DotCloudMultiOrder;
|
|
1882
|
+
/**
|
|
1883
|
+
* Draw a cloud of sprites with a single sprite ID and color
|
|
1884
|
+
*/
|
|
1885
|
+
spriteCloud(positions: {
|
|
1886
|
+
x: number;
|
|
1887
|
+
y: number;
|
|
1888
|
+
}[], spriteId: number, fg?: number, bg?: number): this;
|
|
1889
|
+
static spriteCloud(spriteId: number, positions: {
|
|
1890
|
+
x?: number;
|
|
1891
|
+
y?: number;
|
|
1892
|
+
posX?: number;
|
|
1893
|
+
posY?: number;
|
|
1894
|
+
}[], fg?: number, bg?: number): SpriteCloudOrder;
|
|
1895
|
+
/**
|
|
1896
|
+
* Draw a cloud of sprites with a single sprite ID (multicolor)
|
|
1897
|
+
*/
|
|
1898
|
+
spriteCloudMulti(positions: {
|
|
1899
|
+
x: number;
|
|
1900
|
+
y: number;
|
|
1901
|
+
}[], spriteId: number): this;
|
|
1902
|
+
static spriteCloudMulti(spriteId: number, positions: {
|
|
1903
|
+
x?: number;
|
|
1904
|
+
y?: number;
|
|
1905
|
+
posX?: number;
|
|
1906
|
+
posY?: number;
|
|
1907
|
+
}[]): SpriteCloudMultiOrder;
|
|
1908
|
+
/**
|
|
1909
|
+
* Draw a cloud of sprites where each position has a specific sprite ID (varied)
|
|
1910
|
+
*/
|
|
1911
|
+
spriteCloudVaried(sprites: {
|
|
1912
|
+
x: number;
|
|
1913
|
+
y: number;
|
|
1914
|
+
spriteId: number;
|
|
1915
|
+
fg: number;
|
|
1916
|
+
bg: number;
|
|
1917
|
+
}[]): this;
|
|
1918
|
+
static spriteCloudVaried(sprites: {
|
|
1919
|
+
x?: number;
|
|
1920
|
+
y?: number;
|
|
1921
|
+
posX?: number;
|
|
1922
|
+
posY?: number;
|
|
1923
|
+
spriteId?: number;
|
|
1924
|
+
spriteIndex?: number;
|
|
1925
|
+
fg?: number;
|
|
1926
|
+
fgColor?: number;
|
|
1927
|
+
fgColorCode?: number;
|
|
1928
|
+
bg?: number;
|
|
1929
|
+
bgColor?: number;
|
|
1930
|
+
bgColorCode?: number;
|
|
1931
|
+
}[]): SpriteCloudVariedOrder;
|
|
1932
|
+
/**
|
|
1933
|
+
* Draw a cloud of sprites where each position has a specific sprite ID (varied multicolor)
|
|
1934
|
+
*/
|
|
1935
|
+
spriteCloudVariedMulti(sprites: {
|
|
1936
|
+
x: number;
|
|
1937
|
+
y: number;
|
|
1938
|
+
spriteId: number;
|
|
1939
|
+
}[]): this;
|
|
1940
|
+
static spriteCloudVariedMulti(sprites: {
|
|
1941
|
+
x?: number;
|
|
1942
|
+
y?: number;
|
|
1943
|
+
posX?: number;
|
|
1944
|
+
posY?: number;
|
|
1945
|
+
spriteId?: number;
|
|
1946
|
+
spriteIndex?: number;
|
|
1947
|
+
}[]): SpriteCloudVariedMultiOrder;
|
|
1948
|
+
/**
|
|
1949
|
+
* Draw a 1-bit bitmask (char vs empty)
|
|
1950
|
+
*/
|
|
1951
|
+
bitmask(x: number, y: number, width: number, height: number, mask: ArrayLike<number>, char: string | number, fg?: number, bg?: number, override?: boolean): this;
|
|
1952
|
+
static bitmask(x: number, y: number, width: number, height: number, mask: ArrayLike<number | boolean>, char: string | number, fg?: number, bg?: number, override?: boolean): BitmaskOrder;
|
|
1953
|
+
/**
|
|
1954
|
+
* Draw a 2-bit bitmask (up to 3 variants + empty)
|
|
1955
|
+
*/
|
|
1956
|
+
bitmask4(x: number, y: number, width: number, height: number, mask: ArrayLike<number>, variants: {
|
|
1957
|
+
char: string | number;
|
|
1958
|
+
charCode?: string | number;
|
|
1959
|
+
fg?: number;
|
|
1960
|
+
fgColor?: number;
|
|
1961
|
+
bg?: number;
|
|
1962
|
+
bgColor?: number;
|
|
1963
|
+
}[], override?: boolean): this;
|
|
1964
|
+
static bitmask4(x: number, y: number, width: number, height: number, mask: ArrayLike<number>, variants: {
|
|
1965
|
+
char: string | number;
|
|
1966
|
+
charCode?: string | number;
|
|
1967
|
+
fg?: number;
|
|
1968
|
+
fgColor?: number;
|
|
1969
|
+
bg?: number;
|
|
1970
|
+
bgColor?: number;
|
|
1971
|
+
}[], override?: boolean): Bitmask4Order;
|
|
1972
|
+
/**
|
|
1973
|
+
* Draw a 4-bit bitmask (up to 15 variants + empty)
|
|
1974
|
+
*/
|
|
1975
|
+
bitmask16(x: number, y: number, width: number, height: number, mask: ArrayLike<number>, variants: {
|
|
1976
|
+
char: string | number;
|
|
1977
|
+
charCode?: string | number;
|
|
1978
|
+
fg?: number;
|
|
1979
|
+
fgColor?: number;
|
|
1980
|
+
bg?: number;
|
|
1981
|
+
bgColor?: number;
|
|
1982
|
+
}[], override?: boolean): this;
|
|
1983
|
+
static bitmask16(x: number, y: number, width: number, height: number, mask: ArrayLike<number>, variants: {
|
|
1984
|
+
char: string | number;
|
|
1985
|
+
charCode?: string | number;
|
|
1986
|
+
fg?: number;
|
|
1987
|
+
fgColor?: number;
|
|
1988
|
+
bg?: number;
|
|
1989
|
+
bgColor?: number;
|
|
1990
|
+
}[], override?: boolean): Bitmask16Order;
|
|
1991
|
+
/**
|
|
1992
|
+
* Fill a region or the whole grid
|
|
1993
|
+
*/
|
|
1994
|
+
fill(char: string | number, fg?: number, bg?: number): this;
|
|
1995
|
+
static fill(char: string | number, fg?: number, bg?: number): FillOrder;
|
|
1996
|
+
/**
|
|
1997
|
+
* Fill the grid with a character pattern
|
|
1998
|
+
*/
|
|
1999
|
+
fillChar(patternWidth: number, patternHeight: number, pattern: (string | number)[], fg?: number, bg?: number): this;
|
|
2000
|
+
static fillChar(patternWidth: number, patternHeight: number, pattern: (string | number)[], fg?: number, bg?: number): FillCharOrder;
|
|
2001
|
+
/**
|
|
2002
|
+
* Fill the grid with a unicolor sprite pattern
|
|
2003
|
+
*/
|
|
2004
|
+
fillSprite(spriteId: number, fg?: number, bg?: number): this;
|
|
2005
|
+
static fillSprite(spriteId: number, fg?: number, bg?: number): FillSpriteOrder;
|
|
2006
|
+
/**
|
|
2007
|
+
* Fill the grid with a multicolor sprite pattern
|
|
2008
|
+
*/
|
|
2009
|
+
fillSpriteMulti(spriteId: number): this;
|
|
2010
|
+
static fillSpriteMulti(spriteId: number): FillSpriteMultiOrder;
|
|
2011
|
+
/**
|
|
2012
|
+
* Draw a box with a border (returns two ShapeOrders: filled interior + unfilled border).
|
|
2013
|
+
*
|
|
2014
|
+
* @param x - Left edge
|
|
2015
|
+
* @param y - Top edge
|
|
2016
|
+
* @param width - Total width including border
|
|
2017
|
+
* @param height - Total height including border
|
|
2018
|
+
* @param border - Border appearance { charCode?, fgColor?, bgColor? }
|
|
2019
|
+
* @param fill - Interior fill { charCode?, fgColor?, bgColor? }
|
|
2020
|
+
*/
|
|
2021
|
+
boxWithBorder(x: number, y: number, width: number, height: number, border?: {
|
|
2022
|
+
charCode?: string | number;
|
|
2023
|
+
fgColor?: number;
|
|
2024
|
+
bgColor?: number;
|
|
2025
|
+
}, fill?: {
|
|
2026
|
+
charCode?: string | number;
|
|
2027
|
+
fgColor?: number;
|
|
2028
|
+
bgColor?: number;
|
|
2029
|
+
}): this;
|
|
2030
|
+
static boxWithBorder(x: number, y: number, width: number, height: number, border?: {
|
|
2031
|
+
charCode?: string | number;
|
|
2032
|
+
fgColor?: number;
|
|
2033
|
+
bgColor?: number;
|
|
2034
|
+
}, fill?: {
|
|
2035
|
+
charCode?: string | number;
|
|
2036
|
+
fgColor?: number;
|
|
2037
|
+
bgColor?: number;
|
|
2038
|
+
}): ShapeOrder[];
|
|
2039
|
+
/**
|
|
2040
|
+
* Draw a grid of dots at regular intervals.
|
|
2041
|
+
*
|
|
2042
|
+
* Places a character at every intersection of a grid with the given
|
|
2043
|
+
* cell dimensions and row/col count.
|
|
2044
|
+
*
|
|
2045
|
+
* @param startX - Left origin
|
|
2046
|
+
* @param startY - Top origin
|
|
2047
|
+
* @param cellWidth - Horizontal distance between grid points
|
|
2048
|
+
* @param cellHeight - Vertical distance between grid points
|
|
2049
|
+
* @param rows - Number of rows (grid lines = rows + 1)
|
|
2050
|
+
* @param cols - Number of columns (grid lines = cols + 1)
|
|
2051
|
+
* @param char - Character to place at each intersection
|
|
2052
|
+
* @param fg - Foreground color
|
|
2053
|
+
* @param bg - Background color
|
|
2054
|
+
*/
|
|
2055
|
+
grid(startX: number, startY: number, cellWidth: number, cellHeight: number, rows: number, cols: number, char?: string | number, fg?: number, bg?: number): this;
|
|
2056
|
+
static grid(startX: number, startY: number, cellWidth: number, cellHeight: number, rows: number, cols: number, char?: string | number, fg?: number, bg?: number): DotCloudOrder;
|
|
2057
|
+
}
|
|
2058
|
+
|
|
2059
|
+
/**
|
|
2060
|
+
* BinaryReader - Position-tracked binary buffer reader.
|
|
2061
|
+
*
|
|
2062
|
+
* Shared implementation used by TickPacketDecoder and OrderDecoder.
|
|
2063
|
+
* Supports all primitive read operations needed by the Primitiv V6 protocol.
|
|
2064
|
+
*/
|
|
2065
|
+
declare class BinaryReader {
|
|
2066
|
+
private _buf;
|
|
2067
|
+
private _view;
|
|
2068
|
+
offset: number;
|
|
2069
|
+
constructor(buffer: Uint8Array, offset?: number);
|
|
2070
|
+
get remaining(): number;
|
|
2071
|
+
/** Access the underlying buffer (for sub-slicing). */
|
|
2072
|
+
get rawBuffer(): Uint8Array;
|
|
2073
|
+
readU8(): number;
|
|
2074
|
+
readI8(): number;
|
|
2075
|
+
readU16BE(): number;
|
|
2076
|
+
readI16BE(): number;
|
|
2077
|
+
readU16LE(): number;
|
|
2078
|
+
readBytes(count: number): Uint8Array;
|
|
2079
|
+
}
|
|
2080
|
+
|
|
2081
|
+
/**
|
|
2082
|
+
* BinaryWriter - Growable binary buffer for encoding.
|
|
2083
|
+
*
|
|
2084
|
+
* Shared implementation used by TickPacketEncoder and OrderEncoder.
|
|
2085
|
+
* Supports pooling via reset() to avoid per-tick heap allocations.
|
|
2086
|
+
*/
|
|
2087
|
+
declare class BinaryWriter {
|
|
2088
|
+
private buffer;
|
|
2089
|
+
private view;
|
|
2090
|
+
offset: number;
|
|
2091
|
+
constructor(initialSize?: number);
|
|
2092
|
+
/**
|
|
2093
|
+
* Reset the writer for reuse (zero-alloc).
|
|
2094
|
+
* Keeps the existing buffer - only resets the write cursor.
|
|
2095
|
+
*/
|
|
2096
|
+
reset(): void;
|
|
2097
|
+
private ensure;
|
|
2098
|
+
/**
|
|
2099
|
+
* Ensure capacity and return the underlying buffer for direct writes
|
|
2100
|
+
* (e.g. TextEncoder.encodeInto). Caller must advance offset manually.
|
|
2101
|
+
*/
|
|
2102
|
+
ensureAndGetBuffer(bytes: number): Uint8Array;
|
|
2103
|
+
writeU8(v: number): void;
|
|
2104
|
+
writeI8(v: number): void;
|
|
2105
|
+
writeU16BE(v: number): void;
|
|
2106
|
+
writeI16BE(v: number): void;
|
|
2107
|
+
writeU16LE(v: number): void;
|
|
2108
|
+
writeBytes(data: Uint8Array): void;
|
|
2109
|
+
/**
|
|
2110
|
+
* Return a trimmed copy of the written data.
|
|
2111
|
+
* Safe to use when the writer will be reused/reset afterwards.
|
|
2112
|
+
*/
|
|
2113
|
+
toUint8Array(): Uint8Array;
|
|
2114
|
+
/**
|
|
2115
|
+
* Return a view (subarray) of the written data - zero-copy.
|
|
2116
|
+
* WARNING: The view shares the underlying buffer. Only valid until the next
|
|
2117
|
+
* write or reset. Use when a short-lived read is sufficient (e.g. immediate
|
|
2118
|
+
* copy into a packet).
|
|
2119
|
+
*/
|
|
2120
|
+
getView(): Uint8Array;
|
|
2121
|
+
}
|
|
2122
|
+
|
|
2123
|
+
/**
|
|
2124
|
+
* OrderEncoder - Encodes render orders to compact binary format.
|
|
2125
|
+
*
|
|
2126
|
+
* Each order starts with a 1-byte type tag followed by type-specific payload.
|
|
2127
|
+
* Convention: Big-endian for sizes/positions, charCodes as-is (1 byte 8bit, 2 bytes LE 16bit).
|
|
2128
|
+
*/
|
|
2129
|
+
|
|
2130
|
+
declare class OrderEncoder {
|
|
2131
|
+
private static readonly _sharedWriter;
|
|
2132
|
+
/**
|
|
2133
|
+
* Encode a list of render orders into binary.
|
|
2134
|
+
* @param orders The orders to encode.
|
|
2135
|
+
* @param is16bit Whether charCodes are 16-bit (true) or 8-bit (false).
|
|
2136
|
+
* @returns Encoded binary data.
|
|
2137
|
+
*/
|
|
2138
|
+
static encode(orders: Order[], is16bit?: boolean): Uint8Array;
|
|
2139
|
+
/**
|
|
2140
|
+
* Encode a list of render orders directly into a provided BinaryWriter.
|
|
2141
|
+
* Zero-alloc variant - avoids creating an intermediate Uint8Array.
|
|
2142
|
+
* Used by TickPacketEncoder to write orders inline.
|
|
2143
|
+
*/
|
|
2144
|
+
static encodeInto(w: BinaryWriter, orders: Order[], is16bit?: boolean): void;
|
|
2145
|
+
/**
|
|
2146
|
+
* Encode a single order into the writer.
|
|
2147
|
+
*/
|
|
2148
|
+
private static encodeOne;
|
|
2149
|
+
private static encodeChar;
|
|
2150
|
+
private static encodeText;
|
|
2151
|
+
private static encodeTextMultiline;
|
|
2152
|
+
private static encodeSubFrame;
|
|
2153
|
+
private static encodeSubFrameMulti;
|
|
2154
|
+
private static encodeFullFrame;
|
|
2155
|
+
private static encodeFullFrameMulti;
|
|
2156
|
+
private static encodeSprite;
|
|
2157
|
+
private static encodeSpriteMulti;
|
|
2158
|
+
private static encodeColorMap;
|
|
2159
|
+
private static encodeShape;
|
|
2160
|
+
private static encodePolyline;
|
|
2161
|
+
private static encodeDotCloud;
|
|
2162
|
+
private static encodeDotCloudMulti;
|
|
2163
|
+
private static encodeSpriteCloud;
|
|
2164
|
+
private static encodeSpriteCloudMulti;
|
|
2165
|
+
private static encodeSpriteCloudVaried;
|
|
2166
|
+
private static encodeSpriteCloudVariedMulti;
|
|
2167
|
+
private static encodeBitmask;
|
|
2168
|
+
private static encodeBitmask4;
|
|
2169
|
+
private static encodeBitmask16;
|
|
2170
|
+
private static encodeFill;
|
|
2171
|
+
private static encodeFillChar;
|
|
2172
|
+
private static encodeFillSprite;
|
|
2173
|
+
private static encodeFillSpriteMulti;
|
|
2174
|
+
}
|
|
2175
|
+
|
|
2176
|
+
/**
|
|
2177
|
+
* OrderDecoder - Decodes render orders from compact binary format.
|
|
2178
|
+
*
|
|
2179
|
+
* Mirrors OrderEncoder: Big-endian for sizes/positions, charCodes 1 byte (8bit) or 2 bytes LE (16bit).
|
|
2180
|
+
*/
|
|
2181
|
+
|
|
2182
|
+
declare class OrderDecoder {
|
|
2183
|
+
/**
|
|
2184
|
+
* Decode a binary buffer into a list of render orders.
|
|
2185
|
+
* @param buffer The binary data (may contain 0..N orders concatenated).
|
|
2186
|
+
* @param is16bit Whether charCodes are 16-bit.
|
|
2187
|
+
* @param layerWidth Width of the target layer (needed for FullFrame).
|
|
2188
|
+
* @param layerHeight Height of the target layer (needed for FullFrame).
|
|
2189
|
+
* @returns Decoded orders array.
|
|
2190
|
+
*/
|
|
2191
|
+
static decode(buffer: Uint8Array, is16bit?: boolean, layerWidth?: number, layerHeight?: number): Order[];
|
|
2192
|
+
/**
|
|
2193
|
+
* Decode exactly `count` orders from an existing BinaryReader.
|
|
2194
|
+
*
|
|
2195
|
+
* Unlike decode(), this does not create its own reader and does not
|
|
2196
|
+
* read until end-of-buffer. It advances the shared reader by exactly
|
|
2197
|
+
* the bytes consumed by `count` orders, allowing the caller to
|
|
2198
|
+
* continue reading subsequent sections from the same buffer.
|
|
2199
|
+
*/
|
|
2200
|
+
static decodeN(r: BinaryReader, count: number, is16bit: boolean, layerWidth: number, layerHeight: number): Order[];
|
|
2201
|
+
private static decodeOne;
|
|
2202
|
+
private static decodeChar;
|
|
2203
|
+
private static decodeText;
|
|
2204
|
+
private static decodeTextMultiline;
|
|
2205
|
+
private static decodeSubFrame;
|
|
2206
|
+
private static decodeSubFrameMulti;
|
|
2207
|
+
private static decodeFullFrame;
|
|
2208
|
+
private static decodeFullFrameMulti;
|
|
2209
|
+
private static decodeSprite;
|
|
2210
|
+
private static decodeSpriteMulti;
|
|
2211
|
+
private static decodeColorMap;
|
|
2212
|
+
private static decodeShape;
|
|
2213
|
+
private static decodePolyline;
|
|
2214
|
+
private static decodeDotCloud;
|
|
2215
|
+
private static decodeDotCloudMulti;
|
|
2216
|
+
private static decodeSpriteCloud;
|
|
2217
|
+
private static decodeSpriteCloudMulti;
|
|
2218
|
+
private static decodeSpriteCloudVaried;
|
|
2219
|
+
private static decodeSpriteCloudVariedMulti;
|
|
2220
|
+
private static decodeBitmask;
|
|
2221
|
+
private static decodeBitmask4;
|
|
2222
|
+
private static decodeBitmask16;
|
|
2223
|
+
private static decodeFill;
|
|
2224
|
+
private static decodeFillChar;
|
|
2225
|
+
private static decodeFillSprite;
|
|
2226
|
+
private static decodeFillSpriteMulti;
|
|
2227
|
+
}
|
|
2228
|
+
|
|
2229
|
+
/**
|
|
2230
|
+
* TickPacketDecoder - Decodes a full tick update packet from binary.
|
|
2231
|
+
*
|
|
2232
|
+
* Mirrors TickPacketEncoder. Produces a structured object suitable for
|
|
2233
|
+
* ClientRuntime.applyUpdate().
|
|
2234
|
+
*/
|
|
2235
|
+
|
|
2236
|
+
interface DecodedDisplay {
|
|
2237
|
+
id: number;
|
|
2238
|
+
originX: number;
|
|
2239
|
+
originY: number;
|
|
2240
|
+
width: number;
|
|
2241
|
+
height: number;
|
|
2242
|
+
paletteSlot: number;
|
|
2243
|
+
scalingMode: ScalingMode;
|
|
2244
|
+
cellWidth: number;
|
|
2245
|
+
cellHeight: number;
|
|
2246
|
+
renderPasses?: {
|
|
2247
|
+
id: number;
|
|
2248
|
+
zMin: number;
|
|
2249
|
+
zMax: number;
|
|
2250
|
+
enabled: boolean;
|
|
2251
|
+
}[];
|
|
2252
|
+
postProcess: PostProcessConfig;
|
|
2253
|
+
}
|
|
2254
|
+
interface DecodedLayer {
|
|
2255
|
+
id: number;
|
|
2256
|
+
enabled: boolean;
|
|
2257
|
+
isMacro: boolean;
|
|
2258
|
+
is16bit: boolean;
|
|
2259
|
+
/** True when the server sent new orders this tick. When false, the client should preserve its existing orders. */
|
|
2260
|
+
hasOrders: boolean;
|
|
2261
|
+
zIndex: number;
|
|
2262
|
+
originX: number;
|
|
2263
|
+
originY: number;
|
|
2264
|
+
width: number;
|
|
2265
|
+
height: number;
|
|
2266
|
+
orders: Order[];
|
|
2267
|
+
/** Wire size in bytes consumed by this layer (header + orders). */
|
|
2268
|
+
byteSize: number;
|
|
2269
|
+
}
|
|
2270
|
+
interface DecodedPalette {
|
|
2271
|
+
slot: number;
|
|
2272
|
+
colors: {
|
|
2273
|
+
colorId: number;
|
|
2274
|
+
r: number;
|
|
2275
|
+
g: number;
|
|
2276
|
+
b: number;
|
|
2277
|
+
a: number;
|
|
2278
|
+
}[];
|
|
2279
|
+
}
|
|
2280
|
+
interface DecodedTickPacket {
|
|
2281
|
+
displays: DecodedDisplay[];
|
|
2282
|
+
palettes: DecodedPalette[];
|
|
2283
|
+
layers: DecodedLayer[];
|
|
2284
|
+
audioOrders: AudioOrder[];
|
|
2285
|
+
vibrationOrders: VibrationOrder[];
|
|
2286
|
+
macroDefines: MacroDefine[];
|
|
2287
|
+
macroOrders: MacroOrder[];
|
|
2288
|
+
/** Input binding definitions (only present in LoadBundle / full snapshot). */
|
|
2289
|
+
inputBindings?: InputBindingLoadPacket;
|
|
2290
|
+
/** Wire byte sizes of each packet section (for traffic tracking). */
|
|
2291
|
+
sectionSizes: {
|
|
2292
|
+
displays: number;
|
|
2293
|
+
palettes: number;
|
|
2294
|
+
layers: number;
|
|
2295
|
+
audio: number;
|
|
2296
|
+
vibration: number;
|
|
2297
|
+
macroDefines: number;
|
|
2298
|
+
macroOrders: number;
|
|
2299
|
+
total: number;
|
|
2300
|
+
};
|
|
2301
|
+
}
|
|
2302
|
+
declare class TickPacketDecoder {
|
|
2303
|
+
/**
|
|
2304
|
+
* Decode a binary tick packet into a structured object.
|
|
2305
|
+
*/
|
|
2306
|
+
static decode(buffer: Uint8Array): DecodedTickPacket;
|
|
2307
|
+
/**
|
|
2308
|
+
* Decode N orders from the reader.
|
|
2309
|
+
*
|
|
2310
|
+
* Delegates directly to OrderDecoder.decodeN() which reads exactly
|
|
2311
|
+
* `count` orders from the shared BinaryReader, advancing its offset.
|
|
2312
|
+
* No skip pass needed - single-pass decoding.
|
|
2313
|
+
*/
|
|
2314
|
+
private static decodeOrders;
|
|
2315
|
+
private static decodeAudioOrder;
|
|
2316
|
+
private static decodeSoundTarget;
|
|
2317
|
+
private static decodeVibrationOrder;
|
|
2318
|
+
private static decodeMacroDefine;
|
|
2319
|
+
private static decodeMacroOrder;
|
|
2320
|
+
/**
|
|
2321
|
+
* Decode PostProcessConfig from the binary stream.
|
|
2322
|
+
* Mirrors TickPacketEncoder.encodePostProcess().
|
|
2323
|
+
*/
|
|
2324
|
+
private static decodePostProcess;
|
|
2325
|
+
}
|
|
2326
|
+
|
|
2327
|
+
/**
|
|
2328
|
+
* Unicode to IBM CP437 Conversion Table
|
|
2329
|
+
*
|
|
2330
|
+
* ROBUST VERSION: Uses only numeric codepoints, no literal characters.
|
|
2331
|
+
* This prevents any encoding issues (UTF-8, Latin-1, Windows-1252, etc.)
|
|
2332
|
+
*
|
|
2333
|
+
* Maps Unicode codepoints to CP437 byte values (0-255).
|
|
2334
|
+
*/
|
|
2335
|
+
/**
|
|
2336
|
+
* Unicode -> CP437 Map (built from the numeric table above)
|
|
2337
|
+
*/
|
|
2338
|
+
declare const UNICODE_TO_CP437: Map<number, number>;
|
|
2339
|
+
/**
|
|
2340
|
+
* Convert Unicode codepoint to CP437 byte value.
|
|
2341
|
+
*
|
|
2342
|
+
* @param unicodeChar - Unicode codepoint (from string.charCodeAt())
|
|
2343
|
+
* @returns CP437 byte value (0-255)
|
|
2344
|
+
*
|
|
2345
|
+
* @example
|
|
2346
|
+
* unicodeToCp437(0x2591) // -> 176 (░ Light Shade)
|
|
2347
|
+
* unicodeToCp437(0x0041) // -> 65 (A)
|
|
2348
|
+
* unicodeToCp437('░'.charCodeAt(0)) // -> 176
|
|
2349
|
+
*/
|
|
2350
|
+
declare function unicodeToCp437(unicodeChar: number): number;
|
|
2351
|
+
/**
|
|
2352
|
+
* Convert a JavaScript string to CP437 byte array.
|
|
2353
|
+
*
|
|
2354
|
+
* @param text - Unicode string
|
|
2355
|
+
* @returns Uint8Array of CP437 byte values
|
|
2356
|
+
*
|
|
2357
|
+
* @example
|
|
2358
|
+
* stringToCp437('░▒▓') // -> Uint8Array [176, 177, 178]
|
|
2359
|
+
*/
|
|
2360
|
+
declare function stringToCp437(text: string): Uint8Array;
|
|
2361
|
+
/**
|
|
2362
|
+
* Convert CP437 byte value to Unicode codepoint.
|
|
2363
|
+
*
|
|
2364
|
+
* @param cp437Byte - CP437 byte value (0-255)
|
|
2365
|
+
* @returns Unicode codepoint
|
|
2366
|
+
*
|
|
2367
|
+
* @example
|
|
2368
|
+
* cp437ToUnicode(176) // -> 0x2591 (░)
|
|
2369
|
+
*/
|
|
2370
|
+
declare function cp437ToUnicodeCodepoint(cp437Byte: number): number;
|
|
2371
|
+
/**
|
|
2372
|
+
* Convert CP437 byte value to Unicode character string.
|
|
2373
|
+
*
|
|
2374
|
+
* @param cp437Byte - CP437 byte value (0-255)
|
|
2375
|
+
* @returns Unicode character
|
|
2376
|
+
*
|
|
2377
|
+
* @example
|
|
2378
|
+
* cp437ToUnicode(176) // -> '░'
|
|
2379
|
+
*/
|
|
2380
|
+
declare function cp437ToUnicode(cp437Byte: number): string;
|
|
2381
|
+
/**
|
|
2382
|
+
* Check if a Unicode codepoint has a CP437 mapping.
|
|
2383
|
+
*
|
|
2384
|
+
* @param unicodeChar - Unicode codepoint
|
|
2385
|
+
* @returns true if character can be mapped to CP437
|
|
2386
|
+
*/
|
|
2387
|
+
declare function hasCP437Mapping(unicodeChar: number): boolean;
|
|
2388
|
+
/**
|
|
2389
|
+
* Encodes a string into CP437 character codes packed into a string.
|
|
2390
|
+
*/
|
|
2391
|
+
declare function encodeCp437String(text: string): string;
|
|
2392
|
+
|
|
2393
|
+
/**
|
|
2394
|
+
* Lightweight Event Emitter
|
|
2395
|
+
* Browser/Node compatible implementation to avoid 'events' dependency.
|
|
2396
|
+
*/
|
|
2397
|
+
declare class EventEmitter<T = any> {
|
|
2398
|
+
private listeners;
|
|
2399
|
+
on(event: string, callback: (data: T) => void): void;
|
|
2400
|
+
off(event: string, callback: (data: T) => void): void;
|
|
2401
|
+
emit(event: string, data?: T): void;
|
|
2402
|
+
removeAllListeners(): void;
|
|
2403
|
+
}
|
|
2404
|
+
|
|
2405
|
+
/**
|
|
2406
|
+
* Primitiv Core Constants
|
|
2407
|
+
*/
|
|
2408
|
+
/**
|
|
2409
|
+
* COLOR_SKIP (255)
|
|
2410
|
+
* Used as a special color index to signify transparency/skipping in the rendering pipeline.
|
|
2411
|
+
* Matches UTSP parity.
|
|
2412
|
+
*/
|
|
2413
|
+
declare const COLOR_SKIP = 255;
|
|
2414
|
+
/**
|
|
2415
|
+
* LAYER_SIZE
|
|
2416
|
+
* Maximum width/height for a single layer grid.
|
|
2417
|
+
*/
|
|
2418
|
+
declare const LAYER_SIZE = 256;
|
|
2419
|
+
|
|
2420
|
+
export { BinaryReader, COLOR_SKIP, CellStruct, Display, DisplayCompositor, Engine, EngineStats, EventEmitter, FontType, Grid, ImageFont, ImageFontRegistry, InputBindingRegistry, LAYER_SIZE, Layer, LayerRasterizer, MacroRegistry, OrderBuilder, OrderDecoder, OrderEncoder, SoundRegistry, SpriteRegistry, TickPacketDecoder, TickPacketEncoder, UNICODE_TO_CP437, User, UserUpdateBuilder, UserUpdateParser, cp437ToUnicode, cp437ToUnicodeCodepoint, decodeCompressedInput, encodeCompressedInput, encodeCp437String, getAtlasColumns, getAtlasDimensions, getAtlasLayout, getAtlasRows, getMaxCharCode, hasCP437Mapping, nextPow2, stringToCp437, unicodeToCp437 };
|
|
2421
|
+
export type { AtlasBlocks, AtlasLayout, CharCodeMode, CreateInstanceConfig, DecodedDisplay, DecodedLayer, DecodedPalette, DecodedTickPacket, EngineMode, EngineOptions, EngineStatsSnapshot, GlyphSize, ImageFontConfig, ImageFontOptions, LayerOptions, MacroInstanceState, SoundEntry, TickPackets };
|