@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/index.cjs ADDED
@@ -0,0 +1,147 @@
1
+ // CommonJS wrapper for the Node target. Mirrors `index.js` (ESM) but
2
+ // uses require/module.exports so it interoperates with the CJS
3
+ // `oni_wasm.js` that wasm-pack generates for `--target nodejs`.
4
+ //
5
+ // Same surface as `index.js`: default export is `init` (a no-op on
6
+ // Node since WASM is loaded synchronously at require time), plus the
7
+ // `worldgen` singleton.
8
+
9
+ const _wasm = require('./oni_wasm.js');
10
+
11
+ // JS-side checksum cache. The resident snapshot lives WASM-side (in
12
+ // SNAPSHOT_SLOT). Mutator methods set `_checksumDirty = true`; the
13
+ // hot path is a boolean check + cached string return.
14
+ let _lastChecksum = null;
15
+ let _checksumDirty = true;
16
+
17
+ // No-op init for consistency with the web target. Node's wasm-pack
18
+ // glue loads the WASM at require time via fs.readFileSync; there's
19
+ // nothing to await.
20
+ async function init(_opts) {}
21
+
22
+ function decodeSnapshot(buf) {
23
+ if (!buf || buf.length === 0) {
24
+ throw new Error(
25
+ 'settle_cluster_advance returned an empty buffer — no cached cluster, or tick out of range. Did you call worldgen.generate(coord) first?'
26
+ );
27
+ }
28
+ const view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);
29
+ let offset = 0;
30
+ const version = view.getUint32(offset, true); offset += 4;
31
+ if (version !== 4) {
32
+ throw new Error(`decodeSnapshot: expected version 4, got ${version}`);
33
+ }
34
+ const tick = view.getUint32(offset, true); offset += 4;
35
+ const worldCount = view.getUint32(offset, true); offset += 4;
36
+
37
+ const worlds = [];
38
+ for (let w = 0; w < worldCount; w++) {
39
+ const width = view.getUint32(offset, true); offset += 4;
40
+ const height = view.getUint32(offset, true); offset += 4;
41
+ const cells = width * height;
42
+
43
+ const element_idx = new Uint16Array(cells);
44
+ const mass = new Float32Array(cells);
45
+ const temperature = new Float32Array(cells);
46
+ const disease_idx = new Uint8Array(cells);
47
+ const disease_count = new Int32Array(cells);
48
+
49
+ for (let c = 0; c < cells; c++) {
50
+ element_idx[c] = view.getUint16(offset, true); offset += 2;
51
+ mass[c] = view.getFloat32(offset, true); offset += 4;
52
+ temperature[c] = view.getFloat32(offset, true); offset += 4;
53
+ disease_idx[c] = view.getUint8(offset); offset += 1;
54
+ disease_count[c] = view.getInt32(offset, true); offset += 4;
55
+ }
56
+
57
+ worlds.push({
58
+ width, height,
59
+ element_idx, mass, temperature,
60
+ disease_idx, disease_count,
61
+ });
62
+ }
63
+
64
+ return { tick, worlds };
65
+ }
66
+
67
+ const worldgen = {
68
+ generate(coord) {
69
+ // Typed-array transport: per-cell grids arrive as Uint16Array /
70
+ // Float32Array / Uint8Array / Int32Array — no JSON.parse.
71
+ return _wasm.generate_map_data(coord);
72
+ },
73
+ advance(tick) {
74
+ return decodeSnapshot(_wasm.settle_cluster_advance(tick));
75
+ },
76
+ entities() {
77
+ return JSON.parse(_wasm.get_entity_spawners());
78
+ },
79
+ clear() {
80
+ _wasm.clear_cluster_cache();
81
+ },
82
+
83
+ // Snapshot-based settings I/O. The resident snapshot lives WASM-side
84
+ // in a thread-local slot; JS only tracks a checksum-cache dirty
85
+ // flag. See index.js for the full contract notes.
86
+ snapshot: {
87
+ loadVanilla() {
88
+ _wasm.snapshot_state_vanilla();
89
+ _checksumDirty = true;
90
+ },
91
+ loadVanillaExtensions() {
92
+ _wasm.snapshot_state_vanilla_extensions();
93
+ _checksumDirty = true;
94
+ },
95
+ load(files) {
96
+ _wasm.snapshot_state_load(JSON.stringify(files));
97
+ _checksumDirty = true;
98
+ },
99
+ loadExtensions(files) {
100
+ _wasm.snapshot_state_load_extensions(JSON.stringify(files));
101
+ _checksumDirty = true;
102
+ },
103
+ merge(files) {
104
+ _wasm.snapshot_state_merge(JSON.stringify(files));
105
+ _checksumDirty = true;
106
+ },
107
+ files() {
108
+ return JSON.parse(_wasm.snapshot_state_files());
109
+ },
110
+ checksum() {
111
+ if (!_checksumDirty && _lastChecksum !== null) {
112
+ return _lastChecksum;
113
+ }
114
+ _lastChecksum = _wasm.snapshot_state_checksum();
115
+ _checksumDirty = false;
116
+ return _lastChecksum;
117
+ },
118
+ remove(paths) {
119
+ if (!paths || paths.length === 0) return;
120
+ _wasm.snapshot_state_drop_paths(JSON.stringify(paths));
121
+ _checksumDirty = true;
122
+ },
123
+ schemaVersion() {
124
+ return _wasm.game_version();
125
+ },
126
+ },
127
+
128
+ reset() {
129
+ _wasm.settings_reset();
130
+ _lastChecksum = null;
131
+ _checksumDirty = true;
132
+ },
133
+
134
+ version() {
135
+ return _wasm.game_version();
136
+ },
137
+ };
138
+
139
+ // Re-export the Klei-faithful YAML parser so consumers have a
140
+ // one-stop import for the full ingestion pipeline (YAML → JSON →
141
+ // worldgen.snapshot.merge). Mirrors the ESM variant in `index.js`.
142
+ const { parseKleiYaml } = require('./yaml.cjs');
143
+
144
+ module.exports = init;
145
+ module.exports.default = init;
146
+ module.exports.worldgen = worldgen;
147
+ module.exports.parseKleiYaml = parseKleiYaml;