@onimaxxing/worldgen-node 0.15.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 +442 -0
- package/editor_settings.d.ts +1034 -0
- package/index.cjs +147 -0
- package/index.d.ts +682 -0
- package/oni_wasm.d.ts +274 -0
- package/oni_wasm.js +1047 -0
- package/oni_wasm_bg.wasm +0 -0
- package/package.json +30 -0
- package/yaml.cjs +44 -0
- package/yaml.d.ts +19 -0
|
@@ -0,0 +1,1034 @@
|
|
|
1
|
+
// Type surface for the worldgen editor snapshot. Imported and
|
|
2
|
+
// re-exported by `crates/oni-wasm/index.d.ts`.
|
|
3
|
+
//
|
|
4
|
+
// Usage: the active settings live in a `{ path → JSON-string }` map.
|
|
5
|
+
// Parse the entry you want to edit, mutate, write back, then call
|
|
6
|
+
// `worldgen.snapshot.load(files)`.
|
|
7
|
+
//
|
|
8
|
+
// import init, { worldgen, type World } from
|
|
9
|
+
// '@onimaxxing/worldgen';
|
|
10
|
+
//
|
|
11
|
+
// await init();
|
|
12
|
+
// const files = worldgen.snapshot.files();
|
|
13
|
+
// const world: World = JSON.parse(files['worlds/SandstoneDefault']);
|
|
14
|
+
// world.iconScale = 2.0;
|
|
15
|
+
// files['worlds/SandstoneDefault'] = JSON.stringify(world);
|
|
16
|
+
// worldgen.snapshot.load(files);
|
|
17
|
+
// // Cluster cache invalidated; next worldgen.generate(...) uses mutated settings.
|
|
18
|
+
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
// Bundle aggregates.
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Worldgen settings: world/subworld/cluster defs, noise trees, biome
|
|
25
|
+
* configs, trait pool, feature settings, and the three mixing tables.
|
|
26
|
+
*/
|
|
27
|
+
export interface WorldgenBundle {
|
|
28
|
+
/** Global defaults applied when a world doesn't override them. */
|
|
29
|
+
defaults: DefaultSettings;
|
|
30
|
+
/**
|
|
31
|
+
* World definitions keyed by config path (e.g.
|
|
32
|
+
* `"worlds/SandstoneDefault"` for basegame,
|
|
33
|
+
* `"expansion1::worlds/VanillaSandstoneDefault"` for SpacedOut).
|
|
34
|
+
*/
|
|
35
|
+
worlds: Record<string, World>;
|
|
36
|
+
/**
|
|
37
|
+
* Subworld (biome/zone) definitions keyed by config path. Worlds
|
|
38
|
+
* reference these via `subworldFiles`.
|
|
39
|
+
*/
|
|
40
|
+
subworlds: Record<string, Subworld>;
|
|
41
|
+
/**
|
|
42
|
+
* Cluster layouts keyed by config path. Defines which worlds appear
|
|
43
|
+
* at which ring positions on the starmap.
|
|
44
|
+
*/
|
|
45
|
+
clusters: Record<string, ClusterLayout>;
|
|
46
|
+
/**
|
|
47
|
+
* Noise-tree definitions keyed by config path. Drives terrain shape
|
|
48
|
+
* (base noise), biome borders (override noise), and density fields.
|
|
49
|
+
*/
|
|
50
|
+
noise: Record<string, NoiseTree>;
|
|
51
|
+
/** Biome definitions (elemental banding, noise thresholds). */
|
|
52
|
+
biomes: Record<string, BiomeSettings>;
|
|
53
|
+
/**
|
|
54
|
+
* World trait pool. Each entry is a rollable trait (e.g.
|
|
55
|
+
* `GeoActive`, `Volcanoes`) and the modifiers it applies.
|
|
56
|
+
*/
|
|
57
|
+
traits: Record<string, WorldTrait>;
|
|
58
|
+
/**
|
|
59
|
+
* Story trait pool. Traits applied when the coordinate's story code
|
|
60
|
+
* (`SNDST-C-42-0-4A-*`) names them.
|
|
61
|
+
*/
|
|
62
|
+
story_traits: Record<string, WorldTrait>;
|
|
63
|
+
/** Per-feature configuration (geyser tables, ruins tables, etc.). */
|
|
64
|
+
feature_settings: Record<string, FeatureSettings>;
|
|
65
|
+
/**
|
|
66
|
+
* DLC-level mixing settings keyed by DLC id (e.g. `"expansion1"`).
|
|
67
|
+
* Controls which mixing options are available per cluster.
|
|
68
|
+
*/
|
|
69
|
+
dlc_mixing: Record<string, DlcMixingSettings>;
|
|
70
|
+
/**
|
|
71
|
+
* Whole-world mixing options: substitute one asteroid type for
|
|
72
|
+
* another (e.g. a Ceres world slotted in for Sandstone).
|
|
73
|
+
*/
|
|
74
|
+
world_mixing: Record<string, WorldMixingSettings>;
|
|
75
|
+
/**
|
|
76
|
+
* Subworld mixing options: substitute one biome for another within
|
|
77
|
+
* an asteroid.
|
|
78
|
+
*/
|
|
79
|
+
subworld_mixing: Record<string, SubworldMixingSettings>;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** Lookup tables referenced by name from `WorldgenBundle`. */
|
|
83
|
+
export interface LookupsBundle {
|
|
84
|
+
/** Mob spawn configs (critter placement rules) keyed by mob name. */
|
|
85
|
+
mobs: Record<string, MobConfig>;
|
|
86
|
+
/** Room placement configs keyed by room name. */
|
|
87
|
+
rooms: Record<string, RoomConfig>;
|
|
88
|
+
/** Named `[minKelvin, maxKelvin]` ranges. Subworlds reference these via `temperatureRange`. */
|
|
89
|
+
temperatures: Record<string, [number, number]>;
|
|
90
|
+
/** Pre-authored templates (bases, geyser rooms, POIs) keyed by template path. */
|
|
91
|
+
templates: Record<string, TemplateContainer>;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/** Full snapshot: worldgen and lookups in one blob. */
|
|
95
|
+
export interface FullBundle extends WorldgenBundle, LookupsBundle {}
|
|
96
|
+
|
|
97
|
+
// ---------------------------------------------------------------------------
|
|
98
|
+
// Primitives and shared shapes.
|
|
99
|
+
// ---------------------------------------------------------------------------
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Float range. Used for densities, starting-base positions,
|
|
103
|
+
* border sizes, and many other `{min, max}` fields. Min and max
|
|
104
|
+
* are both inclusive; `{min: 0.5, max: 0.5}` means "always 0.5".
|
|
105
|
+
*/
|
|
106
|
+
export interface MinMax {
|
|
107
|
+
/** Lower bound (inclusive). */
|
|
108
|
+
min: number;
|
|
109
|
+
/** Upper bound (inclusive). */
|
|
110
|
+
max: number;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Integer 2D vector. The Rust struct accepts uppercase `X/Y` from
|
|
115
|
+
* YAML but serializes lowercase `x/y`, which is the shape you'll
|
|
116
|
+
* always see from the WASM API.
|
|
117
|
+
*/
|
|
118
|
+
export interface Vector2I {
|
|
119
|
+
x: number;
|
|
120
|
+
y: number;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/** Integer `{x, y}` world dimensions in cells. */
|
|
124
|
+
export type WorldSize = Vector2I;
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Overworld-cell layout algorithm.
|
|
128
|
+
* - `Default`: standard Voronoi-tree layout (used by every stock world).
|
|
129
|
+
* - `PowerTree`: weighted Voronoi via MIConvexHull, used by a handful of
|
|
130
|
+
* special worlds.
|
|
131
|
+
*/
|
|
132
|
+
export type LayoutMethod = 'Default' | 'PowerTree';
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Display category. `Asteroid` is the usual; `Moon` is used for
|
|
136
|
+
* orbiting micro-worlds in SpacedOut.
|
|
137
|
+
*/
|
|
138
|
+
export type WorldCategory = 'Asteroid' | 'Moon';
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* How aggressively the template-spawning pass tries to satisfy a
|
|
142
|
+
* `TemplateSpawnRules` entry:
|
|
143
|
+
* - `GuaranteeOne`: fail worldgen if at least one can't be placed.
|
|
144
|
+
* - `GuaranteeSome`: guarantee `someCount`, fail otherwise.
|
|
145
|
+
* - `GuaranteeSomeTryMore`: `someCount` guaranteed, plus `moreCount`
|
|
146
|
+
* best-effort.
|
|
147
|
+
* - `GuaranteeAll`: fail if any of the listed names can't be placed.
|
|
148
|
+
* - `GuaranteeRange`: guarantee a count chosen uniformly in
|
|
149
|
+
* `[range.x, range.y]`.
|
|
150
|
+
* - `TryOne` / `TrySome` / `TryRange` / `TryAll`: best-effort variants
|
|
151
|
+
* that never fail worldgen.
|
|
152
|
+
*/
|
|
153
|
+
export type ListRule =
|
|
154
|
+
| 'GuaranteeOne'
|
|
155
|
+
| 'GuaranteeSome'
|
|
156
|
+
| 'GuaranteeSomeTryMore'
|
|
157
|
+
| 'GuaranteeAll'
|
|
158
|
+
| 'GuaranteeRange'
|
|
159
|
+
| 'TryOne'
|
|
160
|
+
| 'TrySome'
|
|
161
|
+
| 'TryRange'
|
|
162
|
+
| 'TryAll';
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* How an `AllowedCellsFilter` treats its `tag` reference.
|
|
166
|
+
* - `Default`: no tag filter.
|
|
167
|
+
* - `AtTag`: only cells with the tag.
|
|
168
|
+
* - `NotAtTag`: only cells without the tag.
|
|
169
|
+
* - `DistanceFromTag`: filter by `minDistance`/`maxDistance` cells
|
|
170
|
+
* away from any cell carrying the tag.
|
|
171
|
+
*/
|
|
172
|
+
export type TagCommand = 'Default' | 'AtTag' | 'NotAtTag' | 'DistanceFromTag';
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Set operation applied to the candidate-cell list when a filter is
|
|
176
|
+
* evaluated. `Replace` is the default (filter results become the new
|
|
177
|
+
* candidate set).
|
|
178
|
+
*/
|
|
179
|
+
export type FilterCommand =
|
|
180
|
+
| 'Clear'
|
|
181
|
+
| 'Replace'
|
|
182
|
+
| 'UnionWith'
|
|
183
|
+
| 'IntersectWith'
|
|
184
|
+
| 'ExceptWith'
|
|
185
|
+
| 'SymmetricExceptWith'
|
|
186
|
+
| 'All';
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Point-sampling strategy used when placing subworld centroids and
|
|
190
|
+
* mob/room sample points. `PoissonDisk` (the default) produces
|
|
191
|
+
* evenly-spaced points; `UniformSquare` is a dense grid used by a
|
|
192
|
+
* few special cases.
|
|
193
|
+
*/
|
|
194
|
+
export type SampleBehaviour = 'PoissonDisk' | 'UniformSquare';
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Subworld zone type. Drives the game's zone colour, the
|
|
198
|
+
* `StateTransition` background element, and some gameplay systems
|
|
199
|
+
* (e.g. Radioactive exposure). Ceres, Prehistoric, and DLC5 (Aquatic)
|
|
200
|
+
* add the later entries in the list.
|
|
201
|
+
*/
|
|
202
|
+
export type ZoneType =
|
|
203
|
+
| 'FrozenWastes'
|
|
204
|
+
| 'CrystalCaverns'
|
|
205
|
+
| 'BoggyMarsh'
|
|
206
|
+
| 'Sandstone'
|
|
207
|
+
| 'ToxicJungle'
|
|
208
|
+
| 'MagmaCore'
|
|
209
|
+
| 'OilField'
|
|
210
|
+
| 'Space'
|
|
211
|
+
| 'Ocean'
|
|
212
|
+
| 'Rust'
|
|
213
|
+
| 'Forest'
|
|
214
|
+
| 'Radioactive'
|
|
215
|
+
| 'Swamp'
|
|
216
|
+
| 'Wasteland'
|
|
217
|
+
| 'RocketInterior'
|
|
218
|
+
| 'Metallic'
|
|
219
|
+
| 'Barren'
|
|
220
|
+
| 'Moo'
|
|
221
|
+
| 'IceCaves'
|
|
222
|
+
| 'CarrotQuarry'
|
|
223
|
+
| 'SugarWoods'
|
|
224
|
+
| 'PrehistoricGarden'
|
|
225
|
+
| 'PrehistoricRaptor'
|
|
226
|
+
| 'PrehistoricWetlands'
|
|
227
|
+
| 'Abyss'
|
|
228
|
+
| 'Beach'
|
|
229
|
+
| 'KelpForest'
|
|
230
|
+
| 'Reef';
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Named temperature band that subworlds reference. The actual Kelvin
|
|
234
|
+
* range for each name lives in `LookupsBundle.temperatures`. Stock
|
|
235
|
+
* ONI defines 13 bands spanning extremely cold → extremely hot; the
|
|
236
|
+
* last few aliases are kept for older configs.
|
|
237
|
+
*/
|
|
238
|
+
export type TemperatureRange =
|
|
239
|
+
| 'ExtremelyCold'
|
|
240
|
+
| 'VeryVeryCold'
|
|
241
|
+
| 'VeryCold'
|
|
242
|
+
| 'Cold'
|
|
243
|
+
| 'Chilly'
|
|
244
|
+
| 'Cool'
|
|
245
|
+
| 'Mild'
|
|
246
|
+
| 'Room'
|
|
247
|
+
| 'HumanWarm'
|
|
248
|
+
| 'HumanHot'
|
|
249
|
+
| 'Hot'
|
|
250
|
+
| 'VeryHot'
|
|
251
|
+
| 'ExtremelyHot'
|
|
252
|
+
| 'HumanIdeal'
|
|
253
|
+
| 'HumanComfortable'
|
|
254
|
+
| 'HotMarginal'
|
|
255
|
+
| 'Warm'
|
|
256
|
+
| 'CoolMarginal';
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* A constraint on which overworld cells a subworld/template is
|
|
260
|
+
* allowed to occupy. Multiple filters chain via `command`; the
|
|
261
|
+
* allowed-cells set is reset/replaced/unioned/intersected in order
|
|
262
|
+
* by `sortOrder`.
|
|
263
|
+
*/
|
|
264
|
+
export interface AllowedCellsFilter {
|
|
265
|
+
/** How to interpret the `tag` reference (see {@link TagCommand}). */
|
|
266
|
+
tagcommand?: TagCommand;
|
|
267
|
+
/** Layout tag this filter keys off. Omitted when `tagcommand` is `Default`. */
|
|
268
|
+
tag?: string | null;
|
|
269
|
+
/** Minimum cell distance when `tagcommand` is `DistanceFromTag`. */
|
|
270
|
+
minDistance?: number;
|
|
271
|
+
/** Maximum cell distance when `tagcommand` is `DistanceFromTag`. */
|
|
272
|
+
maxDistance?: number;
|
|
273
|
+
/** Set operation applied to the running candidate set. */
|
|
274
|
+
command?: FilterCommand;
|
|
275
|
+
/** Only allow cells with a temperature-range matching one of these. */
|
|
276
|
+
temperatureRanges?: TemperatureRange[];
|
|
277
|
+
/** Only allow cells whose subworld zone-type matches one of these. */
|
|
278
|
+
zoneTypes?: ZoneType[];
|
|
279
|
+
/** Only allow cells whose subworld config path is in this list. */
|
|
280
|
+
subworldNames?: string[];
|
|
281
|
+
/** Evaluation order; lower values apply earlier in the chain. */
|
|
282
|
+
sortOrder?: number;
|
|
283
|
+
/**
|
|
284
|
+
* If `tag` is set but no cell in the world has it, drop this filter
|
|
285
|
+
* silently rather than failing the pass.
|
|
286
|
+
*/
|
|
287
|
+
ignoreIfMissingTag?: boolean;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* One entry in `World.worldTraitRules`. The roll picks between `min`
|
|
292
|
+
* and `max` traits for the world; `specificTraits` narrows the pool
|
|
293
|
+
* to a specific list; `required*`/`forbidden*` filter on tags.
|
|
294
|
+
*/
|
|
295
|
+
export interface TraitRule {
|
|
296
|
+
/** Minimum number of traits to pick (inclusive). */
|
|
297
|
+
min?: number;
|
|
298
|
+
/** Maximum number of traits to pick (inclusive). */
|
|
299
|
+
max?: number;
|
|
300
|
+
/** Only pick traits that carry every one of these tags. */
|
|
301
|
+
requiredTags?: string[] | null;
|
|
302
|
+
/** Restrict the pool to exactly these trait names. */
|
|
303
|
+
specificTraits?: string[] | null;
|
|
304
|
+
/** Skip traits carrying any of these tags. */
|
|
305
|
+
forbiddenTags?: string[] | null;
|
|
306
|
+
/** Skip these specific trait names. */
|
|
307
|
+
forbiddenTraits?: string[] | null;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* One entry in `World.subworldMixingRules`. Controls how many copies
|
|
312
|
+
* of a given mixing-subworld can appear in the layout, gated by tag
|
|
313
|
+
* filters.
|
|
314
|
+
*/
|
|
315
|
+
export interface SubworldMixingRule {
|
|
316
|
+
/** Name of the mixing-subworld this rule targets. */
|
|
317
|
+
name?: string;
|
|
318
|
+
/** Minimum copies to place. Default 0. */
|
|
319
|
+
minCount?: number;
|
|
320
|
+
/** Maximum copies to place. Default `i32::MAX`. */
|
|
321
|
+
maxCount?: number;
|
|
322
|
+
/** Skip if any of these tags are present. */
|
|
323
|
+
forbiddenTags?: string[];
|
|
324
|
+
/** Skip if any of these tags are absent. */
|
|
325
|
+
requiredTags?: string[];
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Rule applied post-layout to add/remove layout tags on cells that
|
|
330
|
+
* pass `allowedCellsFilter`. Used to inject things like `"WarpWorld"`
|
|
331
|
+
* or `"StartWorld"` markers that downstream passes consume.
|
|
332
|
+
*/
|
|
333
|
+
export interface ModifyLayoutTagsRule {
|
|
334
|
+
/** Tags to add on matching cells. */
|
|
335
|
+
addTags?: string[];
|
|
336
|
+
/** Tags to remove from matching cells. */
|
|
337
|
+
removeTags?: string[];
|
|
338
|
+
/** Filter chain selecting which cells the tag edits apply to. */
|
|
339
|
+
allowedCellsFilter?: AllowedCellsFilter[];
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* A template-spawn rule: place one of these templates at an overworld
|
|
344
|
+
* cell satisfying this filter. Collected on `World` or `Subworld` and
|
|
345
|
+
* evaluated in priority order.
|
|
346
|
+
*/
|
|
347
|
+
export interface TemplateSpawnRules {
|
|
348
|
+
/** Human-readable identifier for this rule. Optional. */
|
|
349
|
+
ruleId?: string | null;
|
|
350
|
+
/** Template paths this rule picks from (e.g. `["geysers/generic_hot"]`). */
|
|
351
|
+
names?: string[];
|
|
352
|
+
/** How aggressively to satisfy the rule (see {@link ListRule}). */
|
|
353
|
+
listRule?: ListRule;
|
|
354
|
+
/** Used by `GuaranteeSome` / `GuaranteeSomeTryMore`: the guaranteed count. */
|
|
355
|
+
someCount?: number;
|
|
356
|
+
/** Used by `GuaranteeSomeTryMore`: additional best-effort count. */
|
|
357
|
+
moreCount?: number;
|
|
358
|
+
/** Total placements to attempt. Default 1. */
|
|
359
|
+
times?: number;
|
|
360
|
+
/**
|
|
361
|
+
* Priority for template-placement scheduling. Higher-priority rules
|
|
362
|
+
* are placed before lower ones, so hand-authored POIs land before
|
|
363
|
+
* generic fills.
|
|
364
|
+
*/
|
|
365
|
+
priority?: number;
|
|
366
|
+
/** Allow the same template name to be picked more than once. */
|
|
367
|
+
allowDuplicates?: boolean;
|
|
368
|
+
/**
|
|
369
|
+
* Allow this template in `ExtremelyCold` / `ExtremelyHot` cells
|
|
370
|
+
* (normally skipped).
|
|
371
|
+
*/
|
|
372
|
+
allowExtremeTemperatureOverlap?: boolean;
|
|
373
|
+
/**
|
|
374
|
+
* Allow placement inside the ring surrounding the starting base
|
|
375
|
+
* cell (normally excluded).
|
|
376
|
+
*/
|
|
377
|
+
allowNearStart?: boolean;
|
|
378
|
+
/**
|
|
379
|
+
* Skip the usual "don't overlap prior template cells" check. Used
|
|
380
|
+
* sparingly for decorative overlays.
|
|
381
|
+
*/
|
|
382
|
+
useRelaxedFiltering?: boolean;
|
|
383
|
+
/** With `GuaranteeRange`/`TryRange`: roll a uniform count in `[x, y]`. */
|
|
384
|
+
range?: Vector2I;
|
|
385
|
+
/** Relative offset from the centroid of the matched cell. Default `(0, 0)`. */
|
|
386
|
+
overrideOffset?: Vector2I;
|
|
387
|
+
/**
|
|
388
|
+
* Absolute placement override. `(-1, -1)` (the default) means "no
|
|
389
|
+
* override"; the rule picks a cell via the filter.
|
|
390
|
+
*/
|
|
391
|
+
overridePlacement?: Vector2I;
|
|
392
|
+
/** Filter chain selecting candidate cells for placement. */
|
|
393
|
+
allowedCellsFilter?: AllowedCellsFilter[];
|
|
394
|
+
/**
|
|
395
|
+
* Extension knob: when `true` and the world placement has
|
|
396
|
+
* `sizeMultiplier < 1`, this rule's `times` is scaled by the
|
|
397
|
+
* multiplier with a per-rule KRandom roll for the fractional
|
|
398
|
+
* remainder. Lets shrunk worlds keep the same geyser density as
|
|
399
|
+
* full-size worlds.
|
|
400
|
+
*
|
|
401
|
+
* Mirrors the behaviour CGM applies to its geyser rules, but as a
|
|
402
|
+
* per-rule opt-in (no name-pattern matching).
|
|
403
|
+
*/
|
|
404
|
+
scaleCountWithWorldSize?: boolean;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* A single world's full config (ProcGen.World). Editing the worldsize
|
|
409
|
+
* of the starting world changes the grid dimensions of the asteroid
|
|
410
|
+
* you spawn on; editing `subworldFiles` changes which biomes appear
|
|
411
|
+
* in the Voronoi layout. `file_path` is stripped from JSON.
|
|
412
|
+
*/
|
|
413
|
+
export interface World {
|
|
414
|
+
/** Internal identifier; usually matches the config path's last segment. */
|
|
415
|
+
name: string;
|
|
416
|
+
/** Loc-key or inline description shown in the world-select UI. */
|
|
417
|
+
description?: string | null;
|
|
418
|
+
/** Name-table paths used to generate a display name for this world. */
|
|
419
|
+
nameTables?: string[] | null;
|
|
420
|
+
/** Sprite shown for this asteroid in the starmap / cluster UI. */
|
|
421
|
+
asteroidIcon?: string | null;
|
|
422
|
+
/** Size multiplier on the starmap icon. Default 1.0. */
|
|
423
|
+
iconScale?: number;
|
|
424
|
+
/**
|
|
425
|
+
* Tags used by cluster/mixing/trait filters (e.g. `"RocketInterior"`,
|
|
426
|
+
* `"ForbiddenClusterCategory_Ceres"`). Matching rules in
|
|
427
|
+
* `ClusterLayout`/`WorldTrait`/`*MixingSettings` key off these.
|
|
428
|
+
*/
|
|
429
|
+
worldTags?: string[];
|
|
430
|
+
/** Turn the world-traits pass off entirely for this world. */
|
|
431
|
+
disableWorldTraits?: boolean;
|
|
432
|
+
/**
|
|
433
|
+
* One or more rules describing how many traits to roll. Multiple
|
|
434
|
+
* rules stack, e.g. `[{min: 2, max: 4}, {specificTraits: ["GeoActive"]}]`.
|
|
435
|
+
*/
|
|
436
|
+
worldTraitRules?: TraitRule[];
|
|
437
|
+
/**
|
|
438
|
+
* Scalar multiplier applied to trait impact (spawn counts, etc.).
|
|
439
|
+
* Default 1.0.
|
|
440
|
+
*/
|
|
441
|
+
worldTraitScale?: number;
|
|
442
|
+
/** UI category: `Asteroid` or `Moon`. */
|
|
443
|
+
category?: WorldCategory;
|
|
444
|
+
/** Cell dimensions of this world's grid. Canonical sizes are 256×384 etc. */
|
|
445
|
+
worldsize?: WorldSize;
|
|
446
|
+
/**
|
|
447
|
+
* Number of rows at the top of the world hidden behind the
|
|
448
|
+
* starting-region fog of war until scanned. Default 0.
|
|
449
|
+
*/
|
|
450
|
+
hiddenY?: number;
|
|
451
|
+
/**
|
|
452
|
+
* Per-world overrides for global `DefaultSettings`. Example:
|
|
453
|
+
* setting `defaultsOverrides.data.OverworldDensityMin` to a
|
|
454
|
+
* different value changes subworld placement density for this
|
|
455
|
+
* world only, without mutating the cluster-wide defaults.
|
|
456
|
+
*/
|
|
457
|
+
defaultsOverrides?: DefaultSettings | null;
|
|
458
|
+
/** Overworld layout algorithm (default Voronoi tree). */
|
|
459
|
+
layoutMethod?: LayoutMethod;
|
|
460
|
+
/**
|
|
461
|
+
* Weighted list of subworld config paths this world is built from.
|
|
462
|
+
* Each subworld gets dropped into the layout according to its
|
|
463
|
+
* weight; counts are driven by `Subworld.density`.
|
|
464
|
+
*/
|
|
465
|
+
subworldFiles?: WeightedSubworldName[];
|
|
466
|
+
/**
|
|
467
|
+
* Filter chain used when the layout lands a cell that no
|
|
468
|
+
* `subworldFile` claims; picks a fallback zone.
|
|
469
|
+
*/
|
|
470
|
+
unknownCellsAllowedSubworlds?: AllowedCellsFilter[];
|
|
471
|
+
/**
|
|
472
|
+
* Per-world subworld-mixing rules. Populated when a mixing code is
|
|
473
|
+
* active (e.g. `MUWF1` in the coordinate) to inject biomes from
|
|
474
|
+
* other worlds.
|
|
475
|
+
*/
|
|
476
|
+
subworldMixingRules?: SubworldMixingRule[];
|
|
477
|
+
/** Rules that add/remove layout tags after the layout finishes. */
|
|
478
|
+
modifyLayoutTags?: ModifyLayoutTagsRule[];
|
|
479
|
+
/** Name of the subworld that hosts the starting base. */
|
|
480
|
+
startSubworldName?: string | null;
|
|
481
|
+
/** Template stamped at the starting-base position (usually `bases/sandstoneBase`). */
|
|
482
|
+
startingBaseTemplate?: string | null;
|
|
483
|
+
/** Horizontal fraction of the world where the starting base lands, `[0, 1]`. */
|
|
484
|
+
startingBasePositionHorizontal?: MinMax;
|
|
485
|
+
/** Vertical fraction of the world where the starting base lands, `[0, 1]`. */
|
|
486
|
+
startingBasePositionVertical?: MinMax;
|
|
487
|
+
/**
|
|
488
|
+
* Insertion-ordered map of feature-name → priority. Iteration order
|
|
489
|
+
* is load-bearing; the game iterates this map in insertion order
|
|
490
|
+
* during feature distribution.
|
|
491
|
+
*/
|
|
492
|
+
globalFeatures?: Record<string, number>;
|
|
493
|
+
/** World-level template rules (POIs placed by the world, not by subworlds). */
|
|
494
|
+
worldTemplateRules?: TemplateSpawnRules[];
|
|
495
|
+
/**
|
|
496
|
+
* Seasonal-event tags attached to this world (e.g. winter/holiday
|
|
497
|
+
* seasons in SpacedOut).
|
|
498
|
+
*/
|
|
499
|
+
seasons?: string[];
|
|
500
|
+
/**
|
|
501
|
+
* World traits that always apply regardless of rolling (the "fixed"
|
|
502
|
+
* part of the worldTraitRules roll).
|
|
503
|
+
*/
|
|
504
|
+
fixedTraits?: string[];
|
|
505
|
+
/**
|
|
506
|
+
* True if this world should be spawned adjacent to a Temporal Tear
|
|
507
|
+
* node in the SpacedOut starmap. Only honoured for SpacedOut.
|
|
508
|
+
*/
|
|
509
|
+
adjacentTemporalTear?: boolean;
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
/**
|
|
513
|
+
* Weighted entry in a subworld pool. Total subworld count is driven
|
|
514
|
+
* by density; `weight` controls the proportional share each subworld
|
|
515
|
+
* claims. The `minCount` / `maxCount` pair clamps how many copies
|
|
516
|
+
* of this subworld can land in the layout.
|
|
517
|
+
*/
|
|
518
|
+
export interface WeightedSubworldName {
|
|
519
|
+
/** Subworld config path. */
|
|
520
|
+
name: string;
|
|
521
|
+
/**
|
|
522
|
+
* Minimum copies to place (floor on the weighted roll).
|
|
523
|
+
* C# default 0.
|
|
524
|
+
*/
|
|
525
|
+
minCount?: number;
|
|
526
|
+
/**
|
|
527
|
+
* Maximum copies to place (cap on the weighted roll).
|
|
528
|
+
* C# default `int.MaxValue`.
|
|
529
|
+
*/
|
|
530
|
+
maxCount?: number;
|
|
531
|
+
/** Relative weight; higher means more copies placed. C# default 1.0. */
|
|
532
|
+
weight?: number;
|
|
533
|
+
/**
|
|
534
|
+
* Priority. Higher-priority subworlds are placed before lower-priority
|
|
535
|
+
* ones when the count roll contends across the pool. Default 0.
|
|
536
|
+
*/
|
|
537
|
+
priority?: number;
|
|
538
|
+
/**
|
|
539
|
+
* Power-tree weighting override. Only consulted when the hosting
|
|
540
|
+
* world uses `layoutMethod: PowerTree`. Default 0.0.
|
|
541
|
+
*/
|
|
542
|
+
overridePower?: number;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
/**
|
|
546
|
+
* Point-sampling layer used for additional mob/room sample point
|
|
547
|
+
* generation within a Subworld. Each subworld can stack multiple
|
|
548
|
+
* samplers (e.g. one for Hatches, another for sweetle nests).
|
|
549
|
+
*/
|
|
550
|
+
export interface Sampler {
|
|
551
|
+
/** Point-count range for this layer. */
|
|
552
|
+
density?: MinMax;
|
|
553
|
+
/** Minimum cell distance between accepted points. */
|
|
554
|
+
avoidRadius?: number;
|
|
555
|
+
/**
|
|
556
|
+
* If true, reject candidates that are too close to points from
|
|
557
|
+
* prior samplers (used to keep layers from overlapping).
|
|
558
|
+
*/
|
|
559
|
+
doAvoidPoints?: boolean;
|
|
560
|
+
/** Point-sampler algorithm. */
|
|
561
|
+
sampleBehaviour?: SampleBehaviour;
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
/**
|
|
565
|
+
* A biome/zone definition (ProcGen.Subworld). Subworlds are the
|
|
566
|
+
* building blocks of a world's Voronoi layout: each overworld cell
|
|
567
|
+
* is assigned a subworld, and the subworld drives that cell's
|
|
568
|
+
* temperature, elemental banding, feature pool, and template rules.
|
|
569
|
+
*/
|
|
570
|
+
export interface Subworld {
|
|
571
|
+
/** Internal identifier (often null for subworlds loaded by path). */
|
|
572
|
+
name?: string | null;
|
|
573
|
+
/** Loc-key for display name. */
|
|
574
|
+
nameKey?: string | null;
|
|
575
|
+
/** Loc-key for description. */
|
|
576
|
+
descriptionKey?: string | null;
|
|
577
|
+
/** Loc-key for utility/tooltip string. */
|
|
578
|
+
utilityKey?: string | null;
|
|
579
|
+
/** Path into `noise`: the primary biome noise. */
|
|
580
|
+
biomeNoise?: string | null;
|
|
581
|
+
/** Path into `noise`: used for biome-to-biome border transitions. */
|
|
582
|
+
overrideNoise?: string | null;
|
|
583
|
+
/** Path into `noise`: optional density modulation. */
|
|
584
|
+
densityNoise?: string | null;
|
|
585
|
+
/** Name of the border-biome config applied around this subworld. */
|
|
586
|
+
borderOverride?: string | null;
|
|
587
|
+
/** Higher wins when two neighbouring subworlds both claim a border. */
|
|
588
|
+
borderOverridePriority?: number;
|
|
589
|
+
/** Border thickness range in cells. C# default is `{min: 1.0, max: 2.5}`. */
|
|
590
|
+
borderSizeOverride?: MinMax;
|
|
591
|
+
/** Named temperature band (entries in `LookupsBundle.temperatures`). */
|
|
592
|
+
temperatureRange?: TemperatureRange;
|
|
593
|
+
/**
|
|
594
|
+
* Single guaranteed feature placed near the centre of this
|
|
595
|
+
* subworld's region (e.g. a geyser). Null means no central feature.
|
|
596
|
+
*/
|
|
597
|
+
centralFeature?: Feature | null;
|
|
598
|
+
/** Additional features that may spawn scattered through the subworld. */
|
|
599
|
+
features?: Feature[];
|
|
600
|
+
/** Layout tags attached to every cell of this subworld. */
|
|
601
|
+
tags?: string[];
|
|
602
|
+
/** Subworld-count density in the Voronoi layout. */
|
|
603
|
+
density?: MinMax;
|
|
604
|
+
/** Minimum cell distance between centroids. */
|
|
605
|
+
avoidRadius?: number;
|
|
606
|
+
/** Respect the avoid-radius when placing relative to prior subworlds. */
|
|
607
|
+
doAvoidPoints?: boolean;
|
|
608
|
+
/**
|
|
609
|
+
* When true, child-cell Voronoi relaxation is skipped, producing
|
|
610
|
+
* jaggier edges. Used by a handful of biomes (Sandstone included).
|
|
611
|
+
*/
|
|
612
|
+
dontRelaxChildren?: boolean;
|
|
613
|
+
/** Centroid-sampling algorithm. */
|
|
614
|
+
sampleBehaviour?: SampleBehaviour;
|
|
615
|
+
/** Extra point-sample layers for mob/room placement. */
|
|
616
|
+
samplers?: Sampler[];
|
|
617
|
+
/** Minimum child-cell count before the subworld is considered valid. */
|
|
618
|
+
minChildCount?: number;
|
|
619
|
+
/** Force every instance to have exactly one child cell. */
|
|
620
|
+
singleChildCount?: boolean;
|
|
621
|
+
/** Additional children to add on top of the density roll. */
|
|
622
|
+
extraBiomeChildren?: number;
|
|
623
|
+
/** Weighted pool of biome configs used to paint this subworld's cells. */
|
|
624
|
+
biomes?: WeightedBiome[];
|
|
625
|
+
/** Zone type (affects colour, StateTransition background, gameplay). */
|
|
626
|
+
zoneType?: ZoneType;
|
|
627
|
+
/** Weight used by `PowerTree` layouts. Ignored for `Default` layout. */
|
|
628
|
+
pdWeight?: number;
|
|
629
|
+
/** Relaxation iteration count. Advanced; rarely edited. */
|
|
630
|
+
iterations?: number;
|
|
631
|
+
/** Minimum Voronoi-energy threshold before stopping relaxation. */
|
|
632
|
+
minEnergy?: number;
|
|
633
|
+
/** Template-spawn rules scoped to this subworld's cells. */
|
|
634
|
+
subworldTemplateRules?: TemplateSpawnRules[] | null;
|
|
635
|
+
/** Catch-all for Subworld fields not enumerated above. */
|
|
636
|
+
[key: string]: unknown;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
/**
|
|
640
|
+
* A geological feature (geyser room, dormant volcano, ancient ruins)
|
|
641
|
+
* that can spawn inside a subworld. Matches `ProcGen.Feature`.
|
|
642
|
+
*/
|
|
643
|
+
export interface Feature {
|
|
644
|
+
/**
|
|
645
|
+
* Feature type: either a direct prefab name (e.g. `"GeyserGeneric"`)
|
|
646
|
+
* or a feature-settings path.
|
|
647
|
+
*/
|
|
648
|
+
type?: string | null;
|
|
649
|
+
/** Layout tags attached to cells this feature occupies. */
|
|
650
|
+
tags?: string[];
|
|
651
|
+
/**
|
|
652
|
+
* Mobs spawned inside the feature when it generates (e.g. Hatches
|
|
653
|
+
* in a geyser room).
|
|
654
|
+
*/
|
|
655
|
+
internalMobs?: InternalMob[] | null;
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
/**
|
|
659
|
+
* A mob entry inside a `Feature`. Rolls `count` copies of the named
|
|
660
|
+
* mob prefab at generation time.
|
|
661
|
+
*/
|
|
662
|
+
export interface InternalMob {
|
|
663
|
+
/** Integer count range rolled uniformly. */
|
|
664
|
+
count?: CountRange | null;
|
|
665
|
+
/** Mob prefab name (e.g. `"Hatch"`). */
|
|
666
|
+
mob?: string | null;
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
/** Integer range used for internal-mob counts. */
|
|
670
|
+
export interface CountRange {
|
|
671
|
+
min: number;
|
|
672
|
+
max: number;
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
/**
|
|
676
|
+
* Weighted biome entry in `Subworld.biomes`. The worldgen picks
|
|
677
|
+
* one biome per subworld-cell weighted by these entries.
|
|
678
|
+
*/
|
|
679
|
+
export interface WeightedBiome {
|
|
680
|
+
/** Biome config path. */
|
|
681
|
+
name: string;
|
|
682
|
+
/** Relative weight. */
|
|
683
|
+
weight?: number;
|
|
684
|
+
/**
|
|
685
|
+
* Layout tags attached to cells painted with this biome choice
|
|
686
|
+
* (on top of the subworld-level `tags`). Used by downstream
|
|
687
|
+
* filter chains.
|
|
688
|
+
*/
|
|
689
|
+
tags?: string[];
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
/**
|
|
693
|
+
* Normalized-coordinate bounding box for the overworld base region.
|
|
694
|
+
* Lives under `DefaultSettings.baseData`. Units are arbitrary game
|
|
695
|
+
* space (not cells); the game scales this at placement time.
|
|
696
|
+
*/
|
|
697
|
+
export interface BaseLocation {
|
|
698
|
+
left: number;
|
|
699
|
+
right: number;
|
|
700
|
+
bottom: number;
|
|
701
|
+
top: number;
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
/**
|
|
705
|
+
* One starting-inventory element to drop around the printing pod.
|
|
706
|
+
* Lives under `DefaultSettings.startingWorldElements`.
|
|
707
|
+
*/
|
|
708
|
+
export interface StartingWorldElement {
|
|
709
|
+
/** Element name (e.g. `"Algae"`, `"Water"`). */
|
|
710
|
+
element: string;
|
|
711
|
+
/** Total mass in kilograms. */
|
|
712
|
+
amount: number;
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
/**
|
|
716
|
+
* Global default settings (ProcGen.DefaultSettings). The free-form
|
|
717
|
+
* `data` field carries key-value pairs (e.g. `OverworldDensityMin:
|
|
718
|
+
* 600`). Per-world overrides live on `World.defaultsOverrides` and
|
|
719
|
+
* layer on top of these at lookup time.
|
|
720
|
+
*/
|
|
721
|
+
export interface DefaultSettings {
|
|
722
|
+
/** Bounding box used when the overworld renderer positions the base region. */
|
|
723
|
+
baseData?: BaseLocation | null;
|
|
724
|
+
/**
|
|
725
|
+
* Free-form key-value map. Stock keys include `OverworldDensityMin`,
|
|
726
|
+
* `OverworldAvoidRadius`, `OverworldMinNodes`, `DrawWorldBorder`,
|
|
727
|
+
* `OverworldSampleBehaviour`.
|
|
728
|
+
*/
|
|
729
|
+
data?: Record<string, unknown> | null;
|
|
730
|
+
/** Initial resources placed around the printing pod. */
|
|
731
|
+
startingWorldElements?: StartingWorldElement[] | null;
|
|
732
|
+
/** Layout tags added to every overworld cell at the start of generation. */
|
|
733
|
+
overworldAddTags?: string[] | null;
|
|
734
|
+
/** Default `moveTags` applied when populating a subworld with cells. */
|
|
735
|
+
defaultMoveTags?: string[] | null;
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
// ---------------------------------------------------------------------------
|
|
739
|
+
// Mob & room configs.
|
|
740
|
+
// ---------------------------------------------------------------------------
|
|
741
|
+
|
|
742
|
+
/** Integer count range used by mob/room `density`. */
|
|
743
|
+
export interface MinMaxConfig {
|
|
744
|
+
min: number;
|
|
745
|
+
max: number;
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
/**
|
|
749
|
+
* Mob placement region (ProcGen.Mob.Location). Drives where a mob's
|
|
750
|
+
* sample points are valid: `Floor` requires a solid floor below the
|
|
751
|
+
* cell, `Air` requires an empty gas cell, `Liquid` requires a liquid
|
|
752
|
+
* cell, etc. The default is `Floor`.
|
|
753
|
+
*/
|
|
754
|
+
export type MobLocation =
|
|
755
|
+
| 'Floor'
|
|
756
|
+
| 'Ceiling'
|
|
757
|
+
| 'Air'
|
|
758
|
+
| 'BackWall'
|
|
759
|
+
| 'NearWater'
|
|
760
|
+
| 'NearLiquid'
|
|
761
|
+
| 'Solid'
|
|
762
|
+
| 'Water'
|
|
763
|
+
| 'ShallowLiquid'
|
|
764
|
+
| 'Surface'
|
|
765
|
+
| 'LiquidFloor'
|
|
766
|
+
| 'AnyFloor'
|
|
767
|
+
| 'LiquidCeiling'
|
|
768
|
+
| 'Liquid'
|
|
769
|
+
| 'EntombedFloorPeek';
|
|
770
|
+
|
|
771
|
+
/**
|
|
772
|
+
* Mob spawn configuration (ProcGen.Mob). Controls how many copies of
|
|
773
|
+
* a mob prefab get scattered across the grid after layout.
|
|
774
|
+
*/
|
|
775
|
+
export interface MobConfig {
|
|
776
|
+
/** Prefab-selection strategy name (e.g. `"WeightedRandom"`). */
|
|
777
|
+
selectMethod?: string;
|
|
778
|
+
/** Roll range for the count of this mob placed per world. */
|
|
779
|
+
density?: MinMaxConfig;
|
|
780
|
+
/** Point-sampling strategy name for placement. */
|
|
781
|
+
sampleBehaviour?: string;
|
|
782
|
+
/** Cell-type region where sample points are accepted. */
|
|
783
|
+
location?: MobLocation;
|
|
784
|
+
/** Prefab name spawned by this entry. */
|
|
785
|
+
prefabName?: string | null;
|
|
786
|
+
/** Footprint width in cells. */
|
|
787
|
+
width?: number;
|
|
788
|
+
/** Footprint height in cells. */
|
|
789
|
+
height?: number;
|
|
790
|
+
/** Horizontal spacing to enforce between copies. */
|
|
791
|
+
paddingX?: number;
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
/**
|
|
795
|
+
* Room placement configuration (ProcGen.Room). Same mechanics as
|
|
796
|
+
* `MobConfig` but for carved rooms rather than creatures.
|
|
797
|
+
*/
|
|
798
|
+
export interface RoomConfig {
|
|
799
|
+
/** Room-selection strategy name. */
|
|
800
|
+
selectMethod?: string;
|
|
801
|
+
/** Roll range for the number of rooms. */
|
|
802
|
+
density?: MinMaxConfig;
|
|
803
|
+
/** Point-sampling strategy name. */
|
|
804
|
+
sampleBehaviour?: string;
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
// ---------------------------------------------------------------------------
|
|
808
|
+
// Template containers (POIs, geysers, bases).
|
|
809
|
+
// ---------------------------------------------------------------------------
|
|
810
|
+
|
|
811
|
+
/**
|
|
812
|
+
* Template coordinate vector. Uppercase `X/Y` (matches the on-disk
|
|
813
|
+
* YAML), distinct from the lowercase {@link Vector2I} used by
|
|
814
|
+
* world/subworld configs.
|
|
815
|
+
*/
|
|
816
|
+
export interface TemplateVec2I {
|
|
817
|
+
X: number;
|
|
818
|
+
Y: number;
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
/**
|
|
822
|
+
* Template metadata. Populated by Rust's `refresh_info()` when the
|
|
823
|
+
* loaded YAML's `min` is `(0, 0)`.
|
|
824
|
+
*/
|
|
825
|
+
export interface TemplateInfo {
|
|
826
|
+
/** Bounding-box dimensions in cells. */
|
|
827
|
+
size: TemplateVec2I;
|
|
828
|
+
/** Total cell count (`cells.length` in practice). */
|
|
829
|
+
area: number;
|
|
830
|
+
/** Lower-left cell of the bounding box, relative to the template origin. */
|
|
831
|
+
min: TemplateVec2I;
|
|
832
|
+
/** Upper-right cell of the bounding box. */
|
|
833
|
+
max: TemplateVec2I;
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
/**
|
|
837
|
+
* A single cell in a template: one element of mass at a relative
|
|
838
|
+
* grid position. Templates are stamped onto the world grid by
|
|
839
|
+
* translating these positions by the template's spawn point.
|
|
840
|
+
*/
|
|
841
|
+
export interface TemplateCell {
|
|
842
|
+
/** Element name (e.g. `"SandStone"`, `"Oxygen"`). Null for vacuum. */
|
|
843
|
+
element?: string | null;
|
|
844
|
+
/** Element mass in kg. */
|
|
845
|
+
mass: number;
|
|
846
|
+
/** Temperature in Kelvin. */
|
|
847
|
+
temperature: number;
|
|
848
|
+
/** X offset from template origin. */
|
|
849
|
+
location_x: number;
|
|
850
|
+
/** Y offset from template origin. */
|
|
851
|
+
location_y: number;
|
|
852
|
+
/** Disease name (e.g. `"SlimeLung"`). Null for sterile. */
|
|
853
|
+
diseaseName?: string | null;
|
|
854
|
+
/** Germ count. */
|
|
855
|
+
diseaseCount: number;
|
|
856
|
+
/**
|
|
857
|
+
* If true, this cell stays un-revealed (fog-of-war) even when
|
|
858
|
+
* templates are normally pre-revealed. Used by puzzle/POI cells.
|
|
859
|
+
*/
|
|
860
|
+
preventFoWReveal?: boolean | null;
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
/**
|
|
864
|
+
* One item stored inside a container building (e.g. a RationBox
|
|
865
|
+
* pre-filled with meal-lice). Lives under `TemplatePrefab.storage`.
|
|
866
|
+
*/
|
|
867
|
+
export interface TemplateStorageItem {
|
|
868
|
+
/** Prefab id of the stored item. */
|
|
869
|
+
id?: string | null;
|
|
870
|
+
/** Element override, if the item is an element-carrier. */
|
|
871
|
+
element?: string | null;
|
|
872
|
+
/** Quantity (mass for elements, count for creatures/items). */
|
|
873
|
+
units: number;
|
|
874
|
+
/** Temperature in Kelvin. */
|
|
875
|
+
temperature: number;
|
|
876
|
+
/** Free-form rottable state; carried through verbatim. */
|
|
877
|
+
rottable?: unknown;
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
/**
|
|
881
|
+
* A prefab placed by a template (building, pickupable, ore deposit,
|
|
882
|
+
* or other entity). Which `TemplateContainer` array it lives in
|
|
883
|
+
* determines how the game spawns it.
|
|
884
|
+
*/
|
|
885
|
+
export interface TemplatePrefab {
|
|
886
|
+
/** Prefab id (e.g. `"Tile"`, `"Headquarters"`, `"Hatch"`). */
|
|
887
|
+
id?: string | null;
|
|
888
|
+
/** X offset from template origin (can be fractional). */
|
|
889
|
+
location_x: number;
|
|
890
|
+
/** Y offset from template origin (can be fractional). */
|
|
891
|
+
location_y: number;
|
|
892
|
+
/** Element override (for ore-like prefabs). */
|
|
893
|
+
element?: string | null;
|
|
894
|
+
/** Spawn temperature in Kelvin. */
|
|
895
|
+
temperature: number;
|
|
896
|
+
/** Count or mass; interpreted per prefab type. */
|
|
897
|
+
units: number;
|
|
898
|
+
/** Prefab type hint (e.g. `"Pickupable"`, `"Ore"`). */
|
|
899
|
+
type?: string | null;
|
|
900
|
+
/** Container contents (for storage buildings like RationBox). */
|
|
901
|
+
storage?: TemplateStorageItem[];
|
|
902
|
+
/** Rotation hint for orientable buildings. */
|
|
903
|
+
rotationOrientation?: string | null;
|
|
904
|
+
/** Connections bitfield for connectable prefabs (pipes, wires). */
|
|
905
|
+
connections?: number | null;
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
/**
|
|
909
|
+
* A pre-authored template (starting base, geyser room, artifact POI,
|
|
910
|
+
* etc.). Templates are stamped onto the world grid by a
|
|
911
|
+
* `TemplateSpawnRule` that picks this container's path. Matches
|
|
912
|
+
* `ProcGen.TemplateContainer`.
|
|
913
|
+
*/
|
|
914
|
+
export interface TemplateContainer {
|
|
915
|
+
/** Internal template name. Usually matches the config path's last segment. */
|
|
916
|
+
name?: string | null;
|
|
917
|
+
/** Bounding-box metadata. */
|
|
918
|
+
info: TemplateInfo;
|
|
919
|
+
/** Element/mass/temperature per cell. */
|
|
920
|
+
cells: TemplateCell[];
|
|
921
|
+
/** Building prefabs (tiles, machines). */
|
|
922
|
+
buildings: TemplatePrefab[];
|
|
923
|
+
/** Pickupable prefabs (items, creatures). */
|
|
924
|
+
pickupables: TemplatePrefab[];
|
|
925
|
+
/** Elemental-ore deposits. */
|
|
926
|
+
elementalOres: TemplatePrefab[];
|
|
927
|
+
/** Other entities (lights, furniture, decor). */
|
|
928
|
+
otherEntities: TemplatePrefab[];
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
// ---------------------------------------------------------------------------
|
|
932
|
+
// Categories surfaced as opaque records. Editors can round-trip them
|
|
933
|
+
// safely; field-level typing can be added later.
|
|
934
|
+
// ---------------------------------------------------------------------------
|
|
935
|
+
|
|
936
|
+
/** Which worlds appear at which ring positions on the starmap, plus starmap POIs. */
|
|
937
|
+
export interface ClusterLayout { [key: string]: unknown }
|
|
938
|
+
|
|
939
|
+
/**
|
|
940
|
+
* Noise-tree definition (base / override / density). Editing primitive
|
|
941
|
+
* frequencies and seeds changes every cell of every world that
|
|
942
|
+
* references the tree.
|
|
943
|
+
*/
|
|
944
|
+
export interface NoiseTree { [key: string]: unknown }
|
|
945
|
+
|
|
946
|
+
/** Element/mass bands keyed on noise-field thresholds. */
|
|
947
|
+
export interface BiomeSettings { [key: string]: unknown }
|
|
948
|
+
|
|
949
|
+
/** Trait definition: names, tags, and modifiers applied when a roll picks it. */
|
|
950
|
+
export interface WorldTrait { [key: string]: unknown }
|
|
951
|
+
|
|
952
|
+
/** Per-feature configuration (geyser type pool, ruins content tables, etc.). */
|
|
953
|
+
export interface FeatureSettings { [key: string]: unknown }
|
|
954
|
+
|
|
955
|
+
/** DLC-level mixing settings: which asteroid/subworld substitutions are eligible. */
|
|
956
|
+
export interface DlcMixingSettings { [key: string]: unknown }
|
|
957
|
+
|
|
958
|
+
/** Whole-world mixing option (substitute asteroid type A for B). */
|
|
959
|
+
export interface WorldMixingSettings { [key: string]: unknown }
|
|
960
|
+
|
|
961
|
+
/** Subworld mixing option (substitute biome A for B inside an asteroid). */
|
|
962
|
+
export interface SubworldMixingSettings { [key: string]: unknown }
|
|
963
|
+
|
|
964
|
+
|
|
965
|
+
// ---------------------------------------------------------------------------
|
|
966
|
+
// WorldgenSnapshot: the snapshot shape returned by the JSON-in/out
|
|
967
|
+
// snapshot helpers (`snapshot_load_vanilla`, `snapshot_from_files`,
|
|
968
|
+
// `snapshot_merge_files`, `snapshot_to_files`).
|
|
969
|
+
// ---------------------------------------------------------------------------
|
|
970
|
+
|
|
971
|
+
/**
|
|
972
|
+
* - `Strict` (default): closed Klei-parity surface; rejects custom
|
|
973
|
+
* `TemperatureRange` names at load time.
|
|
974
|
+
* - `Extensions`: opens `TemperatureRange` to `Custom(string)`
|
|
975
|
+
* provided the name resolves to a `tables.temperatures.add` entry.
|
|
976
|
+
*/
|
|
977
|
+
export type SnapshotMode = 'Strict' | 'Extensions';
|
|
978
|
+
|
|
979
|
+
/**
|
|
980
|
+
* Klei-style file path key (e.g. `worldgen/biomes/Forest.yaml`, or
|
|
981
|
+
* DLC-qualified `expansion1::worldgen/biomes/Forest.yaml`).
|
|
982
|
+
*/
|
|
983
|
+
export type FilePath = string;
|
|
984
|
+
|
|
985
|
+
/**
|
|
986
|
+
* Add/remove pair for table-shaped YAML files (mobs, rooms,
|
|
987
|
+
* temperatures, borders, rivers). Two snapshots compose by merging
|
|
988
|
+
* the `add` maps (last-wins) and unioning `remove`.
|
|
989
|
+
*/
|
|
990
|
+
export interface ComposableDict<V> {
|
|
991
|
+
add: Record<string, V>;
|
|
992
|
+
remove: string[];
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
/** Whole-file-replace categories, keyed by the on-disk Klei path. */
|
|
996
|
+
export interface SnapshotFiles {
|
|
997
|
+
clusters: Record<FilePath, ClusterLayout>;
|
|
998
|
+
worlds: Record<FilePath, World>;
|
|
999
|
+
subworlds: Record<FilePath, Subworld>;
|
|
1000
|
+
traits: Record<FilePath, WorldTrait>;
|
|
1001
|
+
story_traits: Record<FilePath, WorldTrait>;
|
|
1002
|
+
feature_settings: Record<FilePath, FeatureSettings>;
|
|
1003
|
+
noise: Record<FilePath, NoiseTree>;
|
|
1004
|
+
templates: Record<FilePath, TemplateContainer>;
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
/**
|
|
1008
|
+
* Table-shaped categories: Klei's single-file `add: {…}` /
|
|
1009
|
+
* `remove: […]` layout.
|
|
1010
|
+
*/
|
|
1011
|
+
export interface SnapshotTables {
|
|
1012
|
+
biomes: ComposableDict<BiomeSettings>;
|
|
1013
|
+
mobs: ComposableDict<MobConfig>;
|
|
1014
|
+
rivers: ComposableDict<unknown>;
|
|
1015
|
+
rooms: ComposableDict<RoomConfig>;
|
|
1016
|
+
temperatures: ComposableDict<[number, number]>;
|
|
1017
|
+
borders: ComposableDict<Array<unknown>>;
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
/** Wholesale-replace singletons: defaults + DLC/world/subworld mixing. */
|
|
1021
|
+
export interface SnapshotMixing {
|
|
1022
|
+
defaults: DefaultSettings;
|
|
1023
|
+
dlc_mixing: Record<string, DlcMixingSettings>;
|
|
1024
|
+
world_mixing: Record<string, WorldMixingSettings>;
|
|
1025
|
+
subworld_mixing: Record<string, SubworldMixingSettings>;
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
/** The mod-ingestion snapshot returned and accepted by the snapshot helpers. */
|
|
1029
|
+
export interface WorldgenSnapshot {
|
|
1030
|
+
mode: SnapshotMode;
|
|
1031
|
+
files: SnapshotFiles;
|
|
1032
|
+
tables: SnapshotTables;
|
|
1033
|
+
mixing: SnapshotMixing;
|
|
1034
|
+
}
|