@hypersoniclabs/helix-cli 0.1.25-helix3.501 → 0.1.25-helix3.502

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.
Files changed (27) hide show
  1. package/README.md +1 -0
  2. package/dist/sceneSplit/commands.js +42 -0
  3. package/dist/sceneSplit/commands.js.map +1 -1
  4. package/dist/sceneSplit/ktx2.d.ts +27 -0
  5. package/dist/sceneSplit/ktx2.js +95 -0
  6. package/dist/sceneSplit/ktx2.js.map +1 -1
  7. package/dist/sceneSplit/retexture.d.ts +100 -0
  8. package/dist/sceneSplit/retexture.js +504 -0
  9. package/dist/sceneSplit/retexture.js.map +1 -0
  10. package/dist/tsconfig.build.tsbuildinfo +1 -1
  11. package/docs/scene-split.md +12 -0
  12. package/package.json +1 -1
  13. package/plugins/beamng-vehicle/bin/__pycache__/beamng_abs.cpython-312.pyc +0 -0
  14. package/plugins/beamng-vehicle/bin/__pycache__/beamng_audio.cpython-312.pyc +0 -0
  15. package/plugins/beamng-vehicle/bin/__pycache__/beamng_engine.cpython-312.pyc +0 -0
  16. package/plugins/beamng-vehicle/bin/__pycache__/beamng_expression.cpython-312.pyc +0 -0
  17. package/plugins/beamng-vehicle/bin/__pycache__/beamng_jbeam.cpython-312.pyc +0 -0
  18. package/plugins/beamng-vehicle/bin/__pycache__/beamng_materials.cpython-312.pyc +0 -0
  19. package/plugins/beamng-vehicle/bin/__pycache__/beamng_stock_events.cpython-312.pyc +0 -0
  20. package/plugins/beamng-vehicle/bin/__pycache__/fmod_studio.cpython-312.pyc +0 -0
  21. package/plugins/beamng-vehicle/bin/__pycache__/fsb5.cpython-312.pyc +0 -0
  22. package/plugins/beamng-vehicle/bin/__pycache__/sim_audio.cpython-312.pyc +0 -0
  23. package/plugins/beamng-vehicle/bin/__pycache__/sim_audio_ac.cpython-312.pyc +0 -0
  24. package/plugins/beamng-vehicle/bin/__pycache__/sim_audio_beamng.cpython-312.pyc +0 -0
  25. package/plugins/beamng-vehicle/bin/__pycache__/sim_audio_fixtures.cpython-312.pyc +0 -0
  26. package/plugins/beamng-vehicle/bin/__pycache__/test_beamng_engine.cpython-312.pyc +0 -0
  27. package/plugins/beamng-vehicle/bin/__pycache__/test_sim_audio.cpython-312.pyc +0 -0
package/README.md CHANGED
@@ -107,6 +107,7 @@ The token is stored in `~/.helix/credentials.json` (mode `600`). It's sent as
107
107
  | `helix world scene-source publish <world-id> <package-dir> [--publish]` | Validate the Scene v2 package, refuse it if it breaks the open-world performance rules (docs/scene-perf.md; no override), and print its multipart build receipt. Execution remains dry-run-only until backend private-pin entitlement lands; `--publish` currently fails closed, and access control never changes CC BY rights. |
108
108
  | `helix scene validate <dir\|file> [--perf] [--tier desktop\|mobile\|desktop,mobile] [--out <report.json>]` | Check a Scene v2 package against the shared validator and, with `--perf`, the 14 open-world performance rules (textures, geometry, cells, draws, budget, first-playable bytes). Exit 0 pass, 1 refused, 2 cannot be judged. See `docs/scene-perf.md`. |
109
109
  | `helix scene split <input> -o <dir> [--cell-size m] [--core-radius m] [--spawn x,y,z] [--textures ktx2\|keep]` | Split a monolithic environment (one big shell GLB, or a Scene v2 document with an eager shell) into a small eager spawn core plus distance-streamed cells on a fixed, content-addressed grid. Writes a validated Scene v2 package with per-cell bounds, priority and an honest memory budget, plus a report of eager bytes before and after. Deterministic and byte-identical on a rerun; never publishes. See [`docs/scene-split.md`](docs/scene-split.md). |
