dredless 0.2.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 +21 -0
- package/README.md +48 -0
- package/docs/API_REFERENCE.md +2481 -0
- package/docs/BROWSER_API.md +98 -0
- package/docs/NODE_API.md +359 -0
- package/package.json +173 -0
- package/src/browser.d.ts +212 -0
- package/src/browser.js +133 -0
- package/src/client/core.js +1202 -0
- package/src/client/domains/index.js +1818 -0
- package/src/client/index.d.ts +2 -0
- package/src/client/index.js +1 -0
- package/src/compression/lz4.d.ts +1 -0
- package/src/compression/lz4.js +112 -0
- package/src/constants.js +74 -0
- package/src/crypto/chacha-native.d.ts +9 -0
- package/src/crypto/chacha-native.js +48 -0
- package/src/crypto/chacha.d.ts +25 -0
- package/src/crypto/chacha.js +274 -0
- package/src/data/item-schema.js +2235 -0
- package/src/data/official-client-data.js +156 -0
- package/src/events.js +39 -0
- package/src/index.d.ts +2277 -0
- package/src/index.js +125 -0
- package/src/network/browser-session.js +291 -0
- package/src/network/connection.d.ts +1 -0
- package/src/network/connection.js +31 -0
- package/src/network/cookies.js +85 -0
- package/src/network/http.js +34 -0
- package/src/network/index.d.ts +4 -0
- package/src/network/index.js +4 -0
- package/src/network/servers.d.ts +7 -0
- package/src/network/servers.js +133 -0
- package/src/network/session.d.ts +7 -0
- package/src/network/session.js +320 -0
- package/src/network/ships.d.ts +12 -0
- package/src/network/ships.js +73 -0
- package/src/node.d.ts +2 -0
- package/src/node.js +8 -0
- package/src/protocol/codec/binary.d.ts +3 -0
- package/src/protocol/codec/binary.js +52 -0
- package/src/protocol/codec/msgpack.d.ts +3 -0
- package/src/protocol/codec/msgpack.js +555 -0
- package/src/protocol/inbound/frame.d.ts +1 -0
- package/src/protocol/inbound/frame.js +8 -0
- package/src/protocol/inbound/world-payload.d.ts +3 -0
- package/src/protocol/inbound/world-payload.js +21 -0
- package/src/protocol/index.d.ts +11 -0
- package/src/protocol/index.js +19 -0
- package/src/protocol/outbound/blueprint.d.ts +22 -0
- package/src/protocol/outbound/blueprint.js +36 -0
- package/src/protocol/outbound/commands.d.ts +3 -0
- package/src/protocol/outbound/commands.js +149 -0
- package/src/protocol/outbound/comms.d.ts +28 -0
- package/src/protocol/outbound/comms.js +40 -0
- package/src/protocol/outbound/inventory.d.ts +64 -0
- package/src/protocol/outbound/inventory.js +147 -0
- package/src/protocol/outbound/ship-management.d.ts +84 -0
- package/src/protocol/outbound/ship-management.js +221 -0
- package/src/protocol/outbound/sign.d.ts +18 -0
- package/src/protocol/outbound/sign.js +45 -0
- package/src/protocol/outbound/ui-config.d.ts +157 -0
- package/src/protocol/outbound/ui-config.js +578 -0
- package/src/runtime.js +36 -0
- package/src/state/generator-maze.d.ts +32 -0
- package/src/state/generator-maze.js +370 -0
- package/src/state/index.d.ts +3 -0
- package/src/state/index.js +3 -0
- package/src/state/items.js +20 -0
- package/src/state/model/decoder.js +1554 -0
- package/src/state/model/index.d.ts +33 -0
- package/src/state/model/index.js +2 -0
- package/src/state/model/loader-config.js +1020 -0
- package/src/state/model/reader.js +69 -0
- package/src/state/model/state.js +1257 -0
- package/src/state/overworld.js +72 -0
- package/src/state/tilesets.js +53 -0
- package/src/state/world/index.d.ts +29 -0
- package/src/state/world/index.js +180 -0
- package/src/state/world/state.js +297 -0
|
@@ -0,0 +1,2481 @@
|
|
|
1
|
+
# Dredless API Reference
|
|
2
|
+
|
|
3
|
+
This document describes the public JavaScript API exposed by the package.
|
|
4
|
+
Here, "endpoint" means a public method, constructor, domain method, or exported
|
|
5
|
+
helper function. The actual browser/game wire protocol remains an implementation
|
|
6
|
+
detail unless a helper explicitly builds or decodes protocol payloads.
|
|
7
|
+
|
|
8
|
+
Use the runtime-specific top-level API references for session, token, and start/join helpers:
|
|
9
|
+
|
|
10
|
+
- [NODE_API.md](./NODE_API.md): explicit multi-session `Session` / `AnonSession` API for Node.
|
|
11
|
+
- [BROWSER_API.md](./BROWSER_API.md): ambient browser-session API for browser contexts.
|
|
12
|
+
|
|
13
|
+
This shared reference covers common input/output shapes, `DredlessClient`, world/entity/domain APIs, protocol helpers, and other runtime-neutral APIs.
|
|
14
|
+
|
|
15
|
+
Subpath imports are available for focused low-level helpers:
|
|
16
|
+
|
|
17
|
+
```js
|
|
18
|
+
import { DredlessClient } from "dredless/client";
|
|
19
|
+
import { WorldStore, WorldState } from "dredless/world";
|
|
20
|
+
import { generateGeneratorMaze } from "dredless/game/generator-maze";
|
|
21
|
+
import { encodeMsgpack, decodeMsgpack, decodeIncomingFrame } from "dredless/protocol";
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Public Package Exports
|
|
25
|
+
|
|
26
|
+
`package.json` currently exposes these module specifiers:
|
|
27
|
+
|
|
28
|
+
```txt
|
|
29
|
+
dredless
|
|
30
|
+
dredless/browser
|
|
31
|
+
dredless/node
|
|
32
|
+
dredless/client
|
|
33
|
+
dredless/network
|
|
34
|
+
dredless/state
|
|
35
|
+
dredless/session
|
|
36
|
+
dredless/servers
|
|
37
|
+
dredless/ships
|
|
38
|
+
dredless/connection
|
|
39
|
+
dredless/world
|
|
40
|
+
dredless/model
|
|
41
|
+
dredless/game/generator-maze
|
|
42
|
+
dredless/game/model
|
|
43
|
+
dredless/protocol
|
|
44
|
+
dredless/protocol/blueprint
|
|
45
|
+
dredless/protocol/comms
|
|
46
|
+
dredless/protocol/commands
|
|
47
|
+
dredless/protocol/inventory
|
|
48
|
+
dredless/protocol/ship-management
|
|
49
|
+
dredless/protocol/sign
|
|
50
|
+
dredless/protocol/ui-config
|
|
51
|
+
dredless/crypto/chacha
|
|
52
|
+
dredless/compression/lz4
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
The root module defaults to the Node API for types and direct Node imports. Browser bundlers may use the root `browser` condition for JavaScript, but `dredless/browser` is the reliable import for browser IntelliSense.
|
|
56
|
+
|
|
57
|
+
Both runtime entrypoints re-export world/model classes, protocol builders, config builders, codec helpers, and common type shapes.
|
|
58
|
+
|
|
59
|
+
## Common Input Types
|
|
60
|
+
|
|
61
|
+
### `Server`
|
|
62
|
+
|
|
63
|
+
Returned by `fetchServers()`.
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
interface Server {
|
|
67
|
+
index: number;
|
|
68
|
+
domain: string;
|
|
69
|
+
description: string;
|
|
70
|
+
playerCount: number;
|
|
71
|
+
maxPlayerCount: number;
|
|
72
|
+
ping: number | null;
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### `ServerRef`
|
|
77
|
+
|
|
78
|
+
Accepted anywhere a server is required.
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
type ServerRef = number | Server;
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Passing a number selects a server index. Passing a `Server` object uses its
|
|
85
|
+
domain and index directly.
|
|
86
|
+
|
|
87
|
+
### `Ship`
|
|
88
|
+
|
|
89
|
+
Returned by ship list reads.
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
interface Ship {
|
|
93
|
+
id: number | null;
|
|
94
|
+
hexCode: string | null;
|
|
95
|
+
name: string;
|
|
96
|
+
iconUrl: string | null;
|
|
97
|
+
playerCount: number;
|
|
98
|
+
owned: boolean;
|
|
99
|
+
saved: boolean;
|
|
100
|
+
color: string;
|
|
101
|
+
time: number | null;
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### `ShipList`
|
|
106
|
+
|
|
107
|
+
Returned by `fetchShipList()`.
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
interface ShipList {
|
|
111
|
+
playerCount?: number;
|
|
112
|
+
maxPlayerCount?: number;
|
|
113
|
+
isMuted?: boolean;
|
|
114
|
+
ships: Ship[];
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### `ShipSpec`, `ShipRef`
|
|
119
|
+
|
|
120
|
+
Accepted by join/start methods.
|
|
121
|
+
|
|
122
|
+
```ts
|
|
123
|
+
type ShipSpec =
|
|
124
|
+
| { type: "join_or_load"; id: number | string }
|
|
125
|
+
| { type: "new"; name?: string | null; color?: string | null }
|
|
126
|
+
| { type: "invite"; code: string };
|
|
127
|
+
|
|
128
|
+
type ShipRef = number | string | Ship | ShipSpec | null;
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Useful interpretations:
|
|
132
|
+
|
|
133
|
+
```txt
|
|
134
|
+
number -> ship id
|
|
135
|
+
string -> ship id/hex-like selector, depending on server API
|
|
136
|
+
Ship -> ship from fetchShips/fetchShipList
|
|
137
|
+
{ type: "new" } -> create or start a new ship
|
|
138
|
+
{ type: "invite" } -> join by invite code
|
|
139
|
+
null or undefined -> default behavior for the method
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Runtime Top-Level APIs
|
|
143
|
+
|
|
144
|
+
Top-level runtime APIs are split by environment:
|
|
145
|
+
|
|
146
|
+
- Node explicit session/token/start helpers: [NODE_API.md](./NODE_API.md)
|
|
147
|
+
- Browser ambient session/start helpers: [BROWSER_API.md](./BROWSER_API.md)
|
|
148
|
+
|
|
149
|
+
`Connection`, `Session`, `AnonSession`, `BrowserSession`, `Dredless`, and `DredlessBrowser` are documented in those runtime-specific files.
|
|
150
|
+
|
|
151
|
+
## `DredlessClient`
|
|
152
|
+
|
|
153
|
+
`DredlessClient` owns the websocket, outgoing commands, incoming packets, and
|
|
154
|
+
decoded state domains.
|
|
155
|
+
|
|
156
|
+
```ts
|
|
157
|
+
class DredlessClient {
|
|
158
|
+
constructor(connection: Connection, options?: { connect?: boolean });
|
|
159
|
+
static attachWebSocket(websocket: unknown, options?: AttachWebSocketOptions): DredlessClient;
|
|
160
|
+
|
|
161
|
+
connection: Connection | null;
|
|
162
|
+
session: Session | null;
|
|
163
|
+
baseUrl: string | null;
|
|
164
|
+
attachMode: "observe" | "bootstrap" | "readonly" | null;
|
|
165
|
+
attached: boolean;
|
|
166
|
+
serverId: number | null;
|
|
167
|
+
server: Server | null;
|
|
168
|
+
netPort: number | null;
|
|
169
|
+
gameToken: string;
|
|
170
|
+
ws: unknown;
|
|
171
|
+
sid: number | null;
|
|
172
|
+
connected: boolean;
|
|
173
|
+
ready: boolean;
|
|
174
|
+
packetCount: number;
|
|
175
|
+
lastPacket: unknown;
|
|
176
|
+
|
|
177
|
+
net: ClientNetDomain;
|
|
178
|
+
debug: ClientDebugDomain;
|
|
179
|
+
player: PlayerDomain;
|
|
180
|
+
inventory: InventoryDomain;
|
|
181
|
+
management: ShipManagementDomain;
|
|
182
|
+
readyPromise: Promise<this>;
|
|
183
|
+
|
|
184
|
+
whenReady(): Promise<this>;
|
|
185
|
+
close(code?: number, reason?: string): this;
|
|
186
|
+
disconnect(code?: number, reason?: string): this;
|
|
187
|
+
|
|
188
|
+
currentShip(): ShipDomain | null;
|
|
189
|
+
ship(): ShipDomain | null;
|
|
190
|
+
overworld(): OverworldDomain | null;
|
|
191
|
+
world(id: number): WorldDomain | null;
|
|
192
|
+
shipWorld(options?: { includeTiles?: boolean; includeModel?: boolean }): WorldSnapshot | null;
|
|
193
|
+
state(options?: { includeTiles?: boolean; includeModel?: boolean }): ClientSnapshot;
|
|
194
|
+
entities(scope?: number | string): EntitySummary[];
|
|
195
|
+
entity(entityId: number, scope?: number | string): EntitySnapshot | null;
|
|
196
|
+
currentPlayerEntity(): EntityHandle | null;
|
|
197
|
+
|
|
198
|
+
on(type: string, callback: (...args: unknown[]) => void): this;
|
|
199
|
+
off(type: string, callback: (...args: unknown[]) => void): this;
|
|
200
|
+
once(type: string, callback: (...args: unknown[]) => void): this;
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### Constructor
|
|
205
|
+
|
|
206
|
+
```js
|
|
207
|
+
const client = new DredlessClient(connection);
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
By default the constructor opens the websocket. For tests or offline state
|
|
211
|
+
inspection, pass `{ connect: false }`:
|
|
212
|
+
|
|
213
|
+
```js
|
|
214
|
+
const client = new DredlessClient(connection, { connect: false });
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### `DredlessClient.attachWebSocket(websocket, options?)`
|
|
218
|
+
|
|
219
|
+
```ts
|
|
220
|
+
type WebSocketAttachMode = "observe" | "bootstrap" | "readonly";
|
|
221
|
+
|
|
222
|
+
interface AttachWebSocketOptions {
|
|
223
|
+
mode?: WebSocketAttachMode;
|
|
224
|
+
connected?: boolean | null;
|
|
225
|
+
ready?: boolean;
|
|
226
|
+
sid?: number | null;
|
|
227
|
+
baseUrl?: string | null;
|
|
228
|
+
session?: Session | null;
|
|
229
|
+
serverId?: number | null;
|
|
230
|
+
server?: Server | null;
|
|
231
|
+
netPort?: number | null;
|
|
232
|
+
gameToken?: string;
|
|
233
|
+
}
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
Attaches Dredless to an existing websocket without requiring a `Connection`.
|
|
237
|
+
This is intended for observing or integrating with an already-open browser/game websocket.
|
|
238
|
+
|
|
239
|
+
Modes:
|
|
240
|
+
|
|
241
|
+
- `"observe"` default: decodes incoming packets and allows explicit writes through normal handle/client methods, but does not send hello, bootstrap, or keepalive automatically.
|
|
242
|
+
- `"bootstrap"`: treats the websocket like a normally owned Dredless socket; sends hello on open and runs bootstrap, keepalive, and queued-message flushing on ready.
|
|
243
|
+
- `"readonly"`: decodes incoming packets only and rejects all write methods. `close()` is a no-op in this mode.
|
|
244
|
+
|
|
245
|
+
Optional metadata such as `server`, `serverId`, and `netPort` is only used for snapshots/logging; it is not required to attach.
|
|
246
|
+
|
|
247
|
+
```js
|
|
248
|
+
const client = DredlessClient.attachWebSocket(window.tpgaClient.repsocket.websocket);
|
|
249
|
+
client.on("packet", (packet) => console.log(packet.type));
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### Lifecycle endpoints
|
|
253
|
+
|
|
254
|
+
```ts
|
|
255
|
+
whenReady(): Promise<this>;
|
|
256
|
+
close(code?: number, reason?: string): this;
|
|
257
|
+
disconnect(code?: number, reason?: string): this;
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
`whenReady()` resolves once the ready packet is received. For normally-owned clients and `attachWebSocket(..., { mode: "bootstrap" })`, bootstrap commands have also been sent.
|
|
261
|
+
|
|
262
|
+
### World/domain endpoints
|
|
263
|
+
|
|
264
|
+
```ts
|
|
265
|
+
currentShip(): ShipDomain | null;
|
|
266
|
+
ship(): ShipDomain | null;
|
|
267
|
+
currentPlayerEntity(): EntityHandle | null;
|
|
268
|
+
overworld(): OverworldDomain | null;
|
|
269
|
+
world(id: number): WorldDomain | null;
|
|
270
|
+
shipWorld(options?): WorldSnapshot | null;
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
Use `currentShip()` for the currently loaded ship world. Use `overworld()` for
|
|
274
|
+
zone-level objects such as nearby ships and overworld entities.
|
|
275
|
+
|
|
276
|
+
`currentPlayerEntity()` returns the current player entity handle in the loaded
|
|
277
|
+
ship world, or `null` before the player entity is known.
|
|
278
|
+
|
|
279
|
+
### Compatibility entity endpoints
|
|
280
|
+
|
|
281
|
+
```ts
|
|
282
|
+
entities(scope?: number | string): EntitySummary[];
|
|
283
|
+
entity(entityId: number, scope?: number | string): EntitySnapshot | null;
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
Prefer `client.currentShip()?.entities` and `client.overworld()?.entities` for
|
|
287
|
+
new code. These compatibility methods use `"ship"` by default.
|
|
288
|
+
|
|
289
|
+
Valid common scopes are:
|
|
290
|
+
|
|
291
|
+
```txt
|
|
292
|
+
"ship"
|
|
293
|
+
"current"
|
|
294
|
+
"overworld"
|
|
295
|
+
number world id
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
### Events
|
|
299
|
+
|
|
300
|
+
```ts
|
|
301
|
+
on(type: string, callback: (...args: unknown[]) => void): this;
|
|
302
|
+
off(type: string, callback: (...args: unknown[]) => void): this;
|
|
303
|
+
once(type: string, callback: (...args: unknown[]) => void): this;
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
Events are implementation-defined strings emitted by the client event bus.
|
|
307
|
+
|
|
308
|
+
## `client.state()` Output
|
|
309
|
+
|
|
310
|
+
```ts
|
|
311
|
+
interface ClientSnapshot {
|
|
312
|
+
baseUrl: string;
|
|
313
|
+
session: SessionSnapshot;
|
|
314
|
+
connection: ConnectionSnapshot | null;
|
|
315
|
+
attachMode: "observe" | "bootstrap" | "readonly" | null;
|
|
316
|
+
serverId: number | null;
|
|
317
|
+
server: Server | null;
|
|
318
|
+
netPort: number | null;
|
|
319
|
+
sid: number | null;
|
|
320
|
+
ready: boolean;
|
|
321
|
+
connected: boolean;
|
|
322
|
+
currentWorldId: number | null;
|
|
323
|
+
worlds: WorldSnapshot[];
|
|
324
|
+
cpuLoad: number | null;
|
|
325
|
+
inventory: InventoryState | null;
|
|
326
|
+
puiPanels: PuiEvent[];
|
|
327
|
+
commsPanels: CommsEvent[];
|
|
328
|
+
currentCommsPanel: CommsEvent | null;
|
|
329
|
+
warnings: unknown[];
|
|
330
|
+
effects: unknown[];
|
|
331
|
+
chat: unknown[];
|
|
332
|
+
motd: unknown[];
|
|
333
|
+
sessionMessages: unknown[];
|
|
334
|
+
scannerResults: ScannerResult[];
|
|
335
|
+
lastScannerResult: ScannerResult | null;
|
|
336
|
+
shipConfig: ShipConfig | null;
|
|
337
|
+
captainSubrank: CaptainSubrank | null;
|
|
338
|
+
playerList: ShipPlayerList | null;
|
|
339
|
+
outfits: { sid: number; outfit: unknown }[];
|
|
340
|
+
commandAcks: CommandAck[];
|
|
341
|
+
lastCommandAck: CommandAck | null;
|
|
342
|
+
decodeErrors: unknown[];
|
|
343
|
+
packetCount: number;
|
|
344
|
+
lastPacket: unknown;
|
|
345
|
+
}
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
## Client Domain APIs
|
|
349
|
+
|
|
350
|
+
### `client.net`
|
|
351
|
+
|
|
352
|
+
Low-level outgoing network domain.
|
|
353
|
+
|
|
354
|
+
```ts
|
|
355
|
+
interface ClientNetDomain {
|
|
356
|
+
connected: boolean;
|
|
357
|
+
ready: boolean;
|
|
358
|
+
sid: number | null;
|
|
359
|
+
packetCount: number;
|
|
360
|
+
lastPacket: unknown;
|
|
361
|
+
send(command?: Command): DredlessClient;
|
|
362
|
+
sendMessage(message: unknown, options?: { afterReady?: boolean }): DredlessClient;
|
|
363
|
+
sendRaw(message: unknown, options?: { afterReady?: boolean }): DredlessClient;
|
|
364
|
+
sendEntityCommand(cmd: string, args?: unknown[]): DredlessClient;
|
|
365
|
+
sendUiConfig(data: unknown): DredlessClient;
|
|
366
|
+
sendBlueprintPlacement(placement: BlueprintPlacement): DredlessClient;
|
|
367
|
+
setOutfit(outfit: unknown): DredlessClient;
|
|
368
|
+
}
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
`send()` signs and sends a command-like packet. `sendMessage()` sends a decoded
|
|
372
|
+
protocol message. `sendRaw()` sends already-built/raw content. The specialized
|
|
373
|
+
helpers build the corresponding protocol command and return the client for
|
|
374
|
+
chaining.
|
|
375
|
+
|
|
376
|
+
### `Command`
|
|
377
|
+
|
|
378
|
+
General command shape for movement, actions, UI focus, and drag operations.
|
|
379
|
+
|
|
380
|
+
```ts
|
|
381
|
+
interface Command {
|
|
382
|
+
type?: number;
|
|
383
|
+
n?: number | null;
|
|
384
|
+
x?: number;
|
|
385
|
+
y?: number;
|
|
386
|
+
mx?: number;
|
|
387
|
+
my?: number;
|
|
388
|
+
vx?: number;
|
|
389
|
+
vy?: number;
|
|
390
|
+
jump?: boolean;
|
|
391
|
+
jump_held?: boolean;
|
|
392
|
+
drop?: boolean;
|
|
393
|
+
act1?: boolean;
|
|
394
|
+
act1_held?: boolean;
|
|
395
|
+
exit?: boolean;
|
|
396
|
+
act2?: boolean;
|
|
397
|
+
act_alt?: boolean;
|
|
398
|
+
act_alt_held?: boolean;
|
|
399
|
+
wrench_mode?: number;
|
|
400
|
+
turret_mode?: number;
|
|
401
|
+
scr_w?: number;
|
|
402
|
+
scr_h?: number;
|
|
403
|
+
motion?: number;
|
|
404
|
+
focus_ent?: number | null;
|
|
405
|
+
config_ent?: number | null;
|
|
406
|
+
tip_select?: number | null;
|
|
407
|
+
inv_slot?: number;
|
|
408
|
+
blur?: boolean;
|
|
409
|
+
drag?: DragPayload | null;
|
|
410
|
+
}
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
### `client.debug`
|
|
414
|
+
|
|
415
|
+
Read-only debugging and raw-state access.
|
|
416
|
+
|
|
417
|
+
```ts
|
|
418
|
+
interface ClientDebugDomain {
|
|
419
|
+
packets(): unknown[];
|
|
420
|
+
decodeErrors(): unknown[];
|
|
421
|
+
worldStore(): WorldStore;
|
|
422
|
+
modelTable(worldId: number, tableId: number): Map<number, ModelRecord>;
|
|
423
|
+
modelRecord(worldId: number, tableId: number, entityId: number): ModelRecord | null;
|
|
424
|
+
puiPanels(): PuiEvent[];
|
|
425
|
+
commsPanels(): CommsEvent[];
|
|
426
|
+
}
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
### `client.player`
|
|
430
|
+
|
|
431
|
+
Player input and action domain.
|
|
432
|
+
|
|
433
|
+
```ts
|
|
434
|
+
interface PlayerDomain {
|
|
435
|
+
current(): PlayerSummary | null;
|
|
436
|
+
entity(): EntityHandle | null;
|
|
437
|
+
name(): string | null;
|
|
438
|
+
rank(): CurrentPlayerRank;
|
|
439
|
+
move(vector?: { x?: number; y?: number }, command?: Command): DredlessClient;
|
|
440
|
+
aim(point?: { x?: number; y?: number; mx?: number; my?: number }, command?: Command): DredlessClient;
|
|
441
|
+
action(flags?: Command, command?: Command): DredlessClient;
|
|
442
|
+
useEntity(entity: number | EntityHandle | EntitySummary, options?: { invSlot?: number; hold?: boolean }, command?: Command): DredlessClient;
|
|
443
|
+
useHeldItem(options?: { invSlot?: number; hold?: boolean }, command?: Command): DredlessClient;
|
|
444
|
+
placeHeldItem(options?: { invSlot?: number; hold?: boolean }, command?: Command): DredlessClient;
|
|
445
|
+
placeBlueprint(placement: BlueprintPlacement, options?: { invSlot?: number; hold?: boolean; mx?: number; my?: number }, command?: Command): DredlessClient;
|
|
446
|
+
rotateHeldItem(options?: { invSlot?: number; hold?: boolean }, command?: Command): DredlessClient;
|
|
447
|
+
selectSlot(invSlot?: number, command?: Command): DredlessClient;
|
|
448
|
+
inputSettings(): CurrentInputSettings;
|
|
449
|
+
setInputSettings(settings?: InputSettings, options?: { send?: boolean }): DredlessClient;
|
|
450
|
+
setView(width: number, height: number, options?: { send?: boolean }): DredlessClient;
|
|
451
|
+
setScreenSize(width: number, height: number, options?: { send?: boolean }): DredlessClient;
|
|
452
|
+
setWrenchMode(mode: WrenchMode, options?: { send?: boolean }): DredlessClient;
|
|
453
|
+
setTurretMode(mode: TurretMode, options?: { send?: boolean }): DredlessClient;
|
|
454
|
+
}
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
### Input setting shapes
|
|
458
|
+
|
|
459
|
+
```ts
|
|
460
|
+
const WrenchMode = { DropAllItems: "drop-all-items", GrabPrimaryItems: "grab-primary-items", GrabAllItems: "grab-all-items" } as const;
|
|
461
|
+
type WrenchMode = typeof WrenchMode[keyof typeof WrenchMode];
|
|
462
|
+
|
|
463
|
+
const TurretMode = { ContinuousFire: "continuous-fire", VolleyFire: "volley-fire" } as const;
|
|
464
|
+
type TurretMode = typeof TurretMode[keyof typeof TurretMode];
|
|
465
|
+
|
|
466
|
+
interface InputSettings {
|
|
467
|
+
wrenchMode?: WrenchMode;
|
|
468
|
+
turretMode?: TurretMode;
|
|
469
|
+
viewWidth?: number;
|
|
470
|
+
viewHeight?: number;
|
|
471
|
+
screenWidth?: number;
|
|
472
|
+
screenHeight?: number;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
interface CurrentInputSettings {
|
|
476
|
+
wrenchMode: "drop-all-items" | "grab-primary-items" | "grab-all-items" | null;
|
|
477
|
+
turretMode: "continuous-fire" | "volley-fire" | null;
|
|
478
|
+
viewWidth: number | null;
|
|
479
|
+
viewHeight: number | null;
|
|
480
|
+
screenWidth: number | null;
|
|
481
|
+
screenHeight: number | null;
|
|
482
|
+
}
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
### `client.inventory`
|
|
486
|
+
|
|
487
|
+
Inventory read and slot movement domain.
|
|
488
|
+
|
|
489
|
+
```ts
|
|
490
|
+
type InventoryArea = "all" | "hotbar" | "equipment";
|
|
491
|
+
type InventorySlotRef = number | EquipmentSlot | InventorySlotHandle | InventorySlotSnapshot;
|
|
492
|
+
const EquipmentSlot = { Head: "head", Face: "face", Body: "body", Back: "back", Hands: "hands", Feet: "feet" } as const;
|
|
493
|
+
type EquipmentSlot = typeof EquipmentSlot[keyof typeof EquipmentSlot];
|
|
494
|
+
|
|
495
|
+
interface InventoryDomain {
|
|
496
|
+
state(): InventoryState | null;
|
|
497
|
+
hotbarSize(): number;
|
|
498
|
+
allSlots(): InventorySlotHandle[];
|
|
499
|
+
slot(ref: InventorySlotRef): InventorySlotHandle;
|
|
500
|
+
hotbarSlots(): InventorySlotHandle[];
|
|
501
|
+
equipmentSlots(): { head: InventorySlotHandle; face: InventorySlotHandle; body: InventorySlotHandle; back: InventorySlotHandle; hands: InventorySlotHandle; feet: InventorySlotHandle };
|
|
502
|
+
findItem(itemId: number, options?: { area?: InventoryArea }): InventorySlotHandle | null;
|
|
503
|
+
findItems(itemId: number, options?: { area?: InventoryArea }): InventorySlotHandle[];
|
|
504
|
+
firstEmpty(options?: { area?: InventoryArea }): InventorySlotHandle | null;
|
|
505
|
+
move(source: InventorySlotRef, target: InventorySlotRef, options?: { split?: boolean }, command?: Command): DredlessClient;
|
|
506
|
+
equip(source: InventorySlotRef, equipmentSlot?: EquipmentSlot | { split?: boolean }, options?: { split?: boolean } | Command, command?: Command): DredlessClient;
|
|
507
|
+
unequip(equipmentSlot: EquipmentSlot, target?: InventorySlotRef, options?: { split?: boolean }, command?: Command): DredlessClient;
|
|
508
|
+
select(slot: InventorySlotRef, command?: Command): DredlessClient;
|
|
509
|
+
}
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
Slot handles expose live slot reads and convenience actions:
|
|
513
|
+
|
|
514
|
+
```ts
|
|
515
|
+
interface InventorySlotHandle {
|
|
516
|
+
index: number;
|
|
517
|
+
kind: "hotbar" | "equipment" | null;
|
|
518
|
+
equipmentSlot: "head" | "face" | "body" | "back" | "hands" | "feet" | null;
|
|
519
|
+
itemId: number | null;
|
|
520
|
+
itemName: string | null;
|
|
521
|
+
count: number;
|
|
522
|
+
empty: boolean;
|
|
523
|
+
exists(): boolean;
|
|
524
|
+
snapshot(): InventorySlotSnapshot | null;
|
|
525
|
+
moveTo(target: InventorySlotRef, options?: { split?: boolean }, command?: Command): DredlessClient;
|
|
526
|
+
equip(equipmentSlot?: EquipmentSlot | { split?: boolean }, options?: { split?: boolean } | Command, command?: Command): DredlessClient;
|
|
527
|
+
unequip(target?: InventorySlotRef, options?: { split?: boolean }, command?: Command): DredlessClient;
|
|
528
|
+
select(command?: Command): DredlessClient;
|
|
529
|
+
}
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
Inventory state is normalized and does not expose raw `items`, `item_counts`, or `general_slots` arrays. `hotbarSize` is the protocol-provided hotbar slot count from `general_slots`; equipment slots are separate fixed absolute indexes (`16`, `17`, `18`, `19`, `20`, `21`). `equip()` may omit the equipment slot; in that case it infers the target from the item schema and throws if the source slot is empty or the item is not equipment.
|
|
533
|
+
|
|
534
|
+
```ts
|
|
535
|
+
interface InventorySlotSnapshot {
|
|
536
|
+
index: number;
|
|
537
|
+
itemId: number | null;
|
|
538
|
+
itemName: string | null;
|
|
539
|
+
count: number;
|
|
540
|
+
kind: "hotbar" | "equipment";
|
|
541
|
+
equipmentSlot: "head" | "face" | "body" | "back" | "hands" | "feet" | null;
|
|
542
|
+
empty: boolean;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
interface InventoryState {
|
|
546
|
+
type: "inventory";
|
|
547
|
+
filter?: number;
|
|
548
|
+
hotbarSize: number;
|
|
549
|
+
slots: InventorySlotSnapshot[];
|
|
550
|
+
hotbar: InventorySlotSnapshot[];
|
|
551
|
+
equipment: {
|
|
552
|
+
head: InventorySlotSnapshot;
|
|
553
|
+
face: InventorySlotSnapshot;
|
|
554
|
+
body: InventorySlotSnapshot;
|
|
555
|
+
back: InventorySlotSnapshot;
|
|
556
|
+
hands: InventorySlotSnapshot;
|
|
557
|
+
feet: InventorySlotSnapshot;
|
|
558
|
+
};
|
|
559
|
+
}
|
|
560
|
+
```
|
|
561
|
+
### `client.management`
|
|
562
|
+
|
|
563
|
+
Ship-management command and state domain.
|
|
564
|
+
|
|
565
|
+
```ts
|
|
566
|
+
interface ShipManagementDomain {
|
|
567
|
+
requestPlayerList(): DredlessClient;
|
|
568
|
+
resetInvite(): DredlessClient;
|
|
569
|
+
setPrivacy(privacy: ShipPrivacy): DredlessClient;
|
|
570
|
+
recoverStarterItem(itemId: number): DredlessClient;
|
|
571
|
+
setPlayerRank(refId: number, rank: ShipPlayerRank): DredlessClient;
|
|
572
|
+
kickPlayer(refId: number): DredlessClient;
|
|
573
|
+
banPlayer(refId: number): DredlessClient;
|
|
574
|
+
demoteSelf(): DredlessClient;
|
|
575
|
+
config(): ShipConfig | null;
|
|
576
|
+
hasCheats(): boolean;
|
|
577
|
+
playerList(): ShipPlayerList | null;
|
|
578
|
+
}
|
|
579
|
+
```
|
|
580
|
+
|
|
581
|
+
Input aliases:
|
|
582
|
+
|
|
583
|
+
```ts
|
|
584
|
+
type ShipPrivacy = 0 | 1 | boolean | "public" | "private";
|
|
585
|
+
type ShipPlayerRank = 0 | 1 | 3 | "guest" | "crew" | "captain";
|
|
586
|
+
type PlayerShipRank = "guest" | "crew" | "crew-invite-pending-deprecated" | "captain" | "banned";
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
Output shapes:
|
|
590
|
+
|
|
591
|
+
```ts
|
|
592
|
+
interface ShipConfig {
|
|
593
|
+
privacy: number | null;
|
|
594
|
+
privacyName: "public" | "private" | null;
|
|
595
|
+
inviteKey: string | null;
|
|
596
|
+
teamId: number | null;
|
|
597
|
+
patronPerks: unknown[];
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
interface CaptainSubrank {
|
|
601
|
+
subrank: number | null;
|
|
602
|
+
enableCheats: boolean;
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
interface CurrentPlayerRank {
|
|
606
|
+
shipRank: PlayerShipRank | null;
|
|
607
|
+
subrank: number | null;
|
|
608
|
+
isCaptain: boolean;
|
|
609
|
+
patronTier: "bronze" | "silver" | "gold" | "plat" | "flux" | null;
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
interface PlayerListEntry {
|
|
613
|
+
refId: number | null;
|
|
614
|
+
discrim: string | null;
|
|
615
|
+
discrimColor: number | null;
|
|
616
|
+
teamRank: number | null;
|
|
617
|
+
captainRank: number | null;
|
|
618
|
+
isCaptain: boolean;
|
|
619
|
+
isShipOwner: boolean;
|
|
620
|
+
canBeManaged: boolean;
|
|
621
|
+
time: number | null;
|
|
622
|
+
items: unknown[];
|
|
623
|
+
aliasDiscrims: unknown[];
|
|
624
|
+
extraAliasCount: number;
|
|
625
|
+
onlineCount: number | null;
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
interface ShipPlayerList {
|
|
629
|
+
ownerCaptainRank: number | null;
|
|
630
|
+
shipOwners: PlayerListEntry[];
|
|
631
|
+
players: PlayerListEntry[];
|
|
632
|
+
changes: PlayerListEntry[];
|
|
633
|
+
removedPlayers: number[];
|
|
634
|
+
}
|
|
635
|
+
```
|
|
636
|
+
|
|
637
|
+
## World Domains
|
|
638
|
+
|
|
639
|
+
### `WorldDomain`
|
|
640
|
+
|
|
641
|
+
Available from `client.currentShip()`, `client.overworld()`, and
|
|
642
|
+
`client.world(id)`.
|
|
643
|
+
|
|
644
|
+
```ts
|
|
645
|
+
interface WorldDomain {
|
|
646
|
+
id: number | null;
|
|
647
|
+
entities: EntityCollection;
|
|
648
|
+
machines: MachineCollection;
|
|
649
|
+
players: PlayerCollection;
|
|
650
|
+
blocks: BlockCollection;
|
|
651
|
+
materials: MaterialCollection;
|
|
652
|
+
exists(): boolean;
|
|
653
|
+
snapshot(options?: { includeTiles?: boolean; includeModel?: boolean }): WorldSnapshot | null;
|
|
654
|
+
}
|
|
655
|
+
```
|
|
656
|
+
|
|
657
|
+
### `ShipDomain`
|
|
658
|
+
|
|
659
|
+
```ts
|
|
660
|
+
interface ShipDomain extends WorldDomain {
|
|
661
|
+
metadata: ShipWorldMetadataSummary | null;
|
|
662
|
+
entity(): EntityHandle | null;
|
|
663
|
+
overworldEntity: EntityHandle | null;
|
|
664
|
+
}
|
|
665
|
+
```
|
|
666
|
+
|
|
667
|
+
`entity()` returns the current ship's overworld entity handle, not a ship-world
|
|
668
|
+
placed entity.
|
|
669
|
+
|
|
670
|
+
### `OverworldDomain`
|
|
671
|
+
|
|
672
|
+
```ts
|
|
673
|
+
interface OverworldDomain extends WorldDomain {
|
|
674
|
+
ships(options?: ShipReadOptions): ShipHandle[];
|
|
675
|
+
shipByHex(hexCode: string, options?: ShipReadOptions): ShipHandle | null;
|
|
676
|
+
shipByEntity(entity: number | EntityHandle | EntitySummary, options?: ShipReadOptions): ShipHandle | null;
|
|
677
|
+
}
|
|
678
|
+
```
|
|
679
|
+
|
|
680
|
+
Ship read options:
|
|
681
|
+
|
|
682
|
+
```ts
|
|
683
|
+
interface ShipReadOptions {
|
|
684
|
+
includeWorld?: boolean;
|
|
685
|
+
includeTiles?: boolean;
|
|
686
|
+
includeModel?: boolean;
|
|
687
|
+
sort?: "distance" | null;
|
|
688
|
+
}
|
|
689
|
+
```
|
|
690
|
+
|
|
691
|
+
## Entity API
|
|
692
|
+
|
|
693
|
+
Entity ids are scoped to their world. Overworld entities and ship-world entities
|
|
694
|
+
do not share one global id pool.
|
|
695
|
+
|
|
696
|
+
### `EntityCollection`
|
|
697
|
+
|
|
698
|
+
```ts
|
|
699
|
+
interface EntityCollection {
|
|
700
|
+
all(): EntityHandle[];
|
|
701
|
+
snapshots(): EntitySnapshot[];
|
|
702
|
+
states(): EntitySnapshot[];
|
|
703
|
+
raw(): EntitySummary[];
|
|
704
|
+
get(entity: number | EntityHandle | EntitySummary): EntityHandle;
|
|
705
|
+
}
|
|
706
|
+
```
|
|
707
|
+
|
|
708
|
+
Use:
|
|
709
|
+
|
|
710
|
+
```js
|
|
711
|
+
const shipEntity = client.currentShip().entities.get(14);
|
|
712
|
+
const overworldEntity = client.overworld().entities.get(2495754);
|
|
713
|
+
```
|
|
714
|
+
|
|
715
|
+
Costs:
|
|
716
|
+
|
|
717
|
+
```txt
|
|
718
|
+
all() -> creates lightweight handles
|
|
719
|
+
raw() -> returns current summary objects
|
|
720
|
+
snapshots() -> clones and freezes summaries
|
|
721
|
+
states() -> alias of snapshots()
|
|
722
|
+
get(id) -> creates one lightweight handle
|
|
723
|
+
```
|
|
724
|
+
|
|
725
|
+
### `EntityHandle`
|
|
726
|
+
|
|
727
|
+
```ts
|
|
728
|
+
interface EntityHandle {
|
|
729
|
+
/** @deprecated Use id. */
|
|
730
|
+
entity: number;
|
|
731
|
+
id: number;
|
|
732
|
+
position: TransformSummary | null;
|
|
733
|
+
health: HealthSummary | null;
|
|
734
|
+
contents: EntityContentsSummary | null;
|
|
735
|
+
exists(): boolean;
|
|
736
|
+
snapshot(): EntitySnapshot | null;
|
|
737
|
+
is(type: EntityTypeName): boolean;
|
|
738
|
+
has(feature: EntityFeatureName): boolean;
|
|
739
|
+
feature(feature: EntityFeatureName): unknown | null;
|
|
740
|
+
as(type: EntityTypeName): MachineHandle | null;
|
|
741
|
+
asLoader(): LoaderHandle | null;
|
|
742
|
+
asPusher(): PusherHandle | null;
|
|
743
|
+
asLauncher(): LauncherHandle | null;
|
|
744
|
+
asNavigationUnit(): NavigationUnitHandle | null;
|
|
745
|
+
asCommsStation(): CommsStationHandle | null;
|
|
746
|
+
asSign(): SignHandle | null;
|
|
747
|
+
asGenerator(): GeneratorHandle | null;
|
|
748
|
+
asCargoHatch(): CargoHatchHandle | null;
|
|
749
|
+
asCannon(): CannonHandle | null;
|
|
750
|
+
asThruster(): ThrusterHandle | null;
|
|
751
|
+
asHelm(): HelmHandle | null;
|
|
752
|
+
asDoor(): DoorHandle | null;
|
|
753
|
+
asSpawnPoint(): SpawnPointHandle | null;
|
|
754
|
+
asShieldProjector(): ShieldProjectorHandle | null;
|
|
755
|
+
asFluidTank(): FluidTankHandle | null;
|
|
756
|
+
asCargoEjector(): CargoEjectorHandle | null;
|
|
757
|
+
asExpandoBox(): ExpandoBoxHandle | null;
|
|
758
|
+
use(options?: { invSlot?: number; hold?: boolean }, command?: Command): DredlessClient;
|
|
759
|
+
}
|
|
760
|
+
```
|
|
761
|
+
|
|
762
|
+
### `EntitySnapshot`
|
|
763
|
+
|
|
764
|
+
Frozen point-in-time entity read.
|
|
765
|
+
|
|
766
|
+
```ts
|
|
767
|
+
interface EntitySnapshot extends EntitySummary {
|
|
768
|
+
id: number;
|
|
769
|
+
position: TransformSummary | null;
|
|
770
|
+
rotation: number | null;
|
|
771
|
+
type: EntitySnapshotType;
|
|
772
|
+
is(type: EntityTypeName): boolean;
|
|
773
|
+
has(feature: EntityFeatureName): boolean;
|
|
774
|
+
feature(feature: EntityFeatureName): unknown | null;
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
interface EntitySnapshotType {
|
|
778
|
+
category: EntitySummary["category"] | null;
|
|
779
|
+
machine: string | null;
|
|
780
|
+
item: string | null;
|
|
781
|
+
components: string[];
|
|
782
|
+
}
|
|
783
|
+
```
|
|
784
|
+
|
|
785
|
+
### `EntitySummary`
|
|
786
|
+
|
|
787
|
+
Raw normalized entity shape.
|
|
788
|
+
|
|
789
|
+
```ts
|
|
790
|
+
interface EntitySummary {
|
|
791
|
+
entity: number;
|
|
792
|
+
category:
|
|
793
|
+
| "placed_entity"
|
|
794
|
+
| "loose_item"
|
|
795
|
+
| "untyped_holder"
|
|
796
|
+
| "metadata"
|
|
797
|
+
| "player"
|
|
798
|
+
| "ship_control"
|
|
799
|
+
| "blueprint_preview"
|
|
800
|
+
| "entity";
|
|
801
|
+
typeId: number | null;
|
|
802
|
+
typeName: string | null;
|
|
803
|
+
markerTypeId: number | null;
|
|
804
|
+
markerTypeName: string | null;
|
|
805
|
+
label: string;
|
|
806
|
+
kind: string[];
|
|
807
|
+
transform: TransformSummary | null;
|
|
808
|
+
footprint: {
|
|
809
|
+
width: number;
|
|
810
|
+
height: number;
|
|
811
|
+
source:
|
|
812
|
+
| "type"
|
|
813
|
+
| "marker"
|
|
814
|
+
| "heuristic"
|
|
815
|
+
| "default"
|
|
816
|
+
| "crate"
|
|
817
|
+
| "huge_thruster"
|
|
818
|
+
| "hover_outline";
|
|
819
|
+
};
|
|
820
|
+
contents: EntityContentsSummary | null;
|
|
821
|
+
occupies: { x: number; y: number }[];
|
|
822
|
+
tables: { tableId: number; name: string | null; record: ModelRecord }[];
|
|
823
|
+
}
|
|
824
|
+
```
|
|
825
|
+
|
|
826
|
+
### `EntityContentsSummary`
|
|
827
|
+
|
|
828
|
+
Feature/component container for an entity.
|
|
829
|
+
|
|
830
|
+
```ts
|
|
831
|
+
interface EntityContentsSummary {
|
|
832
|
+
itemHolder?: ItemHolderSummary;
|
|
833
|
+
expandoBox?: ExpandoBoxSummary;
|
|
834
|
+
hoverOutline?: HoverOutlineSummary;
|
|
835
|
+
mapMarker?: MapMarkerSummary;
|
|
836
|
+
dockingSpring?: DockingSpringSummary;
|
|
837
|
+
hugeThruster?: HugeThrusterSummary;
|
|
838
|
+
blueprintPreview?: BlueprintPreviewSummary;
|
|
839
|
+
itemCrate?: ItemCrateSummary;
|
|
840
|
+
health?: HealthSummary;
|
|
841
|
+
bot?: BotSummary;
|
|
842
|
+
fabricator?: FabricatorSummary;
|
|
843
|
+
cargoEjector?: CargoEjectorSummary;
|
|
844
|
+
cannon?: CannonSummary;
|
|
845
|
+
thruster?: ThrusterSummary;
|
|
846
|
+
pusher?: PusherSummary;
|
|
847
|
+
pusherBeam?: PusherBeamSummary;
|
|
848
|
+
launcher?: LauncherSummary;
|
|
849
|
+
loader?: LoaderSummary;
|
|
850
|
+
cargoHatch?: CargoHatchSummary;
|
|
851
|
+
navigationUnit?: NavigationUnitSummary;
|
|
852
|
+
commsStation?: CommsStationSummary;
|
|
853
|
+
fluidTank?: FluidTankSummary;
|
|
854
|
+
shieldGenerator?: ShieldGeneratorSummary;
|
|
855
|
+
shieldProjector?: ShieldProjectorSummary;
|
|
856
|
+
helm?: HelmSummary;
|
|
857
|
+
player?: PlayerSummary;
|
|
858
|
+
shipControl?: ShipControlSummary;
|
|
859
|
+
sign?: SignSummary;
|
|
860
|
+
spawnPoint?: SpawnPointSummary;
|
|
861
|
+
door?: DoorSummary;
|
|
862
|
+
shipSize?: ShipSizeSummary;
|
|
863
|
+
}
|
|
864
|
+
```
|
|
865
|
+
|
|
866
|
+
Feature lookup accepts the canonical component names above and selected aliases
|
|
867
|
+
such as `outline`, `beam`, `inventory`, `filter`, `filterMode`, `filterSlots`,
|
|
868
|
+
`occupied`, `mapMarker`, and `blueprint`.
|
|
869
|
+
|
|
870
|
+
## Machine API
|
|
871
|
+
|
|
872
|
+
### `MachineCollection`
|
|
873
|
+
|
|
874
|
+
```ts
|
|
875
|
+
interface MachineCollection {
|
|
876
|
+
state(): MachineSummary;
|
|
877
|
+
raw(): MachineSummary;
|
|
878
|
+
loaders(): LoaderHandle[];
|
|
879
|
+
loader(entity: number | EntityHandle | EntitySummary): LoaderHandle;
|
|
880
|
+
pushers(): PusherHandle[];
|
|
881
|
+
pusher(entity: number | EntityHandle | EntitySummary): PusherHandle;
|
|
882
|
+
launchers(): LauncherHandle[];
|
|
883
|
+
launcher(entity: number | EntityHandle | EntitySummary): LauncherHandle;
|
|
884
|
+
navigationUnits(): NavigationUnitHandle[];
|
|
885
|
+
navigationUnit(entity?: number | EntityHandle | EntitySummary | null): NavigationUnitHandle | null;
|
|
886
|
+
fabricators(): FabricatorHandle[];
|
|
887
|
+
fabricator(entity: number | EntityHandle | EntitySummary): FabricatorHandle;
|
|
888
|
+
commsStations(): CommsStationHandle[];
|
|
889
|
+
commsStation(entity?: number | EntityHandle | EntitySummary | null): CommsStationHandle | null;
|
|
890
|
+
signs(): SignHandle[];
|
|
891
|
+
sign(entity: number | EntityHandle | EntitySummary): SignHandle;
|
|
892
|
+
generators(): GeneratorHandle[];
|
|
893
|
+
generator(entity: number | EntityHandle | EntitySummary): GeneratorHandle;
|
|
894
|
+
cargoHatches(): CargoHatchHandle[];
|
|
895
|
+
cargoHatch(entity: number | EntityHandle | EntitySummary): CargoHatchHandle;
|
|
896
|
+
cargoEjectors(): CargoEjectorHandle[];
|
|
897
|
+
cargoEjector(entity: number | EntityHandle | EntitySummary): CargoEjectorHandle;
|
|
898
|
+
cannons(): CannonHandle[];
|
|
899
|
+
cannon(entity: number | EntityHandle | EntitySummary): CannonHandle;
|
|
900
|
+
thrusters(): ThrusterHandle[];
|
|
901
|
+
thruster(entity: number | EntityHandle | EntitySummary): ThrusterHandle;
|
|
902
|
+
helms(): HelmHandle[];
|
|
903
|
+
helm(entity: number | EntityHandle | EntitySummary): HelmHandle;
|
|
904
|
+
doors(): DoorHandle[];
|
|
905
|
+
door(entity: number | EntityHandle | EntitySummary): DoorHandle;
|
|
906
|
+
spawnPoints(): SpawnPointHandle[];
|
|
907
|
+
spawnPoint(entity: number | EntityHandle | EntitySummary): SpawnPointHandle;
|
|
908
|
+
shieldProjectors(): ShieldProjectorHandle[];
|
|
909
|
+
shieldProjector(entity: number | EntityHandle | EntitySummary): ShieldProjectorHandle;
|
|
910
|
+
fluidTanks(): FluidTankHandle[];
|
|
911
|
+
fluidTank(entity: number | EntityHandle | EntitySummary): FluidTankHandle;
|
|
912
|
+
expandoBoxes(): ExpandoBoxHandle[];
|
|
913
|
+
expandoBox(entity: number | EntityHandle | EntitySummary): ExpandoBoxHandle;
|
|
914
|
+
}
|
|
915
|
+
```
|
|
916
|
+
|
|
917
|
+
### `MachineSummary`
|
|
918
|
+
|
|
919
|
+
Grouped machine/component state.
|
|
920
|
+
|
|
921
|
+
```ts
|
|
922
|
+
interface MachineSummary {
|
|
923
|
+
itemHolders: ItemHolderSummary[];
|
|
924
|
+
health: HealthSummary[];
|
|
925
|
+
fabricators: FabricatorSummary[];
|
|
926
|
+
cargoEjectors: CargoEjectorSummary[];
|
|
927
|
+
cannons: CannonSummary[];
|
|
928
|
+
thrusters: ThrusterSummary[];
|
|
929
|
+
pushers: PusherSummary[];
|
|
930
|
+
pusherBeams: PusherBeamSummary[];
|
|
931
|
+
launchers: LauncherSummary[];
|
|
932
|
+
loaders: LoaderSummary[];
|
|
933
|
+
cargoHatches: CargoHatchSummary[];
|
|
934
|
+
navigationUnits: NavigationUnitSummary[];
|
|
935
|
+
commsStations: CommsStationSummary[];
|
|
936
|
+
fluidTanks: FluidTankSummary[];
|
|
937
|
+
shieldGenerators: ShieldGeneratorSummary[];
|
|
938
|
+
shieldProjectors: ShieldProjectorSummary[];
|
|
939
|
+
helms: HelmSummary[];
|
|
940
|
+
signs: SignSummary[];
|
|
941
|
+
spawnPoints: SpawnPointSummary[];
|
|
942
|
+
doors: DoorSummary[];
|
|
943
|
+
expandoBoxes: ExpandoBoxSummary[];
|
|
944
|
+
}
|
|
945
|
+
```
|
|
946
|
+
|
|
947
|
+
### Common machine handle
|
|
948
|
+
|
|
949
|
+
```ts
|
|
950
|
+
interface MachineHandle extends EntityHandle {
|
|
951
|
+
open(options?: { invSlot?: number; hold?: boolean }, command?: Command): DredlessClient;
|
|
952
|
+
}
|
|
953
|
+
```
|
|
954
|
+
|
|
955
|
+
`open()` focuses/uses the entity through the player command path.
|
|
956
|
+
|
|
957
|
+
### `LoaderHandle`
|
|
958
|
+
|
|
959
|
+
```ts
|
|
960
|
+
interface LoaderHandle extends MachineHandle {
|
|
961
|
+
state: LoaderSummary | null;
|
|
962
|
+
configure(config?: LoaderConfig): DredlessClient;
|
|
963
|
+
configureFull(config?: LoaderFullConfig): DredlessClient;
|
|
964
|
+
copy(config?: LoaderFullConfig): DredlessClient;
|
|
965
|
+
setPickPlace(pick: LoaderPosition, place: LoaderPosition, config?: LoaderConfig): DredlessClient;
|
|
966
|
+
setPriority(priority: LoaderPriority, config?: LoaderConfig): DredlessClient;
|
|
967
|
+
setStack(stack: number, config?: LoaderConfig): DredlessClient;
|
|
968
|
+
setCycle(cycle: number, config?: LoaderConfig): DredlessClient;
|
|
969
|
+
setRequireOutput(requireOutput: boolean, config?: LoaderConfig): DredlessClient;
|
|
970
|
+
setWaitForStack(waitForStack: boolean, config?: LoaderConfig): DredlessClient;
|
|
971
|
+
setFilterMode(filterMode: LoaderFilterMode): DredlessClient;
|
|
972
|
+
setFilterItems(filterSlots?: Array<number | null | undefined>): DredlessClient;
|
|
973
|
+
pick: number | undefined;
|
|
974
|
+
place: number | undefined;
|
|
975
|
+
priority: number | undefined;
|
|
976
|
+
stack: number | undefined;
|
|
977
|
+
cycle: number | undefined;
|
|
978
|
+
requireOutput: boolean | undefined;
|
|
979
|
+
waitForStack: boolean | undefined;
|
|
980
|
+
filterMode: number | undefined;
|
|
981
|
+
filterSlots: Array<number | null>;
|
|
982
|
+
}
|
|
983
|
+
```
|
|
984
|
+
|
|
985
|
+
Config inputs:
|
|
986
|
+
|
|
987
|
+
```ts
|
|
988
|
+
const LoaderPosition = { TopLeft: "top-left", TopMiddle: "top-middle", TopRight: "top-right", MiddleLeft: "middle-left", MiddleRight: "middle-right", BottomLeft: "bottom-left", BottomMiddle: "bottom-middle", BottomRight: "bottom-right" } as const;
|
|
989
|
+
type LoaderPosition = typeof LoaderPosition[keyof typeof LoaderPosition];
|
|
990
|
+
|
|
991
|
+
const LoaderPriority = { Low: "low", Normal: "normal", High: "high" } as const;
|
|
992
|
+
type LoaderPriority = typeof LoaderPriority[keyof typeof LoaderPriority];
|
|
993
|
+
|
|
994
|
+
const LoaderFilterMode = { AllowAll: "allow-all", BlockFilter: "block-filter", AllowFilter: "allow-filter", BlockAll: "block-all" } as const;
|
|
995
|
+
type LoaderFilterMode = typeof LoaderFilterMode[keyof typeof LoaderFilterMode];
|
|
996
|
+
|
|
997
|
+
interface LoaderConfig {
|
|
998
|
+
pick?: LoaderPosition;
|
|
999
|
+
place?: LoaderPosition;
|
|
1000
|
+
priority?: LoaderPriority;
|
|
1001
|
+
stack?: number;
|
|
1002
|
+
cycle?: number;
|
|
1003
|
+
requireOutput?: boolean;
|
|
1004
|
+
waitForStack?: boolean;
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
interface LoaderFullConfig extends LoaderConfig {
|
|
1008
|
+
filterMode?: LoaderFilterMode;
|
|
1009
|
+
filterSlots?: Array<number | null | undefined>;
|
|
1010
|
+
}
|
|
1011
|
+
```
|
|
1012
|
+
|
|
1013
|
+
State output:
|
|
1014
|
+
|
|
1015
|
+
```ts
|
|
1016
|
+
interface LoaderSummary {
|
|
1017
|
+
entity: number;
|
|
1018
|
+
pick: number | null;
|
|
1019
|
+
pickName: string | null;
|
|
1020
|
+
place: number | null;
|
|
1021
|
+
placeName: string | null;
|
|
1022
|
+
priority: number | null;
|
|
1023
|
+
priorityName: string | null;
|
|
1024
|
+
requireOutput: boolean | null;
|
|
1025
|
+
waitForStack: boolean | null;
|
|
1026
|
+
stack: number | null;
|
|
1027
|
+
cycle: number | null;
|
|
1028
|
+
filterMode: number | null;
|
|
1029
|
+
filterModeName: string | null;
|
|
1030
|
+
filterSlots: (number | null)[] | null;
|
|
1031
|
+
heldItemId: number | null;
|
|
1032
|
+
heldItemName: string | null;
|
|
1033
|
+
heldCount: number | null;
|
|
1034
|
+
active: boolean;
|
|
1035
|
+
progress: number | null;
|
|
1036
|
+
state: ModelRecord;
|
|
1037
|
+
filterState: ModelRecord;
|
|
1038
|
+
filterSlotsState: ModelRecord;
|
|
1039
|
+
}
|
|
1040
|
+
```
|
|
1041
|
+
|
|
1042
|
+
### `PusherHandle`
|
|
1043
|
+
|
|
1044
|
+
```ts
|
|
1045
|
+
interface PusherHandle extends MachineHandle {
|
|
1046
|
+
state: PusherSummary | null;
|
|
1047
|
+
beam: PusherBeamSummary | null;
|
|
1048
|
+
configure(config?: PusherConfig): DredlessClient;
|
|
1049
|
+
setAngle(angle: number, config?: PusherConfig): DredlessClient;
|
|
1050
|
+
setSpeed(speed: number, config?: PusherConfig): DredlessClient;
|
|
1051
|
+
setLength(length: number, config?: PusherConfig): DredlessClient;
|
|
1052
|
+
setMode(mode: PusherMode, config?: PusherConfig): DredlessClient;
|
|
1053
|
+
setFilteredMode(mode: PusherMode, config?: PusherConfig): DredlessClient;
|
|
1054
|
+
setFilterInventory(filterInventory: boolean, config?: PusherConfig): DredlessClient;
|
|
1055
|
+
setFilterItems(filterSlots?: Array<number | null | undefined>): DredlessClient;
|
|
1056
|
+
angle: number | undefined;
|
|
1057
|
+
speed: number | undefined;
|
|
1058
|
+
length: number | undefined;
|
|
1059
|
+
mode: number | undefined;
|
|
1060
|
+
filteredMode: number | undefined;
|
|
1061
|
+
}
|
|
1062
|
+
```
|
|
1063
|
+
|
|
1064
|
+
Config input:
|
|
1065
|
+
|
|
1066
|
+
```ts
|
|
1067
|
+
const PusherMode = { Push: "push", Pull: "pull", DoNothing: "do-nothing" } as const;
|
|
1068
|
+
type PusherMode = typeof PusherMode[keyof typeof PusherMode];
|
|
1069
|
+
|
|
1070
|
+
interface PusherConfig {
|
|
1071
|
+
mode?: PusherMode;
|
|
1072
|
+
filteredMode?: PusherMode;
|
|
1073
|
+
angle?: number;
|
|
1074
|
+
speed?: number;
|
|
1075
|
+
filterInventory?: boolean;
|
|
1076
|
+
length?: number;
|
|
1077
|
+
}
|
|
1078
|
+
```
|
|
1079
|
+
|
|
1080
|
+
State output:
|
|
1081
|
+
|
|
1082
|
+
```ts
|
|
1083
|
+
interface PusherSummary {
|
|
1084
|
+
entity: number;
|
|
1085
|
+
mode: number;
|
|
1086
|
+
modeName: string | null;
|
|
1087
|
+
filteredMode: number;
|
|
1088
|
+
filteredModeName: string | null;
|
|
1089
|
+
angle: number | null;
|
|
1090
|
+
speed: number;
|
|
1091
|
+
length: number;
|
|
1092
|
+
filterInventory: boolean;
|
|
1093
|
+
filterSlots: (number | null)[] | null;
|
|
1094
|
+
state: ModelRecord;
|
|
1095
|
+
filterSlotsState: ModelRecord;
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
interface PusherBeamSummary {
|
|
1099
|
+
entity: number;
|
|
1100
|
+
active: boolean;
|
|
1101
|
+
mode: number;
|
|
1102
|
+
modeName: string | null;
|
|
1103
|
+
lengthRaw: number;
|
|
1104
|
+
length: number;
|
|
1105
|
+
state: ModelRecord;
|
|
1106
|
+
}
|
|
1107
|
+
```
|
|
1108
|
+
|
|
1109
|
+
Pusher beams are associated with the same entity as their parent pusher, exposed
|
|
1110
|
+
as `pusher.beam`, `entity.feature("beam")`, and `machines.state().pusherBeams`.
|
|
1111
|
+
|
|
1112
|
+
### `LauncherHandle`
|
|
1113
|
+
|
|
1114
|
+
```ts
|
|
1115
|
+
interface LauncherHandle extends MachineHandle {
|
|
1116
|
+
state: LauncherSummary | null;
|
|
1117
|
+
setAngle(angle: number): DredlessClient;
|
|
1118
|
+
setPower(power: number): DredlessClient;
|
|
1119
|
+
angleDegrees: number | undefined;
|
|
1120
|
+
angleRadians: number | undefined;
|
|
1121
|
+
angleRaw: number | null | undefined;
|
|
1122
|
+
}
|
|
1123
|
+
|
|
1124
|
+
interface LauncherSummary {
|
|
1125
|
+
entity: number;
|
|
1126
|
+
angleRaw: number | null;
|
|
1127
|
+
angleRadians: number | null;
|
|
1128
|
+
angleDegrees: number | null;
|
|
1129
|
+
state: ModelRecord;
|
|
1130
|
+
}
|
|
1131
|
+
```
|
|
1132
|
+
|
|
1133
|
+
Launcher power may not be present until the relevant UI has exposed it.
|
|
1134
|
+
|
|
1135
|
+
### `NavigationUnitHandle`
|
|
1136
|
+
|
|
1137
|
+
```ts
|
|
1138
|
+
interface NavigationUnitHandle extends MachineHandle {
|
|
1139
|
+
state: NavigationUnitSummary | null;
|
|
1140
|
+
configure(config?: NavigationUnitConfig): DredlessClient;
|
|
1141
|
+
copy(config?: NavigationUnitConfig): DredlessClient;
|
|
1142
|
+
paste(config?: NavigationUnitConfig): DredlessClient;
|
|
1143
|
+
setDestination(destination: number, config?: NavigationUnitConfig): DredlessClient;
|
|
1144
|
+
setAutoWarp(config?: NavigationUnitConfig): DredlessClient;
|
|
1145
|
+
startWarp(config?: NavigationUnitConfig): DredlessClient;
|
|
1146
|
+
cancelWarp(config?: NavigationUnitConfig): DredlessClient;
|
|
1147
|
+
destination: number | undefined;
|
|
1148
|
+
autoWarpOnShieldFailure: boolean | undefined;
|
|
1149
|
+
autoWarpOnNoCaptains: boolean | undefined;
|
|
1150
|
+
warp: string | undefined;
|
|
1151
|
+
}
|
|
1152
|
+
```
|
|
1153
|
+
|
|
1154
|
+
Config and state:
|
|
1155
|
+
|
|
1156
|
+
```ts
|
|
1157
|
+
interface NavigationUnitConfig {
|
|
1158
|
+
destination?: number;
|
|
1159
|
+
page?: number;
|
|
1160
|
+
warp?: boolean | "start" | "idle" | "cancel";
|
|
1161
|
+
autoWarpOnShieldFailure?: boolean;
|
|
1162
|
+
autoWarpOnNoCaptains?: boolean;
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1165
|
+
interface NavigationUnitSummary {
|
|
1166
|
+
entity: number;
|
|
1167
|
+
destination: number;
|
|
1168
|
+
destinationName: string | null;
|
|
1169
|
+
autoWarpOnShieldFailure: boolean | null;
|
|
1170
|
+
autoWarpOnNoCaptains: boolean | null;
|
|
1171
|
+
state: ModelRecord;
|
|
1172
|
+
}
|
|
1173
|
+
```
|
|
1174
|
+
|
|
1175
|
+
### `FabricatorHandle`
|
|
1176
|
+
|
|
1177
|
+
```ts
|
|
1178
|
+
interface FabricatorHandle extends MachineHandle {
|
|
1179
|
+
state: FabricatorSummary | null;
|
|
1180
|
+
panel(): PuiEvent | null;
|
|
1181
|
+
add(itemId: number, count?: number, index?: number): DredlessClient;
|
|
1182
|
+
sub(itemId: number, count?: number, index?: number): DredlessClient;
|
|
1183
|
+
clearQueue(): DredlessClient;
|
|
1184
|
+
toggleRepeat(): DredlessClient;
|
|
1185
|
+
lockResource(row: number): DredlessClient;
|
|
1186
|
+
unlockResource(row: number): DredlessClient;
|
|
1187
|
+
eject(row: number): DredlessClient;
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
const FabricatorType = { Starter: "starter", Munitions: "munitions", Engineering: "engineering", Equipment: "equipment" } as const;
|
|
1191
|
+
type FabricatorType = typeof FabricatorType[keyof typeof FabricatorType];
|
|
1192
|
+
|
|
1193
|
+
interface FabricatorSummary {
|
|
1194
|
+
entity: number;
|
|
1195
|
+
type: FabricatorType | null;
|
|
1196
|
+
typeIndex: number | null;
|
|
1197
|
+
state: ModelRecord;
|
|
1198
|
+
rows: { itemId: number | null; itemName: string | null; count: number | null }[];
|
|
1199
|
+
progress: number | null;
|
|
1200
|
+
progressRaw: number | null;
|
|
1201
|
+
active: boolean;
|
|
1202
|
+
craftingItemId: number | null;
|
|
1203
|
+
craftingItemName: string | null;
|
|
1204
|
+
craftingCount: number | null;
|
|
1205
|
+
}
|
|
1206
|
+
```
|
|
1207
|
+
|
|
1208
|
+
### `CommsStationHandle`
|
|
1209
|
+
|
|
1210
|
+
```ts
|
|
1211
|
+
interface CommsStationHandle extends MachineHandle {
|
|
1212
|
+
state: CommsStationSummary | null;
|
|
1213
|
+
panel(): CommsEvent | null;
|
|
1214
|
+
sendMessage(message?: string): DredlessClient;
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1217
|
+
interface CommsStationSummary {
|
|
1218
|
+
entity: number;
|
|
1219
|
+
typeId: number;
|
|
1220
|
+
typeName: string | null;
|
|
1221
|
+
charges: number | null;
|
|
1222
|
+
maxCharges: number;
|
|
1223
|
+
chargeRatio: number | null;
|
|
1224
|
+
occupied: boolean;
|
|
1225
|
+
state: ModelRecord;
|
|
1226
|
+
}
|
|
1227
|
+
```
|
|
1228
|
+
|
|
1229
|
+
### `SignHandle`
|
|
1230
|
+
|
|
1231
|
+
```ts
|
|
1232
|
+
interface SignHandle extends MachineHandle {
|
|
1233
|
+
state: SignSummary | null;
|
|
1234
|
+
setText(text?: string, mode?: SignDisplayMode): DredlessClient;
|
|
1235
|
+
text: string | undefined;
|
|
1236
|
+
mode: number | undefined;
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1239
|
+
const SignDisplayMode = { Always: "always", WhenNear: "when-near", OnHover: "on-hover" } as const;
|
|
1240
|
+
type SignDisplayMode = typeof SignDisplayMode[keyof typeof SignDisplayMode];
|
|
1241
|
+
|
|
1242
|
+
interface SignSummary {
|
|
1243
|
+
entity: number;
|
|
1244
|
+
text: string;
|
|
1245
|
+
displayMode: number;
|
|
1246
|
+
displayModeName: string | null;
|
|
1247
|
+
state: ModelRecord;
|
|
1248
|
+
}
|
|
1249
|
+
```
|
|
1250
|
+
|
|
1251
|
+
### `GeneratorHandle`
|
|
1252
|
+
|
|
1253
|
+
```ts
|
|
1254
|
+
interface GeneratorHandle extends MachineHandle {
|
|
1255
|
+
state: ShieldGeneratorSummary | null;
|
|
1256
|
+
solvePuzzle(solution: string | number): DredlessClient;
|
|
1257
|
+
}
|
|
1258
|
+
|
|
1259
|
+
interface ShieldGeneratorSummary {
|
|
1260
|
+
entity: number;
|
|
1261
|
+
charge: number;
|
|
1262
|
+
maxCharge: number;
|
|
1263
|
+
chargeRatio: number | null;
|
|
1264
|
+
efficiencyPercent: number | null;
|
|
1265
|
+
efficiency: number | null;
|
|
1266
|
+
storedItemId: number | null;
|
|
1267
|
+
storedItemName: string | null;
|
|
1268
|
+
storedItemCount: number | null;
|
|
1269
|
+
hasShieldCore: boolean;
|
|
1270
|
+
boostState: number;
|
|
1271
|
+
boostStateName: string | null;
|
|
1272
|
+
boostTimer: number;
|
|
1273
|
+
boostActive: boolean;
|
|
1274
|
+
puzzleSeed: number | null;
|
|
1275
|
+
puzzleSolution: string | null;
|
|
1276
|
+
state: ModelRecord;
|
|
1277
|
+
itemState: ModelRecord;
|
|
1278
|
+
boostStateRaw: ModelRecord;
|
|
1279
|
+
}
|
|
1280
|
+
```
|
|
1281
|
+
|
|
1282
|
+
### `CargoHatchHandle`
|
|
1283
|
+
|
|
1284
|
+
```ts
|
|
1285
|
+
interface CargoHatchHandle extends MachineHandle {
|
|
1286
|
+
state: CargoHatchSummary | null;
|
|
1287
|
+
configure(config?: Pick<LoaderFullConfig, "filterMode" | "filterSlots">): DredlessClient;
|
|
1288
|
+
copy(config?: Pick<LoaderFullConfig, "filterMode" | "filterSlots">): DredlessClient;
|
|
1289
|
+
paste(config?: Pick<LoaderFullConfig, "filterMode" | "filterSlots">): DredlessClient;
|
|
1290
|
+
setFilterMode(filterMode: LoaderFilterMode): DredlessClient;
|
|
1291
|
+
setFilterItems(filterSlots?: Array<number | null | undefined>): DredlessClient;
|
|
1292
|
+
}
|
|
1293
|
+
|
|
1294
|
+
interface CargoHatchSummary {
|
|
1295
|
+
entity: number;
|
|
1296
|
+
typeId: number;
|
|
1297
|
+
typeName: string | null;
|
|
1298
|
+
filterMode: number;
|
|
1299
|
+
filterModeName: string | null;
|
|
1300
|
+
filterSlots: (number | null)[] | null;
|
|
1301
|
+
openFraction: number | null;
|
|
1302
|
+
filterState: ModelRecord;
|
|
1303
|
+
filterSlotsState: ModelRecord;
|
|
1304
|
+
}
|
|
1305
|
+
```
|
|
1306
|
+
|
|
1307
|
+
### Other machine handles
|
|
1308
|
+
|
|
1309
|
+
```ts
|
|
1310
|
+
interface CannonHandle extends MachineHandle {
|
|
1311
|
+
state: CannonSummary | null;
|
|
1312
|
+
}
|
|
1313
|
+
|
|
1314
|
+
interface ThrusterHandle extends MachineHandle {
|
|
1315
|
+
state: ThrusterSummary | null;
|
|
1316
|
+
}
|
|
1317
|
+
|
|
1318
|
+
interface HelmHandle extends MachineHandle {
|
|
1319
|
+
state: HelmSummary | null;
|
|
1320
|
+
occupied: boolean | undefined;
|
|
1321
|
+
}
|
|
1322
|
+
|
|
1323
|
+
interface DoorHandle extends MachineHandle {
|
|
1324
|
+
state: DoorSummary | null;
|
|
1325
|
+
rank: number | undefined;
|
|
1326
|
+
open: boolean | undefined;
|
|
1327
|
+
}
|
|
1328
|
+
|
|
1329
|
+
interface SpawnPointHandle extends MachineHandle {
|
|
1330
|
+
state: SpawnPointSummary | null;
|
|
1331
|
+
rank: number | undefined;
|
|
1332
|
+
}
|
|
1333
|
+
|
|
1334
|
+
interface ShieldProjectorHandle extends MachineHandle {
|
|
1335
|
+
state: ShieldProjectorSummary | null;
|
|
1336
|
+
active: boolean | undefined;
|
|
1337
|
+
}
|
|
1338
|
+
|
|
1339
|
+
interface FluidTankHandle extends MachineHandle {
|
|
1340
|
+
state: FluidTankSummary | null;
|
|
1341
|
+
amount: number | null | undefined;
|
|
1342
|
+
}
|
|
1343
|
+
|
|
1344
|
+
interface ExpandoBoxHandle extends MachineHandle {
|
|
1345
|
+
state: ExpandoBoxSummary | null;
|
|
1346
|
+
item: number | null | undefined;
|
|
1347
|
+
count: number | null | undefined;
|
|
1348
|
+
}
|
|
1349
|
+
|
|
1350
|
+
interface CargoEjectorSummary {
|
|
1351
|
+
entity: number;
|
|
1352
|
+
typeId: number;
|
|
1353
|
+
typeName: string | null;
|
|
1354
|
+
progress: number | null;
|
|
1355
|
+
active: boolean | null;
|
|
1356
|
+
}
|
|
1357
|
+
|
|
1358
|
+
interface CargoEjectorHandle extends MachineHandle {
|
|
1359
|
+
state: CargoEjectorSummary | null;
|
|
1360
|
+
progress: number | null | undefined;
|
|
1361
|
+
active: boolean | null | undefined;
|
|
1362
|
+
setDirection(direction: FixedAngleDirection): DredlessClient;
|
|
1363
|
+
copy(direction?: FixedAngleDirection): DredlessClient;
|
|
1364
|
+
paste(direction?: FixedAngleDirection): DredlessClient;
|
|
1365
|
+
}
|
|
1366
|
+
```
|
|
1367
|
+
|
|
1368
|
+
Associated summary shapes:
|
|
1369
|
+
|
|
1370
|
+
```ts
|
|
1371
|
+
interface CannonSummary {
|
|
1372
|
+
entity: number;
|
|
1373
|
+
typeId: number;
|
|
1374
|
+
typeName: string | null;
|
|
1375
|
+
ammoItemId: number | null;
|
|
1376
|
+
ammoName: string | null;
|
|
1377
|
+
ammoCount: number;
|
|
1378
|
+
aim: number | null;
|
|
1379
|
+
recoil: number | null;
|
|
1380
|
+
recoil2: number | null;
|
|
1381
|
+
recoils: [number | null, number | null];
|
|
1382
|
+
charge: number | null;
|
|
1383
|
+
charged: boolean | null;
|
|
1384
|
+
spin: number | null;
|
|
1385
|
+
coolingCellCount: number;
|
|
1386
|
+
state: ModelRecord;
|
|
1387
|
+
}
|
|
1388
|
+
|
|
1389
|
+
interface ThrusterSummary {
|
|
1390
|
+
entity: number;
|
|
1391
|
+
typeId: number;
|
|
1392
|
+
typeName: string | null;
|
|
1393
|
+
facing: number;
|
|
1394
|
+
facingName:
|
|
1395
|
+
| "bottom"
|
|
1396
|
+
| "top"
|
|
1397
|
+
| "right"
|
|
1398
|
+
| "left"
|
|
1399
|
+
| "bottom-right"
|
|
1400
|
+
| "bottom-left"
|
|
1401
|
+
| "top-right"
|
|
1402
|
+
| "top-left"
|
|
1403
|
+
| null;
|
|
1404
|
+
fuel: number | null;
|
|
1405
|
+
state: ModelRecord;
|
|
1406
|
+
}
|
|
1407
|
+
|
|
1408
|
+
interface HelmSummary {
|
|
1409
|
+
entity: number;
|
|
1410
|
+
typeId: number;
|
|
1411
|
+
typeName: string | null;
|
|
1412
|
+
occupied: boolean;
|
|
1413
|
+
}
|
|
1414
|
+
|
|
1415
|
+
interface DoorSummary {
|
|
1416
|
+
entity: number;
|
|
1417
|
+
rank: number;
|
|
1418
|
+
rankName: string | null;
|
|
1419
|
+
open: boolean;
|
|
1420
|
+
rankState: ModelRecord;
|
|
1421
|
+
state: ModelRecord;
|
|
1422
|
+
}
|
|
1423
|
+
|
|
1424
|
+
interface SpawnPointSummary {
|
|
1425
|
+
entity: number;
|
|
1426
|
+
rank: number;
|
|
1427
|
+
rankName: string | null;
|
|
1428
|
+
state: ModelRecord;
|
|
1429
|
+
}
|
|
1430
|
+
|
|
1431
|
+
interface ShieldProjectorSummary {
|
|
1432
|
+
entity: number;
|
|
1433
|
+
active: boolean;
|
|
1434
|
+
state: ModelRecord;
|
|
1435
|
+
}
|
|
1436
|
+
|
|
1437
|
+
interface FluidTankSummary {
|
|
1438
|
+
entity: number;
|
|
1439
|
+
amount: number | null;
|
|
1440
|
+
state: ModelRecord;
|
|
1441
|
+
}
|
|
1442
|
+
|
|
1443
|
+
interface ExpandoBoxSummary {
|
|
1444
|
+
entity: number;
|
|
1445
|
+
itemId: number | null;
|
|
1446
|
+
itemName: string | null;
|
|
1447
|
+
count: number | null;
|
|
1448
|
+
width: number | null;
|
|
1449
|
+
height: number | null;
|
|
1450
|
+
rawWidth: number | null;
|
|
1451
|
+
rawHeight: number | null;
|
|
1452
|
+
itemState: ModelRecord;
|
|
1453
|
+
sizeState: ModelRecord;
|
|
1454
|
+
}
|
|
1455
|
+
```
|
|
1456
|
+
|
|
1457
|
+
## Ship Reads
|
|
1458
|
+
|
|
1459
|
+
### `ShipHandle`
|
|
1460
|
+
|
|
1461
|
+
Returned by `client.overworld()?.ships()`.
|
|
1462
|
+
|
|
1463
|
+
```ts
|
|
1464
|
+
interface ShipHandle {
|
|
1465
|
+
entity: number;
|
|
1466
|
+
name: string | null;
|
|
1467
|
+
hexCode: string | null;
|
|
1468
|
+
distance: number | null;
|
|
1469
|
+
worldId: number | null;
|
|
1470
|
+
hasWorldData: boolean;
|
|
1471
|
+
world(): WorldDomain | null;
|
|
1472
|
+
snapshot(): ShipReadSummary;
|
|
1473
|
+
}
|
|
1474
|
+
```
|
|
1475
|
+
|
|
1476
|
+
### `ShipReadSummary`
|
|
1477
|
+
|
|
1478
|
+
```ts
|
|
1479
|
+
interface ShipReadSummary {
|
|
1480
|
+
entity: number;
|
|
1481
|
+
name: string | null;
|
|
1482
|
+
hexCode: string | null;
|
|
1483
|
+
color: number | null;
|
|
1484
|
+
colorCss: string | null;
|
|
1485
|
+
position: { x: number | null; y: number | null; rot: number | null } | null;
|
|
1486
|
+
distance: number | null;
|
|
1487
|
+
footprint: EntitySummary["footprint"];
|
|
1488
|
+
label: string;
|
|
1489
|
+
kind: string[];
|
|
1490
|
+
thrust: { x: number | null; y: number | null };
|
|
1491
|
+
shield: ShipShieldSummary | null;
|
|
1492
|
+
warp: ShipWarpSummary | null;
|
|
1493
|
+
worldId: number | null;
|
|
1494
|
+
hasWorldData: boolean;
|
|
1495
|
+
world: WorldSnapshot | null;
|
|
1496
|
+
control: ShipControlSummary;
|
|
1497
|
+
entitySummary: EntitySummary;
|
|
1498
|
+
}
|
|
1499
|
+
```
|
|
1500
|
+
|
|
1501
|
+
### `ShipControlSummary`
|
|
1502
|
+
|
|
1503
|
+
```ts
|
|
1504
|
+
interface ShipControlSummary {
|
|
1505
|
+
entity: number;
|
|
1506
|
+
name: string | null;
|
|
1507
|
+
hexCode: string | null;
|
|
1508
|
+
shipWorldId: number | null;
|
|
1509
|
+
color: number | null;
|
|
1510
|
+
colorCss: string | null;
|
|
1511
|
+
thrustX: number | null;
|
|
1512
|
+
thrustY: number | null;
|
|
1513
|
+
value52: number | null;
|
|
1514
|
+
value84: number | null;
|
|
1515
|
+
value96: number | null;
|
|
1516
|
+
shield: ShipShieldSummary | null;
|
|
1517
|
+
warp: ShipWarpSummary | null;
|
|
1518
|
+
state: ModelRecord;
|
|
1519
|
+
}
|
|
1520
|
+
```
|
|
1521
|
+
|
|
1522
|
+
### Ship shield and warp summaries
|
|
1523
|
+
|
|
1524
|
+
```ts
|
|
1525
|
+
interface ShipShieldSummary {
|
|
1526
|
+
maxHp: number | null;
|
|
1527
|
+
baseHp: number | null;
|
|
1528
|
+
activeTankHp: number | null;
|
|
1529
|
+
inactiveTankHp: number | null;
|
|
1530
|
+
tankValues: number[];
|
|
1531
|
+
}
|
|
1532
|
+
|
|
1533
|
+
interface ShipWarpSummary {
|
|
1534
|
+
active: boolean;
|
|
1535
|
+
ticks: number;
|
|
1536
|
+
elapsedSeconds: number;
|
|
1537
|
+
durationSeconds: number;
|
|
1538
|
+
remainingSeconds: number;
|
|
1539
|
+
}
|
|
1540
|
+
```
|
|
1541
|
+
|
|
1542
|
+
## Player, Blocks, Materials
|
|
1543
|
+
|
|
1544
|
+
```ts
|
|
1545
|
+
interface PlayerCollection {
|
|
1546
|
+
all(): PlayerSummary[];
|
|
1547
|
+
current(): PlayerSummary | null;
|
|
1548
|
+
}
|
|
1549
|
+
|
|
1550
|
+
interface BlockCollection {
|
|
1551
|
+
all(): BlockSummary[];
|
|
1552
|
+
at(x: number, y: number): BlockSummary | null;
|
|
1553
|
+
}
|
|
1554
|
+
|
|
1555
|
+
interface MaterialCollection {
|
|
1556
|
+
all(): MaterialSummary[];
|
|
1557
|
+
}
|
|
1558
|
+
```
|
|
1559
|
+
|
|
1560
|
+
### `PlayerSummary`
|
|
1561
|
+
|
|
1562
|
+
```ts
|
|
1563
|
+
interface PlayerSummary {
|
|
1564
|
+
entity: number;
|
|
1565
|
+
name: string | null;
|
|
1566
|
+
heldItemId: number | null;
|
|
1567
|
+
heldItemName: string | null;
|
|
1568
|
+
repairTargetDistance: number | null;
|
|
1569
|
+
repairTargetAngle: number | null;
|
|
1570
|
+
shipRank: PlayerShipRank | null;
|
|
1571
|
+
patronTier: "bronze" | "silver" | "gold" | "plat" | "flux" | null;
|
|
1572
|
+
isDeveloper: boolean;
|
|
1573
|
+
isPatron: boolean;
|
|
1574
|
+
piloting: boolean;
|
|
1575
|
+
muted: boolean;
|
|
1576
|
+
actionPreview: PlayerActionPreviewSummary | null;
|
|
1577
|
+
state: ModelRecord;
|
|
1578
|
+
}
|
|
1579
|
+
```
|
|
1580
|
+
|
|
1581
|
+
### `PlayerActionPreviewSummary`
|
|
1582
|
+
|
|
1583
|
+
```ts
|
|
1584
|
+
interface PlayerActionPreviewSummary {
|
|
1585
|
+
entity: number;
|
|
1586
|
+
active: boolean;
|
|
1587
|
+
x: number | null;
|
|
1588
|
+
y: number | null;
|
|
1589
|
+
width: number | null;
|
|
1590
|
+
height: number | null;
|
|
1591
|
+
progress: number | null;
|
|
1592
|
+
color: number | null;
|
|
1593
|
+
colorCss: string | null;
|
|
1594
|
+
actionName: "place" | "break" | "blueprint" | null;
|
|
1595
|
+
blueprintId: number | null;
|
|
1596
|
+
blueprintItems: BlueprintPreviewSummary[];
|
|
1597
|
+
state: ModelRecord;
|
|
1598
|
+
}
|
|
1599
|
+
```
|
|
1600
|
+
|
|
1601
|
+
### `BlockSummary`
|
|
1602
|
+
|
|
1603
|
+
```ts
|
|
1604
|
+
interface BlockSummary {
|
|
1605
|
+
x: number;
|
|
1606
|
+
y: number;
|
|
1607
|
+
entities: EntitySummary[];
|
|
1608
|
+
}
|
|
1609
|
+
```
|
|
1610
|
+
|
|
1611
|
+
### `MaterialSummary`
|
|
1612
|
+
|
|
1613
|
+
```ts
|
|
1614
|
+
interface MaterialSummary {
|
|
1615
|
+
material: number;
|
|
1616
|
+
name: string | null;
|
|
1617
|
+
count: number;
|
|
1618
|
+
solid: boolean | null;
|
|
1619
|
+
hp: number | null;
|
|
1620
|
+
}
|
|
1621
|
+
```
|
|
1622
|
+
|
|
1623
|
+
## World State Classes
|
|
1624
|
+
|
|
1625
|
+
These classes are public mostly for inspection, replay, testing, and lower-level
|
|
1626
|
+
tooling.
|
|
1627
|
+
|
|
1628
|
+
### `WorldStore`
|
|
1629
|
+
|
|
1630
|
+
```ts
|
|
1631
|
+
class WorldStore {
|
|
1632
|
+
currentWorldId: number | null;
|
|
1633
|
+
worlds: Map<number, WorldState>;
|
|
1634
|
+
|
|
1635
|
+
get(id: number): WorldState;
|
|
1636
|
+
apply(packet: unknown): WorldUpdate | null;
|
|
1637
|
+
snapshot(options?: { includeTiles?: boolean; includeModel?: boolean }): WorldSnapshot[];
|
|
1638
|
+
ids(): number[];
|
|
1639
|
+
overworld(): WorldState | null;
|
|
1640
|
+
shipWorld(): WorldState | null;
|
|
1641
|
+
currentShipEntity(): EntitySummary | null;
|
|
1642
|
+
}
|
|
1643
|
+
```
|
|
1644
|
+
|
|
1645
|
+
### `WorldState`
|
|
1646
|
+
|
|
1647
|
+
```ts
|
|
1648
|
+
class WorldState {
|
|
1649
|
+
constructor(id: number);
|
|
1650
|
+
|
|
1651
|
+
id: number;
|
|
1652
|
+
seed: number | null;
|
|
1653
|
+
isOverworld: boolean | null;
|
|
1654
|
+
tileset: Tileset | null;
|
|
1655
|
+
blockWidth: number | null;
|
|
1656
|
+
blockHeight: number | null;
|
|
1657
|
+
parentWorld: number | null;
|
|
1658
|
+
parentEntity: number | null;
|
|
1659
|
+
tiles: Map<string, Tile>;
|
|
1660
|
+
chunks: unknown[];
|
|
1661
|
+
events: unknown[];
|
|
1662
|
+
modelPackets: unknown[];
|
|
1663
|
+
commsBubbles: CommsBubbleSummary[];
|
|
1664
|
+
model: ModelState;
|
|
1665
|
+
lastChunkPatch: unknown;
|
|
1666
|
+
lastPacket: unknown;
|
|
1667
|
+
meta: unknown;
|
|
1668
|
+
|
|
1669
|
+
readMeta(packet: unknown): void;
|
|
1670
|
+
addCommsBubble(packet: unknown): CommsBubbleSummary;
|
|
1671
|
+
decodeEncrypted(data: Uint8Array | ArrayBuffer | number[]): unknown;
|
|
1672
|
+
applyTile(value: unknown): Tile | null;
|
|
1673
|
+
applyChunk(value: unknown): Tile[] | null;
|
|
1674
|
+
setTile(tile: Tile): Tile;
|
|
1675
|
+
normalizeTile(tile: Tile): Tile;
|
|
1676
|
+
materials(): MaterialSummary[];
|
|
1677
|
+
snapshot(options?: { includeTiles?: boolean; includeModel?: boolean }): WorldSnapshot;
|
|
1678
|
+
table(id: number): Map<number, ModelRecord>;
|
|
1679
|
+
record(tableId: number, entityId: number): ModelRecord | null;
|
|
1680
|
+
tileDefinition(material: number): TileDefinition | null;
|
|
1681
|
+
entity(entityId: number): EntitySummary | null;
|
|
1682
|
+
entities(): EntitySummary[];
|
|
1683
|
+
blocks(): BlockSummary[];
|
|
1684
|
+
}
|
|
1685
|
+
```
|
|
1686
|
+
|
|
1687
|
+
### `ModelState`
|
|
1688
|
+
|
|
1689
|
+
```ts
|
|
1690
|
+
class ModelState {
|
|
1691
|
+
generation: number | null;
|
|
1692
|
+
tables: Map<number, Map<number, ModelRecord>>;
|
|
1693
|
+
removedEntities: number[];
|
|
1694
|
+
lastUpdate: unknown;
|
|
1695
|
+
errors: unknown[];
|
|
1696
|
+
|
|
1697
|
+
table(id: number): Map<number, ModelRecord>;
|
|
1698
|
+
record(tableId: number, entityId: number): ModelRecord | null;
|
|
1699
|
+
entity(entityId: number): EntitySummary | null;
|
|
1700
|
+
entities(): EntitySummary[];
|
|
1701
|
+
blocks(): BlockSummary[];
|
|
1702
|
+
apply(bytes: Uint8Array | ArrayBuffer | number[]): unknown;
|
|
1703
|
+
snapshot(options?: { includeTables?: boolean }): ModelSnapshot;
|
|
1704
|
+
tablesSnapshot(): unknown[];
|
|
1705
|
+
transforms(): TransformSummary[];
|
|
1706
|
+
itemHolders(): ItemHolderSummary[];
|
|
1707
|
+
fabricators(): FabricatorSummary[];
|
|
1708
|
+
players(): PlayerSummary[];
|
|
1709
|
+
shipControls(): ShipControlSummary[];
|
|
1710
|
+
shipMetadata(): ShipWorldMetadataSummary | null;
|
|
1711
|
+
machines(): MachineSummary;
|
|
1712
|
+
}
|
|
1713
|
+
|
|
1714
|
+
type ModelRecord = Record<string, unknown>;
|
|
1715
|
+
```
|
|
1716
|
+
|
|
1717
|
+
### `WorldSnapshot`
|
|
1718
|
+
|
|
1719
|
+
```ts
|
|
1720
|
+
interface WorldSnapshot {
|
|
1721
|
+
id: number;
|
|
1722
|
+
is_overworld: boolean | null;
|
|
1723
|
+
overworldZone: OverworldZoneSummary | null;
|
|
1724
|
+
shipMetadata: ShipWorldMetadataSummary | null;
|
|
1725
|
+
tileset: Tileset | null;
|
|
1726
|
+
seed: number | null;
|
|
1727
|
+
block_w: number | null;
|
|
1728
|
+
block_h: number | null;
|
|
1729
|
+
parent_world: number | null;
|
|
1730
|
+
parent_ent: number | null;
|
|
1731
|
+
tileCount: number;
|
|
1732
|
+
chunkCount: number;
|
|
1733
|
+
lastChunkPatch: unknown;
|
|
1734
|
+
lastPacket: unknown;
|
|
1735
|
+
meta: unknown;
|
|
1736
|
+
materials: MaterialSummary[];
|
|
1737
|
+
model: ModelSnapshot;
|
|
1738
|
+
entities: EntitySummary[];
|
|
1739
|
+
blocks: BlockSummary[];
|
|
1740
|
+
transforms: TransformSummary[];
|
|
1741
|
+
machines: MachineSummary;
|
|
1742
|
+
players: PlayerSummary[];
|
|
1743
|
+
shipControls: ShipControlSummary[];
|
|
1744
|
+
commsBubbles: CommsBubbleSummary[];
|
|
1745
|
+
tiles?: Tile[];
|
|
1746
|
+
}
|
|
1747
|
+
```
|
|
1748
|
+
|
|
1749
|
+
### World metadata
|
|
1750
|
+
|
|
1751
|
+
```ts
|
|
1752
|
+
interface OverworldZoneSummary {
|
|
1753
|
+
id: number;
|
|
1754
|
+
baseId: number;
|
|
1755
|
+
layer: number;
|
|
1756
|
+
key: string;
|
|
1757
|
+
name: string;
|
|
1758
|
+
tiered: boolean;
|
|
1759
|
+
displayName: string;
|
|
1760
|
+
}
|
|
1761
|
+
|
|
1762
|
+
interface ShipWorldMetadataSummary {
|
|
1763
|
+
name: string | null;
|
|
1764
|
+
color: number | null;
|
|
1765
|
+
colorCss: string | null;
|
|
1766
|
+
width: number | null;
|
|
1767
|
+
height: number | null;
|
|
1768
|
+
lockdownTimerSeconds: number | null;
|
|
1769
|
+
lockdownCountdownSeconds: number | null;
|
|
1770
|
+
onlineShipOwnerCount: number | null;
|
|
1771
|
+
requiredShipOwnerCount: number | null;
|
|
1772
|
+
allShipOwnersOnline: boolean | null;
|
|
1773
|
+
lockdownEngaged: boolean | null;
|
|
1774
|
+
lockdownState: ModelRecord;
|
|
1775
|
+
shipState: ModelRecord;
|
|
1776
|
+
}
|
|
1777
|
+
|
|
1778
|
+
interface WorldUpdate {
|
|
1779
|
+
type: string;
|
|
1780
|
+
world: WorldState | null;
|
|
1781
|
+
packet?: unknown;
|
|
1782
|
+
bubble?: CommsBubbleSummary;
|
|
1783
|
+
decoded?: unknown;
|
|
1784
|
+
updates?: unknown[];
|
|
1785
|
+
result?: unknown;
|
|
1786
|
+
}
|
|
1787
|
+
```
|
|
1788
|
+
|
|
1789
|
+
### Tiles
|
|
1790
|
+
|
|
1791
|
+
```ts
|
|
1792
|
+
interface Tile {
|
|
1793
|
+
x: number;
|
|
1794
|
+
y: number;
|
|
1795
|
+
material: number;
|
|
1796
|
+
materialName?: string | null;
|
|
1797
|
+
shape: number;
|
|
1798
|
+
shapeName?: string | null;
|
|
1799
|
+
hp: number;
|
|
1800
|
+
/** @deprecated Use hp. Raw 0-255 HP fraction byte, not absolute integrity. */
|
|
1801
|
+
integrity: number;
|
|
1802
|
+
color: number | null;
|
|
1803
|
+
solid?: boolean | null;
|
|
1804
|
+
maxHp?: number | null;
|
|
1805
|
+
hpRatio?: number | null;
|
|
1806
|
+
hpValue?: number | null;
|
|
1807
|
+
}
|
|
1808
|
+
|
|
1809
|
+
interface TilePhysics {
|
|
1810
|
+
filter?: {
|
|
1811
|
+
categoryBits: number;
|
|
1812
|
+
maskBits: number;
|
|
1813
|
+
groupIndex: number;
|
|
1814
|
+
};
|
|
1815
|
+
transparent?: boolean;
|
|
1816
|
+
walkway?: boolean;
|
|
1817
|
+
restitution?: number;
|
|
1818
|
+
friction?: number;
|
|
1819
|
+
}
|
|
1820
|
+
|
|
1821
|
+
interface TileDefinition {
|
|
1822
|
+
name?: string;
|
|
1823
|
+
solid: boolean;
|
|
1824
|
+
destruct_item?: number;
|
|
1825
|
+
blocks_bullets?: boolean;
|
|
1826
|
+
hp?: number;
|
|
1827
|
+
no_build_surface?: boolean;
|
|
1828
|
+
physics?: TilePhysics;
|
|
1829
|
+
}
|
|
1830
|
+
|
|
1831
|
+
interface Tileset {
|
|
1832
|
+
scale: number;
|
|
1833
|
+
atlas: string;
|
|
1834
|
+
tile_width: number;
|
|
1835
|
+
tiles: TileDefinition[];
|
|
1836
|
+
}
|
|
1837
|
+
```
|
|
1838
|
+
|
|
1839
|
+
### `ModelSnapshot`
|
|
1840
|
+
|
|
1841
|
+
```ts
|
|
1842
|
+
interface ModelSnapshot {
|
|
1843
|
+
generation: number | null;
|
|
1844
|
+
tableCount: number;
|
|
1845
|
+
entityCount: number;
|
|
1846
|
+
removedEntities: number[];
|
|
1847
|
+
lastUpdate: unknown;
|
|
1848
|
+
errors: unknown[];
|
|
1849
|
+
entities: EntitySummary[];
|
|
1850
|
+
blocks: BlockSummary[];
|
|
1851
|
+
transforms: TransformSummary[];
|
|
1852
|
+
players: PlayerSummary[];
|
|
1853
|
+
shipControls: ShipControlSummary[];
|
|
1854
|
+
machines: MachineSummary;
|
|
1855
|
+
tables: unknown[];
|
|
1856
|
+
}
|
|
1857
|
+
```
|
|
1858
|
+
|
|
1859
|
+
## Additional Entity Component Shapes
|
|
1860
|
+
|
|
1861
|
+
```ts
|
|
1862
|
+
interface TransformSummary {
|
|
1863
|
+
entity: number;
|
|
1864
|
+
x: number | null;
|
|
1865
|
+
y: number | null;
|
|
1866
|
+
rot: number | null;
|
|
1867
|
+
flags: unknown[];
|
|
1868
|
+
}
|
|
1869
|
+
|
|
1870
|
+
interface ItemHolderSummary {
|
|
1871
|
+
entity: number;
|
|
1872
|
+
itemId: number | null;
|
|
1873
|
+
itemName: string | null;
|
|
1874
|
+
count: number | null;
|
|
1875
|
+
}
|
|
1876
|
+
|
|
1877
|
+
interface ItemCrateSummary {
|
|
1878
|
+
entity: number;
|
|
1879
|
+
itemId: number | null;
|
|
1880
|
+
itemName: string | null;
|
|
1881
|
+
count: number | null;
|
|
1882
|
+
width: number | null;
|
|
1883
|
+
height: number | null;
|
|
1884
|
+
itemState: ModelRecord;
|
|
1885
|
+
sizeState: ModelRecord;
|
|
1886
|
+
}
|
|
1887
|
+
|
|
1888
|
+
interface HoverOutlineSummary {
|
|
1889
|
+
entity: number;
|
|
1890
|
+
width: number | null;
|
|
1891
|
+
height: number | null;
|
|
1892
|
+
rawWidth: number | null;
|
|
1893
|
+
rawHeight: number | null;
|
|
1894
|
+
state: ModelRecord;
|
|
1895
|
+
}
|
|
1896
|
+
|
|
1897
|
+
interface MapMarkerSummary {
|
|
1898
|
+
entity: number;
|
|
1899
|
+
kind: string;
|
|
1900
|
+
title: string | null;
|
|
1901
|
+
key: string | null;
|
|
1902
|
+
description: string | null;
|
|
1903
|
+
color: number | null;
|
|
1904
|
+
colorCss: string | null;
|
|
1905
|
+
accentColor: number | null;
|
|
1906
|
+
accentColorCss: string | null;
|
|
1907
|
+
width: number | null;
|
|
1908
|
+
height: number | null;
|
|
1909
|
+
labelState: ModelRecord;
|
|
1910
|
+
zoneState: ModelRecord;
|
|
1911
|
+
}
|
|
1912
|
+
|
|
1913
|
+
interface DockingSpringSummary {
|
|
1914
|
+
entity: number;
|
|
1915
|
+
id: number | null;
|
|
1916
|
+
width: number;
|
|
1917
|
+
height: number;
|
|
1918
|
+
state: ModelRecord;
|
|
1919
|
+
}
|
|
1920
|
+
|
|
1921
|
+
interface HugeThrusterSummary {
|
|
1922
|
+
entity: number;
|
|
1923
|
+
width: number;
|
|
1924
|
+
height: number;
|
|
1925
|
+
state: ModelRecord;
|
|
1926
|
+
}
|
|
1927
|
+
|
|
1928
|
+
interface ShipSizeSummary {
|
|
1929
|
+
entity: number;
|
|
1930
|
+
width: number | null;
|
|
1931
|
+
height: number | null;
|
|
1932
|
+
rawWidth: number | null;
|
|
1933
|
+
rawHeight: number | null;
|
|
1934
|
+
state: ModelRecord;
|
|
1935
|
+
}
|
|
1936
|
+
|
|
1937
|
+
interface HealthSummary {
|
|
1938
|
+
entity: number;
|
|
1939
|
+
hp: number | null;
|
|
1940
|
+
maxHp: number | null;
|
|
1941
|
+
ratio: number | null;
|
|
1942
|
+
state: ModelRecord;
|
|
1943
|
+
}
|
|
1944
|
+
|
|
1945
|
+
interface BotSummary {
|
|
1946
|
+
entity: number;
|
|
1947
|
+
className: string;
|
|
1948
|
+
identifier: string;
|
|
1949
|
+
typeA: number | null;
|
|
1950
|
+
typeB: number | null;
|
|
1951
|
+
}
|
|
1952
|
+
```
|
|
1953
|
+
|
|
1954
|
+
## Blueprint Shapes
|
|
1955
|
+
|
|
1956
|
+
### Placement request
|
|
1957
|
+
|
|
1958
|
+
```ts
|
|
1959
|
+
interface BlueprintPlacement {
|
|
1960
|
+
x: number;
|
|
1961
|
+
y: number;
|
|
1962
|
+
width?: number;
|
|
1963
|
+
height?: number;
|
|
1964
|
+
w?: number;
|
|
1965
|
+
h?: number;
|
|
1966
|
+
source: string;
|
|
1967
|
+
}
|
|
1968
|
+
|
|
1969
|
+
interface BlueprintPlacementMessage {
|
|
1970
|
+
type: 9;
|
|
1971
|
+
x: number;
|
|
1972
|
+
y: number;
|
|
1973
|
+
w: number;
|
|
1974
|
+
h: number;
|
|
1975
|
+
source: string;
|
|
1976
|
+
}
|
|
1977
|
+
```
|
|
1978
|
+
|
|
1979
|
+
### Preview state
|
|
1980
|
+
|
|
1981
|
+
```ts
|
|
1982
|
+
interface BlueprintPreviewSummary {
|
|
1983
|
+
entity: number;
|
|
1984
|
+
itemId: number;
|
|
1985
|
+
itemName: string | null;
|
|
1986
|
+
bits: number;
|
|
1987
|
+
rawBits: number | null;
|
|
1988
|
+
placementOffsets: number[];
|
|
1989
|
+
placementCount: number;
|
|
1990
|
+
placements: {
|
|
1991
|
+
offset: number;
|
|
1992
|
+
x: number | null;
|
|
1993
|
+
y: number | null;
|
|
1994
|
+
itemId: number;
|
|
1995
|
+
itemName: string | null;
|
|
1996
|
+
}[];
|
|
1997
|
+
x: number | null;
|
|
1998
|
+
y: number | null;
|
|
1999
|
+
rot: number | null;
|
|
2000
|
+
state: ModelRecord;
|
|
2001
|
+
}
|
|
2002
|
+
```
|
|
2003
|
+
|
|
2004
|
+
## PUI And Comms Shapes
|
|
2005
|
+
|
|
2006
|
+
```ts
|
|
2007
|
+
interface PuiEvent {
|
|
2008
|
+
type: "pui";
|
|
2009
|
+
filter?: number;
|
|
2010
|
+
ent_id?: number;
|
|
2011
|
+
update?: boolean;
|
|
2012
|
+
data?: unknown;
|
|
2013
|
+
world?: number | null;
|
|
2014
|
+
}
|
|
2015
|
+
|
|
2016
|
+
interface CommsMessage {
|
|
2017
|
+
type: 3;
|
|
2018
|
+
msg: string;
|
|
2019
|
+
}
|
|
2020
|
+
|
|
2021
|
+
interface NormalizedCommsMessage {
|
|
2022
|
+
raw: unknown;
|
|
2023
|
+
text: string;
|
|
2024
|
+
}
|
|
2025
|
+
|
|
2026
|
+
interface CommsEvent {
|
|
2027
|
+
type: "comms";
|
|
2028
|
+
filter?: number;
|
|
2029
|
+
ent_id: number | null;
|
|
2030
|
+
entity: number | null;
|
|
2031
|
+
msgs_text: unknown[];
|
|
2032
|
+
rawMessages: unknown[];
|
|
2033
|
+
messages: NormalizedCommsMessage[];
|
|
2034
|
+
update?: boolean;
|
|
2035
|
+
world?: number | null;
|
|
2036
|
+
}
|
|
2037
|
+
|
|
2038
|
+
interface CommsBubbleSummary {
|
|
2039
|
+
sequence: number;
|
|
2040
|
+
worldId: number;
|
|
2041
|
+
entity: number | null;
|
|
2042
|
+
modelId: number | null;
|
|
2043
|
+
message: string;
|
|
2044
|
+
color: number | null;
|
|
2045
|
+
colorCss: string | null;
|
|
2046
|
+
durationSeconds: number | null;
|
|
2047
|
+
raw: unknown;
|
|
2048
|
+
}
|
|
2049
|
+
```
|
|
2050
|
+
|
|
2051
|
+
## Scanner And Ack Shapes
|
|
2052
|
+
|
|
2053
|
+
```ts
|
|
2054
|
+
interface CommandAck {
|
|
2055
|
+
world: number;
|
|
2056
|
+
commandNumber: number;
|
|
2057
|
+
}
|
|
2058
|
+
|
|
2059
|
+
interface ScannerResult {
|
|
2060
|
+
kind: "manifest" | "bom" | "unknown";
|
|
2061
|
+
sid: number | null;
|
|
2062
|
+
shipHex: string | null;
|
|
2063
|
+
shipName: string | null;
|
|
2064
|
+
blocks: Record<string, number> | null;
|
|
2065
|
+
objects: Record<string, number> | null;
|
|
2066
|
+
inventories: Record<string, number> | null;
|
|
2067
|
+
materials: Record<string, number> | null;
|
|
2068
|
+
}
|
|
2069
|
+
```
|
|
2070
|
+
|
|
2071
|
+
## Helper Function Exports
|
|
2072
|
+
|
|
2073
|
+
These are public lower-level helpers. Prefer the object/domain methods unless
|
|
2074
|
+
you explicitly need protocol payloads or decoded utility functions.
|
|
2075
|
+
|
|
2076
|
+
### Msgpack
|
|
2077
|
+
|
|
2078
|
+
Module: `dredless/protocol/msgpack` or root.
|
|
2079
|
+
|
|
2080
|
+
```ts
|
|
2081
|
+
function decodeMsgpack(bytes: Uint8Array | ArrayBuffer | number[]): unknown;
|
|
2082
|
+
function encodeMsgpack(value: unknown): Uint8Array;
|
|
2083
|
+
```
|
|
2084
|
+
|
|
2085
|
+
### Commands
|
|
2086
|
+
|
|
2087
|
+
Module: `dredless/protocol/commands` or root.
|
|
2088
|
+
|
|
2089
|
+
```ts
|
|
2090
|
+
function buildSignedCommandPacket(command: Command, sessionId: number): Uint8Array;
|
|
2091
|
+
```
|
|
2092
|
+
|
|
2093
|
+
### Inventory helpers
|
|
2094
|
+
|
|
2095
|
+
Module: `dredless/protocol/inventory` or root.
|
|
2096
|
+
|
|
2097
|
+
```ts
|
|
2098
|
+
function normalizeEquipmentSlot(slot: EquipmentSlot): 16 | 17 | 18 | 19 | 20 | 21;
|
|
2099
|
+
function equipmentSlotName(slot: number): "head" | "face" | "body" | "back" | "hands" | "feet" | null;
|
|
2100
|
+
function buildInventoryDragCommand(source: number, target: number, split?: boolean): InventoryDragCommand;
|
|
2101
|
+
function buildEquipItemCommand(source: number, slot: EquipmentSlot, split?: boolean): InventoryDragCommand;
|
|
2102
|
+
function buildUnequipItemCommand(slot: EquipmentSlot, target?: number, split?: boolean): InventoryDragCommand;
|
|
2103
|
+
function normalizeInventoryEvent(event: unknown): InventoryState;
|
|
2104
|
+
```
|
|
2105
|
+
|
|
2106
|
+
Inventory drag output remains protocol-shaped:
|
|
2107
|
+
|
|
2108
|
+
```ts
|
|
2109
|
+
interface InventoryDragCommand {
|
|
2110
|
+
drag: {
|
|
2111
|
+
source: number;
|
|
2112
|
+
target: number;
|
|
2113
|
+
split: boolean;
|
|
2114
|
+
};
|
|
2115
|
+
}
|
|
2116
|
+
```
|
|
2117
|
+
|
|
2118
|
+
`normalizeInventoryEvent()` returns the normalized `InventoryState` shape documented under `client.inventory`.
|
|
2119
|
+
|
|
2120
|
+
### Comms helpers
|
|
2121
|
+
|
|
2122
|
+
Module: `dredless/protocol/comms` or root.
|
|
2123
|
+
|
|
2124
|
+
```ts
|
|
2125
|
+
function buildCommsMessage(message?: string): CommsMessage;
|
|
2126
|
+
function normalizeCommsEvent(event: unknown): CommsEvent;
|
|
2127
|
+
function flattenRichText(value: unknown): string;
|
|
2128
|
+
```
|
|
2129
|
+
|
|
2130
|
+
### Sign helpers
|
|
2131
|
+
|
|
2132
|
+
Module: `dredless/protocol/sign` or root.
|
|
2133
|
+
|
|
2134
|
+
```ts
|
|
2135
|
+
function buildSignTextMessage(text?: string, mode?: SignDisplayMode): SignTextMessage;
|
|
2136
|
+
function normalizeSignDisplayMode(mode?: SignDisplayMode): 0 | 1 | 2;
|
|
2137
|
+
function signDisplayModeName(mode: number): SignDisplayMode | null;
|
|
2138
|
+
```
|
|
2139
|
+
|
|
2140
|
+
Output:
|
|
2141
|
+
|
|
2142
|
+
```ts
|
|
2143
|
+
interface SignTextMessage {
|
|
2144
|
+
type: 5;
|
|
2145
|
+
cmd: "sign_text";
|
|
2146
|
+
args: [string, 0 | 1 | 2];
|
|
2147
|
+
}
|
|
2148
|
+
```
|
|
2149
|
+
|
|
2150
|
+
### Ship-management helpers
|
|
2151
|
+
|
|
2152
|
+
Module: `dredless/protocol/ship-management` or root.
|
|
2153
|
+
|
|
2154
|
+
```ts
|
|
2155
|
+
function buildShipManagementMessage(act: string, arg?: unknown, extra?: Record<string, unknown> | null): ShipManagementMessage;
|
|
2156
|
+
function buildShipPrivacyMessage(privacy: ShipPrivacy): ShipManagementMessage;
|
|
2157
|
+
function buildStarterRecoveryMessage(itemId: number): ShipManagementMessage;
|
|
2158
|
+
function buildPlayerListMessage(): ShipManagementMessage;
|
|
2159
|
+
function buildInviteResetMessage(): ShipManagementMessage;
|
|
2160
|
+
function buildSetPlayerRankMessage(refId: number, rank: ShipPlayerRank): ShipManagementMessage;
|
|
2161
|
+
function buildKickPlayerMessage(refId: number): ShipManagementMessage;
|
|
2162
|
+
function buildBanPlayerMessage(refId: number): ShipManagementMessage;
|
|
2163
|
+
function buildDemoteSelfMessage(): ShipManagementMessage;
|
|
2164
|
+
function normalizePrivacy(privacy: ShipPrivacy): 0 | 1;
|
|
2165
|
+
function normalizePlayerRank(rank: ShipPlayerRank): 0 | 1 | 3;
|
|
2166
|
+
function normalizeShipConfig(event: unknown): ShipConfig;
|
|
2167
|
+
function normalizeCaptainSubrank(event: unknown): CaptainSubrank;
|
|
2168
|
+
function normalizeShipPlayerList(event: unknown, previous?: ShipPlayerList | null, currentCaptainSubrank?: CaptainSubrank | null): ShipPlayerList;
|
|
2169
|
+
```
|
|
2170
|
+
|
|
2171
|
+
Message output:
|
|
2172
|
+
|
|
2173
|
+
```ts
|
|
2174
|
+
interface ShipManagementMessage {
|
|
2175
|
+
type: 4;
|
|
2176
|
+
act: string;
|
|
2177
|
+
arg: unknown;
|
|
2178
|
+
rank?: unknown;
|
|
2179
|
+
}
|
|
2180
|
+
```
|
|
2181
|
+
|
|
2182
|
+
### Blueprint helpers
|
|
2183
|
+
|
|
2184
|
+
Module: `dredless/protocol/blueprint` or root.
|
|
2185
|
+
|
|
2186
|
+
```ts
|
|
2187
|
+
function buildBlueprintPlacementMessage(placement: BlueprintPlacement): BlueprintPlacementMessage;
|
|
2188
|
+
```
|
|
2189
|
+
|
|
2190
|
+
### UI config helpers
|
|
2191
|
+
|
|
2192
|
+
Module: `dredless/protocol/ui-config` or root.
|
|
2193
|
+
|
|
2194
|
+
```ts
|
|
2195
|
+
function buildNavigationUnitConfigData(entity: number, config: NavigationUnitConfig & { destination: number }): Uint8Array;
|
|
2196
|
+
function buildNavigationUnitClipboardConfigData(config: NavigationUnitConfig & { destination: number }): Uint8Array;
|
|
2197
|
+
function buildNavigationUnitPasteConfigData(entity: number, config: NavigationUnitConfig & { destination: number }): Uint8Array;
|
|
2198
|
+
function buildGeneratorMazePuzzleData(entity: number, solution: string | number): Uint8Array;
|
|
2199
|
+
function buildCargoHatchFilterConfigData(entity: number, filterMode?: LoaderFilterMode): Uint8Array;
|
|
2200
|
+
function buildCargoHatchFilterItemsData(entity: number, filterSlots?: Array<number | null | undefined>): Uint8Array;
|
|
2201
|
+
function buildCargoHatchFullConfigData(entity: number, config?: Pick<LoaderFullConfig, "filterMode" | "filterSlots">): Uint8Array;
|
|
2202
|
+
function buildCargoHatchCopyConfigData(config?: Pick<LoaderFullConfig, "filterMode" | "filterSlots">): Uint8Array;
|
|
2203
|
+
function buildClipboardConfigData(target: ClipboardTarget, commandName: string, values?: Iterable<number>): Uint8Array;
|
|
2204
|
+
function buildClipboardFixedAngleData(target: ClipboardTarget, direction: FixedAngleDirection): Uint8Array;
|
|
2205
|
+
function buildGeneratorClipboardDirectionData(direction: FixedAngleDirection): Uint8Array;
|
|
2206
|
+
function buildCargoEjectorDirectionData(entity: number, direction: FixedAngleDirection): Uint8Array;
|
|
2207
|
+
function buildCargoEjectorPasteConfigData(entity: number, direction: FixedAngleDirection): Uint8Array;
|
|
2208
|
+
function buildCargoEjectorCopyConfigData(direction: FixedAngleDirection): Uint8Array;
|
|
2209
|
+
function buildCargoEjectorClipboardDirectionData(direction: FixedAngleDirection): Uint8Array;
|
|
2210
|
+
function buildExpandoClipboardAngleData(angle: number): Uint8Array;
|
|
2211
|
+
function buildLoaderClipboardConfigData(config?: LoaderConfig): Uint8Array;
|
|
2212
|
+
function buildLoaderConfigData(entity: number, config?: LoaderConfig): Uint8Array;
|
|
2213
|
+
function buildLoaderCopyConfigData(config?: LoaderFullConfig): Uint8Array;
|
|
2214
|
+
function buildLoaderFilterConfigData(entity: number, filterMode?: LoaderFilterMode): Uint8Array;
|
|
2215
|
+
function buildLoaderFilterItemsData(entity: number, filterSlots?: Array<number | null | undefined>): Uint8Array;
|
|
2216
|
+
function buildLoaderFullConfigData(entity: number, config?: LoaderFullConfig): Uint8Array;
|
|
2217
|
+
function buildPusherConfigData(entity: number, config?: PusherConfig): Uint8Array;
|
|
2218
|
+
function buildPusherFilterItemsData(entity: number, filterSlots?: Array<number | null | undefined>): Uint8Array;
|
|
2219
|
+
```
|
|
2220
|
+
|
|
2221
|
+
Clipboard/config input types:
|
|
2222
|
+
|
|
2223
|
+
```ts
|
|
2224
|
+
type ClipboardTarget =
|
|
2225
|
+
| number
|
|
2226
|
+
| "loader" | "loader-config" | "loaderConfig"
|
|
2227
|
+
| "hatch" | "cargo-hatch" | "cargoHatch"
|
|
2228
|
+
| "ejector" | "cargo-ejector" | "cargoEjector"
|
|
2229
|
+
| "expando" | "expando-box" | "expandoBox"
|
|
2230
|
+
| "generator" | "shield-generator" | "shieldGenerator"
|
|
2231
|
+
| "navigation" | "navigation-unit" | "navigationUnit"
|
|
2232
|
+
| "nav" | "nav-unit" | "navUnit";
|
|
2233
|
+
|
|
2234
|
+
const FixedAngleDirection = { Right: "right", Up: "up", Left: "left", Down: "down" } as const;
|
|
2235
|
+
type FixedAngleDirection = typeof FixedAngleDirection[keyof typeof FixedAngleDirection];
|
|
2236
|
+
```
|
|
2237
|
+
|
|
2238
|
+
### Generator maze helpers
|
|
2239
|
+
|
|
2240
|
+
Module: `dredless/game/generator-maze` or root.
|
|
2241
|
+
|
|
2242
|
+
```ts
|
|
2243
|
+
function generateGeneratorMaze(seed: number): GeneratorMaze;
|
|
2244
|
+
function solveGeneratorMazeSeed(seed: number): string;
|
|
2245
|
+
function maybeSolveGeneratorMazeSeed(seed: number | null | undefined): string | null;
|
|
2246
|
+
```
|
|
2247
|
+
|
|
2248
|
+
Output:
|
|
2249
|
+
|
|
2250
|
+
```ts
|
|
2251
|
+
interface GeneratorMazeCellWalls {
|
|
2252
|
+
up: boolean;
|
|
2253
|
+
down: boolean;
|
|
2254
|
+
left: boolean;
|
|
2255
|
+
right: boolean;
|
|
2256
|
+
}
|
|
2257
|
+
|
|
2258
|
+
interface GeneratorMazeCell {
|
|
2259
|
+
x: number;
|
|
2260
|
+
y: number;
|
|
2261
|
+
value: number;
|
|
2262
|
+
hex: string;
|
|
2263
|
+
digit: number;
|
|
2264
|
+
walls: GeneratorMazeCellWalls;
|
|
2265
|
+
backtrackDirection: number;
|
|
2266
|
+
marker: number;
|
|
2267
|
+
}
|
|
2268
|
+
|
|
2269
|
+
interface GeneratorMaze {
|
|
2270
|
+
seed: number;
|
|
2271
|
+
width: number;
|
|
2272
|
+
height: number;
|
|
2273
|
+
cells: GeneratorMazeCell[];
|
|
2274
|
+
rows: GeneratorMazeCell[][];
|
|
2275
|
+
solution: string;
|
|
2276
|
+
}
|
|
2277
|
+
```
|
|
2278
|
+
|
|
2279
|
+
### Crypto, compression, and model decoding
|
|
2280
|
+
|
|
2281
|
+
Modules: `dredless/crypto/chacha`, `dredless/compression/lz4`,
|
|
2282
|
+
`dredless/model`, and root.
|
|
2283
|
+
|
|
2284
|
+
```ts
|
|
2285
|
+
function decryptPayload(
|
|
2286
|
+
wireBytes: Uint8Array | ArrayBuffer | number[],
|
|
2287
|
+
worldId: number,
|
|
2288
|
+
seed: number
|
|
2289
|
+
): Uint8Array;
|
|
2290
|
+
|
|
2291
|
+
function decompressLz4Frame(bytes: Uint8Array | ArrayBuffer | number[]): Uint8Array;
|
|
2292
|
+
|
|
2293
|
+
function decodeModelData(bytes: Uint8Array | ArrayBuffer | number[]): unknown;
|
|
2294
|
+
```
|
|
2295
|
+
|
|
2296
|
+
### Ship spec helpers
|
|
2297
|
+
|
|
2298
|
+
Module: `dredless/ships`.
|
|
2299
|
+
|
|
2300
|
+
```ts
|
|
2301
|
+
function createShipSpec(name?: string, color?: string): ShipSpec;
|
|
2302
|
+
function createInviteShipSpec(code: string): ShipSpec;
|
|
2303
|
+
```
|
|
2304
|
+
|
|
2305
|
+
`createShipSpec()` returns a `{ type: "new", ... }` ship spec.
|
|
2306
|
+
`createInviteShipSpec()` returns a `{ type: "invite", code }` ship spec.
|
|
2307
|
+
|
|
2308
|
+
## Public Constants From Subpath Modules
|
|
2309
|
+
|
|
2310
|
+
These constants are exported by helper subpaths for consumers that need protocol
|
|
2311
|
+
symbols. They are not required for normal object-domain use.
|
|
2312
|
+
|
|
2313
|
+
### `dredless/protocol/blueprint`
|
|
2314
|
+
|
|
2315
|
+
```ts
|
|
2316
|
+
const BLUEPRINT_PLACEMENT_TYPE: 9;
|
|
2317
|
+
```
|
|
2318
|
+
|
|
2319
|
+
### `dredless/protocol/comms`
|
|
2320
|
+
|
|
2321
|
+
```ts
|
|
2322
|
+
const COMMS_MESSAGE_TYPE: 3;
|
|
2323
|
+
```
|
|
2324
|
+
|
|
2325
|
+
### `dredless/protocol/inventory`
|
|
2326
|
+
|
|
2327
|
+
```ts
|
|
2328
|
+
const EQUIPMENT_SLOT_INDEXES: Readonly<{
|
|
2329
|
+
head: 16;
|
|
2330
|
+
face: 17;
|
|
2331
|
+
body: 18;
|
|
2332
|
+
back: 19;
|
|
2333
|
+
hands: 20;
|
|
2334
|
+
feet: 21;
|
|
2335
|
+
}>;
|
|
2336
|
+
```
|
|
2337
|
+
|
|
2338
|
+
### `dredless/protocol/ship-management`
|
|
2339
|
+
|
|
2340
|
+
```ts
|
|
2341
|
+
const BAN_ACTION: "ban";
|
|
2342
|
+
const DEMOTE_SELF_ACTION: "demote_self";
|
|
2343
|
+
const KICK_ACTION: "kick";
|
|
2344
|
+
const PLAYER_LIST_ACTION: "player_list";
|
|
2345
|
+
const INVITE_RESET_ACTION: "invite_reset";
|
|
2346
|
+
const SET_PRIVACY_ACTION: "set_privacy";
|
|
2347
|
+
const SET_RANK_ACTION: "set_rank";
|
|
2348
|
+
const SHIP_MANAGEMENT_TYPE: 4;
|
|
2349
|
+
const STARTER_RECOVERY_ACTION: "starter_recovery";
|
|
2350
|
+
```
|
|
2351
|
+
|
|
2352
|
+
### `dredless/protocol/sign`
|
|
2353
|
+
|
|
2354
|
+
```ts
|
|
2355
|
+
const SIGN_TEXT_COMMAND: "sign_text";
|
|
2356
|
+
const SIGN_DISPLAY_MODES: Map<0 | 1 | 2, "always" | "when-near" | "on-hover">;
|
|
2357
|
+
```
|
|
2358
|
+
|
|
2359
|
+
### `dredless/protocol/ui-config`
|
|
2360
|
+
|
|
2361
|
+
```ts
|
|
2362
|
+
const CLIPBOARD_ACTION: 1;
|
|
2363
|
+
const CLIPBOARD_ANGLE_COMMAND: "angle";
|
|
2364
|
+
const CLIPBOARD_FIXED_ANGLE_COMMAND: "angle_fixed";
|
|
2365
|
+
const CLIPBOARD_TARGET_VALUES: Map<string, number>;
|
|
2366
|
+
const FIXED_ANGLE_VALUES: Map<string, 0 | 1 | 2 | 3>;
|
|
2367
|
+
const GENERATOR_MAZE_PUZZLE_COMMAND: "maze_puzzle";
|
|
2368
|
+
const LOADER_CONFIG_COMMAND: "config_loader";
|
|
2369
|
+
const LOADER_FALSE: 0x8e;
|
|
2370
|
+
const LOADER_FILTER_CONFIG_COMMAND: "filter_config";
|
|
2371
|
+
const LOADER_FILTER_ITEMS_COMMAND: "filter_items";
|
|
2372
|
+
const LOADER_TRUE: 0x8d;
|
|
2373
|
+
const NAV_UNIT_COMMAND: "config_nav_unit";
|
|
2374
|
+
const NAV_UNIT_FALSE: 0x8d;
|
|
2375
|
+
const NAV_UNIT_TRUE: 0x8e;
|
|
2376
|
+
const PUSHER_CONFIG_COMMAND: "config_pusher";
|
|
2377
|
+
const PUSHER_FILTER_ITEMS_COMMAND: "filter_items";
|
|
2378
|
+
```
|
|
2379
|
+
|
|
2380
|
+
## Usage Patterns
|
|
2381
|
+
|
|
2382
|
+
### Read loaders from a live client
|
|
2383
|
+
|
|
2384
|
+
Use [NODE_API.md](./NODE_API.md) or [BROWSER_API.md](./BROWSER_API.md) to start a client for the current runtime.
|
|
2385
|
+
|
|
2386
|
+
```js
|
|
2387
|
+
await client.whenReady();
|
|
2388
|
+
|
|
2389
|
+
for (const loader of client.currentShip().machines.loaders()) {
|
|
2390
|
+
console.log(loader.id, loader.pick, loader.place, loader.cycle);
|
|
2391
|
+
}
|
|
2392
|
+
```
|
|
2393
|
+
|
|
2394
|
+
### Read all nearby ships, including detailed loaded worlds when available
|
|
2395
|
+
|
|
2396
|
+
```js
|
|
2397
|
+
const ships = client.overworld().ships({
|
|
2398
|
+
includeWorld: true,
|
|
2399
|
+
includeModel: true,
|
|
2400
|
+
sort: "distance"
|
|
2401
|
+
});
|
|
2402
|
+
|
|
2403
|
+
for (const ship of ships) {
|
|
2404
|
+
const snapshot = ship.snapshot();
|
|
2405
|
+
console.log(snapshot.name, snapshot.hexCode, snapshot.hasWorldData);
|
|
2406
|
+
}
|
|
2407
|
+
```
|
|
2408
|
+
|
|
2409
|
+
### Use generic features before narrowing to a machine type
|
|
2410
|
+
|
|
2411
|
+
```js
|
|
2412
|
+
const entity = client.currentShip().entities.get(14);
|
|
2413
|
+
|
|
2414
|
+
if (entity.has("loader")) {
|
|
2415
|
+
const loader = entity.asLoader();
|
|
2416
|
+
loader.setCycle(10);
|
|
2417
|
+
}
|
|
2418
|
+
|
|
2419
|
+
if (entity.has("outline")) {
|
|
2420
|
+
console.log(entity.feature("outline"));
|
|
2421
|
+
}
|
|
2422
|
+
```
|
|
2423
|
+
|
|
2424
|
+
### Configure a pusher
|
|
2425
|
+
|
|
2426
|
+
```js
|
|
2427
|
+
const pusher = client.currentShip().machines.pusher(27);
|
|
2428
|
+
|
|
2429
|
+
pusher.configure({
|
|
2430
|
+
mode: "push",
|
|
2431
|
+
filteredMode: "pull",
|
|
2432
|
+
angle: 90,
|
|
2433
|
+
speed: 20,
|
|
2434
|
+
length: 30,
|
|
2435
|
+
filterInventory: true
|
|
2436
|
+
});
|
|
2437
|
+
```
|
|
2438
|
+
|
|
2439
|
+
### Configure a navigation unit
|
|
2440
|
+
|
|
2441
|
+
```js
|
|
2442
|
+
const nav = client.currentShip().machines.navigationUnit();
|
|
2443
|
+
|
|
2444
|
+
nav.setDestination(30, {
|
|
2445
|
+
autoWarpOnShieldFailure: true,
|
|
2446
|
+
autoWarpOnNoCaptains: false
|
|
2447
|
+
});
|
|
2448
|
+
```
|
|
2449
|
+
|
|
2450
|
+
## Cost Guidelines
|
|
2451
|
+
|
|
2452
|
+
Use handles for normal live code:
|
|
2453
|
+
|
|
2454
|
+
```js
|
|
2455
|
+
client.currentShip().entities.get(id);
|
|
2456
|
+
client.currentShip().machines.loader(id);
|
|
2457
|
+
```
|
|
2458
|
+
|
|
2459
|
+
Use raw grouped state for display, sorting, and cheap bulk reads:
|
|
2460
|
+
|
|
2461
|
+
```js
|
|
2462
|
+
client.currentShip().entities.raw();
|
|
2463
|
+
client.currentShip().machines.state();
|
|
2464
|
+
```
|
|
2465
|
+
|
|
2466
|
+
Use snapshots when you need immutable point-in-time data:
|
|
2467
|
+
|
|
2468
|
+
```js
|
|
2469
|
+
entity.snapshot();
|
|
2470
|
+
client.currentShip().entities.snapshots();
|
|
2471
|
+
client.state({ includeModel: true });
|
|
2472
|
+
```
|
|
2473
|
+
|
|
2474
|
+
Use debug and world/model classes when reverse engineering, replaying captures,
|
|
2475
|
+
or validating protocol assumptions:
|
|
2476
|
+
|
|
2477
|
+
```js
|
|
2478
|
+
client.debug.modelRecord(worldId, tableId, entityId);
|
|
2479
|
+
client.debug.decodeErrors();
|
|
2480
|
+
client.debug.worldStore();
|
|
2481
|
+
```
|