From d243bde307ac7c2b4e2ce0ebc626ce33c23ad2c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=9D=89=E6=81=AF?= Date: Tue, 4 Aug 2026 18:46:15 +0800 Subject: [PATCH 1/3] fix(templates): remove dead 3D screen config The three.js renderer sizes from its container and never consumes the inherited 2D reference dimensions. Removing the unused leaves gives both standalone core3d and threed_basic a zero-dead-config baseline. --- agent-test/templates/core3d/src/gameConfig.json | 4 ---- agent-test/templates/modules/threed_basic/src/gameConfig.json | 4 ---- 2 files changed, 8 deletions(-) diff --git a/agent-test/templates/core3d/src/gameConfig.json b/agent-test/templates/core3d/src/gameConfig.json index f23a8fad7..4b8593717 100644 --- a/agent-test/templates/core3d/src/gameConfig.json +++ b/agent-test/templates/core3d/src/gameConfig.json @@ -1,8 +1,4 @@ { - "screenSize": { - "width": { "value": 1152, "type": "number", "description": "Reference width" }, - "height": { "value": 768, "type": "number", "description": "Reference height" } - }, "renderConfig": { "pixelRatioCap": { "value": 2, "type": "number", "description": "Renderer pixel ratio cap" }, "fogNear": { "value": 18, "type": "number", "description": "Fog near distance" }, diff --git a/agent-test/templates/modules/threed_basic/src/gameConfig.json b/agent-test/templates/modules/threed_basic/src/gameConfig.json index 3bec72a8f..57231e400 100644 --- a/agent-test/templates/modules/threed_basic/src/gameConfig.json +++ b/agent-test/templates/modules/threed_basic/src/gameConfig.json @@ -1,8 +1,4 @@ { - "screenSize": { - "width": { "value": 1152, "type": "number", "description": "Reference width" }, - "height": { "value": 768, "type": "number", "description": "Reference height" } - }, "renderConfig": { "pixelRatioCap": { "value": 2, "type": "number", "description": "Renderer pixel ratio cap" }, "fogNear": { "value": 16, "type": "number", "description": "Fog near distance" }, From 2cf29c098a15be2988f1ff9d3f6717e2e586a27a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=9D=89=E6=81=AF?= Date: Tue, 4 Aug 2026 18:46:15 +0800 Subject: [PATCH 2/3] docs(templates): require consumed 3D config Generated v1.1 code duplicated fog, pickup, and count values. Make the builder keep one canonical path per runtime value, remove superseded aliases, and record the leaf-to-consumer map in GDD completion notes. --- agent-test/docs/modules/threed_basic/design_rules.md | 9 +++++++++ agent-test/docs/modules/threed_basic/template_api.md | 10 ++++++++++ agent-test/docs/modules/threed_basic/threed_basic.md | 9 ++++++++- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/agent-test/docs/modules/threed_basic/design_rules.md b/agent-test/docs/modules/threed_basic/design_rules.md index 82a3ed896..35a60471f 100644 --- a/agent-test/docs/modules/threed_basic/design_rules.md +++ b/agent-test/docs/modules/threed_basic/design_rules.md @@ -43,11 +43,20 @@ distance checks are enough for pickups and static collision; do not introduce a physics dependency. Give every obstacle an explicit `collisionRadius` instead of deriving gameplay collision from rendered scale. +Every `gameConfig.json` leaf must have one literal runtime consumer. Do not keep +aliases for the same value: if pickup code moves from +`levelConfig.collectRadius` to another path, delete the old leaf in the same +edit. The current linear fog consumes `renderConfig.fogNear` and `fogFar`; do +not add `fogDensity` unless the implementation changes and the superseded +linear-fog leaves are removed. Derive authored counts from `SceneMap` arrays +unless a separately consumed completion threshold is required. + ## 5. GDD completion notes The GDD must end with: - the actual generated keys and their runtime consumers; +- a config leaf-to-consumer table with no duplicate or unconsumed leaf; - any placeholder/fallback used; - `3D scope: primitives + generated image textures; no model generation`; - the command evidence from build and smoke. diff --git a/agent-test/docs/modules/threed_basic/template_api.md b/agent-test/docs/modules/threed_basic/template_api.md index cbf674c74..9ca0949b7 100644 --- a/agent-test/docs/modules/threed_basic/template_api.md +++ b/agent-test/docs/modules/threed_basic/template_api.md @@ -43,6 +43,16 @@ Each obstacle declares `collisionRadius` independently from visual `scale`. patch, subdivides long moves to prevent tunnelling, and slides along an unblocked axis. Dynamic bodies, impulses, and gravity remain v2 concerns. +## Config ownership + +The shipped config is a starting contract, not a compatibility registry. Keep +one leaf per runtime value and require a literal consumer for every leaf. When +renaming or regrouping a field, update its consumer and delete the old field in +the same change. Do not preserve unused 2D infrastructure fields in a 3D game. + +Before build, search every config leaf outside `gameConfig.json`. A leaf with no +consumer is a failed implementation check, not a harmless preset. + ## Texture keys `Preloader` reads Phaser-compatible `asset-pack.json` sections and loads image diff --git a/agent-test/docs/modules/threed_basic/threed_basic.md b/agent-test/docs/modules/threed_basic/threed_basic.md index f9e436747..7e6c11c1a 100644 --- a/agent-test/docs/modules/threed_basic/threed_basic.md +++ b/agent-test/docs/modules/threed_basic/threed_basic.md @@ -10,7 +10,7 @@ and the one level rather than replacing the shell. |---|---|---| | 1 | map GDD asset keys to `skybox_texture`, `floor_patch`, `energy_billboard` | every used key exists in `asset-pack.json` | | 2 | edit `SceneMap.ts` | main route and every pickup are reachable; obstacle collision radii leave a traversable lane | -| 3 | merge tuning into `gameConfig.json` | wrapper shape and core fields remain | +| 3 | merge tuning into `gameConfig.json` | every leaf has one runtime consumer; superseded aliases are deleted | | 4 | theme materials and DOM text | canvas remains WebGL-only; HUD remains DOM-only | | 5 | run build and smoke | zero errors, non-black canvas, WebGL context, ESC resume | @@ -31,6 +31,12 @@ Keep `CollisionResolver.ts` pure. Floor patches and obstacle circles come from `SceneMap.ts`; player radius comes from `gameConfig.json`. Do not replace this with a physics dependency in v1. +Treat config as executable data. Keep the existing path when it already serves +the intended value; if a generated design chooses a new path, update the code +and remove the old path together. Never add `fogDensity`, a second pickup +radius, or a duplicate collectible count while their existing equivalents stay +in the file. Record the final leaf-to-consumer mapping in GDD completion notes. + ## Asset hookup Only call `generate_game_assets`. A skybox is a generated 2D equirectangular @@ -58,4 +64,5 @@ playable; it does not authorize skipping the required asset call. | image 404s | invented key or leading slash mismatch | read the generated `asset-pack.json`; use its key/url | | movement depends on frame rate | raw per-frame displacement | multiply by capped `deltaSeconds` | | player leaves the road or crosses a pylon | movement bypasses `resolveMovement` or collision radii are missing | route every XZ move through the resolver and keep SceneMap radii explicit | +| acceptance reports dead config | a field was copied or renamed without removing its old path | keep one canonical leaf, update its consumer, and delete the duplicate | | huge GPU cost | uncapped DPR or oversized textures | DPR <= 2; texture/display size <= 1024 squared | From 74a7c9fbd21b024f7da78b8753c95cbc687c8ecf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=9D=89=E6=81=AF?= Date: Tue, 4 Aug 2026 19:10:30 +0800 Subject: [PATCH 3/3] fix(core): specialize 3D config merge guidance The universal GDD reminder contradicted threed_basic zero-dead-config rules by forbidding deletion of inherited fields. Keep the Phaser reminder unchanged while requiring consumed, single-source leaves for 3D. --- packages/core/src/tools/generate-gdd.test.ts | 23 ++++++++++++++++++++ packages/core/src/tools/generate-gdd.ts | 9 +++++++- 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 packages/core/src/tools/generate-gdd.test.ts diff --git a/packages/core/src/tools/generate-gdd.test.ts b/packages/core/src/tools/generate-gdd.test.ts new file mode 100644 index 000000000..010a64dbd --- /dev/null +++ b/packages/core/src/tools/generate-gdd.test.ts @@ -0,0 +1,23 @@ +import { describe, expect, it } from 'vitest'; +import { configMergeInstruction } from './generate-gdd.js'; + +describe('configMergeInstruction', () => { + it('requires consumed config and deletion of superseded 3D leaves', () => { + const instruction = configMergeInstruction('threed_basic'); + + expect(instruction).toContain('every leaf must have a runtime consumer'); + expect(instruction).toContain('superseded leaves must be removed'); + expect(instruction).not.toContain('NEVER delete infrastructure fields'); + }); + + it.each(['platformer', 'top_down'] as const)( + 'preserves the existing Phaser config contract for %s', + (archetype) => { + const instruction = configMergeInstruction(archetype); + + expect(instruction).toContain('NEVER delete infrastructure fields'); + expect(instruction).toContain('screenSize'); + expect(instruction).toContain('debugConfig'); + }, + ); +}); diff --git a/packages/core/src/tools/generate-gdd.ts b/packages/core/src/tools/generate-gdd.ts index 2bb20eb48..c77d4c000 100644 --- a/packages/core/src/tools/generate-gdd.ts +++ b/packages/core/src/tools/generate-gdd.ts @@ -41,6 +41,13 @@ export interface GenerateGDDParams { config_summary?: string; } +export function configMergeInstruction(archetype: GameArchetype): string { + if (archetype === 'threed_basic') { + return '- MERGE GDD Section 2 values INTO the existing `src/gameConfig.json`; every leaf must have a runtime consumer, and renamed or superseded leaves must be removed in the same edit.'; + } + return '- MERGE GDD Section 2 values INTO the existing `src/gameConfig.json` -- add/update game-specific fields using `{ "value": X }` wrapper format, but NEVER delete infrastructure fields (`screenSize`, `renderConfig`, and Phaser\'s `debugConfig`)'; +} + export interface GDDModelConfig { apiKey: string; baseUrl: string; @@ -116,7 +123,7 @@ Save content between tags to \`GAME_DESIGN.md\` - Read \`public/assets/asset-pack.json\` for generated texture keys ### Phase 4: Config (use GDD Section 2) -- MERGE GDD Section 2 values INTO the existing \`src/gameConfig.json\` -- add/update game-specific fields using \`{ "value": X }\` wrapper format, but NEVER delete infrastructure fields (\`screenSize\`, \`renderConfig\`, and Phaser's \`debugConfig\`) +${configMergeInstruction(this.params.archetype)} ### Phase 5: Code Implementation (use GDD Sections 0, 3, 5) - **GDD Section 0** has scene keys -> update \`LevelManager.ts\` and \`main.ts\`