110
+ | `helix scene retexture <split-dir> -o <dir> [--merge-psnr dB] [--uastc-rdo 2,1\|off] [--dry-run]` | Shrink the textures of a split Scene bundle without moving a cell: merge textures that decode to the same picture, re-encode UASTC data and normal maps with RDO above a PSNR floor, rewrite the image uris in the GLBs that named them, reseal and validate. Nodes, stream groups, bounds, spawn and budgets are untouched. Never publishes. See [`docs/scene-split.md`](docs/scene-split.md). |
110
111
  | `helix continuum publish-source-map\|publish-scratch\|publish-package\|publish-glb\|make-item\|publish-owned-item` | Resume exact-CID object adoption/ingestion, Package lease/seal, optional explicitly authorized Listing, and WorldRelease publication through one creator-owned pipeline. |
111
112
  | `helix continuum receipt <job-id>` | Read the sanitized durable receipt for a completed Continuum publication. |
112
113
  | `helix unreal init\|validate\|doctor\|package [project]` | Create and gate a shared-runtime or native-game publish manifest, check optional editor MCP, and assemble a local upload-shaped package. |
@@ -51,6 +51,15 @@ function vec3Option(value) {
51
51
  }
52
52
  return parts;
53
53
  }
54
+ function parseRdoScalars(value) {
55
+ if (value === 'off')
56
+ return [];
57
+ const scalars = value.split(',').map(Number);
58
+ if (scalars.some((n) => !Number.isFinite(n) || n <= 0 || n > 10)) {
59
+ throw new Error(`--uastc-rdo must be 'off' or comma-separated numbers in (0, 10], got '${value}'`);
60
+ }
61
+ return scalars;
62
+ }
54
63
  /** `helix scene split`: turn a monolithic environment into a spawn core plus streamed cells. */
55
64
  function registerSceneSplitCommands(scene, fail) {
56
65
  scene
@@ -111,5 +120,38 @@ function registerSceneSplitCommands(scene, fail) {
111
120
  fail(`✖ ${error instanceof Error ? error.message : String(error)}`);
112
121
  }
113
122
  });
123
+ scene
124
+ .command('retexture')
125
+ .description('Shrink the textures of a split Scene bundle without moving a cell: merge textures that decode to the same picture, ' +
126
+ 're-encode UASTC data and normal maps with RDO (each only above a PSNR floor), rewrite the image uris in the ' +
127
+ 'affected GLBs, reseal and validate the document. Nodes, stream groups, bounds, spawn and budgets are copied through untouched.')
128
+ .argument('<input>', 'a folder holding scene.helix-scene.json and the files its resources name (what `helix scene split` writes)')
129
+ .requiredOption('-o, --output <dir>', 'new or empty output directory')
130
+ .option('--merge-psnr <dB>', 'merge two textures when their decoded PSNR is at least this (default 44)', numberOption('--merge-psnr', 20, 99))
131
+ .option('--merge-max-delta <levels>', 'and no texel differs by more than this, 0-255 (default 24)', numberOption('--merge-max-delta', 0, 255))
132
+ .option('--uastc-rdo <scalars>', 'comma-separated UASTC RDO quality scalars to try for data and normal maps, highest first (higher is smaller and lossier); "off" turns RDO off (default 2,1)')
133
+ .option('--reencode-psnr <dB>', 'floor for an RDO re-encode against the decoded original (default 40)', numberOption('--reencode-psnr', 20, 99))
134
+ .option('--dry-run', 'measure and report without writing files')
135
+ .option('--json', 'machine-readable report')
136
+ .action(async (input, opts) => {
137
+ try {
138
+ const { retextureBundle, formatRetextureReport } = await Promise.resolve().then(() => __importStar(require('./retexture')));
139
+ const report = await retextureBundle({
140
+ input: (0, node_path_1.resolve)(input),
141
+ output: (0, node_path_1.resolve)(opts.output),
142
+ options: {
143
+ ...(opts.mergePsnr !== undefined ? { mergePsnrDb: opts.mergePsnr } : {}),
144
+ ...(opts.mergeMaxDelta !== undefined ? { mergeMaxDelta: opts.mergeMaxDelta } : {}),
145
+ ...(opts.uastcRdo !== undefined ? { uastcRdo: parseRdoScalars(opts.uastcRdo) } : {}),
146
+ ...(opts.reencodePsnr !== undefined ? { reencodePsnrDb: opts.reencodePsnr } : {}),
147
+ },
148
+ ...(opts.dryRun ? { dryRun: true } : {}),
149
+ });
150
+ console.log(opts.json ? JSON.stringify(report, null, 2) : formatRetextureReport(report));
151
+ }
152
+ catch (error) {
153
+ fail(`✖ ${error instanceof Error ? error.message : String(error)}`);
154
+ }
155
+ });
114
156
  }
