@onimaxxing/worldgen-node 0.21.2 → 0.22.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/README.md CHANGED
@@ -10,6 +10,7 @@ same cluster the game would generate for a given coordinate.
10
10
  - Geyser, building, pickupable, and other entity spawn positions.
11
11
  - Per-cell mass, temperature, and disease (raw after `worldgen.generate`; settled after `worldgen.advance`).
12
12
  - Both basegame and Spaced Out clusters, including story traits, mixing codes, and DLC toggles.
13
+ - Partial generation of selected worlds (`worldgen.partials`).
13
14
 
14
15
  Output is verified cell-by-cell against snapshots captured from the
15
16
  running game, with a slight modification to force determinism during
@@ -133,6 +134,28 @@ Generate a cluster from a game coordinate and return the decoded
133
134
  map (see [`MapData` shape](#mapdata-shape)). Caches the cluster
134
135
  internally, replacing anything previously cached.
135
136
 
137
+ ```ts
138
+ worldgen.partials(coord: string, opts: PartialsOptions): PartialsResult
139
+ ```
140
+
141
+ Generate only the selected worlds of a cluster. Stateless; does not
142
+ touch the cluster cache.
143
+
144
+ `opts.worlds` selects by placement index or world path (full path or
145
+ last segment, matched after mixing). Selectors that match nothing come
146
+ back in `absent` rather than erroring. Cell grids are pre-settle; for
147
+ settled state use `worldgen.generate` + `worldgen.advance`.
148
+
149
+ ```ts
150
+ const r = worldgen.partials('V-SNDST-C-42-0-4A-MUWF1', {
151
+ worlds: ['VanillaSandstoneDefault'],
152
+ });
153
+ for (const g of r.worlds[0]?.geysers ?? []) console.log(g.type, g.x, g.y);
154
+ ```
155
+
156
+ Geyser output matches a full generate exactly. Story-trait templates
157
+ and starmap locations are not generated in partial mode.
158
+
136
159
  ```ts
137
160
  worldgen.entities(): EntitySpawners
138
161
  ```
package/index.cjs CHANGED
@@ -87,6 +87,10 @@ const worldgen = {
87
87
  entities() {
88
88
  return JSON.parse(_wasm.get_entity_spawners());
89
89
  },
90
+ // Partial worldgen; see index.js for the full contract notes.
91
+ partials(coord, opts) {
92
+ return JSON.parse(_wasm.partials_from_coordinate(coord, JSON.stringify(opts ?? {})));
93
+ },
90
94
  clear() {
91
95
  _wasm.clear_cluster_cache();
92
96
  },
package/index.d.ts CHANGED
@@ -451,6 +451,99 @@ export interface EntitySpawnerWorld {
451
451
  other_entities: EntitySpawn[];
452
452
  }
453
453
 
454
+ // -----------------------------------------------------------------------
455
+ // Partial worldgen
456
+ // -----------------------------------------------------------------------
457
+
458
+ export interface PartialsOptions {
459
+ /**
460
+ * Placement indices and/or world-path strings. A string matches the
461
+ * POST-mixing world path for this seed, in full
462
+ * (`"expansion1::worlds/SandstoneDefault"`) or by its last segment,
463
+ * case-insensitive, not the localized display name ("Terra").
464
+ * Selectors that match nothing land in the result's `absent` list
465
+ * instead of erroring.
466
+ */
467
+ worlds: Array<number | string>;
468
+ /** `"templates"` (default) or `"notemplates"` (skip template placement). */
469
+ mode?: 'templates' | 'notemplates';
470
+ }
471
+
472
+ /**
473
+ * One generated world from `worldgen.partials`. Grid fields arrive as
474
+ * plain JSON arrays (not the typed arrays `generate` uses) and hold
475
+ * pre-settle state.
476
+ */
477
+ export interface PartialWorld {
478
+ /** Placement index in the cluster layout (stable slot identity). */
479
+ index: number;
480
+ /** Post-mixing world path; see `WorldMapData.name`. */
481
+ name: string;
482
+ remixed_from: string | null;
483
+ remixed_source: string | null;
484
+ width: number;
485
+ height: number;
486
+ is_starting: boolean;
487
+ world_traits: string[];
488
+ geysers: GeyserSpawn[];
489
+ /**
490
+ * Digest-format per-world geyser hashes (FNV-1a-64, uppercase hex,
491
+ * empty when count is 0): the exact values the committed parity
492
+ * digests store. The counts hash a fixed tag allowlist that excludes
493
+ * some DLC5 spawners (e.g. SmallReefGeyser), so `geyser_spawns_count`
494
+ * can be less than `geysers.length`; the `geysers` array is the
495
+ * complete list.
496
+ */
497
+ geyser_spawns_sha: string;
498
+ geyser_spawns_count: number;
499
+ geyser_stats_sha: string;
500
+ geyser_stats_count: number;
501
+ element_idx: number[];
502
+ mass: number[];
503
+ temperature: number[];
504
+ disease_idx: number[];
505
+ disease_count: number[];
506
+ backwall_element_idx: number[];
507
+ backwall_mass: number[];
508
+ backwall_temperature: number[];
509
+ zone_idx: number[];
510
+ zone_table: string[];
511
+ subworld_idx: number[];
512
+ subworld_table: string[];
513
+ biome_cells: BiomeCell[];
514
+ buildings: EntitySpawn[];
515
+ pickupables: EntitySpawn[];
516
+ other_entities: EntitySpawn[];
517
+ }
518
+
519
+ export interface PartialsMixingApplied {
520
+ /** Placement index whose vanilla world was substituted. */
521
+ slot: number;
522
+ from: string;
523
+ to: string;
524
+ source: string;
525
+ }
526
+
527
+ export interface PartialsResult {
528
+ coordinate: string;
529
+ seed: number;
530
+ cluster: string;
531
+ /**
532
+ * Markers: story-trait templates were skipped, so cell grids on
533
+ * worlds that would have received one differ from a full `generate`.
534
+ * Geysers are unaffected.
535
+ */
536
+ partial: true;
537
+ story_traits_skipped: true;
538
+ /** World-mixing substitutions applied for this seed (all slots). */
539
+ mixing_applied: PartialsMixingApplied[];
540
+ /** Generated worlds, one per selected slot present this seed. */
541
+ worlds: PartialWorld[];
542
+ /** Requested selectors that matched no slot this seed. */
543
+ absent: string[];
544
+ failure?: { stage: string; world_index: number; message: string } | null;
545
+ }
546
+
454
547
  // -----------------------------------------------------------------------
455
548
  // init + worldgen singleton
456
549
  // -----------------------------------------------------------------------
@@ -536,6 +629,17 @@ export const worldgen: {
536
629
  */
537
630
  entities(): EntitySpawners | { error: string };
538
631
 
632
+ /**
633
+ * Partial worldgen: generate only the selected worlds of a cluster.
634
+ * Geyser output is bit-identical to a full generate. Partial mode
635
+ * never places story-trait templates or assigns starmap locations.
636
+ * Stateless: does not populate the cluster cache used by
637
+ * `advance()` / `entities()`.
638
+ *
639
+ * Returns `{ error }` (not a throw) on parse/config failures.
640
+ */
641
+ partials(coordinate: string, opts: PartialsOptions): PartialsResult | { error: string };
642
+
539
643
  /**
540
644
  * Drop the cached generated cluster. Editor settings (if mutated)
541
645
  * are preserved.
package/oni_wasm.d.ts CHANGED
@@ -92,6 +92,25 @@ export function get_entity_spawners(): string;
92
92
  */
93
93
  export function noise_node_kinds(): string;
94
94
 
95
+ /**
96
+ * Partial worldgen: generate only the selected worlds of a cluster.
97
+ * Cluster-level pre-passes (mixing, trait selection) run over every
98
+ * placement; per-world phases run only for the selected slots.
99
+ * Stateless; does not touch `CLUSTER_CACHE`.
100
+ *
101
+ * Geyser output matches a full generate exactly, and each world
102
+ * carries the digest-format geyser hashes. Verified element-wise by
103
+ * `tests/partial_parity.rs` and against the digest corpus by
104
+ * `scripts/partials_geyser_verify.mjs`.
105
+ *
106
+ * Story-trait templates and starmap locations are never produced;
107
+ * both depend on cross-world state a partial run lacks. Stock story
108
+ * traits carry no geysers, so geyser output is unaffected. Cell
109
+ * grids are pre-settle, as with `generate`; there is no partial
110
+ * settle (use `generate` + `advance` for settled state).
111
+ */
112
+ export function partials_from_coordinate(coordinate: string, options_json: string): string;
113
+
95
114
  /**
96
115
  * Toggle template placement. WASM-side counterpart of the native
97
116
  * `SKIP_TEMPLATES` env var.
package/oni_wasm.js CHANGED
@@ -250,6 +250,44 @@ function noise_node_kinds() {
250
250
  }
251
251
  exports.noise_node_kinds = noise_node_kinds;
252
252
 
253
+ /**
254
+ * Partial worldgen: generate only the selected worlds of a cluster.
255
+ * Cluster-level pre-passes (mixing, trait selection) run over every
256
+ * placement; per-world phases run only for the selected slots.
257
+ * Stateless; does not touch `CLUSTER_CACHE`.
258
+ *
259
+ * Geyser output matches a full generate exactly, and each world
260
+ * carries the digest-format geyser hashes. Verified element-wise by
261
+ * `tests/partial_parity.rs` and against the digest corpus by
262
+ * `scripts/partials_geyser_verify.mjs`.
263
+ *
264
+ * Story-trait templates and starmap locations are never produced;
265
+ * both depend on cross-world state a partial run lacks. Stock story
266
+ * traits carry no geysers, so geyser output is unaffected. Cell
267
+ * grids are pre-settle, as with `generate`; there is no partial
268
+ * settle (use `generate` + `advance` for settled state).
269
+ * @param {string} coordinate
270
+ * @param {string} options_json
271
+ * @returns {string}
272
+ */
273
+ function partials_from_coordinate(coordinate, options_json) {
274
+ let deferred3_0;
275
+ let deferred3_1;
276
+ try {
277
+ const ptr0 = passStringToWasm0(coordinate, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
278
+ const len0 = WASM_VECTOR_LEN;
279
+ const ptr1 = passStringToWasm0(options_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
280
+ const len1 = WASM_VECTOR_LEN;
281
+ const ret = wasm.partials_from_coordinate(ptr0, len0, ptr1, len1);
282
+ deferred3_0 = ret[0];
283
+ deferred3_1 = ret[1];
284
+ return getStringFromWasm0(ret[0], ret[1]);
285
+ } finally {
286
+ wasm.__wbindgen_free(deferred3_0, deferred3_1, 1);
287
+ }
288
+ }
289
+ exports.partials_from_coordinate = partials_from_coordinate;
290
+
253
291
  /**
254
292
  * Toggle template placement. WASM-side counterpart of the native
255
293
  * `SKIP_TEMPLATES` env var.
package/oni_wasm_bg.wasm CHANGED
Binary file
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@onimaxxing/worldgen-node",
3
3
  "description": "WASM entry point for ONI worldgen",
4
- "version": "0.21.2",
4
+ "version": "0.22.0",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",