@forgeax/game 0.3.4 → 0.3.5

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,7 +10,7 @@ runtime.
10
10
 
11
11
  > [!IMPORTANT]
12
12
  > The published package carries `forgeax-game` and scoped `game` binary aliases and resolves the exact
13
- > `@forgeax/engine-sdk@0.1.7` and `pnpm@11.7.0` dependencies. It has no
13
+ > `@forgeax/engine-sdk@0.1.26` and `pnpm@11.7.0` dependencies. It has no
14
14
  > `@forgeax/game-runtime` dependency and no static Preview fallback.
15
15
 
16
16
  ## Supported flow
@@ -44,9 +44,11 @@ cd ./empty-game-directory
44
44
  npx -y @forgeax/game init
45
45
  ```
46
46
 
47
- The first command writes only the `forgeax` MCP member in the canonical Codex,
47
+ The first command writes the `forgeax` MCP member in the canonical Codex,
48
48
  Cursor, and Claude Code user configs. It preserves unrelated bytes and values,
49
49
  reports `CURRENT` on an idempotent rerun, and says which host must restart or reload.
50
+ Existing older package-owned Asset3D MCP entries are also refreshed; absent or
51
+ custom Asset3D entries are not added or overwritten.
50
52
  The second command must run from the intended blank directory. It creates the Engine
51
53
  game there, binds the exact release identity, and reports the canonical root and
52
54
  host-skill result. Existing exact games are read back and bound without recreation;
@@ -60,9 +62,13 @@ npx -y @forgeax/game@latest update --ide codex
60
62
  ```
61
63
 
62
64
  `update` reports the configured transition, for example
63
- `plugin 0.3.3 -> 0.3.4`. It refreshes configuration, skills, and routing from the
65
+ `plugin 0.3.4 -> 0.3.5`. It refreshes configuration, skills, and routing from the
64
66
  package being executed; it does not independently fetch another package.
65
67
 
68
+ See [0.3.5 compatibility notes](docs/release-0.3.5.md) before upgrading games pinned
69
+ to older Engine versions. This release recognizes strict v2 manifests without
70
+ requiring the removed `entry` field, but does not migrate game dependencies.
71
+
66
72
  > [!NOTE]
67
73
  > Asset3D is optional and **disabled by default**. The two commands above never contact
68
74
  > the internal asset catalog, provision the bundled platform Provider, or add