115
157
  //# sourceMappingURL=commands.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/sceneSplit/commands.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/sceneSplit/commands.ts"],"names":[],"mappings":"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"}
@@ -7,3 +7,30 @@ export declare function decodeToRgba(bytes: Uint8Array): Promise<{
7
7
  height: number;
8
8
  }>;
9
9
  export declare function encodeKtx2(rgba: Uint8Array, width: number, height: number, role: TextureRole): Promise<Uint8Array>;
10
+ export interface Ktx2Header {
11
+ codec: 'etc1s' | 'uastc' | 'other';
12
+ /** Colour space the file declares in its data format descriptor. */
13
+ srgb: boolean;
14
+ width: number;
15
+ height: number;
16
+ levels: number;
17
+ supercompression: number;
18
+ }
19
+ /** The fields of a Basis KTX2 file that decide how it may be re-encoded. Throws on anything that is not a KTX2 file. */
20
+ export declare function readKtx2Header(bytes: Uint8Array): Ktx2Header;
21
+ /** Decode the top mip of a Basis KTX2 file to RGBA8 the way a GPU-less transcode sees it. */
22
+ export declare function decodeKtx2ToRgba(bytes: Uint8Array): Promise<{
23
+ data: Uint8Array;
24
+ width: number;
25
+ height: number;
26
+ }>;
27
+ export interface Ktx2EncodeOptions {
28
+ codec: 'etc1s' | 'uastc';
29
+ srgb: boolean;
30
+ /** ETC1S quality 1-255 (default ETC1S_QUALITY). */
31
+ quality?: number;
32
+ /** UASTC RDO quality scalar (basis `-uastc_rdo_l`, higher = smaller and lossier); omitted or 0 = off. */
33
+ rdo?: number;
34
+ }
35
+ /** Encode RGBA8 to a mipmapped Basis KTX2 file with an explicit codec and colour space (the split itself uses encodeKtx2). */
36
+ export declare function encodeKtx2Rgba(rgba: Uint8Array, width: number, height: number, options: Ktx2EncodeOptions): Promise<Uint8Array>;
@@ -6,6 +6,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.ETC1S_QUALITY = void 0;
7
7
  exports.decodeToRgba = decodeToRgba;
8
8
  exports.encodeKtx2 = encodeKtx2;
9
+ exports.readKtx2Header = readKtx2Header;
10
+ exports.decodeKtx2ToRgba = decodeKtx2ToRgba;
11
+ exports.encodeKtx2Rgba = encodeKtx2Rgba;
9
12
  const promises_1 = require("node:fs/promises");
10
13
  const node_path_1 = require("node:path");
11
14
  const node_url_1 = require("node:url");
@@ -77,4 +80,96 @@ async function encodeKtx2(rgba, width, height, role) {
77
80
  encoder.delete();
78
81
  }
79
82
  }
