@bitmagic/cli 0.1.83-dev.0 → 0.1.83-dev.2

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 (199) hide show
  1. package/README.md +70 -1
  2. package/assets/skills/publishing-to-steam/SKILL.md +218 -0
  3. package/dist/assets/vxl-summary.d.ts +6 -20
  4. package/dist/assets/vxl-summary.js +9 -100
  5. package/dist/assets/vxl-summary.js.map +1 -1
  6. package/dist/cli.d.ts +1 -0
  7. package/dist/cli.js +2 -0
  8. package/dist/cli.js.map +1 -1
  9. package/dist/commands/check.js +5 -0
  10. package/dist/commands/check.js.map +1 -1
  11. package/dist/commands/forge.js +1 -1
  12. package/dist/commands/forge.js.map +1 -1
  13. package/dist/commands/import.js +2 -4
  14. package/dist/commands/import.js.map +1 -1
  15. package/dist/commands/init.js +0 -3
  16. package/dist/commands/init.js.map +1 -1
  17. package/dist/commands/ios.js +88 -136
  18. package/dist/commands/ios.js.map +1 -1
  19. package/dist/commands/promote.js +2 -4
  20. package/dist/commands/promote.js.map +1 -1
  21. package/dist/commands/publish.js +0 -1
  22. package/dist/commands/publish.js.map +1 -1
  23. package/dist/commands/steam-build.d.ts +67 -0
  24. package/dist/commands/steam-build.js +286 -0
  25. package/dist/commands/steam-build.js.map +1 -0
  26. package/dist/commands/steam-portal.d.ts +1 -0
  27. package/dist/commands/steam-portal.js +319 -0
  28. package/dist/commands/steam-portal.js.map +1 -0
  29. package/dist/commands/steam-upload.d.ts +37 -0
  30. package/dist/commands/steam-upload.js +172 -0
  31. package/dist/commands/steam-upload.js.map +1 -0
  32. package/dist/commands/steam.d.ts +1 -0
  33. package/dist/commands/steam.js +502 -0
  34. package/dist/commands/steam.js.map +1 -0
  35. package/dist/commands/verify.js +6 -0
  36. package/dist/commands/verify.js.map +1 -1
  37. package/dist/editor/asset-viewer.js +5 -4
  38. package/dist/editor/asset-viewer.js.map +1 -1
  39. package/dist/editor/game-info-panel.d.ts +2 -2
  40. package/dist/editor/game-info-panel.js +1 -2
  41. package/dist/editor/game-info-panel.js.map +1 -1
  42. package/dist/editor/game-info.d.ts +1 -3
  43. package/dist/editor/game-info.js +1 -2
  44. package/dist/editor/game-info.js.map +1 -1
  45. package/dist/editor/server.js +2 -3
  46. package/dist/editor/server.js.map +1 -1
  47. package/dist/editor/shell-page.js +9 -7
  48. package/dist/editor/shell-page.js.map +1 -1
  49. package/dist/forge/browser-host.d.ts +6 -12
  50. package/dist/forge/browser-host.js +5 -11
  51. package/dist/forge/browser-host.js.map +1 -1
  52. package/dist/ios/native-overrides.d.ts +27 -0
  53. package/dist/ios/native-overrides.js +87 -0
  54. package/dist/ios/native-overrides.js.map +1 -0
  55. package/dist/ios/record-validate.d.ts +1 -33
  56. package/dist/ios/record-validate.js +2 -100
  57. package/dist/ios/record-validate.js.map +1 -1
  58. package/dist/ios/store-bridge.d.ts +26 -0
  59. package/dist/ios/store-bridge.js +224 -0
  60. package/dist/ios/store-bridge.js.map +1 -0
  61. package/dist/ios/storekit-config.d.ts +15 -0
  62. package/dist/ios/storekit-config.js +106 -0
  63. package/dist/ios/storekit-config.js.map +1 -0
  64. package/dist/ios/xcode-template.d.ts +12 -3
  65. package/dist/ios/xcode-template.js +158 -27
  66. package/dist/ios/xcode-template.js.map +1 -1
  67. package/dist/package/collect-urls.d.ts +1 -1
  68. package/dist/package/collect-urls.js +10 -2
  69. package/dist/package/collect-urls.js.map +1 -1
  70. package/dist/package/offline-payload.d.ts +35 -0
  71. package/dist/package/offline-payload.js +142 -0
  72. package/dist/package/offline-payload.js.map +1 -0
  73. package/dist/package/packaged-check.d.ts +39 -0
  74. package/dist/package/packaged-check.js +104 -0
  75. package/dist/package/packaged-check.js.map +1 -0
  76. package/dist/package/transform.d.ts +4 -4
  77. package/dist/package/transform.js +3 -3
  78. package/dist/project/context.d.ts +7 -2
  79. package/dist/project/context.js +1 -2
  80. package/dist/project/context.js.map +1 -1
  81. package/dist/project/published-three.d.ts +14 -0
  82. package/dist/project/published-three.js +93 -0
  83. package/dist/project/published-three.js.map +1 -0
  84. package/dist/publish/bundle.d.ts +1 -1
  85. package/dist/publish/bundle.js +8 -3
  86. package/dist/publish/bundle.js.map +1 -1
  87. package/dist/publish/platform.d.ts +1 -1
  88. package/dist/publish/platform.js +1 -1
  89. package/dist/publish/source-zip.d.ts +0 -1
  90. package/dist/publish/source-zip.js +1 -2
  91. package/dist/publish/source-zip.js.map +1 -1
  92. package/dist/scaffold/aliases.js +8 -5
  93. package/dist/scaffold/aliases.js.map +1 -1
  94. package/dist/scaffold/engine-download.d.ts +1 -1
  95. package/dist/scaffold/engine-download.js +1 -1
  96. package/dist/scaffold/export-zip.d.ts +0 -1
  97. package/dist/scaffold/export-zip.js +3 -6
  98. package/dist/scaffold/export-zip.js.map +1 -1
  99. package/dist/scaffold/import-project.js +1 -1
  100. package/dist/scaffold/project-export.js +0 -1
  101. package/dist/scaffold/project-export.js.map +1 -1
  102. package/dist/scaffold/project-files.d.ts +0 -1
  103. package/dist/scaffold/project-files.js +8 -5
  104. package/dist/scaffold/project-files.js.map +1 -1
  105. package/dist/scaffold/project.d.ts +15 -4
  106. package/dist/scaffold/project.js +30 -13
  107. package/dist/scaffold/project.js.map +1 -1
  108. package/dist/scaffold/skill-files.js +3 -1
  109. package/dist/scaffold/skill-files.js.map +1 -1
  110. package/dist/scaffold/steam-skill-files.d.ts +2 -0
  111. package/dist/scaffold/steam-skill-files.js +7 -0
  112. package/dist/scaffold/steam-skill-files.js.map +1 -0
  113. package/dist/scaffold/suggest-template.js +0 -1
  114. package/dist/scaffold/suggest-template.js.map +1 -1
  115. package/dist/scaffold/unity-skill-files.js +1 -1
  116. package/dist/steam/art-generate.d.ts +55 -0
  117. package/dist/steam/art-generate.js +173 -0
  118. package/dist/steam/art-generate.js.map +1 -0
  119. package/dist/steam/art-render.d.ts +25 -0
  120. package/dist/steam/art-render.js +157 -0
  121. package/dist/steam/art-render.js.map +1 -0
  122. package/dist/steam/art-use.d.ts +20 -0
  123. package/dist/steam/art-use.js +84 -0
  124. package/dist/steam/art-use.js.map +1 -0
  125. package/dist/steam/art.d.ts +98 -0
  126. package/dist/steam/art.js +243 -0
  127. package/dist/steam/art.js.map +1 -0
  128. package/dist/steam/check.d.ts +21 -0
  129. package/dist/steam/check.js +113 -0
  130. package/dist/steam/check.js.map +1 -0
  131. package/dist/steam/config.d.ts +57 -0
  132. package/dist/steam/config.js +145 -0
  133. package/dist/steam/config.js.map +1 -0
  134. package/dist/steam/electron-cache.d.ts +11 -0
  135. package/dist/steam/electron-cache.js +105 -0
  136. package/dist/steam/electron-cache.js.map +1 -0
  137. package/dist/steam/fuses.d.ts +16 -0
  138. package/dist/steam/fuses.js +75 -0
  139. package/dist/steam/fuses.js.map +1 -0
  140. package/dist/steam/icon-files.d.ts +16 -0
  141. package/dist/steam/icon-files.js +70 -0
  142. package/dist/steam/icon-files.js.map +1 -0
  143. package/dist/steam/image-info.d.ts +16 -0
  144. package/dist/steam/image-info.js +89 -0
  145. package/dist/steam/image-info.js.map +1 -0
  146. package/dist/steam/launch-check.d.ts +12 -0
  147. package/dist/steam/launch-check.js +101 -0
  148. package/dist/steam/launch-check.js.map +1 -0
  149. package/dist/steam/media.d.ts +48 -0
  150. package/dist/steam/media.js +151 -0
  151. package/dist/steam/media.js.map +1 -0
  152. package/dist/steam/package-macos.d.ts +52 -0
  153. package/dist/steam/package-macos.js +268 -0
  154. package/dist/steam/package-macos.js.map +1 -0
  155. package/dist/steam/package-windows.d.ts +24 -0
  156. package/dist/steam/package-windows.js +84 -0
  157. package/dist/steam/package-windows.js.map +1 -0
  158. package/dist/steam/paths.d.ts +37 -0
  159. package/dist/steam/paths.js +45 -0
  160. package/dist/steam/paths.js.map +1 -0
  161. package/dist/steam/playtest-shots.d.ts +18 -0
  162. package/dist/steam/playtest-shots.js +83 -0
  163. package/dist/steam/playtest-shots.js.map +1 -0
  164. package/dist/steam/portal-recipes.d.ts +25 -0
  165. package/dist/steam/portal-recipes.js +61 -0
  166. package/dist/steam/portal-recipes.js.map +1 -0
  167. package/dist/steam/portal.d.ts +58 -0
  168. package/dist/steam/portal.js +340 -0
  169. package/dist/steam/portal.js.map +1 -0
  170. package/dist/steam/raster.d.ts +59 -0
  171. package/dist/steam/raster.js +285 -0
  172. package/dist/steam/raster.js.map +1 -0
  173. package/dist/steam/shell-files.d.ts +17 -0
  174. package/dist/steam/shell-files.js +268 -0
  175. package/dist/steam/shell-files.js.map +1 -0
  176. package/dist/steam/specs.d.ts +61 -0
  177. package/dist/steam/specs.js +103 -0
  178. package/dist/steam/specs.js.map +1 -0
  179. package/dist/steam/steampipe.d.ts +46 -0
  180. package/dist/steam/steampipe.js +170 -0
  181. package/dist/steam/steampipe.js.map +1 -0
  182. package/dist/steam/store-copy.d.ts +89 -0
  183. package/dist/steam/store-copy.js +221 -0
  184. package/dist/steam/store-copy.js.map +1 -0
  185. package/dist/steam/tags.d.ts +9 -0
  186. package/dist/steam/tags.js +49 -0
  187. package/dist/steam/tags.js.map +1 -0
  188. package/dist/steam/trailer.d.ts +34 -0
  189. package/dist/steam/trailer.js +141 -0
  190. package/dist/steam/trailer.js.map +1 -0
  191. package/dist/verify/browser.d.ts +11 -0
  192. package/dist/verify/browser.js +195 -152
  193. package/dist/verify/browser.js.map +1 -1
  194. package/dist/verify/classify.d.ts +11 -2
  195. package/dist/verify/classify.js +16 -4
  196. package/dist/verify/classify.js.map +1 -1
  197. package/dist/verify/mobile-parity.d.ts +1 -1
  198. package/dist/verify/mobile-parity.js +1 -1
  199. package/package.json +5 -4
