@genex-ai/multiplayer 0.17.6 → 0.17.8
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/PROTOCOL.md +101 -30
- package/README.md +35 -14
- package/WORLD-GLTF.md +109 -0
- package/WORLD-SCENE.md +135 -0
- package/dist/authority/fast-udp.d.ts +4 -2
- package/dist/authority/fast-udp.js +8 -46
- package/dist/authority/fast-webtransport.d.ts +26 -4
- package/dist/authority/fast-webtransport.js +12 -115
- package/dist/authority/index.d.ts +379 -41
- package/dist/authority/index.js +247 -47
- package/dist/authority/module.d.ts +2 -1
- package/dist/authority/module.js +1 -1
- package/dist/bridge-authority.d.ts +3 -2
- package/dist/bridge-authority.global.js +10 -9
- package/dist/bridge-authority.js +11 -6
- package/dist/bridge.global.js +5 -5
- package/dist/bridge.js +3 -3
- package/dist/chunk-2NGXXQDS.js +1916 -0
- package/dist/{chunk-ZSWF4VCN.js → chunk-CSQEEANB.js} +78 -2
- package/dist/{chunk-UX3F6YTV.js → chunk-FPWP22Y7.js} +1 -1
- package/dist/{chunk-5JGRFT2N.js → chunk-NFMGIKFZ.js} +879 -1898
- package/dist/{chunk-K3SF5VDS.js → chunk-OD6NRSX2.js} +3 -1
- package/dist/{chunk-7QVOIHJF.js → chunk-QY3QQNDJ.js} +2 -2
- package/dist/{chunk-Y6XHXDIK.js → chunk-QZOCUQJT.js} +820 -537
- package/dist/chunk-TSYEWPVO.js +44 -0
- package/dist/chunk-TVTVIMIH.js +675 -0
- package/dist/chunk-YWQ3ALYY.js +69 -0
- package/dist/{fast-client-CZ41v-oB.d.ts → fast-client--A88q0kk.d.ts} +85 -4
- package/dist/index.js +3 -3
- package/dist/level-build-CbRqrYJq.d.ts +140 -0
- package/dist/{module-DqtFb5wA.d.ts → module-CSpXrzFc.d.ts} +151 -400
- package/dist/{physics-predict-49udN3a1.d.ts → physics-predict-C7ZB1gDG.d.ts} +18 -3
- package/dist/protocol.d.ts +87 -2
- package/dist/protocol.js +15 -1
- package/dist/shot-world-D22tqOUT.d.ts +485 -0
- package/dist/world-fit/index.d.ts +549 -0
- package/dist/world-fit/index.js +4763 -0
- package/dist/world-fit/three.d.ts +77 -0
- package/dist/world-fit/three.js +140 -0
- package/package.json +15 -3
|
@@ -0,0 +1,549 @@
|
|
|
1
|
+
import { C as ClaimVerdict } from '../shot-world-D22tqOUT.js';
|
|
2
|
+
export { J as WorldLimits } from '../shot-world-D22tqOUT.js';
|
|
3
|
+
import { L as LevelScene, a as LevelHull } from '../level-build-CbRqrYJq.js';
|
|
4
|
+
export { b as LEVEL_LIMITS, c as LevelCollide, d as LevelMark, e as LevelRefusal, f as LevelRefusalCode, g as LevelShape, R as RawWorldScene, l as levelMarkOf } from '../level-build-CbRqrYJq.js';
|
|
5
|
+
|
|
6
|
+
interface Lattice {
|
|
7
|
+
/** Cell side in scene units. */
|
|
8
|
+
readonly h: number;
|
|
9
|
+
/** The corner of cell (0, 0, 0). A point's centre is x0 + (i + 0.5) h; a plane of height is z0 + k h. */
|
|
10
|
+
readonly x0: number;
|
|
11
|
+
readonly y0: number;
|
|
12
|
+
readonly z0: number;
|
|
13
|
+
readonly nx: number;
|
|
14
|
+
readonly ny: number;
|
|
15
|
+
readonly nz: number;
|
|
16
|
+
/** 32-bit words a column. */
|
|
17
|
+
readonly w: number;
|
|
18
|
+
}
|
|
19
|
+
type Layer = Uint32Array;
|
|
20
|
+
|
|
21
|
+
/** The format's name and the one version this reader takes. A new meaning is a new version, never a changed one. */
|
|
22
|
+
declare const WORLD_SCENE_FORMAT = "genex-world-scene";
|
|
23
|
+
declare const WORLD_SCENE_VERSION = 1;
|
|
24
|
+
/** Which traces a surface answers. `move` stops a hull, `shot` stops a bullet. A clip wall is `move` only, a thin fence
|
|
25
|
+
* a hull may not walk through and a bullet may pass is `move` too, a mesh that stops bullets alone is `shot`. */
|
|
26
|
+
declare const SceneChannel: {
|
|
27
|
+
readonly Move: "move";
|
|
28
|
+
readonly Shot: "shot";
|
|
29
|
+
};
|
|
30
|
+
type SceneChannel = (typeof SceneChannel)[keyof typeof SceneChannel];
|
|
31
|
+
/** Tags the fit reads. Any other tag is carried through for the game's own use. */
|
|
32
|
+
declare const SceneTag: {
|
|
33
|
+
/** Moves or disappears at run time: never part of the static world. Named in the report. */
|
|
34
|
+
readonly Movable: "movable";
|
|
35
|
+
/** May be simplified or dropped when a budget runs out, before anything else that costs reach. */
|
|
36
|
+
readonly Prop: "prop";
|
|
37
|
+
};
|
|
38
|
+
type SceneTag = (typeof SceneTag)[keyof typeof SceneTag];
|
|
39
|
+
declare const SceneSurfaceKind: {
|
|
40
|
+
readonly Box: "box";
|
|
41
|
+
readonly Hull: "hull";
|
|
42
|
+
readonly Sphere: "sphere";
|
|
43
|
+
readonly Capsule: "capsule";
|
|
44
|
+
readonly Mesh: "mesh";
|
|
45
|
+
readonly Heightfield: "heightfield";
|
|
46
|
+
};
|
|
47
|
+
type SceneSurfaceKind = (typeof SceneSurfaceKind)[keyof typeof SceneSurfaceKind];
|
|
48
|
+
type SceneVec3 = readonly [number, number, number];
|
|
49
|
+
interface SurfaceCommon {
|
|
50
|
+
/** Defaults to both channels. */
|
|
51
|
+
readonly channels?: readonly SceneChannel[];
|
|
52
|
+
readonly tags?: readonly string[];
|
|
53
|
+
}
|
|
54
|
+
/** An oriented box: `axes` are three orthonormal rows (identity when left out), `half` the half extents along them. */
|
|
55
|
+
interface SceneBox extends SurfaceCommon {
|
|
56
|
+
readonly kind: 'box';
|
|
57
|
+
readonly center: SceneVec3;
|
|
58
|
+
readonly axes?: readonly [SceneVec3, SceneVec3, SceneVec3];
|
|
59
|
+
readonly half: SceneVec3;
|
|
60
|
+
}
|
|
61
|
+
/** The convex hull of its points. */
|
|
62
|
+
interface SceneHull extends SurfaceCommon {
|
|
63
|
+
readonly kind: 'hull';
|
|
64
|
+
readonly points: readonly SceneVec3[];
|
|
65
|
+
}
|
|
66
|
+
interface SceneSphere extends SurfaceCommon {
|
|
67
|
+
readonly kind: 'sphere';
|
|
68
|
+
readonly center: SceneVec3;
|
|
69
|
+
readonly radius: number;
|
|
70
|
+
}
|
|
71
|
+
interface SceneCapsule extends SurfaceCommon {
|
|
72
|
+
readonly kind: 'capsule';
|
|
73
|
+
readonly a: SceneVec3;
|
|
74
|
+
readonly b: SceneVec3;
|
|
75
|
+
readonly radius: number;
|
|
76
|
+
}
|
|
77
|
+
/** Triangles: x y z per vertex, three indices per triangle. Open or closed, wound either way: the surface is what counts. */
|
|
78
|
+
interface SceneMesh extends SurfaceCommon {
|
|
79
|
+
readonly kind: 'mesh';
|
|
80
|
+
readonly vertices: Float32Array;
|
|
81
|
+
readonly indices: Uint32Array;
|
|
82
|
+
}
|
|
83
|
+
/** A regular grid of heights (a landscape, a terrain): `heights[row * cols + col]` at
|
|
84
|
+
* `origin + (col * cell[0], row * cell[1])`. Solid below its surface. NaN in `heights` is a hole. */
|
|
85
|
+
interface SceneHeightfield extends SurfaceCommon {
|
|
86
|
+
readonly kind: 'heightfield';
|
|
87
|
+
readonly origin: readonly [number, number];
|
|
88
|
+
readonly cell: readonly [number, number];
|
|
89
|
+
readonly cols: number;
|
|
90
|
+
readonly rows: number;
|
|
91
|
+
readonly heights: Float32Array;
|
|
92
|
+
}
|
|
93
|
+
type SceneSurface = SceneBox | SceneHull | SceneSphere | SceneCapsule | SceneMesh | SceneHeightfield;
|
|
94
|
+
interface SceneActor {
|
|
95
|
+
/** What a refusal names: the engine's own name for it, so a creator can find it. */
|
|
96
|
+
readonly name: string;
|
|
97
|
+
readonly tags: readonly string[];
|
|
98
|
+
readonly surfaces: readonly SceneSurface[];
|
|
99
|
+
}
|
|
100
|
+
interface SceneSpawn {
|
|
101
|
+
readonly at: SceneVec3;
|
|
102
|
+
readonly name?: string;
|
|
103
|
+
readonly tags?: readonly string[];
|
|
104
|
+
}
|
|
105
|
+
/** The hull the fit serves, in scene units: the room's own firstperson parameters. */
|
|
106
|
+
interface SceneHullSize {
|
|
107
|
+
/** Half the side of the square footprint. */
|
|
108
|
+
readonly radius: number;
|
|
109
|
+
readonly height: number;
|
|
110
|
+
readonly crouchHeight: number;
|
|
111
|
+
/** The highest ledge walked up without a jump. */
|
|
112
|
+
readonly step: number;
|
|
113
|
+
/** The highest a jump lifts the feet. */
|
|
114
|
+
readonly jump: number;
|
|
115
|
+
/** The farthest a running jump carries over flat ground. */
|
|
116
|
+
readonly leap: number;
|
|
117
|
+
}
|
|
118
|
+
/** Where a creator says a level ends, in plan: the fit adds solid around it, and over it at `ceiling` if one is stated. */
|
|
119
|
+
interface SceneBound {
|
|
120
|
+
readonly min: readonly [number, number];
|
|
121
|
+
readonly max: readonly [number, number];
|
|
122
|
+
readonly ceiling?: number;
|
|
123
|
+
}
|
|
124
|
+
interface WorldScene {
|
|
125
|
+
readonly format: typeof WORLD_SCENE_FORMAT;
|
|
126
|
+
readonly version: typeof WORLD_SCENE_VERSION;
|
|
127
|
+
/** World units in a metre: what the report's areas are in, and how a missing `hull` is sized. */
|
|
128
|
+
readonly unitsPerMeter: number;
|
|
129
|
+
/** Where the scene came from, for the report: `{ engine, level, tool }` or whatever an exporter knows. */
|
|
130
|
+
readonly source?: Readonly<Record<string, string>>;
|
|
131
|
+
readonly hull?: SceneHullSize;
|
|
132
|
+
readonly actors: readonly SceneActor[];
|
|
133
|
+
readonly spawns: readonly SceneSpawn[];
|
|
134
|
+
readonly bound?: SceneBound;
|
|
135
|
+
}
|
|
136
|
+
/** Why a scene was refused: the path of the first bad value. */
|
|
137
|
+
declare class WorldSceneError extends RangeError {
|
|
138
|
+
readonly path: string;
|
|
139
|
+
constructor(path: string, message: string);
|
|
140
|
+
}
|
|
141
|
+
/** Checks a scene as read from JSON and decodes its arrays. Throws {@link WorldSceneError} with the first bad value's path. */
|
|
142
|
+
declare function parseWorldScene(raw: unknown): WorldScene;
|
|
143
|
+
/** Whether a surface answers a channel. A surface that names no channels answers both. */
|
|
144
|
+
declare function surfaceAnswers(surface: SceneSurface, channel: SceneChannel): boolean;
|
|
145
|
+
|
|
146
|
+
type WorldBox = [number, number, number, number, number, number];
|
|
147
|
+
type WorldRamp = [number, number, number, number, number, number, number, number, number];
|
|
148
|
+
declare const SolidStage: {
|
|
149
|
+
readonly Exact: "exact";
|
|
150
|
+
readonly Ramp: "ramp";
|
|
151
|
+
readonly Tile: "tile";
|
|
152
|
+
readonly Cover: "cover";
|
|
153
|
+
readonly Prop: "prop";
|
|
154
|
+
};
|
|
155
|
+
type SolidStage = (typeof SolidStage)[keyof typeof SolidStage];
|
|
156
|
+
|
|
157
|
+
/** The cells to clear from a hull-footprint layer so the lattice sees the doors it can't, as a layer of its own: a check of a
|
|
158
|
+
* fitted world clears the same ones, since the fit leaves them open by the same reasoning. */
|
|
159
|
+
/** A door a hull clears by under a cell, between walls the fit can't keep exact: its cover can't hold a gap finer than its lattice
|
|
160
|
+
* without either closing it or widening it into a place a hull stands on nothing the source has. It is kept shut and named. */
|
|
161
|
+
interface ShutDoor {
|
|
162
|
+
readonly actor: string;
|
|
163
|
+
readonly at: readonly [number, number, number];
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
interface Reach {
|
|
167
|
+
/** Each hull position standing: column * nz + height cell. */
|
|
168
|
+
readonly nodes: Int32Array;
|
|
169
|
+
readonly count: number;
|
|
170
|
+
/** One bit per standing position. */
|
|
171
|
+
readonly standing: Layer;
|
|
172
|
+
/** Every cell a hull's body was in, on a hull position's column. */
|
|
173
|
+
readonly body: Layer;
|
|
174
|
+
/** Columns a hull fell out of the bottom of everything from, one a column. */
|
|
175
|
+
readonly fell: Uint8Array;
|
|
176
|
+
readonly fellOut: number;
|
|
177
|
+
/** Spawns with nowhere to stand within the lattice, by index. */
|
|
178
|
+
readonly unplaced: readonly number[];
|
|
179
|
+
}
|
|
180
|
+
interface ReachCompare {
|
|
181
|
+
readonly truthNodes: number;
|
|
182
|
+
readonly fitNodes: number;
|
|
183
|
+
/** Truth's positions the fit has nothing for within the height tolerance, and the same the other way. */
|
|
184
|
+
readonly lostNodes: number;
|
|
185
|
+
readonly extraNodes: number;
|
|
186
|
+
readonly lostPct: number;
|
|
187
|
+
/** Of the lost, the share with no position of the fit's within the slack: real, not a wall's face moved. */
|
|
188
|
+
readonly lostBeyondSlackPct: number;
|
|
189
|
+
readonly extraPct: number;
|
|
190
|
+
readonly worstLostM2: number;
|
|
191
|
+
readonly worstExtraM2: number;
|
|
192
|
+
/** Extra positions with no source surface near the feet and the source above them: under a floor. A hard fail. A hull
|
|
193
|
+
* above everything the source has is lifted, which is the floor figures' business. */
|
|
194
|
+
readonly underFloorNodes: number;
|
|
195
|
+
/** Columns a hull falls out of the level from where the source holds it. A hard fail. */
|
|
196
|
+
readonly newFalls: number;
|
|
197
|
+
/** Lost positions beyond the slack, to repair. */
|
|
198
|
+
readonly lost: readonly number[];
|
|
199
|
+
readonly extra: readonly number[];
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/** How a fit ended. Only `ok` carries a world. */
|
|
203
|
+
declare const FitStatus: {
|
|
204
|
+
readonly Ok: "ok";
|
|
205
|
+
/** Even the coarsest fit needs more solids than the budget. */
|
|
206
|
+
readonly OverBudget: "over_budget";
|
|
207
|
+
/** A hull gets under the source's floor or out of the level in every fit tried. */
|
|
208
|
+
readonly FallsThrough: "falls_through";
|
|
209
|
+
/** A fit within budget loses more reach than a fit may. */
|
|
210
|
+
readonly ReachLost: "reach_lost";
|
|
211
|
+
/** A gap the source has shut is open, or shut by less than the stated margin, in every fit tried: never a world. */
|
|
212
|
+
readonly OpenSlits: "open_slits";
|
|
213
|
+
/** In every fit tried, feet stay further from the source's floor than a player can miss, and the budget cannot buy them back. */
|
|
214
|
+
readonly FloorOver: "floor_over";
|
|
215
|
+
/** No spawn stands anywhere, so there is no reach to fit. */
|
|
216
|
+
readonly NoReach: "no_reach";
|
|
217
|
+
};
|
|
218
|
+
type FitStatus = (typeof FitStatus)[keyof typeof FitStatus];
|
|
219
|
+
interface FitOptions {
|
|
220
|
+
readonly maxBoxes: number;
|
|
221
|
+
readonly maxRamps: number;
|
|
222
|
+
/** A finer or coarser lattice than the level's size asks for, in scene units. */
|
|
223
|
+
readonly cell?: number;
|
|
224
|
+
/** A fixed floor range and slack rather than a search: for tests and comparisons. */
|
|
225
|
+
readonly rung?: FitRung;
|
|
226
|
+
/** Skips the repair rounds: what the unchecked fit gives. For tests. */
|
|
227
|
+
readonly noRepair?: boolean;
|
|
228
|
+
readonly keepProbe?: boolean;
|
|
229
|
+
readonly log?: (line: string) => void;
|
|
230
|
+
}
|
|
231
|
+
interface FitRung {
|
|
232
|
+
/** Cells of height a floor tile may span. */
|
|
233
|
+
readonly floorRange: number;
|
|
234
|
+
/** Cells a wall may recede from a hull. */
|
|
235
|
+
readonly slack: number;
|
|
236
|
+
/** Small actors as a box a surface. */
|
|
237
|
+
readonly props: boolean;
|
|
238
|
+
}
|
|
239
|
+
interface FitActorCost {
|
|
240
|
+
readonly name: string;
|
|
241
|
+
readonly boxes: number;
|
|
242
|
+
readonly ramps: number;
|
|
243
|
+
/** The reach this actor's bounds stand on: what a creator loses by making it one box. */
|
|
244
|
+
readonly reachIfBoxedPct: number;
|
|
245
|
+
}
|
|
246
|
+
/** Sampled hull positions: the highest surface under the footprint in the fit, against the same in the source. */
|
|
247
|
+
/** How far the source's reach runs past what the level holds. Flagged, never refused: a creator answers with a `bound`. */
|
|
248
|
+
interface FitReachExtent {
|
|
249
|
+
/** The plan of the spawns and every actor but flat ground as wide as the level. */
|
|
250
|
+
readonly coreMin: readonly [number, number];
|
|
251
|
+
readonly coreMax: readonly [number, number];
|
|
252
|
+
readonly reachM2: number;
|
|
253
|
+
/** What a hull gets to from a spawn walking and stepping, with no jump. */
|
|
254
|
+
readonly walkedM2: number;
|
|
255
|
+
/** The share of the reach only a jump gets to. */
|
|
256
|
+
readonly beyondWalkPct: number;
|
|
257
|
+
/** The share of the reach further than a run jump past the plan of all that walking gets to. */
|
|
258
|
+
readonly outsideWalkedPct: number;
|
|
259
|
+
/** The reach further than a run jump past the core. */
|
|
260
|
+
readonly outsideCoreM2: number;
|
|
261
|
+
readonly outsideCorePct: number;
|
|
262
|
+
readonly farthestFromCoreM: number;
|
|
263
|
+
/** The scene states a bound. */
|
|
264
|
+
readonly bounded: boolean;
|
|
265
|
+
readonly flagged: boolean;
|
|
266
|
+
}
|
|
267
|
+
interface FitFloorError {
|
|
268
|
+
readonly samples: number;
|
|
269
|
+
readonly p50Units: number;
|
|
270
|
+
readonly p95Units: number;
|
|
271
|
+
readonly p99Units: number;
|
|
272
|
+
/** The worst at the lattice's points. A real hull stands between them and can read more: see upperBoundUnits. */
|
|
273
|
+
readonly maxUnits: number;
|
|
274
|
+
/** No grounded hull, at any position over the reach, reads further from the source than this. A ledge's height wherever a
|
|
275
|
+
* footprint can overlap a ledge by a hair more in one world than the other. */
|
|
276
|
+
readonly upperBoundUnits: number;
|
|
277
|
+
/** The same with a hair's overlap taken out: at every position, a hull within half a cell reads the source's height to this. */
|
|
278
|
+
readonly edgeFreeUnits: number;
|
|
279
|
+
/** Share of positions standing above the source's surface. */
|
|
280
|
+
readonly abovePct: number;
|
|
281
|
+
/** The worst positions, so a creator can go and look: feet, and the highest surface under the footprint on each side. */
|
|
282
|
+
readonly worst: readonly {
|
|
283
|
+
readonly at: readonly [number, number, number];
|
|
284
|
+
readonly source: number;
|
|
285
|
+
readonly fit: number;
|
|
286
|
+
}[];
|
|
287
|
+
}
|
|
288
|
+
interface FitReport {
|
|
289
|
+
readonly status: FitStatus;
|
|
290
|
+
/** Why, in a sentence that names what to do. */
|
|
291
|
+
readonly detail: string;
|
|
292
|
+
readonly budget: {
|
|
293
|
+
readonly maxBoxes: number;
|
|
294
|
+
readonly maxRamps: number;
|
|
295
|
+
};
|
|
296
|
+
readonly boxes: number;
|
|
297
|
+
readonly ramps: number;
|
|
298
|
+
readonly stages: Readonly<Record<SolidStage, number>>;
|
|
299
|
+
readonly cell: number;
|
|
300
|
+
readonly rung: FitRung;
|
|
301
|
+
/** How far the fit's floors are from the source's, measured under a hull's whole footprint. Null if never checked. */
|
|
302
|
+
readonly floor: FitFloorError | null;
|
|
303
|
+
/** How far a floor tile may span, and a wall's face may recede: the settings of this fit, not its error. */
|
|
304
|
+
readonly floorTileSpanUnits: number;
|
|
305
|
+
readonly wallSlackUnits: number;
|
|
306
|
+
readonly reach: Omit<ReachCompare, 'lost' | 'extra'> & {
|
|
307
|
+
readonly truthFellOut: number;
|
|
308
|
+
readonly fitFellOut: number;
|
|
309
|
+
};
|
|
310
|
+
/** How much narrower a hull could be and still fit nowhere the source's doesn't: a gap shut in the source stays shut by this. */
|
|
311
|
+
readonly gapMarginUnits: number;
|
|
312
|
+
/** Gaps between solids the fit made shut by less than that margin, or open, too narrow for the lattice to see. Zero is the rule. */
|
|
313
|
+
readonly openSlits: number;
|
|
314
|
+
/** Doors a hull clears by under a lattice cell in walls the fit can't keep exact: shut in this world, by name. */
|
|
315
|
+
readonly narrowDoorsShut: readonly ShutDoor[];
|
|
316
|
+
/** Positions on a leaning face or a lip under a cell wide, with the face rising beside them, closed as no floor. */
|
|
317
|
+
readonly leanLedges: number;
|
|
318
|
+
readonly reachExtent: FitReachExtent;
|
|
319
|
+
/** Rounds of re-covering around places the check found a difference. */
|
|
320
|
+
readonly repairs: number;
|
|
321
|
+
readonly unreachableActors: number;
|
|
322
|
+
/** Named: what moves at run time and so is not in a static world. */
|
|
323
|
+
readonly movableActors: readonly string[];
|
|
324
|
+
/** Actors baked as boxes because the budget ran out. */
|
|
325
|
+
readonly cutProps: readonly string[];
|
|
326
|
+
/** The costliest actors, first. On a refusal these are what to simplify. */
|
|
327
|
+
readonly actors: readonly FitActorCost[];
|
|
328
|
+
readonly spawnsNotPlaced: readonly string[];
|
|
329
|
+
readonly seconds: number;
|
|
330
|
+
}
|
|
331
|
+
interface FitWorld {
|
|
332
|
+
readonly boxes: readonly WorldBox[];
|
|
333
|
+
readonly ramps: readonly WorldRamp[];
|
|
334
|
+
readonly hash: number;
|
|
335
|
+
}
|
|
336
|
+
interface FitResult {
|
|
337
|
+
readonly report: FitReport;
|
|
338
|
+
/** Present only with status `ok`. */
|
|
339
|
+
readonly world: FitWorld | null;
|
|
340
|
+
/** With `keepProbe`: the lattice and the source's reach, and what the last try placed even when refused. */
|
|
341
|
+
readonly probe?: FitProbe;
|
|
342
|
+
}
|
|
343
|
+
/** What a test needs to walk a world over the source's own reach. */
|
|
344
|
+
interface FitProbe {
|
|
345
|
+
readonly l: Lattice;
|
|
346
|
+
readonly truth: Reach;
|
|
347
|
+
readonly attempted: {
|
|
348
|
+
readonly boxes: readonly WorldBox[];
|
|
349
|
+
readonly ramps: readonly WorldRamp[];
|
|
350
|
+
};
|
|
351
|
+
/** The flood of what was placed, when it was checked. */
|
|
352
|
+
readonly fitted: Reach | null;
|
|
353
|
+
}
|
|
354
|
+
/** Feet against the highest surface under the footprint, in hull radii: at the 99th percentile and at worst. Past this a player sees
|
|
355
|
+
* the float. Floors win over budget: a level that cannot hold them is refused by name, never fitted floating. */
|
|
356
|
+
declare const FLOOR_P99_RADII = 0.5;
|
|
357
|
+
declare const FLOOR_MAX_RADII = 1;
|
|
358
|
+
/** The actor a stated bound's solid goes by, in a report and a budget. */
|
|
359
|
+
declare const BOUND_ACTOR = "Bound";
|
|
360
|
+
declare function sceneHull(scene: WorldScene): SceneHullSize;
|
|
361
|
+
/** §17.7's hash: 32-bit FNV-1a over the counts and every value as a little-endian binary32. */
|
|
362
|
+
declare function fitWorldHash(boxes: readonly (readonly number[])[], ramps: readonly (readonly number[])[]): number;
|
|
363
|
+
/** The ladder, finest first. Floors loosen before walls: a floor's error is a foot's height, a wall's is a clipped shoulder. */
|
|
364
|
+
declare function fitRungs(hull: SceneHullSize, h: number): readonly FitRung[];
|
|
365
|
+
/** Where a hull can be in a scene, with no world made: what a shot world starts from. */
|
|
366
|
+
declare function sceneReach(scene: WorldScene, cell?: number): {
|
|
367
|
+
readonly hull: SceneHullSize;
|
|
368
|
+
readonly l: Lattice;
|
|
369
|
+
readonly truth: Reach;
|
|
370
|
+
};
|
|
371
|
+
/** Fits a scene to a world within a budget, or refuses by name. */
|
|
372
|
+
declare function fitScene(scene: WorldScene, options: FitOptions): FitResult;
|
|
373
|
+
|
|
374
|
+
/** How a shot fit ended. Only `ok` carries a world. */
|
|
375
|
+
declare const ShotFitStatus: {
|
|
376
|
+
readonly Ok: "ok";
|
|
377
|
+
/** Even the coarsest shot world needs more boxes or bytes than the budget. */
|
|
378
|
+
readonly OverBudget: "over_budget";
|
|
379
|
+
/** No spawn stands anywhere, so no muzzle sees anything. */
|
|
380
|
+
readonly NoReach: "no_reach";
|
|
381
|
+
/** Within budget, but rays disagree with the source past what a shot world may. */
|
|
382
|
+
readonly Inaccurate: "inaccurate";
|
|
383
|
+
};
|
|
384
|
+
type ShotFitStatus = (typeof ShotFitStatus)[keyof typeof ShotFitStatus];
|
|
385
|
+
interface ShotFitOptions {
|
|
386
|
+
readonly maxBoxes: number;
|
|
387
|
+
/** The shot world's JSON may be at most this long: what it adds to a module. */
|
|
388
|
+
readonly maxBytes?: number;
|
|
389
|
+
/** One lattice rather than the ladder, in scene units. */
|
|
390
|
+
readonly cell?: number;
|
|
391
|
+
/** Rays the report's accuracy is read from. */
|
|
392
|
+
readonly rays?: number;
|
|
393
|
+
/** Least facings to measure claims at, for choosing `MIN_CLAIM_FACING` from data. */
|
|
394
|
+
readonly facings?: readonly number[];
|
|
395
|
+
/** A surface further than this from any hull is not in it. Default 1,024 hull radii. */
|
|
396
|
+
readonly range?: number;
|
|
397
|
+
readonly log?: (line: string) => void;
|
|
398
|
+
}
|
|
399
|
+
/** Rays from where a hull stands, the fitted world against the source's own surfaces. */
|
|
400
|
+
interface ShotAccuracy {
|
|
401
|
+
readonly rays: number;
|
|
402
|
+
/** Share of rays on which one world stopped the ray and the other did not. */
|
|
403
|
+
readonly hitMissPct: number;
|
|
404
|
+
/** The source stopped it, the shot world did not: a bullet through a wall. */
|
|
405
|
+
readonly passesPct: number;
|
|
406
|
+
/** The shot world stopped it, the source did not: a bullet stopped by air. */
|
|
407
|
+
readonly stopsPct: number;
|
|
408
|
+
/** Rays both stop: how far apart along the ray. */
|
|
409
|
+
readonly stopped: number;
|
|
410
|
+
readonly p50Units: number;
|
|
411
|
+
readonly p95Units: number;
|
|
412
|
+
readonly p99Units: number;
|
|
413
|
+
readonly maxUnits: number;
|
|
414
|
+
/** Where the fit's stops are from a surface of the source, on any axis, by steps of the lattice. Along a ray a near miss of an edge reads
|
|
415
|
+
* as the whole way to the next wall; this reads what is really off. */
|
|
416
|
+
readonly surfaceP50Units: number;
|
|
417
|
+
readonly surfaceP99Units: number;
|
|
418
|
+
readonly surfaceMaxUnits: number;
|
|
419
|
+
/** The worst rays, so a creator can go and look. */
|
|
420
|
+
readonly worst: readonly {
|
|
421
|
+
readonly from: readonly [number, number, number];
|
|
422
|
+
readonly dir: readonly [number, number, number];
|
|
423
|
+
readonly source: number | null;
|
|
424
|
+
readonly fit: number | null;
|
|
425
|
+
}[];
|
|
426
|
+
}
|
|
427
|
+
/** What a tolerance is worth, read from the same rays by the rule a room's `ctx.world.claim` uses. */
|
|
428
|
+
interface ShotClaimMargin {
|
|
429
|
+
readonly toleranceUnits: number;
|
|
430
|
+
/** The least a ray is taken to face a surface: `tolerance / minFacing` is the most a graze reaches along the ray. */
|
|
431
|
+
readonly minFacing: number;
|
|
432
|
+
/** Rays either world stops on which an honest claim, the source's own stop, is refused or capped. */
|
|
433
|
+
readonly honestOffPct: number;
|
|
434
|
+
/** Rays the source stops on which a hostile claim, `HOSTILE_PAST_RADII` beyond the source's stop, stands: a body behind what it hit. */
|
|
435
|
+
readonly hostilePassPct: number;
|
|
436
|
+
/** How far past the source's real surface the most a claim may say reaches. */
|
|
437
|
+
readonly hostileGainP50Units: number;
|
|
438
|
+
readonly hostileGainP99Units: number;
|
|
439
|
+
readonly hostileGainMaxUnits: number;
|
|
440
|
+
}
|
|
441
|
+
interface ShotActorCost {
|
|
442
|
+
readonly name: string;
|
|
443
|
+
readonly boxes: number;
|
|
444
|
+
}
|
|
445
|
+
interface ShotFitReport {
|
|
446
|
+
readonly status: ShotFitStatus;
|
|
447
|
+
/** Why, in a sentence that names what to do. */
|
|
448
|
+
readonly detail: string;
|
|
449
|
+
readonly budget: {
|
|
450
|
+
readonly maxBoxes: number;
|
|
451
|
+
readonly maxBytes: number;
|
|
452
|
+
};
|
|
453
|
+
readonly boxes: number;
|
|
454
|
+
/** Source boxes on the axes, kept to a grid of a few hundredths of a cell. */
|
|
455
|
+
readonly exactBoxes: number;
|
|
456
|
+
readonly coverBoxes: number;
|
|
457
|
+
/** What it adds to a module, as JSON. */
|
|
458
|
+
readonly bytes: number;
|
|
459
|
+
readonly cell: number;
|
|
460
|
+
/** How far off a surface this world's stops are at the 99th percentile, at least a grid step: the world's own `tolerance`. */
|
|
461
|
+
readonly toleranceUnits: number;
|
|
462
|
+
readonly accuracy: ShotAccuracy | null;
|
|
463
|
+
/** Tolerances, measured: the cheat margin each buys and the honest shots each refuses. */
|
|
464
|
+
readonly claims: readonly ShotClaimMargin[];
|
|
465
|
+
/** With `facings`: the same at each of them, at each tolerance. */
|
|
466
|
+
readonly claimGrid: readonly ShotClaimMargin[];
|
|
467
|
+
/** Share of the lattice's cells a muzzle's line can reach. */
|
|
468
|
+
readonly seenAirPct: number;
|
|
469
|
+
/** Named: what moves at run time and so is not in a static world. */
|
|
470
|
+
readonly movableActors: readonly string[];
|
|
471
|
+
/** Actors no muzzle sees: nothing of them is in the world. */
|
|
472
|
+
readonly unseenActors: readonly string[];
|
|
473
|
+
/** The costliest actors, first. */
|
|
474
|
+
readonly actors: readonly ShotActorCost[];
|
|
475
|
+
readonly seconds: number;
|
|
476
|
+
}
|
|
477
|
+
/** What a module exports as `shotWorld`. */
|
|
478
|
+
interface ShotWorld {
|
|
479
|
+
readonly boxes: readonly (readonly number[])[];
|
|
480
|
+
readonly ramps: readonly (readonly number[])[];
|
|
481
|
+
readonly tolerance: number;
|
|
482
|
+
}
|
|
483
|
+
interface ShotFitResult {
|
|
484
|
+
readonly report: ShotFitReport;
|
|
485
|
+
readonly world: ShotWorld | null;
|
|
486
|
+
}
|
|
487
|
+
/** Where a hostile claim says a shot stopped, past the source's stop: a body behind what it hit. */
|
|
488
|
+
declare const HOSTILE_PAST_RADII = 3;
|
|
489
|
+
/** A ray through a fitted shot world, by the rule a room's `ctx.world.ray` uses: boxes as open solids. For the fit's own check and tests. */
|
|
490
|
+
declare function shotRay(world: ShotWorld, origin: readonly [number, number, number], dir: readonly [number, number, number], range?: number): {
|
|
491
|
+
readonly dist: number;
|
|
492
|
+
readonly solid: number;
|
|
493
|
+
readonly axis: number;
|
|
494
|
+
} | null;
|
|
495
|
+
/** A verdict from a ray's stop, with no ray in it: the rule of a room's `ctx.world.claim` for a weapon that does not pierce (guest-prelude.ts
|
|
496
|
+
* `worldClaim`, held to it by authority-host's world-claim-model.test.ts). `facing` is how squarely the ray meets its stop, 1 for none. */
|
|
497
|
+
declare function claimArithmetic(server: number, facing: number, claimed: number | null, tolerance: number, range: number, minFacing?: number): {
|
|
498
|
+
readonly dist: number;
|
|
499
|
+
readonly verdict: ClaimVerdict;
|
|
500
|
+
readonly slack: number;
|
|
501
|
+
};
|
|
502
|
+
/** What a room's `ctx.world.claim` answers for a weapon that does not pierce: for a report to measure, and a test to hold to the room. */
|
|
503
|
+
declare function claimedStop(world: ShotWorld, origin: readonly [number, number, number], dir: readonly [number, number, number], claimed: number | null, tolerance: number, range: number, minFacing?: number): {
|
|
504
|
+
readonly dist: number;
|
|
505
|
+
readonly verdict: ClaimVerdict;
|
|
506
|
+
readonly slack: number;
|
|
507
|
+
readonly server: number | null;
|
|
508
|
+
};
|
|
509
|
+
/** A ray against a scene's own shot surfaces: what an exporter's check holds its file to an engine's physics with. */
|
|
510
|
+
declare function sceneShotRays(scene: WorldScene): (origin: readonly [number, number, number], dir: readonly [number, number, number], range: number) => number | null;
|
|
511
|
+
/** Fits what a muzzle can see of a scene, within a budget, or refuses by name. */
|
|
512
|
+
declare function fitShotWorld(scene: WorldScene, options: ShotFitOptions): ShotFitResult;
|
|
513
|
+
|
|
514
|
+
/** Room units in a metre when a level does not say: the Source defaults every preset starts from. */
|
|
515
|
+
declare const DEFAULT_UNITS_PER_METER = 39.37;
|
|
516
|
+
interface GltfLevelOptions {
|
|
517
|
+
readonly unitsPerMeter?: number;
|
|
518
|
+
readonly hull?: LevelHull;
|
|
519
|
+
readonly spawns?: readonly {
|
|
520
|
+
readonly at: readonly [number, number, number];
|
|
521
|
+
readonly name?: string;
|
|
522
|
+
readonly tags?: readonly string[];
|
|
523
|
+
}[];
|
|
524
|
+
}
|
|
525
|
+
interface GltfLevel extends LevelScene {
|
|
526
|
+
readonly sha256: string;
|
|
527
|
+
}
|
|
528
|
+
/** Reads a `.glb` or `.gltf` into the scene format. Throws {@link LevelRefusal} naming what to change. Same file, same
|
|
529
|
+
* bytes and hash, on every OS: `json` is what to write and `sha256` its hash. */
|
|
530
|
+
declare function readGltfLevel(path: string, options?: GltfLevelOptions): GltfLevel;
|
|
531
|
+
|
|
532
|
+
/** Exit codes, as `genex world fit` has them: fine, a call that is not this command's, a level that is refused. */
|
|
533
|
+
declare const WorldGltfExit: {
|
|
534
|
+
readonly Ok: 0;
|
|
535
|
+
readonly Usage: 1;
|
|
536
|
+
readonly Refused: 3;
|
|
537
|
+
};
|
|
538
|
+
type WorldGltfExit = (typeof WorldGltfExit)[keyof typeof WorldGltfExit];
|
|
539
|
+
/** Where the lines go, the shape `genex world` hands in: `print` carries one result line a caller can parse, `error` what a
|
|
540
|
+
* person reads. */
|
|
541
|
+
interface WorldGltfIo {
|
|
542
|
+
readonly print: (line: string) => void;
|
|
543
|
+
readonly error: (line: string) => void;
|
|
544
|
+
}
|
|
545
|
+
/** Reads one level and writes its scene. Takes positional arguments and nothing else. Prints `SCENE {...}` on success
|
|
546
|
+
* and `REFUSED {"code","message"}` on a refusal, which writes nothing. */
|
|
547
|
+
declare function runWorldGltf(args: readonly string[], io?: WorldGltfIo): WorldGltfExit;
|
|
548
|
+
|
|
549
|
+
export { BOUND_ACTOR, DEFAULT_UNITS_PER_METER, FLOOR_MAX_RADII, FLOOR_P99_RADII, type FitActorCost, type FitFloorError, type FitOptions, type FitProbe, type FitReachExtent, type FitReport, type FitResult, type FitRung, FitStatus, type FitWorld, type GltfLevel, type GltfLevelOptions, HOSTILE_PAST_RADII, LevelHull, LevelScene, type SceneActor, type SceneBound, type SceneBox, type SceneCapsule, SceneChannel, type SceneHeightfield, type SceneHull, type SceneHullSize, type SceneMesh, type SceneSpawn, type SceneSphere, type SceneSurface, SceneSurfaceKind, SceneTag, type SceneVec3, type ShotAccuracy, type ShotActorCost, type ShotClaimMargin, type ShotFitOptions, type ShotFitReport, type ShotFitResult, ShotFitStatus, type ShotWorld, WORLD_SCENE_FORMAT, WORLD_SCENE_VERSION, WorldGltfExit, type WorldGltfIo, type WorldScene, WorldSceneError, claimArithmetic, claimedStop, fitRungs, fitScene, fitShotWorld, fitWorldHash, parseWorldScene, readGltfLevel, runWorldGltf, sceneHull, sceneReach, sceneShotRays, shotRay, surfaceAnswers };
|