@onimaxxing/worldgen-node 0.31.3 → 0.33.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
@@ -325,6 +325,7 @@ interface WorldgenFailure {
325
325
  stage: string; // pipeline stage that reported the error
326
326
  world_index: number; // -1 for cluster-level failures
327
327
  message: string;
328
+ origin?: TemplateRuleOrigin; // failing rule, when a guaranteed template rule failed
328
329
  }
329
330
 
330
331
  interface WorldgenEvent {
@@ -352,11 +353,47 @@ interface WorldMapData {
352
353
  subworld_table: string[]; // distinct subworld type paths (same vocab as biome_cells[].type)
353
354
  biome_cells: BiomeCell[];
354
355
  geysers: GeyserSpawn[];
356
+ template_placements: TemplatePlacement[];
357
+ template_rule_outcomes: TemplateRuleOutcome[];
355
358
  buildings: EntitySpawn[];
356
359
  pickupables: EntitySpawn[];
357
360
  other_entities: EntitySpawn[];
358
361
  }
359
362
 
363
+ interface TemplatePlacement {
364
+ template: string; // e.g. "poi/frozen/heatsink_a"
365
+ x: number; y: number; // anchor cell
366
+ rule: string | null; // ruleId, "storytrait:<path>", "starting_base", or null
367
+ origin: TemplateRuleOrigin; // exact rule that placed it
368
+ }
369
+
370
+ // (file, index) joins against the yaml as read: index is the position in
371
+ // the authored rule array, before trait removals and the priority sort.
372
+ interface TemplateRuleOrigin {
373
+ kind: 'world' | 'subworld' | 'worldTrait' | 'clusterMixing'
374
+ | 'subworldMixing' | 'storyTrait' | 'startingBase';
375
+ file: string; // snapshot files-map key
376
+ index: number | null; // null for startingBase
377
+ ruleId: string | null;
378
+ world?: string; // world whose pass ran it (all kinds but world/startingBase)
379
+ placement?: number; // clusterMixing: worldPlacements index in file
380
+ }
381
+
382
+ // One per rule evaluated, in evaluation order (rule pass, then story
383
+ // traits), including rules that placed nothing.
384
+ interface TemplateRuleOutcome {
385
+ origin: TemplateRuleOrigin;
386
+ listRule: string; // yaml listRule, e.g. "GuaranteeSomeTryMore"
387
+ someCount: number;
388
+ moreCount: number;
389
+ times: number;
390
+ template_count: number; // names.length
391
+ guaranteed: number; // placements the game requires, over all iterations
392
+ placed: number;
393
+ failed: boolean; // ApplyTemplateRule returned false
394
+ rolled_back: boolean; // story trait failed here; its placements were removed
395
+ }
396
+
360
397
  interface BiomeCell {
361
398
  id: number;
362
399
  type: string; // subworld type path
package/index.d.ts CHANGED
@@ -204,6 +204,13 @@ export interface WorldgenFailure {
204
204
  world_index: number;
205
205
  /** Human-readable description. */
206
206
  message: string;
207
+ /**
208
+ * Present when a guaranteed template rule failed (`stage:
209
+ * "TemplateSpawning"`): the rule's origin, with `world` always set to
210
+ * the world whose pass ran it. That world can differ from
211
+ * `world_index`, which follows the game's error-reporting world.
212
+ */
213
+ origin?: TemplateRuleOrigin;
207
214
  }
208
215
 
209
216
  export interface WorldgenEvent {
@@ -303,6 +310,7 @@ export interface WorldMapData {
303
310
  biome_cells: BiomeCell[];
304
311
  geysers: GeyserSpawn[];
305
312
  template_placements: TemplatePlacement[];
313
+ template_rule_outcomes: TemplateRuleOutcome[];
306
314
  buildings: EntitySpawn[];
307
315
  pickupables: EntitySpawn[];
308
316
  other_entities: EntitySpawn[];
@@ -316,6 +324,100 @@ export interface TemplatePlacement {
316
324
  y: number;
317
325
  /** `ruleId`, `"storytrait:<path>"`, `"starting_base"`, or `null`. */
318
326
  rule: string | null;
327
+ /** The rule (or starting base) that placed this template. */
328
+ origin: TemplateRuleOrigin;
329
+ }
330
+
331
+ /**
332
+ * Where a template rule is authored:
333
+ * - `world`: world yaml `worldTemplateRules[index]`.
334
+ * - `subworld`: subworld yaml `subworldTemplateRules[index]`, for every
335
+ * subworld in the world's `subworldFiles`, including subworlds that
336
+ * subworld mixing or `worldMixing.additionalSubworldFiles` added.
337
+ * - `worldTrait`: world trait yaml `additionalWorldTemplateRules[index]`.
338
+ * - `clusterMixing`: cluster yaml
339
+ * `worldPlacements[placement].worldMixing.additionalWorldTemplateRules[index]`.
340
+ * Applied to a placement whose world was substituted by world mixing.
341
+ * - `subworldMixing`: subworld-mixing settings yaml
342
+ * `additionalWorldTemplateRules[index]`.
343
+ * - `storyTrait`: story trait yaml `additionalWorldTemplateRules[index]`.
344
+ * - `startingBase`: the world yaml's `startingBaseTemplate`. Not a rule
345
+ * array, so `index` is `null`.
346
+ *
347
+ * `index` is the position in the authored array, before a trait's
348
+ * `removeWorldTemplateRulesById` and before the priority sort, so
349
+ * `(file, index)` joins against the yaml as read, independent of seed.
350
+ * A world that lists the same subworld twice, or a subworld-mixing file
351
+ * chosen for two slots, evaluates that rule twice under the same key.
352
+ */
353
+ export interface TemplateRuleOrigin {
354
+ kind:
355
+ | 'world'
356
+ | 'subworld'
357
+ | 'worldTrait'
358
+ | 'clusterMixing'
359
+ | 'subworldMixing'
360
+ | 'storyTrait'
361
+ | 'startingBase';
362
+ /** Snapshot files-map key, e.g. `"expansion1::worldgen/worlds/TerraMoonlet.yaml"`. */
363
+ file: string;
364
+ index: number | null;
365
+ ruleId: string | null;
366
+ /**
367
+ * Files-map key of the world whose pass ran the rule. Set for every
368
+ * kind except `world` and `startingBase`, whose `file` is that world.
369
+ */
370
+ world?: string;
371
+ /** `worldPlacements` index in `file`; `clusterMixing` only. */
372
+ placement?: number;
373
+ }
374
+
375
+ /**
376
+ * One template rule evaluated in a world's template pass, in evaluation
377
+ * order: the rule pass (priority-sorted world, trait, mixing and
378
+ * subworld rules), then the story-trait pass. Rules that placed nothing
379
+ * are included. Yaml-sourced fields keep their yaml names.
380
+ */
381
+ export interface TemplateRuleOutcome {
382
+ origin: TemplateRuleOrigin;
383
+ listRule:
384
+ | 'GuaranteeOne'
385
+ | 'GuaranteeSome'
386
+ | 'GuaranteeSomeTryMore'
387
+ | 'GuaranteeAll'
388
+ | 'GuaranteeRange'
389
+ | 'TryOne'
390
+ | 'TrySome'
391
+ | 'TryRange'
392
+ | 'TryAll';
393
+ someCount: number;
394
+ moreCount: number;
395
+ times: number;
396
+ /** Length of the rule's `names` list. */
397
+ template_count: number;
398
+ /**
399
+ * Placements the game requires, summed over `times` iterations: the
400
+ * per-iteration guarantee from `listRule` (`someCount`, 1, the
401
+ * candidate count for `GuaranteeAll`, the rolled range value). An
402
+ * iteration with no usable candidates (all used, missing, or none
403
+ * left without `allowDuplicates`) is skipped and adds nothing.
404
+ */
405
+ guaranteed: number;
406
+ /** Templates this rule placed. `GuaranteeSomeTryMore` can exceed `guaranteed`. */
407
+ placed: number;
408
+ /**
409
+ * The game's `ApplyTemplateRule` returned false: a guarantee went
410
+ * unmet, or `overridePlacement` hit a cell that already has a
411
+ * template. Outside the story-trait pass this aborts worldgen in game
412
+ * (see `failure`).
413
+ */
414
+ failed: boolean;
415
+ /**
416
+ * Story-trait rule whose trait failed on this world: every placement
417
+ * of that trait here was removed, and the trait moved on to another
418
+ * world. `placed` still counts what this rule placed before removal.
419
+ */
420
+ rolled_back: boolean;
319
421
  }
320
422
 
321
423
  export interface BiomeCell {
@@ -497,6 +599,8 @@ export interface PartialWorld {
497
599
  world_traits: string[];
498
600
  geysers: GeyserSpawn[];
499
601
  template_placements: TemplatePlacement[];
602
+ /** Story-trait rules are absent (`story_traits_skipped`). */
603
+ template_rule_outcomes: TemplateRuleOutcome[];
500
604
  element_idx: Uint16Array;
501
605
  mass: Float32Array;
502
606
  temperature: Float32Array;
@@ -540,7 +644,7 @@ export interface PartialsResult {
540
644
  worlds: PartialWorld[];
541
645
  /** Requested selectors that matched no slot this seed. */
542
646
  absent: string[];
543
- failure?: { stage: string; world_index: number; message: string } | null;
647
+ failure?: WorldgenFailure | null;
544
648
  }
545
649
 
546
650
  // -----------------------------------------------------------------------
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.31.3",
4
+ "version": "0.33.0",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",