83
+ /** The fields of a Basis KTX2 file that decide how it may be re-encoded. Throws on anything that is not a KTX2 file. */
84
+ function readKtx2Header(bytes) {
85
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
86
+ const magic = [0xab, 0x4b, 0x54, 0x58, 0x20, 0x32, 0x30, 0xbb, 0x0d, 0x0a, 0x1a, 0x0a];
87
+ if (bytes.length < 80 || magic.some((byte, i) => bytes[i] !== byte))
88
+ throw new Error('not a KTX2 file');
89
+ const dfd = view.getUint32(48, true);
90
+ const model = bytes[dfd + 12];
91
+ const transfer = bytes[dfd + 14];
92
+ return {
93
+ codec: model === 163 ? 'etc1s' : model === 166 ? 'uastc' : 'other',
94
+ srgb: transfer === 2,
95
+ width: view.getUint32(20, true),
96
+ height: view.getUint32(24, true),
97
+ levels: view.getUint32(40, true),
98
+ supercompression: view.getUint32(44, true),
99
+ };
100
+ }
101
+ let transcoderPromise;
102
+ function getTranscoder() {
103
+ return (transcoderPromise ??= (async () => {
104
+ const file = require.resolve('three/examples/jsm/libs/basis/basis_transcoder.js');
105
+ // The bundled Basis UMD file has no ESM export, although Three's package marks .js as ESM.
106
+ const holder = { exports: undefined };
107
+ new Function('module', 'exports', 'require', '__filename', '__dirname', await (0, promises_1.readFile)(file, 'utf8'))(holder, {}, require, file, (0, node_path_1.dirname)(file));
108
+ const factory = holder.exports;
109
+ const module = await factory({ wasmBinary: await (0, promises_1.readFile)((0, node_path_1.join)((0, node_path_1.dirname)(file), 'basis_transcoder.wasm')) });
110
+ module.initializeBasis();
111
+ return module;
112
+ })());
113
+ }
114
+ /** Decode the top mip of a Basis KTX2 file to RGBA8 the way a GPU-less transcode sees it. */
115
+ async function decodeKtx2ToRgba(bytes) {
116
+ const module = await getTranscoder();
117
+ const file = new module.KTX2File(bytes);
118
+ try {
119
+ const width = file.getWidth();
120
+ const height = file.getHeight();
121
+ const rgba32 = 13;
122
+ if (!file.isValid() || !file.startTranscoding() || file.getImageTranscodedSizeInBytes(0, 0, 0, rgba32) !== width * height * 4) {
123
+ throw new Error('unsupported KTX2 texture');
124
+ }
125
+ const data = new Uint8Array(width * height * 4);
126
+ if (!file.transcodeImage(data, 0, 0, 0, rgba32, 0, -1, -1))
127
+ throw new Error('KTX2 decode failed');
128
+ return { data, width, height };
129
+ }
130
+ finally {
131
+ file.close();
132
+ file.delete();
133
+ }
134
+ }
135
+ /** Encode RGBA8 to a mipmapped Basis KTX2 file with an explicit codec and colour space (the split itself uses encodeKtx2). */
136
+ async function encodeKtx2Rgba(rgba, width, height, options) {
137
+ if (rgba.byteLength !== width * height * 4)
138
+ throw new Error('invalid RGBA texture');
139
+ const module = await getEncoderModule();
140
+ const encoder = new module.BasisEncoder();
141
+ try {
142
+ const uastc = options.codec === 'uastc';
143
+ encoder.setDebug(false);
144
+ encoder.setUASTC(uastc);
145
+ encoder.setCreateKTX2File(true);
146
+ encoder.setKTX2SRGBTransferFunc(options.srgb);
147
+ encoder.setMipGen(true);
148
+ encoder.setPerceptual(options.srgb);
149
+ if (uastc) {
150
+ encoder.setKTX2UASTCSupercompression(true);
151
+ encoder.setPackUASTCFlags(2);
152
+ encoder.setQualityLevel(150);
153
+ if (options.rdo && options.rdo > 0) {
154
+ if (!encoder.setRDOUASTC || !encoder.setRDOUASTCQualityScalar)
155
+ throw new Error('this Basis encoder build has no UASTC RDO');
156
+ encoder.setRDOUASTC(true);
157
+ encoder.setRDOUASTCQualityScalar(options.rdo);
158
+ }
159
+ }
160
+ else {
161
+ encoder.setQualityLevel(options.quality ?? exports.ETC1S_QUALITY);
162
+ }
163
+ encoder.setSliceSourceImage(0, rgba, width, height, 0);
164
+ const capacity = Math.ceil(width * height * 4 * (4 / 3)) * 2 + 65536;
165
+ const output = new Uint8Array(capacity);
166
+ const length = encoder.encode(output);
167
+ if (!length || length > capacity)
168
+ throw new Error('Basis encoding failed');
169
+ return output.slice(0, length);
170
+ }
171
+ finally {
172
+ encoder.delete();
173
+ }
174
+ }
80
175
  //# sourceMappingURL=ktx2.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ktx2.js","sourceRoot":"","sources":["../../src/sceneSplit/ktx2.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ktx2.js","sourceRoot":"","sources":["../../src/sceneSplit/ktx2.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,100 @@