@@ -0,0 +1,142 @@
1
+ /**
2
+ * The game as a packaged app ships it: the self-contained bundle, every asset it loads mirrored
3
+ * into a `vendor/` tree beside it, the page rewritten to load them from there — and PROOF that it
4
+ * boots with no network, on each renderer the target runs. Shared by `bitmagic ios build` and
5
+ * `bitmagic steam build`; the steps are §4c-f of docs/ios-export-design.md.
6
+ */
7
+ import * as fs from 'fs';
8
+ import * as path from 'path';
9
+ import { CliError } from '../errors.js';
10
+ import { buildBundlePaths, isCurrentBundle, runBuild } from '../publish/bundle.js';
11
+ import { computeFingerprint } from '../publish/fingerprint.js';
12
+ import { collectUrls } from './collect-urls.js';
13
+ import { runPackagedCheck } from './packaged-check.js';
14
+ import { transformBundleHtml } from './transform.js';
15
+ import { vendorBasePathFor, vendorUrls } from './vendor.js';
16
+ /**
17
+ * The bundle to package: the self-contained `--single-file` build, reused when it was built from
18
+ * this exact source and rebuilt otherwise. Never the default build, which loads three.js, Rapier
19
+ * and the other CDN packages from esm.sh at runtime and so cannot boot without a network.
20
+ * `json` sends the compiler's and bundler's output to stderr, keeping stdout for the result.
21
+ */
22
+ export function ensureSelfContainedBundle(context, output, json) {
23
+ const fingerprint = computeFingerprint(context.root);
24
+ if (isCurrentBundle(context.root, fingerprint, true)) {
25
+ output.info('Reusing the existing self-contained bundle (source unchanged).');
26
+ }
27
+ else {
28
+ output.info('Building the self-contained game bundle…');
29
+ runBuild(context.root, context.metadata.engineVersion, { singleFile: true, stderr: json });
30
+ }
31
+ const { htmlPath } = buildBundlePaths(context.root);
32
+ try {
33
+ return fs.readFileSync(htmlPath, 'utf-8');
34
+ }
35
+ catch {
36
+ throw new CliError(`The built bundle at ${htmlPath} is missing. Run \`bitmagic build\`, then package again.`);
37
+ }
38
+ }
39
+ const RENDERER_LABELS = { webgpu: 'WebGPU', webgl: 'WebGL' };
40
+ /**
41
+ * Stage the payload afresh: vendored files land here, then the transformed page. The
42
+ * sw-cache-buster stub rides along for a project still on an engine that registered it on
43
+ * localhost, so the validation passes find the file; current engines register no worker.
44
+ */
45
+ function stagePayload(payloadDir, root) {
46
+ fs.rmSync(payloadDir, { recursive: true, force: true });
47
+ fs.mkdirSync(payloadDir, { recursive: true });
48
+ const stub = path.join(root, 'sw-cache-buster.js');
49
+ if (fs.existsSync(stub))
50
+ fs.copyFileSync(stub, path.join(payloadDir, 'sw-cache-buster.js'));
51
+ }
52
+ export async function buildOfflinePayload(options) {
53
+ const { output } = options;
54
+ const collected = await collectUrls(options.root);
55
+ for (const note of collected.notes)
56
+ output.info(note);
57
+ stagePayload(options.payloadDir, options.root);
58
+ /** Mirror `urls` into the payload, narrating cache reuse and anything that would not fetch. */
59
+ const vendor = async (urls) => {
60
+ const result = await vendorUrls({ urls, cacheDir: options.cacheDir, payloadDir: options.payloadDir });
61
+ if (result.cacheHits > 0)
62
+ output.info(` ${result.cacheHits} from the local cache.`);
63
+ for (const failure of result.failures) {
64
+ // A warning, not a refusal: a stale URL the game never loads must not block packaging, and
65
+ // the offline validation below is the gate that catches one the game DOES load.
66
+ output.info(` warning: could not vendor ${failure.url} (${failure.error})`);
67
+ }
68
+ return result.entries;
69
+ };
70
+ output.info(`Vendoring ${collected.urls.size} assets into the app…`);
71
+ const assetMap = await vendor(collected.urls);
72
+ const baseRewrites = new Map();
73
+ for (const base of collected.bases) {
74
+ const rel = vendorBasePathFor(base);
75
+ if (rel !== null)
76
+ baseRewrites.set(base, rel);
77
+ }
78
+ const indexPath = path.join(options.payloadDir, 'index.html');
79
+ const writeTransformed = () => {
80
+ const transformed = transformBundleHtml({ html: options.html, distribution: options.distribution, assetMap, baseRewrites });
81
+ fs.writeFileSync(indexPath, transformed.html);
82
+ return transformed.rewrites;
83
+ };
84
+ const rewrites = writeTransformed();
85
+ output.info(`Asset map: ${assetMap.size} entries, ${rewrites} URL literals rewritten.`);
86
+ if (options.skipValidation) {
87
+ output.info('Offline validation skipped — this app is NOT confirmed to work without a network.');
88
+ return { assetMap, offlineValidated: false };
89
+ }
90
+ // Record passes: play the game the way the app will, once per renderer, and vendor whatever
91
+ // either one still fetched — the empirical net under the static collection (§4e of the design).
92
+ const recordedMisses = new Set();
93
+ for (const renderer of options.renderers) {
94
+ output.info(`Recording runtime asset requests (headless Chrome, ${options.deviceLabel}, ${RENDERER_LABELS[renderer]})…`);
95
+ const recorded = await runPackagedCheck({
96
+ payloadDir: options.payloadDir,
97
+ artifactDir: path.join(options.checkDir, `record-${renderer}`),
98
+ mode: 'record',
99
+ renderer,
100
+ platform: options.platform,
101
+ ...(options.orientation !== undefined ? { orientation: options.orientation } : {}),
102
+ });
103
+ for (const url of recorded.misses)
104
+ recordedMisses.add(url);
105
+ }
106
+ if (recordedMisses.size > 0) {
107
+ output.info(` ${recordedMisses.size} runtime-discovered asset(s) — vendoring those too.`);
108
+ for (const [url, rel] of await vendor(recordedMisses))
109
+ assetMap.set(url, rel);
110
+ writeTransformed();
111
+ }
112
+ // Every offline pass runs even when an earlier one fails, so one error lists every problem.
113
+ const problems = [];
114
+ const failedArtifacts = [];
115
+ for (const renderer of options.renderers) {
116
+ const label = RENDERER_LABELS[renderer];
117
+ output.info(`Validating the app works offline (${label})…`);
118
+ const artifactDir = path.join(options.checkDir, `offline-${renderer}`);
119
+ const offline = await runPackagedCheck({
120
+ payloadDir: options.payloadDir,
121
+ artifactDir,
122
+ mode: 'offline',
123
+ renderer,
124
+ platform: options.platform,
125
+ ...(options.orientation !== undefined ? { orientation: options.orientation } : {}),
126
+ });
127
+ for (const warning of offline.result.warnings)
128
+ output.info(` warning (${label}): ${warning}`);
129
+ if (!offline.result.ok || offline.misses.length > 0) {
130
+ problems.push(...offline.result.failures.map((failure) => ` ✗ ${label}: ${failure}`), ...offline.misses.map((url) => ` ✗ ${label}: still requests ${url}`));
131
+ failedArtifacts.push(artifactDir);
132
+ }
133
+ }
134
+ if (failedArtifacts.length > 0) {
135
+ throw new CliError('The packaged game does not work without a network:\n'
136
+ + problems.join('\n')
137
+ + `\nArtifacts: ${failedArtifacts.join(', ')}`, 5);
138
+ }
139
+ output.info(`Offline validation passed on ${options.renderers.map((r) => RENDERER_LABELS[r]).join(' and ')} — the game renders with no network.`);
140
+ return { assetMap, offlineValidated: true };
141
+ }
142
+ //# sourceMappingURL=offline-payload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"offline-payload.js","sourceRoot":"","sources":["../../src/package/offline-payload.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import { type RendererChoice } from '../browser-gl.js';
2
+ import { type VerifyResult } from '../verify/classify.js';
3
+ import type { MobileOrientation } from '../project/platform-declaration.js';
4
+ /** Long enough for a forged level's worth of local loads; adaptive settle exits earlier. */
5
+ export declare const PACKAGED_CHECK_SETTLE_MS = 25000;
6
+ /**
7
+ * Online-only endpoints the packaged game may talk to when a network exists, and must live
8
+ * without when one does not. Never vendored, aborted during both passes.
9
+ */
10
+ export declare function isOnlineOnlyUrl(url: string): boolean;
11
+ export interface PackagedCheckOptions {
12
+ payloadDir: string;
13
+ /** Where console.log / screenshot.png land — one subdirectory per pass. */
14
+ artifactDir: string;
15
+ mode: 'record' | 'offline';
16
+ /**
17
+ * The renderer this pass boots, pinned with `?renderer=`. A device on iOS 26 or later runs
18
+ * WebGPU; older iOS and the Simulator run the classic WebGL renderer. For WebGPU the run also
19
+ * probes the backend, so a headless Chrome that silently fell back to WebGL2 fails the pass
20
+ * instead of passing it on the wrong renderer.
21
+ */
22
+ renderer: RendererChoice;
23
+ orientation?: MobileOrientation;
24
+ /**
25
+ * Which game the payload is checked as. iOS ships the mobile game (`?platform=mobile` and a phone
26
+ * viewport, the default); the Steam lane ships the desktop game, booted the way its shell boots
27
+ * it — no platform override, a desktop window.
28
+ */
29
+ platform?: 'mobile' | 'desktop';
30
+ settleMs?: number;
31
+ }
32
+ export interface PackagedCheckOutcome {
33
+ result: VerifyResult;
34
+ /** Remote, non-online-only URLs the game requested — the vendoring gap. */
35
+ misses: string[];
36
+ consolePath: string;
37
+ screenshotPath: string;
38
+ }
39
+ export declare function runPackagedCheck(options: PackagedCheckOptions): Promise<PackagedCheckOutcome>;
@@ -0,0 +1,104 @@
1
+ /**
2
+ * §4e/f of docs/ios-export-design.md: boot the staged payload the way the packaged app will run
3
+ * it — headless system Chrome as an iPhone with `?platform=mobile` for iOS, as a desktop window for
4
+ * the Steam lane — in two modes, once per renderer the target can boot (`ios build` and
5
+ * `steam build` run each mode on WebGPU and on WebGL).
6
+ *
7
+ * - `record`: remote requests are allowed through and every one on a non-denylisted host is
8
+ * reported as a miss for the caller to vendor. This is the empirical net under the static
9
+ * collector: whatever the running game actually fetches, however the URL was constructed.
10
+ * - `offline`: every remote request is aborted. The run must still pass `classifyVerifyRun`
11
+ * (the same "did the game render" verdict verify and the publish smoke check use) with zero
12
+ * remote asset requests — that is the design's acceptance criterion for "no internet needed".
13
+ *
14
+ * Denylisted endpoints are the online-only features the engine already degrades without
15
+ * (game-server, play-auth, play sessions, fonts, analytics) — aborted in BOTH passes so the
16
+ * record run observes the same world the device will.
17
+ */
18
+ import * as fs from 'fs';
19
+ import * as path from 'path';
20
+ import { browserLaunchPlan } from '../browser-gl.js';
21
+ import { runHeadlessCheck } from '../verify/browser.js';
22
+ import { DEFAULT_START_INTERACTION } from '../verify/start.js';
23
+ import { classifyVerifyRun } from '../verify/classify.js';
24
+ import { mobileContextOptions } from '../verify/device.js';
25
+ import { startPayloadServer } from './local-server.js';
26
+ /** Long enough for a forged level's worth of local loads; adaptive settle exits earlier. */
27
+ export const PACKAGED_CHECK_SETTLE_MS = 25_000;
28
+ /**
29
+ * Online-only endpoints the packaged game may talk to when a network exists, and must live
30
+ * without when one does not. Never vendored, aborted during both passes.
31
+ */
32
+ export function isOnlineOnlyUrl(url) {
33
+ let parsed;
34
+ try {
35
+ parsed = new URL(url);
36
+ }
37
+ catch {
38
+ return false;
39
+ }
40
+ const host = parsed.hostname;
41
+ return (host.includes('game-server')
42
+ || parsed.pathname.endsWith('/play-auth.html')
43
+ || host === 'fonts.googleapis.com'
44
+ || host === 'fonts.gstatic.com'
45
+ || host === 'esm.sh'
46
+ || host === 'esm.run'
47
+ || host.endsWith('.sentry.io')
48
+ || host.endsWith('google-analytics.com')
49
+ || host.endsWith('googletagmanager.com')
50
+ // Local dev services (api-server 3002, game-server 1666, agent 4111, lid relay 8765) —
51
+ // NOT the payload server, whose exact origin is allowed before this predicate runs.
52
+ || host === 'localhost'
53
+ || host === '127.0.0.1');
54
+ }
55
+ export async function runPackagedCheck(options) {
56
+ fs.mkdirSync(options.artifactDir, { recursive: true });
57
+ const consolePath = path.join(options.artifactDir, 'console.log');
58
+ const screenshotPath = path.join(options.artifactDir, 'screenshot.png');
59
+ const server = await startPayloadServer(options.payloadDir);
60
+ const misses = new Set();
61
+ const routes = async (context) => {
62
+ await context.route('**/*', (route) => {
63
+ const url = route.request().url();
64
+ if (url.startsWith(server.origin)) {
65
+ void route.continue();
66
+ return;
67
+ }
68
+ if (isOnlineOnlyUrl(url)) {
69
+ void route.abort('internetdisconnected');
70
+ return;
71
+ }
72
+ misses.add(url);
73
+ if (options.mode === 'record')
74
+ void route.continue();
75
+ else
76
+ void route.abort('internetdisconnected');
77
+ });
78
+ };
79
+ try {
80
+ const observations = await runHeadlessCheck({
81
+ url: options.platform === 'desktop'
82
+ ? `${server.origin}/index.html?renderer=${options.renderer}`
83
+ : `${server.origin}/index.html?platform=mobile&renderer=${options.renderer}`,
84
+ screenshotPath,
85
+ consolePath,
86
+ settleMs: options.settleMs ?? PACKAGED_CHECK_SETTLE_MS,
87
+ startInteraction: DEFAULT_START_INTERACTION,
88
+ launch: browserLaunchPlan(process.env, options.renderer),
89
+ requestedRenderer: options.renderer,
90
+ ...(options.platform === 'desktop' ? {} : { device: mobileContextOptions(options.orientation ?? 'portrait') }),
91
+ routes,
92
+ });
93
+ return {
94
+ result: classifyVerifyRun(observations),
95
+ misses: [...misses],
96
+ consolePath,
97
+ screenshotPath,
98
+ };
99
+ }
100
+ finally {
101
+ await server.close();
102
+ }
103
+ }
104
+ //# sourceMappingURL=packaged-check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"packaged-check.js","sourceRoot":"","sources":["../../src/package/packaged-check.ts"],"names":[],"mappings":"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"}
@@ -3,10 +3,10 @@
3
3
  * the payload page. Two deliberately redundant mechanisms:
4
4
  *
5
5
  * - the `bm-bundled-assets` map (original URL → relative vendor path), which the engine's own
6
- * ASSET_MAP mechanism resolves through — every three.js loader plus the explicit
7
- * `ASSET_MAP.get` fetch sites;
6
+ * ASSET_MAP mechanism resolves through — every three.js loader plus the explicit fetch
7
+ * sites (`bundledAssetUrl`, `resolveAssetUrl`);
8
8
  * - a literal rewrite of every vendored URL AND the animation base-URL constants, which fixes
9
- * the sites that bypass the map (raw fetch in PlacedObjectSystem/HeightmapSystem/
9
+ * the sites that bypass the map (raw fetch in HeightmapSystem/
10
10
  * splat loaders, and the StartScreen/SelectionSteps/AchievementToast DOM urls): the world
11
11
  * data is inlined in this HTML, so rewriting the literals fixes what those sites read.
12
12
  *
@@ -15,7 +15,7 @@
15
15
  */
16
16
  export interface TransformOptions {
17
17
  html: string;
18
- distribution: 'ios' | 'poki';
18
+ distribution: 'ios' | 'poki' | 'steam';
19
19
  /** Original absolute URL → document-relative vendor path (`vendor/<host>/<path>`). */
20
20
  assetMap: ReadonlyMap<string, string>;
21
21
  /** Base-URL constant → relative base (see vendor.ts vendorBasePathFor). */
@@ -3,10 +3,10 @@
3
3
  * the payload page. Two deliberately redundant mechanisms:
4
4
  *
5
5
  * - the `bm-bundled-assets` map (original URL → relative vendor path), which the engine's own
6
- * ASSET_MAP mechanism resolves through — every three.js loader plus the explicit
7
- * `ASSET_MAP.get` fetch sites;
6
+ * ASSET_MAP mechanism resolves through — every three.js loader plus the explicit fetch
7
+ * sites (`bundledAssetUrl`, `resolveAssetUrl`);
8
8
  * - a literal rewrite of every vendored URL AND the animation base-URL constants, which fixes
9
- * the sites that bypass the map (raw fetch in PlacedObjectSystem/HeightmapSystem/
9
+ * the sites that bypass the map (raw fetch in HeightmapSystem/
10
10
  * splat loaders, and the StartScreen/SelectionSteps/AchievementToast DOM urls): the world
11
11
  * data is inlined in this HTML, so rewriting the literals fixes what those sites read.
12
12
  *
@@ -1,7 +1,12 @@
1
1
  export interface ProjectMetadata {
2
2
  gameId: string;
3
3
  engineVersion: string;
4
- genre: string;
4
+ /**
5
+ * Retired. The engine has one baseline, so nothing reads this to decide anything. Still written
6
+ * by `init`/`import`/`promote` because older CLIs require the field; never required here, so a
7
+ * bitmagic.json without it loads.
8
+ */
9
+ genre?: string;
5
10
  template: string;
6
11
  /** See the same field in scaffold/project-files.ts. Absent on projects scaffolded before it. */
7
12
  agentsMdHash?: string;
@@ -57,7 +62,7 @@ export declare function loadProjectContext(startDir?: string): ProjectContext;
57
62
  * project scaffolded before the field existed. "No project" is an answer here, not an error.
58
63
  *
59
64
  * Deliberately does NOT run findMissingField. `login` and `whoami` do not operate on the project,
60
- * and refusing to log in because a bitmagic.json two directories up is missing `genre` would be a
65
+ * and refusing to log in because a bitmagic.json two directories up is missing `template` would be a
61
66
  * brand new failure for commands that never needed a project at all. A marker that cannot be
62
67
  * PARSED still throws: that is not a "no project" answer, and swallowing it would point the user
63
68
  * at `bitmagic init` when their file is merely malformed.
@@ -9,7 +9,6 @@ const MARKER = 'bitmagic.json';
9
9
  const REQUIRED_STRING_FIELDS = [
10
10
  'gameId',
11
11
  'engineVersion',
12
- 'genre',
13
12
  'template',
14
13
  ];
15
14
  /**
@@ -100,7 +99,7 @@ export function loadProjectContext(startDir = process.cwd()) {
100
99
  * project scaffolded before the field existed. "No project" is an answer here, not an error.
101
100
  *
102
101
  * Deliberately does NOT run findMissingField. `login` and `whoami` do not operate on the project,
103
- * and refusing to log in because a bitmagic.json two directories up is missing `genre` would be a
102
+ * and refusing to log in because a bitmagic.json two directories up is missing `template` would be a
104
103
  * brand new failure for commands that never needed a project at all. A marker that cannot be
105
104
  * PARSED still throws: that is not a "no project" answer, and swallowing it would point the user
106
105
  * at `bitmagic init` when their file is merely malformed.
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/project/context.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/project/context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /** Exported by three's full build and missing from the published shim, with each one's own module. */
2
+ export declare const DEV_ONLY_THREE_EXPORTS: Readonly<Record<string, string>>;
3
+ export interface DevOnlyThreeUse {
4
+ /** Path relative to the project root. */
5
+ file: string;
6
+ line: number;
7
+ name: string;
8
+ }
9
+ /** Pure scan of one file's source — exported for tests. */
10
+ export declare function findDevOnlyThreeUses(file: string, source: string): DevOnlyThreeUse[];
11
+ /** Every dev-only `three` use under the project's `src/work`. */
12
+ export declare function scanWorkForDevOnlyThree(root: string): DevOnlyThreeUse[];
13
+ /** The message for a non-empty scan: every site, then the one fix. */
14
+ export declare function describeDevOnlyThreeUses(uses: DevOnlyThreeUse[]): string;
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Game code that reaches a `three` export only the dev server has.
3
+ *
4
+ * A published game resolves `three` to the shim in `scaffold/project-files.ts` (`THREE_SHIM`):
5
+ * three's WebGPU build plus the three names the classic addons need. Dev does not — Vite
6
+ * pre-bundles `three` from node_modules, three's full build. Four exports live only in the full
7
+ * build, so `new THREE.WebGLRenderer(...)` compiles, runs in `bitmagic dev` and `bitmagic
8
+ * verify`, and throws "WebGLRenderer is not a constructor" only once published. Each one has its
9
+ * own module under `three/src/`, which both builds serve — the engine's preview renderers import
10
+ * `WebGLRenderer` that way.
11
+ *
12
+ * Plain string checks over `src/work`, no AST: what is flagged is a VALUE use (`new`,
13
+ * `instanceof`, static access, a value import). A type annotation such as
14
+ * `renderer: THREE.WebGLRenderer` is erased by tsc and stays legal. The Creator lane's agent gate
15
+ * carries the same rule (`game-play-agent/src/mastra/utils/game-code-mechanics-lint.ts`,
16
+ * `dev-only-three`) — keep the two lists in step.
17
+ */
18
+ import fs from 'node:fs';
19
+ import path from 'node:path';
20
+ /** Exported by three's full build and missing from the published shim, with each one's own module. */
21
+ export const DEV_ONLY_THREE_EXPORTS = {
22
+ WebGLRenderer: 'three/src/renderers/WebGLRenderer.js',
23
+ WebGLCubeRenderTarget: 'three/src/renderers/WebGLCubeRenderTarget.js',
24
+ WebGLUtils: 'three/src/renderers/webgl/WebGLUtils.js',
25
+ ShaderChunk: 'three/src/renderers/shaders/ShaderChunk.js',
26
+ };
27
+ const NAMES = Object.keys(DEV_ONLY_THREE_EXPORTS).join('|');
28
+ const NAMESPACE_IMPORT = /import\s+\*\s+as\s+(\w+)\s+from\s+['"]three['"]/g;
29
+ const NAMED_IMPORT = /import\s+(type\s+)?\{([^}]*)\}\s*from\s*['"]three['"]/g;
30
+ /** Blank out comments, keeping every newline so offsets still map to the right line. */
31
+ function stripComments(src) {
32
+ return src
33
+ .replace(/\/\*[\s\S]*?\*\//g, (block) => block.replace(/[^\n]/g, ' '))
34
+ .replace(/\/\/[^\n]*/g, (line) => ' '.repeat(line.length));
35
+ }
36
+ function lineAt(src, offset) {
37
+ return src.slice(0, offset).split('\n').length;
38
+ }
39
+ /** Pure scan of one file's source — exported for tests. */
40
+ export function findDevOnlyThreeUses(file, source) {
41
+ const src = stripComments(source);
42
+ const uses = [];
43
+ for (const ns of src.matchAll(NAMESPACE_IMPORT)) {
44
+ const alias = ns[1];
45
+ // `new T.X`, `instanceof T.X`, `T.X.something` — or any use of the two that are only values.
46
+ const valueUse = new RegExp(`(?:\\bnew\\s+|\\binstanceof\\s+)${alias}\\.(${NAMES})\\b`
47
+ + `|\\b${alias}\\.(${NAMES})\\s*\\.`
48
+ + `|\\b${alias}\\.(ShaderChunk|WebGLUtils)\\b`, 'g');
49
+ for (const use of src.matchAll(valueUse)) {
50
+ const name = use[1] ?? use[2] ?? use[3];
51
+ uses.push({ file, line: lineAt(src, use.index), name });
52
+ }
53
+ }
54
+ for (const named of src.matchAll(NAMED_IMPORT)) {
55
+ if (named[1] !== undefined)
56
+ continue; // `import type { ... }` is erased.
57
+ for (const specifier of named[2].split(',')) {
58
+ const parts = specifier.trim().split(/\s+/);
59
+ if (parts[0] === 'type')
60
+ continue; // `import { type WebGLRenderer }` is erased too.
61
+ if (parts[0] in DEV_ONLY_THREE_EXPORTS) {
62
+ uses.push({ file, line: lineAt(src, named.index), name: parts[0] });
63
+ }
64
+ }
65
+ }
66
+ return uses.sort((a, b) => a.line - b.line);
67
+ }
68
+ /** Every dev-only `three` use under the project's `src/work`. */
69
+ export function scanWorkForDevOnlyThree(root) {
70
+ const workDir = path.join(root, 'src', 'work');
71
+ if (!fs.existsSync(workDir))
72
+ return [];
73
+ const uses = [];
74
+ for (const entry of fs.readdirSync(workDir, { recursive: true, withFileTypes: true })) {
75
+ if (!entry.isFile() || !entry.name.endsWith('.ts') || entry.name.endsWith('.d.ts'))
76
+ continue;
77
+ const abs = path.join(entry.parentPath, entry.name);
78
+ uses.push(...findDevOnlyThreeUses(path.relative(root, abs), fs.readFileSync(abs, 'utf-8')));
79
+ }
80
+ return uses;
81
+ }
82
+ /** The message for a non-empty scan: every site, then the one fix. */
83
+ export function describeDevOnlyThreeUses(uses) {
84
+ const sites = uses.map((u) => ` ${u.file}:${u.line} ${u.name}`).join('\n');
85
+ const fixes = [...new Set(uses.map((u) => u.name))]
86
+ .map((name) => ` import { ${name} } from '${DEV_ONLY_THREE_EXPORTS[name]}';`)
87
+ .join('\n');
88
+ return (`Game code uses a \`three\` export the published game does not have:\n${sites}\n`
89
+ + 'A published game loads three\'s WebGPU build, which lacks these, so the game works in '
90
+ + '`bitmagic dev` and `bitmagic verify` and throws "… is not a constructor" only once published. '
91
+ + `Import each from its own module instead, which both builds serve:\n${fixes}`);
92
+ }
93
+ //# sourceMappingURL=published-three.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"published-three.js","sourceRoot":"","sources":["../../src/project/published-three.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,sGAAsG;AACtG,MAAM,CAAC,MAAM,sBAAsB,GAAqC;IACtE,aAAa,EAAE,sCAAsC;IACrD,qBAAqB,EAAE,8CAA8C;IACrE,UAAU,EAAE,yCAAyC;IACrD,WAAW,EAAE,4CAA4C;CAC1D,CAAC;AASF,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC5D,MAAM,gBAAgB,GAAG,kDAAkD,CAAC;AAC5E,MAAM,YAAY,GAAG,wDAAwD,CAAC;AAE9E,wFAAwF;AACxF,SAAS,aAAa,CAAC,GAAW;IAChC,OAAO,GAAG;SACP,OAAO,CAAC,mBAAmB,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;SACrE,OAAO,CAAC,aAAa,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;AAC/D,CAAC;AAED,SAAS,MAAM,CAAC,GAAW,EAAE,MAAc;IACzC,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;AACjD,CAAC;AAED,2DAA2D;AAC3D,MAAM,UAAU,oBAAoB,CAAC,IAAY,EAAE,MAAc;IAC/D,MAAM,GAAG,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IAClC,MAAM,IAAI,GAAsB,EAAE,CAAC;IAEnC,KAAK,MAAM,EAAE,IAAI,GAAG,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC;QAChD,MAAM,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;QACpB,6FAA6F;QAC7F,MAAM,QAAQ,GAAG,IAAI,MAAM,CACzB,mCAAmC,KAAK,OAAO,KAAK,MAAM;cACtD,OAAO,KAAK,OAAO,KAAK,UAAU;cAClC,OAAO,KAAK,gCAAgC,EAChD,GAAG,CACJ,CAAC;QACF,KAAK,MAAM,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YACzC,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;YACxC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,GAAG,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;QAC/C,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,SAAS;YAAE,SAAS,CAAC,mCAAmC;QACzE,KAAK,MAAM,SAAS,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YAC5C,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC5C,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,MAAM;gBAAE,SAAS,CAAC,iDAAiD;YACpF,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,sBAAsB,EAAE,CAAC;gBACvC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACtE,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;AAC9C,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,uBAAuB,CAAC,IAAY;IAClD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAC/C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,EAAE,CAAC;IACvC,MAAM,IAAI,GAAsB,EAAE,CAAC;IACnC,KAAK,MAAM,KAAK,IAAI,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QACtF,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;YAAE,SAAS;QAC7F,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACpD,IAAI,CAAC,IAAI,CAAC,GAAG,oBAAoB,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IAC9F,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,wBAAwB,CAAC,IAAuB;IAC9D,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7E,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;SAChD,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,cAAc,IAAI,YAAY,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC;SAC7E,IAAI,CAAC,IAAI,CAAC,CAAC;IACd,OAAO,CACL,wEAAwE,KAAK,IAAI;UAC/E,wFAAwF;UACxF,gGAAgG;UAChG,sEAAsE,KAAK,EAAE,CAChF,CAAC;AACJ,CAAC"}
@@ -12,7 +12,7 @@ export declare const VITE_PUBLISH_STANDALONE_CONFIG = "vite.publish-standalone.c
12
12
  export declare function publishConfigFor(singleFile: boolean): string;
13
13
  /**
14
14
  * The single Rapier flavor this project's bundle ships — the game's EFFECTIVE
15
- * physics mode (src/work/game.json genre + physicsMode + physics2d, clamped
15
+ * physics mode (src/work/game.json physicsMode + physics2d, clamped
16
16
  * exactly the way the engine clamps at boot), not the raw declared value.
17
17
  *
18
18
  * A build ships exactly one physics engine, never both: a game.json that
@@ -6,6 +6,7 @@ import { CliError } from '../errors.js';
6
6
  import { projectBin } from '../project/context.js';
7
7
  import { spawnBinSync } from '../project/spawn-bin.js';
8
8
  import { computeFingerprint } from './fingerprint.js';
9
+ import { describeDevOnlyThreeUses, scanWorkForDevOnlyThree } from '../project/published-three.js';
9
10
  /**
10
11
  * The configs the scaffold vendors alongside `engine/`, one per bundle mode.
11
12
  *
@@ -21,7 +22,7 @@ export function publishConfigFor(singleFile) {
21
22
  }
22
23
  /**
23
24
  * The single Rapier flavor this project's bundle ships — the game's EFFECTIVE
24
- * physics mode (src/work/game.json genre + physicsMode + physics2d, clamped
25
+ * physics mode (src/work/game.json physicsMode + physics2d, clamped
25
26
  * exactly the way the engine clamps at boot), not the raw declared value.
26
27
  *
27
28
  * A build ships exactly one physics engine, never both: a game.json that
@@ -40,8 +41,7 @@ export function resolveRapierFlavor(root) {
40
41
  `(${err instanceof Error ? err.message : String(err)}). A build ships exactly one Rapier flavor, ` +
41
42
  "chosen from the game's physicsMode.", 1);
42
43
  }
43
- const gameGenre = typeof raw.gameGenre === 'string' ? raw.gameGenre : '';
44
- return rapierFlavorForGame(gameGenre, raw.physicsMode, raw.physics2d === true);
44
+ return rapierFlavorForGame(raw.physicsMode, raw.physics2d === true);
45
45
  }
46
46
  export function buildBundlePaths(root) {
47
47
  const dir = path.join(root, '.bitmagic', 'build');
@@ -141,6 +141,11 @@ options = {}) {
141
141
  throw new CliError(`Could not run the TypeScript compiler: ${compile.error.message}`, 1);
142
142
  if (compile.status !== 0)
143
143
  throw new CliError('Build failed: the project does not compile.', 1);
144
+ // The bundle below is where `three` becomes the WebGPU build; a dev-only export would compile,
145
+ // bundle and only throw in the player's browser.
146
+ const devOnlyThree = scanWorkForDevOnlyThree(root);
147
+ if (devOnlyThree.length > 0)
148
+ throw new CliError(`Build failed. ${describeDevOnlyThreeUses(devOnlyThree)}`, 1);
144
149
  const { dir, htmlPath } = buildBundlePaths(root);
145
150
  fs.mkdirSync(dir, { recursive: true });
146
151
  const vite = projectBin(root, 'vite');
@@ -1 +1 @@
1
- {"version":3,"file":"bundle.js","sourceRoot":"","sources":["../../src/publish/bundle.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bundle.js","sourceRoot":"","sources":["../../src/publish/bundle.ts"],"names":[],"mappings":"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"}
@@ -20,7 +20,7 @@ export interface PlatformIndicatorsResult {
20
20
  * which are publish's alone.
21
21
  *
22
22
  * The project files are the source of truth, exactly as they are in the web lane — the columns
23
- * are "indicators synced from game.json at publish, like `genre`" (migration 048). So a value
23
+ * are indicators synced from game.json at publish (migration 048). So a value
24
24
  * changed anywhere else is reverted by the creator's next publish, and the way to make a game
25
25
  * mobile is to edit `src/work/game.json`.
26
26
  *
@@ -9,7 +9,7 @@ import { readPlatformDeclaration } from '../project/platform-declaration.js';
9
9
  * which are publish's alone.
10
10
  *
11
11
  * The project files are the source of truth, exactly as they are in the web lane — the columns
12
- * are "indicators synced from game.json at publish, like `genre`" (migration 048). So a value
12
+ * are indicators synced from game.json at publish (migration 048). So a value
13
13
  * changed anywhere else is reverted by the creator's next publish, and the way to make a game
14
14
  * mobile is to edit `src/work/game.json`.
15
15
  *
@@ -26,7 +26,6 @@ export interface BuildSourceArchiveOptions {
26
26
  index: SourceIndex;
27
27
  gameId: string;
28
28
  engineVersion: string;
29
- genre: string;
30
29
  /** Injected so tests get a stable manifest; production passes the real clock. */
31
30
  now?: () => Date;
32
31
  }