package/dist/main.js CHANGED
@@ -342,7 +342,7 @@ function engineGameId(root) {
342
342
  try {
343
343
  const manifest = JSON.parse(readFileSync(join2(root, "forge.json"), "utf8"));
344
344
  const pkg = JSON.parse(readFileSync(join2(root, "package.json"), "utf8"));
345
- return typeof manifest.id === "string" && SLUG_RE.test(manifest.id) && typeof manifest.entry === "string" && typeof pkg.dependencies?.["@forgeax/engine"] === "string" ? manifest.id : undefined;
345
+ return typeof manifest.id === "string" && SLUG_RE.test(manifest.id) && (manifest.schemaVersion === "2.0.0" ? typeof manifest.defaultScene === "string" && /^[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}$/i.test(manifest.defaultScene) : (manifest.schemaVersion === undefined || manifest.schemaVersion === "1.0.0") && typeof manifest.entry === "string") && typeof pkg.dependencies?.["@forgeax/engine"] === "string" ? manifest.id : undefined;
346
346
  } catch {
347
347
  return;
348
348
  }
@@ -710,8 +710,8 @@ import { existsSync as existsSync3, lstatSync as lstatSync3, readFileSync as rea
710
710
  import { isAbsolute as isAbsolute2, relative as relative3, resolve as resolve4, sep as sep2 } from "node:path";
711
711
 
712
712
  // src/engine/constants.ts
713
- var ENGINE_VERSION = "0.1.7";
714
- var ENGINE_COMMIT = "984e80ac55b5f4f2afed3211c854b482a4018199";
713
+ var ENGINE_VERSION = "0.1.26";
714
+ var ENGINE_COMMIT = "f3d0db12405e168e4204e32a9cde32e0df8d87ae";
715
715
  var ENGINE_SDK_PACKAGE = "@forgeax/engine-sdk";
716
716
  var PNPM_VERSION = "11.7.0";
717
717
 
@@ -732,7 +732,7 @@ import { createRequire } from "node:module";
732
732
  import { basename, delimiter, dirname as dirname4, isAbsolute, relative as relative2, resolve as resolve3, sep } from "node:path";
733
733
  import { tmpdir } from "node:os";
734
734
  import { fileURLToPath as fileURLToPath2 } from "node:url";
735
- var SDK_MANIFEST_SCHEMA = "1.6.0";
735
+ var SDK_MANIFEST_SCHEMA = "1.7.0";
736
736
  var SDK_CLI_RELATIVE = ["bin", "forgeax.mjs"];
737
737
  var CARRIER_ENVIRONMENT_ALLOWLIST = [
738
738
  "HOME",
@@ -1690,7 +1690,7 @@ async function startEnginePreview(projectRoot, gameRoot, options = {}) {
1690
1690
  }
1691
1691
  const token = randomBytes(32).toString("hex");
1692
1692
  const previewInstanceId = randomUUID();
1693
- const child = spawn(process.execPath, [release.cliPath, "preview", "--json"], {
1693
+ const child = spawn(process.execPath, [release.cliPath, "preview", "--port", "0", "--json"], {
1694
1694
  cwd: release.gameRoot,
1695
1695
  detached: true,
1696
1696
  env: { ...process.env, FORGEAX_PREVIEW_INSTANCE_TOKEN: token },
@@ -2946,12 +2946,12 @@ var RELEASE_IDENTITY_MIME = "application/vnd.forgeax.game-release-identity+json"
2946
2946
  var RELEASE_IDENTITY = Object.freeze({
2947
2947
  schema: RELEASE_IDENTITY_SCHEMA,
2948
2948
  gamePackage: "@forgeax/game",
2949
- gameVersion: "0.3.4",
2949
+ gameVersion: "0.3.5",
2950
2950
  gameBin: "forgeax-game",
2951
2951
  engineSdkPackage: ENGINE_SDK_PACKAGE,
2952
2952
  engineSdkVersion: ENGINE_VERSION,
2953
2953
  engineSourceCommit: ENGINE_COMMIT,
2954
- carrierIntegrity: "sha512-f3Nz+ZoIOLVjNeKPock46+gwmC1wOWh9TJupQPl25+wZbIN1dJmki5LK6mNhchPxF7fffarbcFWGMqpKHkjQSw==",
2954
+ carrierIntegrity: "sha512-G5ovsbdzkWWeMfFy3MxVk0qcAvWnZxJnlypMGgxFUDaKr3Wv9uVuhPV88LZ1A9mhFJJSfrE1d5R3WvHgulygRQ==",
2955
2955
  sdkManifestDigest: `sha256:${"0".repeat(64)}`,
2956
2956
  sdkTreeDigest: `sha256:${"0".repeat(64)}`,
2957
2957
  fullZipDigest: `sha256:${"0".repeat(64)}`,
@@ -3356,7 +3356,7 @@ function launchSpec(mode) {
3356
3356
  }
3357
3357
  return {
3358
3358
  command: "npx",
3359
- args: ["-y", "-p", "@forgeax/game@0.3.4", "forgeax-game", "mcp"]
3359
+ args: ["-y", "-p", "@forgeax/game@0.3.5", "forgeax-game", "mcp"]
3360
3360
  };
3361
3361
  }
3362
3362
  function asset3dLaunchSpec(mode) {
@@ -5872,7 +5872,7 @@ async function runDormantAsset3dMcp() {
5872
5872
  result: {
5873
5873
  protocolVersion,
5874
5874
  capabilities: { tools: {} },
5875
- serverInfo: { name: "asset3d-search", version: "0.3.4" }
5875
+ serverInfo: { name: "asset3d-search", version: "0.3.5" }
5876
5876
  }
5877
5877
  };
5878
5878
  } else if (request2.method === "tools/list") {
@@ -6086,6 +6086,38 @@ async function runAsset3dMcpProxy(projectRoot, launch) {
6086
6086
  });
6087
6087
  }
6088
6088
 
6089
+ // src/asset3d/host-config.ts
6090
+ function inspectAsset3dHost(client, root) {
6091
+ const launch = asset3dLaunchSpec("npx");
6092
+ const status = inspectConfig(client, root, launch, ASSET3D_SERVER_KEY);
6093
+ if (status.state !== "different")
6094
+ return status;
6095
+ const previous = configuredGameVersion(client, root, ASSET3D_SERVER_KEY);
6096
+ const current = launch.args.find((arg) => arg.startsWith("@forgeax/game@"))?.slice("@forgeax/game@".length);
6097
+ if (!previous || !current || !/^\d+\.\d+\.\d+$/.test(previous) || !/^\d+\.\d+\.\d+$/.test(current))
6098
+ return status;
6099
+ const oldParts = previous.split(".").map(Number);
6100
+ const newParts = current.split(".").map(Number);
6101
+ const differing = oldParts.findIndex((part, index) => part !== newParts[index]);
6102
+ if (differing < 0 || oldParts[differing] >= newParts[differing])
6103
+ return status;
6104
+ const oldLaunch = { ...launch, args: launch.args.map((arg) => arg === `@forgeax/game@${current}` ? `@forgeax/game@${previous}` : arg) };
6105
+ if (inspectConfig(client, root, oldLaunch, ASSET3D_SERVER_KEY).state !== "current")
6106
+ return status;
6107
+ return { ...status, state: "outdated" };
6108
+ }
6109
+ function refreshAsset3dHost(client, root) {
6110
+ const status = inspectAsset3dHost(client, root);
6111
+ if (status.state === "outdated") {
6112
+ const result = applyConfig(client, root, asset3dLaunchSpec("npx"), ASSET3D_SERVER_KEY);
6113
+ process.stdout.write(`UPDATED ${client.label} Asset3D bridge: ${result.path}
6114
+ `);
6115
+ } else if (status.state === "different" || status.state === "invalid") {
6116
+ process.stderr.write(`WARN ${client.label}: existing ${ASSET3D_SERVER_KEY} configuration was preserved; it is not a recognized older package launcher.
6117
+ `);
6118
+ }
6119
+ }
6120
+
6089
6121
  // src/cli/dispatch.ts
6090
6122
  var HELP = `ForgeaX game development plugin
6091
6123
 
@@ -6190,6 +6222,7 @@ async function installCommand(args) {
6190
6222
  }
6191
6223
  try {
6192
6224
  const result = applyConfig(client, project.root ?? process.cwd(), launch);
6225
+ refreshAsset3dHost(client, project.root ?? process.cwd());
6193
6226
  process.stdout.write(`${result.changed ? "UPDATED" : "CURRENT"} ${client.label}: ${result.path}${result.backup ? ` (backup: ${result.backup})` : ""}
6194
6227
  `);
6195
6228
  if (client.postInstallNote)
@@ -6569,6 +6602,7 @@ async function updateCommand(args) {
6569
6602
  for (const client of configured) {
6570
6603
  const previousVersion = configuredGameVersion(client, root);
6571
6604
  const result = applyConfig(client, root, launch);
6605
+ refreshAsset3dHost(client, root);
6572
6606
  process.stdout.write(`${result.changed ? "UPDATED" : "CURRENT"} ${client.label}: ${result.path} (plugin ${formatVersionTransition(previousVersion)})
6573
6607
  `);
6574
6608
  }
@@ -6691,7 +6725,7 @@ async function asset3dCommand(args) {
6691
6725
  const client = findClient(id);
6692
6726
  if (!client)
6693
6727
  throw new Error(`asset3d_client_invalid: ${id}`);
6694
- const state = inspectConfig(client, projectRoot, bridge, ASSET3D_SERVER_KEY);
6728
+ const state = inspectAsset3dHost(client, projectRoot);
6695
6729
  if (state.state === "different") {
6696
6730
  throw new Error(`asset3d_client_server_conflict: ${client.label} already has a different ${ASSET3D_SERVER_KEY} entry`);
6697
6731
  }
@@ -0,0 +1,32 @@
1
+ # @forgeax/game 0.3.5
2
+
3
+ ## Compatibility repair
4
+
5
+ | Boundary | Release behavior |
6
+ |:--|:--|
7
+ | Engine SDK | Exact dependency 0.1.26, commit `f3d0db12405e168e4204e32a9cde32e0df8d87ae` |
8
+ | Project discovery | Recognizes strict `forge.json` v2 with `defaultScene`; does not inject the forbidden legacy `entry` field |
9
+ | SDK manifest | Validates the released 1.7.0 manifest and exact Engine/DevKit identities |
10
+ | Preview | Uses Engine-owned `--port 0` allocation instead of conflicting with another game on port 5173 |
11
+ | Asset3D upgrade | Refreshes existing older package-owned bridges during install/update; preserves custom configurations |
12
+
13
+ ## Install or update
14
+
15
+ ```bash
16
+ npx -y @forgeax/game@0.3.5 install --ide codex,cursor,claude
17
+ # In a genuinely empty game directory:
18
+ npx -y @forgeax/game@0.3.5 init
19
+ ```
20
+
21
+ For an existing Engine 0.1.26 project, run `update --ide codex` with this package,
22
+ then restart the host session. Asset3D remains opt-in with `asset3d enable`.
23
+
24
+ > [!IMPORTANT]
25
+ > This release pins Engine 0.1.26. It does not silently migrate games using Engine
26
+ > 0.1.7. Keep those games on plugin 0.3.4 until deliberately migrating through the
27
+ > Engine-supported workflow. Do not add `entry` to a v2 manifest to work around the
28
+ > old plugin's project detection.
29
+
30
+ The plugin must return Engine-owned Preview readiness and matching root/build
31
+ identity. A direct Engine CLI preview or a listening port alone is not MCP
32
+ acceptance. Asset search/import and visible gameplay require separate verification.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "packageManager": "bun@1.3.14",
3
3
  "name": "@forgeax/game",
4
- "version": "0.3.4",
4
+ "version": "0.3.5",
5
5
  "private": false,
6
6
  "type": "module",
7
7
  "description": "@forgeax/game — an MCP/CLI connector for exact released ForgeaX Engine games and Engine-owned Preview.",
@@ -26,6 +26,7 @@
26
26
  "docs/release-0.3.2.md",
27
27
  "docs/release-0.3.3.md",
28
28
  "docs/release-0.3.4.md",
29
+ "docs/release-0.3.5.md",
29
30
  "README.md"
30
31
  ],
31
32
  "scripts": {
@@ -51,7 +52,7 @@
51
52
  ],
52
53
  "license": "MIT",
53
54
  "dependencies": {
54
- "@forgeax/engine-sdk": "0.1.7",
55
+ "@forgeax/engine-sdk": "0.1.26",
55
56
  "pnpm": "11.7.0"
56
57
  },
57
58
  "devDependencies": {