1
+ import { type Ktx2Header } from './ktx2';
2
+ /**
3
+ * Re-texture a split Scene package without moving a single cell.
4
+ *
5
+ * `helix scene split` shares each distinct texture once, but "distinct" means distinct SOURCE BYTES. A shell
6
+ * exported from a DCC tool routinely carries one image many times with different encoder noise (Hyperspace's
7
+ * metal/rough map appears five times, 253 KB each, to within 0.1/255 mean difference), and every UASTC data map is
8
+ * written without rate-distortion optimisation. Both are paid in full on the first-playable path.
9
+ *
10
+ * This step reads a finished split bundle (the folder `helix scene split` writes: scene document, cells/, textures/,
11
+ * assets/) and changes ONLY texture bytes:
12
+ *
13
+ * 1. merges textures that decode to the same picture (same codec, colour space, size and role; high PSNR) onto one
14
+ * representative, by renaming the image uri inside each GLB that referenced the others;
15
+ * 2. re-encodes a UASTC data/normal map with RDO when that is smaller and still above a PSNR floor. Data and
16
+ * normal maps stay UASTC: scene perf rule P03 refuses ETC1S there, and its blocks facet a normal map.
17
+ *
18
+ * Nodes, transforms, stream groups, cell bounds, spawn, budgets and every GLB's geometry are copied through
19
+ * untouched, so what loads when (and what stands where) cannot change. Only the resource rows of the files that did
20
+ * change (GLB integrity/bytes/name, texture rows) are rewritten, then the document is resealed and validated.
21
+ */
22
+ export interface RetextureOptions {
23
+ /** Merge two textures when their level-0 PSNR (RGB) is at least this many dB. Default 44. */
24
+ mergePsnrDb?: number;
25
+ /** Also require the largest single-texel difference to stay below this (0-255). Default 24. */
26
+ mergeMaxDelta?: number;
27
+ /**
28
+ * UASTC RDO quality scalars to try for data and normal maps, highest first (basis `-uastc_rdo_l`: higher is smaller and
29
+ * lossier). The first that stays above `reencodePsnrDb` and saves `minSavingFraction` wins; empty disables. Default [2, 1].
30
+ */
31
+ uastcRdo?: number[];
32
+ /** Keep an RDO re-encode only when it is at least this much smaller. Default 0.08 (8 percent). */
33
+ minSavingFraction?: number;
34
+ /** Floor for a re-encode against the decoded original, in dB, on the channels the maps use. Default 40. */
35
+ reencodePsnrDb?: number;
36
+ }
37
+ type TextureKind = 'colour' | 'normal' | 'data';
38
+ export interface RetextureTexture {
39
+ name: string;
40
+ codec: Ktx2Header['codec'];
41
+ kind: TextureKind;
42
+ width: number;
43
+ height: number;
44
+ bytesBefore: number;
45
+ bytesAfter: number;
46
+ action: 'kept' | 'merged' | 'rdo' | 'dropped-unreferenced';
47
+ into?: string;
48
+ psnrDb?: number;
49
+ rdo?: number;
50
+ }
51
+ export interface RetextureReport {
52
+ schemaVersion: 'helix.scene-retexture-report/1';
53
+ options: Required<RetextureOptions>;
54
+ input: {
55
+ scene: string;
56
+ revision: string;
57
+ integritySha256: string;
58
+ };
59
+ output: {
60
+ scene: string;
61
+ revision: string;
62
+ integritySha256: string;
63
+ };
64
+ textures: {
65
+ before: {
66
+ files: number;
67
+ bytes: number;
68
+ };
69
+ after: {
70
+ files: number;
71
+ bytes: number;
72
+ };
73
+ };
74
+ glbs: {
75
+ rewritten: number;
76
+ unchanged: number;
77
+ bytesBefore: number;
78
+ bytesAfter: number;
79
+ };
80
+ totals: {
81
+ bytesBefore: number;
82
+ bytesAfter: number;
83
+ };
84
+ detail: RetextureTexture[];
85
+ warnings: string[];
86
+ }
87
+ /**
88
+ * Point the images of a GLB that name a texture in `rename` at its replacement (uri and, when it carried the old file
89
+ * name, the image name). Returns the new GLB, or undefined when it references none of them. Nothing else changes: the
90
+ * binary chunk is copied through byte for byte.
91
+ */
92
+ export declare function renameGlbImages(bytes: Uint8Array, rename: ReadonlyMap<string, string>): Uint8Array | undefined;
93
+ export declare function retextureBundle(args: {
94
+ input: string;
95
+ output: string;
96
+ options?: RetextureOptions;
97
+ dryRun?: boolean;
98
+ }): Promise<RetextureReport>;
99
+ export declare function formatRetextureReport(report: RetextureReport): string;
100
+ export {};