Add first stage source reconstruction baseline
This commit is contained in:
parent
e7bb64da7d
commit
0241a6b58b
BIN
artifacts/canvas_preview/stage1_source_preview.png
Normal file
BIN
artifacts/canvas_preview/stage1_source_preview.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 23 KiB |
11
artifacts/canvas_preview/stage1_source_preview_report.json
Normal file
11
artifacts/canvas_preview/stage1_source_preview_report.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"status": "generated",
|
||||
"image": "/Users/hy/Documents/hy/hygame/farm/artifacts/canvas_preview/stage1_source_preview.png",
|
||||
"resolution": {
|
||||
"width": 720,
|
||||
"height": 1280
|
||||
},
|
||||
"land_candidates_rendered": 36,
|
||||
"visible_land_selection": "blocked_missing_runtime_visible_land_rule",
|
||||
"note": "Diagnostic rendering only; it does not define final Cocos coordinates."
|
||||
}
|
||||
0
artifacts/cocos_capture/.gitkeep
Normal file
0
artifacts/cocos_capture/.gitkeep
Normal file
40
artifacts/cocos_capture/stage1_cocos_verify.json
Normal file
40
artifacts/cocos_capture/stage1_cocos_verify.json
Normal file
@ -0,0 +1,40 @@
|
||||
{
|
||||
"generated_at": "2026-06-19T09:41:49.332153+00:00",
|
||||
"package": {
|
||||
"type": "2d",
|
||||
"version": "4.0.0",
|
||||
"creator_version": "4.0.0"
|
||||
},
|
||||
"cocos_version": {
|
||||
"cmd": [
|
||||
"zsh",
|
||||
"-lc",
|
||||
"cocos --version"
|
||||
],
|
||||
"returncode": 0,
|
||||
"stdout_tail": "0.0.1-alpha.30\n",
|
||||
"stderr_tail": ""
|
||||
},
|
||||
"node_abi": {
|
||||
"cmd": [
|
||||
"zsh",
|
||||
"-lc",
|
||||
"~/.local/tools/node-v24.14.1-darwin-arm64/bin/node -p 'process.version + \" abi=\" + process.versions.modules'"
|
||||
],
|
||||
"returncode": 0,
|
||||
"stdout_tail": "v24.14.1 abi=137\n",
|
||||
"stderr_tail": ""
|
||||
},
|
||||
"build": {
|
||||
"cmd": [
|
||||
"zsh",
|
||||
"-lc",
|
||||
"rm -rf temp library build && cocos build --project . --platform web-mobile"
|
||||
],
|
||||
"returncode": 1,
|
||||
"stdout_tail": "Start record log in {file(/Users/hy/Documents/hy/hygame/farm/temp/logs)}\n[Migration] 已注册 8 个迁移器\n[Migration] 开始执行迁移\n[Migration] 所有迁移执行成功\nℹ injectWebAssembly ...\nInit Base: 9.767ms\nInit Infrastructure: 3.164ms\nInit SubSystem: 3.011ms\nInit Project: 3.151ms\ninitEngine success\n",
|
||||
"stderr_tail": "Application Support/cocos-default/cocos-4.0.0-alpha.22/packages/cc-module/src/loader.ts:62:35)\n at wrapModuleLoad (node:internal/modules/cjs/loader:255:19)\n at Module.<anonymous> (node:internal/modules/cjs/loader:1556:12)\n at Module.patchedRequire (/Users/hy/Library/Application Support/cocos-default/cocos-4.0.0-alpha.22/node_modules/require-in-the-middle/index.js:256:27)\n at Module.Hook._require.Module.require (/Users/hy/Library/Application Support/cocos-default/cocos-4.0.0-alpha.22/node_modules/require-in-the-middle/index.js:181:27)\n at Module.patchedRequire (/Users/hy/Library/Application Support/cocos-default/cocos-4.0.0-alpha.22/node_modules/require-in-the-middle/index.js:256:27)\n at Module.Hook._require.Module.require (/Users/hy/Library/Application Support/cocos-default/cocos-4.0.0-alpha.22/node_modules/require-in-the-middle/index.js:181:27)\n\n\n ERROR register asset-handler effect failed!\n\n\n ERROR Error: The module '/Users/hy/Library/Application Support/cocos-default/cocos-4.0.0-alpha.22/node_modules/gl/build/Release/webgl.node'\nwas compiled against a different Node.js version using\nNODE_MODULE_VERSION 140. This version of Node.js requires\nNODE_MODULE_VERSION 137. Please try re-compiling or re-installing\nthe module (for instance, using npm rebuild or npm install).\n at Object..node (node:internal/modules/cjs/loader:1970:18)\n at Module.load (node:internal/modules/cjs/loader:1533:32)\n at Module.<anonymous> (node:internal/modules/cjs/loader:1335:12)\n at ModuleInternal._load (/Users/hy/Library/Application Support/cocos-default/cocos-4.0.0-alpha.22/packages/cc-module/src/loader.ts:62:35)\n at wrapModuleLoad (node:internal/modules/cjs/loader:255:19)\n at Module.<anonymous> (node:internal/modules/cjs/loader:1556:12)\n at Module.patchedRequire (/Users/hy/Library/Application Support/cocos-default/cocos-4.0.0-alpha.22/node_modules/require-in-the-middle/index.js:256:27)\n at Module.Hook._require.Module.require (/Users/hy/Library/Application Support/cocos-default/cocos-4.0.0-alpha.22/node_modules/require-in-the-middle/index.js:181:27)\n at Module.patchedRequire (/Users/hy/Library/Application Support/cocos-default/cocos-4.0.0-alpha.22/node_modules/require-in-the-middle/index.js:256:27)\n at Module.Hook._require.Module.require (/Users/hy/Library/Application Support/cocos-default/cocos-4.0.0-alpha.22/node_modules/require-in-the-middle/index.js:181:27)\n\n\n ERROR register asset-handler effect failed!\n\n\n ERROR Failed to build project: Error: The module '/Users/hy/Library/Application Support/cocos-default/cocos-4.0.0-alpha.22/node_modules/gl/build/Release/webgl.node'\nwas compiled against a different Node.js version using\nNODE_MODULE_VERSION 140. This version of Node.js requires\nNODE_MODULE_VERSION 137. Please try re-compiling or re-installing\nthe module (for instance, using npm rebuild or npm install).\n at Object..node (node:internal/modules/cjs/loader:1970:18)\n at Module.load (node:internal/modules/cjs/loader:1533:32)\n at Module.<anonymous> (node:internal/modules/cjs/loader:1335:12)\n at ModuleInternal._load (/Users/hy/Library/Application Support/cocos-default/cocos-4.0.0-alpha.22/packages/cc-module/src/loader.ts:62:35)\n at wrapModuleLoad (node:internal/modules/cjs/loader:255:19)\n at Module.<anonymous> (node:internal/modules/cjs/loader:1556:12)\n at Module.patchedRequire (/Users/hy/Library/Application Support/cocos-default/cocos-4.0.0-alpha.22/node_modules/require-in-the-middle/index.js:256:27)\n at Module.Hook._require.Module.require (/Users/hy/Library/Application Support/cocos-default/cocos-4.0.0-alpha.22/node_modules/require-in-the-middle/index.js:181:27)\n at Module.patchedRequire (/Users/hy/Library/Application Support/cocos-default/cocos-4.0.0-alpha.22/node_modules/require-in-the-middle/index.js:256:27)\n at Module.Hook._require.Module.require (/Users/hy/Library/Application Support/cocos-default/cocos-4.0.0-alpha.22/node_modules/require-in-the-middle/index.js:181:27)\n\n"
|
||||
},
|
||||
"status": "blocked",
|
||||
"blocker": "Cocos 4 alpha CLI native gl module expects NODE_MODULE_VERSION 140; local Node 24 reports ABI 137."
|
||||
}
|
||||
0
artifacts/visual_compare/.gitkeep
Normal file
0
artifacts/visual_compare/.gitkeep
Normal file
18
artifacts/visual_compare/stage1_roi_report.json
Normal file
18
artifacts/visual_compare/stage1_roi_report.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"generated_at": "2026-06-19T09:41:45.956598+00:00",
|
||||
"module": "main_scene_first_milestone",
|
||||
"status": "blocked",
|
||||
"rois": [
|
||||
"world_static",
|
||||
"land_area",
|
||||
"decor_area",
|
||||
"bottom_buttons"
|
||||
],
|
||||
"reason": "Cocos-produced screenshot is unavailable because Cocos 4 alpha CLI build fails on native webgl.node ABI mismatch.",
|
||||
"diagnostic_preview": "/Users/hy/Documents/hy/hygame/farm/artifacts/canvas_preview/stage1_source_preview.png",
|
||||
"target_thresholds": {
|
||||
"static_bitmap_similarity": 0.99,
|
||||
"object_center_delta_px": 2,
|
||||
"object_size_delta_percent": 1
|
||||
}
|
||||
}
|
||||
9
assets/audio.meta
Normal file
9
assets/audio.meta
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "ff660dd4-0445-4fc3-bc32-9f29b863f6a5",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
0
assets/audio/.gitkeep
Normal file
0
assets/audio/.gitkeep
Normal file
9
assets/bundles.meta
Normal file
9
assets/bundles.meta
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "7fc0096d-c38d-414e-9f9c-69e59f20a8c9",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
0
assets/bundles/.gitkeep
Normal file
0
assets/bundles/.gitkeep
Normal file
9
assets/configs.meta
Normal file
9
assets/configs.meta
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "ba427efa-2367-4264-a430-7cb4e18ba5f0",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
0
assets/configs/.gitkeep
Normal file
0
assets/configs/.gitkeep
Normal file
9
assets/i18n.meta
Normal file
9
assets/i18n.meta
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "3fa67f20-7171-4f96-8936-0c0ec82f9bc1",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
0
assets/i18n/.gitkeep
Normal file
0
assets/i18n/.gitkeep
Normal file
9
assets/prefabs.meta
Normal file
9
assets/prefabs.meta
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "261f65a6-c027-4d00-a45c-044c02776849",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
0
assets/prefabs/.gitkeep
Normal file
0
assets/prefabs/.gitkeep
Normal file
14
assets/resources.meta
Normal file
14
assets/resources.meta
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "220989bc-812e-49a7-b132-7bdad9d29b69",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {
|
||||
"isBundle": true,
|
||||
"bundleConfigID": "default",
|
||||
"bundleName": "resources",
|
||||
"priority": 8
|
||||
}
|
||||
}
|
||||
0
assets/resources/.gitkeep
Normal file
0
assets/resources/.gitkeep
Normal file
9
assets/scenes.meta
Normal file
9
assets/scenes.meta
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "20ae4bac-fad8-49ae-9b07-9de2dd0e6599",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
0
assets/scenes/.gitkeep
Normal file
0
assets/scenes/.gitkeep
Normal file
2904
assets/scenes/main_stage1.source_scene.json
Normal file
2904
assets/scenes/main_stage1.source_scene.json
Normal file
File diff suppressed because it is too large
Load Diff
11
assets/scenes/main_stage1.source_scene.json.meta
Normal file
11
assets/scenes/main_stage1.source_scene.json.meta
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"ver": "2.0.1",
|
||||
"importer": "json",
|
||||
"imported": true,
|
||||
"uuid": "46aa1585-38e2-47f7-a4e5-ad5279b2c9be",
|
||||
"files": [
|
||||
".json"
|
||||
],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
9
assets/scripts.meta
Normal file
9
assets/scripts.meta
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "3047f5ff-1705-489f-8f88-d64e2eb33789",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
0
assets/scripts/.gitkeep
Normal file
0
assets/scripts/.gitkeep
Normal file
9
assets/scripts/mock.meta
Normal file
9
assets/scripts/mock.meta
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "31121ddd-5696-4588-b960-d64ac181dbfe",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
0
assets/scripts/mock/.gitkeep
Normal file
0
assets/scripts/mock/.gitkeep
Normal file
9
assets/spine.meta
Normal file
9
assets/spine.meta
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "fb2e6ac5-f60e-4dda-811d-e0da00a80779",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
0
assets/spine/.gitkeep
Normal file
0
assets/spine/.gitkeep
Normal file
9
assets/textures.meta
Normal file
9
assets/textures.meta
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "5e3eab9f-16d5-457d-bd69-25af825af2f1",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
0
assets/textures/.gitkeep
Normal file
0
assets/textures/.gitkeep
Normal file
27
docs/cocos4_reconstruction_core.md
Normal file
27
docs/cocos4_reconstruction_core.md
Normal file
@ -0,0 +1,27 @@
|
||||
# Cocos 4 Reconstruction Core
|
||||
|
||||
This project rebuilds QQ Farm from the extracted original Cocos package using Cocos 4.0 and the Cocos 4 CLI.
|
||||
|
||||
The source package is `/Users/hy/Documents/dev/qq_farm_godot_rebuild_20260616`.
|
||||
|
||||
Rules:
|
||||
|
||||
- Original extracted Cocos data is the layout authority.
|
||||
- Godot output and screenshot-derived coordinates are not allowed.
|
||||
- Every module pass must export source evidence, generate a diagnostic Canvas preview, attempt Cocos verification, produce an ROI report, and update rebuild docs.
|
||||
- Runtime mocks may change visible state, but must not change recovered layout.
|
||||
|
||||
First milestone scope:
|
||||
|
||||
- `Canvas`
|
||||
- main `Camera`
|
||||
- root `scene`
|
||||
- background layers
|
||||
- visible land plots
|
||||
- house
|
||||
- doghouse
|
||||
- bottom menu buttons
|
||||
|
||||
Known first-stage blocker:
|
||||
|
||||
- Static Cocos source currently exposes 36 visual land cells. The required 24 visible plots need runtime selection evidence before final Cocos node generation.
|
||||
17
docs/rebuild_list.md
Normal file
17
docs/rebuild_list.md
Normal file
@ -0,0 +1,17 @@
|
||||
# Rebuild List
|
||||
|
||||
## First Stage
|
||||
|
||||
- [x] Migrate project metadata to Cocos 4.0 CLI format.
|
||||
- [x] Remove old Cocos Creator 3.8 project files.
|
||||
- [x] Export first-stage source evidence into `source_export/`.
|
||||
- [x] Generate diagnostic Canvas preview from exported evidence.
|
||||
- [x] Generate first-stage Cocos-facing intermediate scene data.
|
||||
- [x] Write ROI report.
|
||||
- [x] Run Cocos 4 CLI verification and record current blocker.
|
||||
|
||||
## Blocked
|
||||
|
||||
- [ ] Decode runtime rule for selecting 24 visible land plots from 36 static visual grid cells.
|
||||
- [ ] Resolve final Cocos 4 texture/SpriteFrame import bindings for background, land, house, doghouse, and bottom menu visuals.
|
||||
- [ ] Fix Cocos 4 alpha CLI runtime ABI mismatch before producing real Cocos build screenshots.
|
||||
34
docs/rebuild_log.md
Normal file
34
docs/rebuild_log.md
Normal file
@ -0,0 +1,34 @@
|
||||
# Rebuild Log
|
||||
|
||||
## 2026-06-19 First Stage Start
|
||||
|
||||
Commands run:
|
||||
|
||||
```bash
|
||||
python3 tools/extract_source_evidence.py
|
||||
python3 tools/generate_cocos4_project.py
|
||||
python3 tools/render_canvas_preview.py
|
||||
python3 tools/compare_visual_rois.py
|
||||
python3 tools/verify_cocos4_project.py
|
||||
```
|
||||
|
||||
Outputs:
|
||||
|
||||
- `source_export/source_nodes.json`
|
||||
- `source_export/source_prefabs.json`
|
||||
- `source_export/source_assets.json`
|
||||
- `source_export/source_spriteframes.json`
|
||||
- `source_export/source_spine.json`
|
||||
- `source_export/source_animations.json`
|
||||
- `source_export/source_runtime_notes.md`
|
||||
- `source_export/source_blockers.md`
|
||||
- `assets/scenes/main_stage1.source_scene.json`
|
||||
- `artifacts/canvas_preview/stage1_source_preview.png`
|
||||
- `artifacts/canvas_preview/stage1_source_preview_report.json`
|
||||
- `artifacts/visual_compare/stage1_roi_report.json`
|
||||
- `artifacts/cocos_capture/stage1_cocos_verify.json`
|
||||
|
||||
Verification result:
|
||||
|
||||
- Source extraction and diagnostic preview pass.
|
||||
- Cocos 4 CLI build is blocked by `webgl.node` ABI mismatch.
|
||||
29
docs/rebuild_notes.md
Normal file
29
docs/rebuild_notes.md
Normal file
@ -0,0 +1,29 @@
|
||||
# Rebuild Notes
|
||||
|
||||
## First Stage Source Evidence
|
||||
|
||||
Used source inventory:
|
||||
|
||||
- `/Users/hy/Documents/dev/qq_farm_godot_rebuild_20260616/source_first/out/main_scene_elements.json`
|
||||
|
||||
Authoritative source files referenced by the inventory:
|
||||
|
||||
- Startup scene: `assets/main/import/ee/ee605885-16e1-4a63-bf4b-d9663c5764b2.2fd9c.json`
|
||||
- World visual prefab: `downloads/raw/remote/extraRes/import/0a/0ada99ac7.403b3.json`
|
||||
- World mount prefab: `downloads/raw/remote/extraRes/import/0e/0ec3b3100.19268.json`
|
||||
- Main UI prefab: `downloads/raw/remote/extraRes/import/0d/0d7027270.4bc05.json`
|
||||
- Skin config: `downloads/raw/remote/delayRes/import/2d/2d201122-b5a7-4181-8f60-d67a399ec757.edfbe.json`
|
||||
|
||||
Recovered evidence:
|
||||
|
||||
- Startup root, `scene`, `ui`, main `Camera`, and `uiCamera`.
|
||||
- Background source nodes from `farm_scene_v3_sprite`.
|
||||
- 36 static land cell candidates under `Scaled/Rotate/GridOrigin`.
|
||||
- Default house and doghouse records from `SkinCfg`.
|
||||
- Bottom menu node chain under `main_ui_v2/Menu`.
|
||||
|
||||
Not recovered yet:
|
||||
|
||||
- Runtime rule selecting 24 visible land plots.
|
||||
- Final Cocos 4 texture and SpriteFrame bindings.
|
||||
- Cocos-produced screenshot, because the local Cocos 4 alpha CLI build is blocked by native ABI mismatch.
|
||||
93
source_export/source_animations.json
Normal file
93
source_export/source_animations.json
Normal file
@ -0,0 +1,93 @@
|
||||
{
|
||||
"status": "not_in_first_stage_scope",
|
||||
"animation_clips": [
|
||||
{
|
||||
"id": "one_click_loop",
|
||||
"asset_path": "gui/anim/OneClickOperationTools/anim_ui_loop",
|
||||
"index": 118,
|
||||
"role": "animation_clip",
|
||||
"bundle": "extraRes",
|
||||
"mode": "import",
|
||||
"pack_key": null,
|
||||
"pack_position": null,
|
||||
"source_file": "downloads/raw/remote/extraRes/import/17/17c93ab6-b487-40b7-9a81-b787931b235f.831f6.json"
|
||||
},
|
||||
{
|
||||
"id": "one_click_click_effect",
|
||||
"asset_path": "gui/anim/OneClickOperationTools/anim_ui_clickEffect1",
|
||||
"index": 342,
|
||||
"role": "animation_clip",
|
||||
"bundle": "extraRes",
|
||||
"mode": "import",
|
||||
"pack_key": null,
|
||||
"pack_position": null,
|
||||
"source_file": "downloads/raw/remote/extraRes/import/40/40cc1e7e-d851-4ec8-ac89-836857c9fbf8.9b8b6.json"
|
||||
},
|
||||
{
|
||||
"id": "one_click_click",
|
||||
"asset_path": "gui/anim/OneClickOperationTools/anim_ui_click",
|
||||
"index": 1029,
|
||||
"role": "animation_clip",
|
||||
"bundle": "extraRes",
|
||||
"mode": "import",
|
||||
"pack_key": null,
|
||||
"pack_position": null,
|
||||
"source_file": "downloads/raw/remote/extraRes/import/c1/c1f26263-07c4-4875-b778-b8c86889d85d.159c2.json"
|
||||
},
|
||||
{
|
||||
"id": "one_click_into",
|
||||
"asset_path": "gui/anim/OneClickOperationTools/anim_ui_into",
|
||||
"index": 1314,
|
||||
"role": "animation_clip",
|
||||
"bundle": "extraRes",
|
||||
"mode": "import",
|
||||
"pack_key": null,
|
||||
"pack_position": null,
|
||||
"source_file": "downloads/raw/remote/extraRes/import/f6/f6bbd33f-5b38-4b44-abcd-b338d38a0da8.3383f.json"
|
||||
},
|
||||
{
|
||||
"id": "task_book_light_loop",
|
||||
"asset_path": "gui/anim/btn_task/book_light_loop",
|
||||
"index": 161,
|
||||
"role": "animation_clip",
|
||||
"bundle": "extraRes",
|
||||
"mode": "import",
|
||||
"pack_key": null,
|
||||
"pack_position": null,
|
||||
"source_file": "downloads/raw/remote/extraRes/import/1f/1ff9a8a2-2819-445d-9c7c-aeb7677551f0.83805.json"
|
||||
},
|
||||
{
|
||||
"id": "task_bg_light_loop",
|
||||
"asset_path": "gui/anim/btn_task/bg_light_loop",
|
||||
"index": 407,
|
||||
"role": "animation_clip",
|
||||
"bundle": "extraRes",
|
||||
"mode": "import",
|
||||
"pack_key": null,
|
||||
"pack_position": null,
|
||||
"source_file": "downloads/raw/remote/extraRes/import/4b/4b9a94ba-9ef8-470a-baf6-d2b34a511480.1facb.json"
|
||||
},
|
||||
{
|
||||
"id": "task_into",
|
||||
"asset_path": "gui/anim/btn_task/ui_anim_into",
|
||||
"index": 715,
|
||||
"role": "animation_clip",
|
||||
"bundle": "extraRes",
|
||||
"mode": "import",
|
||||
"pack_key": null,
|
||||
"pack_position": null,
|
||||
"source_file": "downloads/raw/remote/extraRes/import/8a/8a6b50ad-fbf9-4408-b58f-94b5b03f9226.aa450.json"
|
||||
},
|
||||
{
|
||||
"id": "task_out",
|
||||
"asset_path": "gui/anim/btn_task/ui_anim_out",
|
||||
"index": 1301,
|
||||
"role": "animation_clip",
|
||||
"bundle": "extraRes",
|
||||
"mode": "import",
|
||||
"pack_key": null,
|
||||
"pack_position": null,
|
||||
"source_file": "downloads/raw/remote/extraRes/import/f4/f4e1c3a2-7a53-4e46-a645-71c6e3bb4e53.618a6.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
261
source_export/source_assets.json
Normal file
261
source_export/source_assets.json
Normal file
@ -0,0 +1,261 @@
|
||||
{
|
||||
"backgrounds": [
|
||||
{
|
||||
"id": "scene_bg",
|
||||
"asset_path": "scene/bg",
|
||||
"index": 13,
|
||||
"role": "large_scene_background_texture",
|
||||
"bundle": "delayRes",
|
||||
"mode": "import",
|
||||
"pack_key": null,
|
||||
"pack_position": null,
|
||||
"source_file": "downloads/raw/remote/delayRes/import/14/146c722a-2371-420b-9958-6ff8ca81ff57.19fac.json"
|
||||
},
|
||||
{
|
||||
"id": "scene_fg",
|
||||
"asset_path": "scene/fg",
|
||||
"index": 172,
|
||||
"role": "large_scene_foreground_texture",
|
||||
"bundle": "delayRes",
|
||||
"mode": "import",
|
||||
"pack_key": null,
|
||||
"pack_position": null,
|
||||
"source_file": "downloads/raw/remote/delayRes/import/df/df3ba319-262f-49a8-9f74-afdc97dc0ab1.19fac.json"
|
||||
},
|
||||
{
|
||||
"id": "model_scene_bg",
|
||||
"asset_path": "model/v3/scene/bg",
|
||||
"index": 1152,
|
||||
"role": "small_scene_background_fallback",
|
||||
"bundle": "extraRes",
|
||||
"mode": "import",
|
||||
"pack_key": null,
|
||||
"pack_position": null,
|
||||
"source_file": "downloads/raw/remote/extraRes/import/db/dbe047f4-d92a-4abe-b7dd-c9fb7b784577.19fac.json"
|
||||
},
|
||||
{
|
||||
"id": "model_scene_fg",
|
||||
"asset_path": "model/v3/scene/fg",
|
||||
"index": 1289,
|
||||
"role": "small_scene_foreground_fallback",
|
||||
"bundle": "extraRes",
|
||||
"mode": "import",
|
||||
"pack_key": null,
|
||||
"pack_position": null,
|
||||
"source_file": "downloads/raw/remote/extraRes/import/f3/f3826219-91f1-43b2-9fa7-2c504543aee0.19fac.json"
|
||||
}
|
||||
],
|
||||
"config_assets": [
|
||||
{
|
||||
"asset_path": "config/SkinCfg",
|
||||
"index": 323,
|
||||
"role": "skin_and_decor_runtime_config",
|
||||
"bundle": "delayRes",
|
||||
"mode": "import",
|
||||
"pack_key": null,
|
||||
"pack_position": null,
|
||||
"source_file": "downloads/raw/remote/delayRes/import/2d/2d201122-b5a7-4181-8f60-d67a399ec757.edfbe.json",
|
||||
"id": "skin_cfg",
|
||||
"json_asset_name": "SkinCfg",
|
||||
"record_count": 51,
|
||||
"default_records": [
|
||||
{
|
||||
"id": 201001,
|
||||
"skin_type": 1,
|
||||
"skin_name": "默认小屋",
|
||||
"parent_node": "Scene/FgLayer/FarmSkin/Layer2",
|
||||
"position": {
|
||||
"x": 347.6,
|
||||
"y": 179.8
|
||||
},
|
||||
"spine_asset": "spine/v2/costume/house/201001",
|
||||
"icon_asset": "gui/texture/skinDetail/img_skin_house/spriteFrame"
|
||||
},
|
||||
{
|
||||
"id": 202001,
|
||||
"skin_type": 2,
|
||||
"skin_name": "默认木牌",
|
||||
"parent_node": "Scene/FgLayer/Board",
|
||||
"position": {
|
||||
"x": -259.1,
|
||||
"y": 104.1
|
||||
},
|
||||
"spine_asset": "spine/v2/costume/brand/202001",
|
||||
"icon_asset": "gui/texture/skinDetail/img_skin_board/spriteFrame"
|
||||
},
|
||||
{
|
||||
"id": 203001,
|
||||
"skin_type": 3,
|
||||
"skin_name": "默认栅栏",
|
||||
"parent_node": "Scene/FgLayer/FarmSkin/Layer3",
|
||||
"position": {
|
||||
"x": -185.4,
|
||||
"y": -280.5
|
||||
},
|
||||
"spine_asset": "spine/v2/costume/fence/203001",
|
||||
"icon_asset": "gui/texture/skinDetail/img_skin_barrier/spriteFrame"
|
||||
},
|
||||
{
|
||||
"id": 204001,
|
||||
"skin_type": 4,
|
||||
"skin_name": "空",
|
||||
"parent_node": "Scene/FgLayer/Tower",
|
||||
"position": {
|
||||
"x": -454,
|
||||
"y": 28.6
|
||||
},
|
||||
"spine_asset": null,
|
||||
"icon_asset": null
|
||||
},
|
||||
{
|
||||
"id": 205001,
|
||||
"skin_type": 5,
|
||||
"skin_name": "默认狗屋",
|
||||
"parent_node": "Scene/FgLayer/FarmSkin",
|
||||
"position": {
|
||||
"x": 24.2,
|
||||
"y": 223.9
|
||||
},
|
||||
"spine_asset": "spine/v2/costume/doghouse/205001",
|
||||
"icon_asset": "gui/texture/skinDetail/img_skin_doghouse/spriteFrame"
|
||||
},
|
||||
{
|
||||
"id": 206001,
|
||||
"skin_type": 6,
|
||||
"skin_name": "默认仓库",
|
||||
"parent_node": "Scene/FgLayer/Storage",
|
||||
"position": {
|
||||
"x": -770.8,
|
||||
"y": -28.6
|
||||
},
|
||||
"spine_asset": "spine/v2/costume/warehouse/206001",
|
||||
"icon_asset": "gui/texture/skinDetail/img_skin_warehouse/spriteFrame"
|
||||
},
|
||||
{
|
||||
"id": 207001,
|
||||
"skin_type": 7,
|
||||
"skin_name": "默认街道",
|
||||
"parent_node": "Scene/FgLayer/FarmSkin/Layer1",
|
||||
"position": {
|
||||
"x": 76.6,
|
||||
"y": -193.5
|
||||
},
|
||||
"spine_asset": "spine/v2/costume/load/207001",
|
||||
"icon_asset": "gui/texture/skinDetail/img_skin_road/spriteFrame"
|
||||
},
|
||||
{
|
||||
"id": 208001,
|
||||
"skin_type": 8,
|
||||
"skin_name": "默认围栏",
|
||||
"parent_node": "Scene/FgLayer/FarmSkin/Layer1",
|
||||
"position": {
|
||||
"x": -629,
|
||||
"y": 163.8
|
||||
},
|
||||
"spine_asset": "spine/v2/costume/fence_2/208001",
|
||||
"icon_asset": "gui/texture/skinDetail/img_skin_fence/spriteFrame"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"asset_path": "config/SkinTypeCfg",
|
||||
"index": 453,
|
||||
"role": "skin_type_runtime_config",
|
||||
"bundle": "delayRes",
|
||||
"mode": "import",
|
||||
"pack_key": null,
|
||||
"pack_position": null,
|
||||
"source_file": "downloads/raw/remote/delayRes/import/62/6276caa6-6ab0-472c-8a57-e32ce1dd5de2.f1c60.json",
|
||||
"id": "skin_type_cfg",
|
||||
"json_asset_name": "SkinTypeCfg",
|
||||
"record_count": 8
|
||||
},
|
||||
{
|
||||
"asset_path": "config/Plant",
|
||||
"index": 422,
|
||||
"role": "crop_runtime_config",
|
||||
"bundle": "delayRes",
|
||||
"mode": "import",
|
||||
"pack_key": null,
|
||||
"pack_position": null,
|
||||
"source_file": "downloads/raw/remote/delayRes/import/52/524bdf1d-e595-4a42-941c-556b06fdbb4b.bce5d.json",
|
||||
"id": "plant_cfg",
|
||||
"json_asset_name": "Plant",
|
||||
"record_count": 226,
|
||||
"sample_records": [
|
||||
{
|
||||
"id": 2020002,
|
||||
"name": "白萝卜",
|
||||
"level": null,
|
||||
"stage_asset": null
|
||||
},
|
||||
{
|
||||
"id": 1020002,
|
||||
"name": "白萝卜",
|
||||
"level": null,
|
||||
"stage_asset": null
|
||||
},
|
||||
{
|
||||
"id": 1020003,
|
||||
"name": "胡萝卜",
|
||||
"level": null,
|
||||
"stage_asset": null
|
||||
},
|
||||
{
|
||||
"id": 1020059,
|
||||
"name": "大白菜",
|
||||
"level": null,
|
||||
"stage_asset": null
|
||||
},
|
||||
{
|
||||
"id": 1020065,
|
||||
"name": "大蒜",
|
||||
"level": null,
|
||||
"stage_asset": null
|
||||
},
|
||||
{
|
||||
"id": 1020064,
|
||||
"name": "大葱",
|
||||
"level": null,
|
||||
"stage_asset": null
|
||||
},
|
||||
{
|
||||
"id": 1020060,
|
||||
"name": "水稻",
|
||||
"level": null,
|
||||
"stage_asset": null
|
||||
},
|
||||
{
|
||||
"id": 1020061,
|
||||
"name": "小麦",
|
||||
"level": null,
|
||||
"stage_asset": null
|
||||
},
|
||||
{
|
||||
"id": 1020004,
|
||||
"name": "玉米",
|
||||
"level": null,
|
||||
"stage_asset": null
|
||||
},
|
||||
{
|
||||
"id": 1020066,
|
||||
"name": "鲜姜",
|
||||
"level": null,
|
||||
"stage_asset": null
|
||||
},
|
||||
{
|
||||
"id": 1020005,
|
||||
"name": "土豆",
|
||||
"level": null,
|
||||
"stage_asset": null
|
||||
},
|
||||
{
|
||||
"id": 1020071,
|
||||
"name": "小白菜",
|
||||
"level": null,
|
||||
"stage_asset": null
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
5
source_export/source_blockers.md
Normal file
5
source_export/source_blockers.md
Normal file
@ -0,0 +1,5 @@
|
||||
# Source Blockers
|
||||
|
||||
- `visible_land_count`: Static source prefab has 36 visual grid cells. The first-milestone spec requires 24 visible land plots, but the runtime rule selecting those 24 is not yet decoded.
|
||||
- `background_texture_binding`: Background ImageAsset entries are located, but final texture/SpriteFrame binding for Cocos 4 import is not yet resolved from metadata.
|
||||
- `cocos4_cli_build`: Cocos 4 alpha CLI reaches engine init, then fails because node_modules/gl/build/Release/webgl.node requires NODE_MODULE_VERSION 140 while local Node 24 provides 137.
|
||||
3328
source_export/source_nodes.json
Normal file
3328
source_export/source_nodes.json
Normal file
File diff suppressed because it is too large
Load Diff
63
source_export/source_prefabs.json
Normal file
63
source_export/source_prefabs.json
Normal file
@ -0,0 +1,63 @@
|
||||
{
|
||||
"farm_scene_v3_sprite": {
|
||||
"source": {
|
||||
"asset_path": "scene/farm_scene_v3_sprite",
|
||||
"index": 1635,
|
||||
"role": "world_visual_prefab",
|
||||
"bundle": "extraRes",
|
||||
"mode": "pack",
|
||||
"pack_key": "0ada99ac7",
|
||||
"pack_position": 0,
|
||||
"source_file": "downloads/raw/remote/extraRes/import/0a/0ada99ac7.403b3.json"
|
||||
},
|
||||
"node_count": 131,
|
||||
"category_counts": {
|
||||
"source_node": 8,
|
||||
"visual_land_cell": 36,
|
||||
"visual_land_cell_child": 72,
|
||||
"world_background": 3,
|
||||
"world_decor": 1,
|
||||
"world_layer": 11
|
||||
}
|
||||
},
|
||||
"farm_scene_v3": {
|
||||
"source": {
|
||||
"asset_path": "scene/farm_scene_v3",
|
||||
"index": 3914,
|
||||
"role": "world_mount_and_logic_prefab",
|
||||
"bundle": "extraRes",
|
||||
"mode": "pack",
|
||||
"pack_key": "0ec3b3100",
|
||||
"pack_position": 1,
|
||||
"source_file": "downloads/raw/remote/extraRes/import/0e/0ec3b3100.19268.json"
|
||||
},
|
||||
"node_count": 119,
|
||||
"category_counts": {
|
||||
"skin_mount": 11,
|
||||
"source_node": 36,
|
||||
"visual_land_cell": 24,
|
||||
"visual_land_cell_child": 48
|
||||
}
|
||||
},
|
||||
"main_ui_v2": {
|
||||
"source": {
|
||||
"asset_path": "gui/prefab/main_ui_v2",
|
||||
"index": 2487,
|
||||
"role": "main_ui_prefab",
|
||||
"bundle": "extraRes",
|
||||
"mode": "pack",
|
||||
"pack_key": "0d7027270",
|
||||
"pack_position": 2,
|
||||
"source_file": "downloads/raw/remote/extraRes/import/0d/0d7027270.4bc05.json"
|
||||
},
|
||||
"node_count": 141,
|
||||
"category_counts": {
|
||||
"friend_visit_ui": 8,
|
||||
"hud_bottom_or_task": 25,
|
||||
"hud_left_setting": 29,
|
||||
"hud_right": 35,
|
||||
"hud_top": 39,
|
||||
"main_ui_other": 5
|
||||
}
|
||||
}
|
||||
}
|
||||
7
source_export/source_runtime_notes.md
Normal file
7
source_export/source_runtime_notes.md
Normal file
@ -0,0 +1,7 @@
|
||||
# Source Runtime Notes
|
||||
|
||||
- Startup scene source has Canvas/root/ui/scene and two cameras.
|
||||
- `farm_scene_v3_sprite` contains 36 static visual land cells under `Scaled/Rotate/GridOrigin`.
|
||||
- First-stage spec requires 24 visible land plots, but the runtime rule selecting visible or unlocked plots is not decoded yet.
|
||||
- Default house and doghouse come from `SkinCfg` records `201001` and `205001`, not only from the static visual prefab.
|
||||
- Bottom menu source nodes are under `main_ui_v2/Menu`; feature logic for warehouse/shop/friend/task is outside first-stage scope.
|
||||
30
source_export/source_spine.json
Normal file
30
source_export/source_spine.json
Normal file
@ -0,0 +1,30 @@
|
||||
{
|
||||
"status": "default house and doghouse reference Spine assets through SkinCfg; Cocos 4 import binding not generated yet",
|
||||
"manifest": "/Users/hy/Documents/dev/qq_farm_godot_rebuild_20260616/downloads/spine_regions/spine_region_manifest.json",
|
||||
"records": [
|
||||
{
|
||||
"id": 201001,
|
||||
"skin_type": 1,
|
||||
"skin_name": "默认小屋",
|
||||
"parent_node": "Scene/FgLayer/FarmSkin/Layer2",
|
||||
"position": {
|
||||
"x": 347.6,
|
||||
"y": 179.8
|
||||
},
|
||||
"spine_asset": "spine/v2/costume/house/201001",
|
||||
"icon_asset": "gui/texture/skinDetail/img_skin_house/spriteFrame"
|
||||
},
|
||||
{
|
||||
"id": 205001,
|
||||
"skin_type": 5,
|
||||
"skin_name": "默认狗屋",
|
||||
"parent_node": "Scene/FgLayer/FarmSkin",
|
||||
"position": {
|
||||
"x": 24.2,
|
||||
"y": 223.9
|
||||
},
|
||||
"spine_asset": "spine/v2/costume/doghouse/205001",
|
||||
"icon_asset": "gui/texture/skinDetail/img_skin_doghouse/spriteFrame"
|
||||
}
|
||||
]
|
||||
}
|
||||
4
source_export/source_spriteframes.json
Normal file
4
source_export/source_spriteframes.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"status": "metadata_manifest_available_but_stage1_bindings_unresolved",
|
||||
"manifest": "/Users/hy/Documents/dev/qq_farm_godot_rebuild_20260616/downloads/spriteframes/sprite_manifest.json"
|
||||
}
|
||||
40
tools/compare_visual_rois.py
Normal file
40
tools/compare_visual_rois.py
Normal file
@ -0,0 +1,40 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Write a first-stage ROI validation report.
|
||||
|
||||
This pass records why ROI cannot pass yet: no Cocos-produced screenshot exists
|
||||
because the Cocos 4 alpha CLI is blocked by a native ABI mismatch.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
PROJECT = Path(__file__).resolve().parents[1]
|
||||
|
||||
|
||||
def main() -> None:
|
||||
out_dir = PROJECT / "artifacts/visual_compare"
|
||||
out_dir.mkdir(parents=True, exist_ok=True)
|
||||
report = {
|
||||
"generated_at": datetime.now(timezone.utc).isoformat(),
|
||||
"module": "main_scene_first_milestone",
|
||||
"status": "blocked",
|
||||
"rois": ["world_static", "land_area", "decor_area", "bottom_buttons"],
|
||||
"reason": "Cocos-produced screenshot is unavailable because Cocos 4 alpha CLI build fails on native webgl.node ABI mismatch.",
|
||||
"diagnostic_preview": str(PROJECT / "artifacts/canvas_preview/stage1_source_preview.png"),
|
||||
"target_thresholds": {
|
||||
"static_bitmap_similarity": 0.99,
|
||||
"object_center_delta_px": 2,
|
||||
"object_size_delta_percent": 1,
|
||||
},
|
||||
}
|
||||
path = out_dir / "stage1_roi_report.json"
|
||||
path.write_text(json.dumps(report, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
|
||||
print(path)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
199
tools/extract_source_evidence.py
Normal file
199
tools/extract_source_evidence.py
Normal file
@ -0,0 +1,199 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Export first-milestone source evidence for the Cocos 4 rebuild.
|
||||
|
||||
The extractor consumes the already decoded source-first inventory from the
|
||||
original Cocos package. It does not read Godot output and does not infer layout
|
||||
from screenshots.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
|
||||
PROJECT = Path(__file__).resolve().parents[1]
|
||||
SOURCE_ROOT = Path("/Users/hy/Documents/dev/qq_farm_godot_rebuild_20260616")
|
||||
SOURCE_INVENTORY = SOURCE_ROOT / "source_first/out/main_scene_elements.json"
|
||||
OUT = PROJECT / "source_export"
|
||||
|
||||
|
||||
def read_json(path: Path) -> Any:
|
||||
with path.open("r", encoding="utf-8") as fh:
|
||||
return json.load(fh)
|
||||
|
||||
|
||||
def write_json(path: Path, value: Any) -> None:
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
path.write_text(json.dumps(value, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
|
||||
|
||||
|
||||
def write_text(path: Path, value: str) -> None:
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
path.write_text(value, encoding="utf-8")
|
||||
|
||||
|
||||
def find_default_records(config_assets: list[dict[str, Any]]) -> list[dict[str, Any]]:
|
||||
for item in config_assets:
|
||||
if item.get("id") == "skin_cfg":
|
||||
return item.get("default_records", [])
|
||||
return []
|
||||
|
||||
|
||||
def only_paths(elements: list[dict[str, Any]], *needles: str) -> list[dict[str, Any]]:
|
||||
return [item for item in elements if any(needle in str(item.get("full_path")) for needle in needles)]
|
||||
|
||||
|
||||
def build_stage1(data: dict[str, Any]) -> dict[str, Any]:
|
||||
sprite_prefab = data["prefabs"]["farm_scene_v3_sprite"]
|
||||
mount_prefab = data["prefabs"]["farm_scene_v3"]
|
||||
main_ui = data["prefabs"]["main_ui_v2"]
|
||||
|
||||
land_candidates = [
|
||||
item for item in sprite_prefab["elements"]
|
||||
if item.get("category") == "visual_land_cell"
|
||||
]
|
||||
background_nodes = [
|
||||
item for item in sprite_prefab["elements"]
|
||||
if item.get("category") == "world_background"
|
||||
or str(item.get("full_path")).endswith("/Scene/bg")
|
||||
or "BgLayer" in str(item.get("full_path"))
|
||||
]
|
||||
bottom_menu_nodes = only_paths(
|
||||
main_ui["elements"],
|
||||
"main_ui_v2/Menu",
|
||||
"main_ui_v2/Menu/btn_layout",
|
||||
"main_ui_v2/Menu/Node_task",
|
||||
"main_ui_v2/Menu/Node_Friend",
|
||||
)
|
||||
default_skin_records = find_default_records(data.get("config_assets", []))
|
||||
house_records = [
|
||||
item for item in default_skin_records
|
||||
if item.get("skin_type") in {1, 5}
|
||||
]
|
||||
doghouse_nodes = only_paths(sprite_prefab["elements"], "dogHouse") + only_paths(mount_prefab["elements"], "dogHouse")
|
||||
|
||||
return {
|
||||
"module": "main_scene_first_milestone",
|
||||
"generated_at": datetime.now(timezone.utc).isoformat(),
|
||||
"source_inventory": str(SOURCE_INVENTORY),
|
||||
"design_resolution": data["summary"]["design_resolution"],
|
||||
"scope": [
|
||||
"Canvas",
|
||||
"main Camera",
|
||||
"root scene",
|
||||
"background layers",
|
||||
"visible land plots",
|
||||
"house",
|
||||
"doghouse",
|
||||
"bottom menu buttons",
|
||||
],
|
||||
"startup_scene": data["startup_scene"],
|
||||
"prefab_sources": {
|
||||
"farm_scene_v3_sprite": sprite_prefab["source"],
|
||||
"farm_scene_v3": mount_prefab["source"],
|
||||
"main_ui_v2": main_ui["source"],
|
||||
},
|
||||
"canvas_and_cameras": data["startup_scene"]["elements"],
|
||||
"background_nodes": background_nodes,
|
||||
"land_candidates": {
|
||||
"source_count": len(land_candidates),
|
||||
"visible_count_required_by_spec": 24,
|
||||
"selection_status": "blocked_missing_runtime_visible_land_rule",
|
||||
"nodes": land_candidates,
|
||||
},
|
||||
"house_and_doghouse": {
|
||||
"skin_cfg_default_records": house_records,
|
||||
"doghouse_nodes": doghouse_nodes,
|
||||
},
|
||||
"bottom_menu_nodes": bottom_menu_nodes,
|
||||
"asset_inputs": {
|
||||
"backgrounds": data.get("source_assets", {}).get("backgrounds", []),
|
||||
"config_assets": data.get("config_assets", []),
|
||||
},
|
||||
"blockers": [
|
||||
{
|
||||
"id": "visible_land_count",
|
||||
"status": "blocked",
|
||||
"detail": "Static source prefab has 36 visual grid cells. The first-milestone spec requires 24 visible land plots, but the runtime rule selecting those 24 is not yet decoded.",
|
||||
},
|
||||
{
|
||||
"id": "background_texture_binding",
|
||||
"status": "blocked",
|
||||
"detail": "Background ImageAsset entries are located, but final texture/SpriteFrame binding for Cocos 4 import is not yet resolved from metadata.",
|
||||
},
|
||||
{
|
||||
"id": "cocos4_cli_build",
|
||||
"status": "blocked",
|
||||
"detail": "Cocos 4 alpha CLI reaches engine init, then fails because node_modules/gl/build/Release/webgl.node requires NODE_MODULE_VERSION 140 while local Node 24 provides 137.",
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
def main() -> None:
|
||||
data = read_json(SOURCE_INVENTORY)
|
||||
stage1 = build_stage1(data)
|
||||
|
||||
sprite_prefab = data["prefabs"]["farm_scene_v3_sprite"]
|
||||
mount_prefab = data["prefabs"]["farm_scene_v3"]
|
||||
main_ui = data["prefabs"]["main_ui_v2"]
|
||||
|
||||
write_json(OUT / "source_nodes.json", stage1)
|
||||
write_json(OUT / "source_prefabs.json", {
|
||||
"farm_scene_v3_sprite": {
|
||||
"source": sprite_prefab["source"],
|
||||
"node_count": len(sprite_prefab["elements"]),
|
||||
"category_counts": sprite_prefab.get("category_counts", {}),
|
||||
},
|
||||
"farm_scene_v3": {
|
||||
"source": mount_prefab["source"],
|
||||
"node_count": len(mount_prefab["elements"]),
|
||||
"category_counts": mount_prefab.get("category_counts", {}),
|
||||
},
|
||||
"main_ui_v2": {
|
||||
"source": main_ui["source"],
|
||||
"node_count": len(main_ui["elements"]),
|
||||
"category_counts": main_ui.get("category_counts", {}),
|
||||
},
|
||||
})
|
||||
write_json(OUT / "source_assets.json", stage1["asset_inputs"])
|
||||
write_json(OUT / "source_spriteframes.json", {
|
||||
"status": "metadata_manifest_available_but_stage1_bindings_unresolved",
|
||||
"manifest": str(SOURCE_ROOT / "downloads/spriteframes/sprite_manifest.json"),
|
||||
})
|
||||
write_json(OUT / "source_spine.json", {
|
||||
"status": "default house and doghouse reference Spine assets through SkinCfg; Cocos 4 import binding not generated yet",
|
||||
"manifest": str(SOURCE_ROOT / "downloads/spine_regions/spine_region_manifest.json"),
|
||||
"records": stage1["house_and_doghouse"]["skin_cfg_default_records"],
|
||||
})
|
||||
write_json(OUT / "source_animations.json", {
|
||||
"status": "not_in_first_stage_scope",
|
||||
"animation_clips": data.get("source_assets", {}).get("animation_clips", []),
|
||||
})
|
||||
|
||||
runtime_notes = """# Source Runtime Notes
|
||||
|
||||
- Startup scene source has Canvas/root/ui/scene and two cameras.
|
||||
- `farm_scene_v3_sprite` contains 36 static visual land cells under `Scaled/Rotate/GridOrigin`.
|
||||
- First-stage spec requires 24 visible land plots, but the runtime rule selecting visible or unlocked plots is not decoded yet.
|
||||
- Default house and doghouse come from `SkinCfg` records `201001` and `205001`, not only from the static visual prefab.
|
||||
- Bottom menu source nodes are under `main_ui_v2/Menu`; feature logic for warehouse/shop/friend/task is outside first-stage scope.
|
||||
"""
|
||||
write_text(OUT / "source_runtime_notes.md", runtime_notes)
|
||||
|
||||
blocker_lines = ["# Source Blockers", ""]
|
||||
for item in stage1["blockers"]:
|
||||
blocker_lines.append(f"- `{item['id']}`: {item['detail']}")
|
||||
blocker_lines.append("")
|
||||
write_text(OUT / "source_blockers.md", "\n".join(blocker_lines))
|
||||
|
||||
print(f"wrote {OUT / 'source_nodes.json'}")
|
||||
print(f"land candidates: {stage1['land_candidates']['source_count']}")
|
||||
print("visible land selection: blocked_missing_runtime_visible_land_rule")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
70
tools/generate_cocos4_project.py
Normal file
70
tools/generate_cocos4_project.py
Normal file
@ -0,0 +1,70 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Generate first-stage Cocos-facing scene data from source evidence.
|
||||
|
||||
The Cocos 4 alpha CLI on this machine cannot currently build because of a
|
||||
native ABI mismatch. This script therefore writes source-backed scene data that
|
||||
can be consumed by a later Cocos 4 scene writer once the CLI/runtime is fixed.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
|
||||
PROJECT = Path(__file__).resolve().parents[1]
|
||||
SOURCE_NODES = PROJECT / "source_export/source_nodes.json"
|
||||
|
||||
|
||||
def read_json(path: Path) -> Any:
|
||||
with path.open("r", encoding="utf-8") as fh:
|
||||
return json.load(fh)
|
||||
|
||||
|
||||
def mkdir_keep(path: Path) -> None:
|
||||
path.mkdir(parents=True, exist_ok=True)
|
||||
keep = path / ".gitkeep"
|
||||
if not keep.exists():
|
||||
keep.write_text("", encoding="utf-8")
|
||||
|
||||
|
||||
def main() -> None:
|
||||
data = read_json(SOURCE_NODES)
|
||||
for rel in [
|
||||
"assets/scenes",
|
||||
"assets/prefabs",
|
||||
"assets/scripts",
|
||||
"assets/scripts/mock",
|
||||
"assets/resources",
|
||||
"assets/bundles",
|
||||
"assets/textures",
|
||||
"assets/spine",
|
||||
"assets/audio",
|
||||
"assets/configs",
|
||||
"assets/i18n",
|
||||
"artifacts/cocos_capture",
|
||||
"artifacts/visual_compare",
|
||||
]:
|
||||
mkdir_keep(PROJECT / rel)
|
||||
|
||||
scene = {
|
||||
"format": "cocos4_stage1_source_scene",
|
||||
"status": "source_backed_intermediate_scene_data",
|
||||
"design_resolution": data["design_resolution"],
|
||||
"nodes": {
|
||||
"startup": data["canvas_and_cameras"],
|
||||
"backgrounds": data["background_nodes"],
|
||||
"land_candidates": data["land_candidates"],
|
||||
"house_and_doghouse": data["house_and_doghouse"],
|
||||
"bottom_menu": data["bottom_menu_nodes"],
|
||||
},
|
||||
"blockers": data["blockers"],
|
||||
}
|
||||
out = PROJECT / "assets/scenes/main_stage1.source_scene.json"
|
||||
out.write_text(json.dumps(scene, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
|
||||
print(out)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
93
tools/render_canvas_preview.py
Normal file
93
tools/render_canvas_preview.py
Normal file
@ -0,0 +1,93 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Render a diagnostic first-stage preview from source evidence."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
|
||||
|
||||
PROJECT = Path(__file__).resolve().parents[1]
|
||||
SOURCE_NODES = PROJECT / "source_export/source_nodes.json"
|
||||
OUT_DIR = PROJECT / "artifacts/canvas_preview"
|
||||
|
||||
|
||||
def read_json(path: Path) -> Any:
|
||||
with path.open("r", encoding="utf-8") as fh:
|
||||
return json.load(fh)
|
||||
|
||||
|
||||
def cocos_to_image(point: dict[str, float], width: int, height: int) -> tuple[float, float]:
|
||||
return width / 2 + float(point.get("x", 0)), height / 2 - float(point.get("y", 0))
|
||||
|
||||
|
||||
def draw_centered_rect(draw: ImageDraw.ImageDraw, node: dict[str, Any], canvas: tuple[int, int], outline: str, fill: str | None = None) -> None:
|
||||
pos = node.get("world_position_transformed") or node.get("position") or {"x": 0, "y": 0}
|
||||
size = node.get("primary_size") or node.get("content_size") or {"width": 40, "height": 40}
|
||||
cx, cy = cocos_to_image(pos, canvas[0], canvas[1])
|
||||
w = float(size.get("width") or 40)
|
||||
h = float(size.get("height") or 40)
|
||||
box = [cx - w / 2, cy - h / 2, cx + w / 2, cy + h / 2]
|
||||
draw.rectangle(box, outline=outline, fill=fill, width=2)
|
||||
|
||||
|
||||
def draw_land_cell(draw: ImageDraw.ImageDraw, node: dict[str, Any], canvas: tuple[int, int]) -> None:
|
||||
pos = node.get("world_position_transformed") or {"x": 0, "y": 0}
|
||||
cx, cy = cocos_to_image(pos, canvas[0], canvas[1])
|
||||
size = node.get("primary_size") or {"width": 130, "height": 130}
|
||||
w = float(size.get("width") or 130)
|
||||
h = float(size.get("height") or 130) * 0.5
|
||||
pts = [(cx, cy - h / 2), (cx + w / 2, cy), (cx, cy + h / 2), (cx - w / 2, cy)]
|
||||
draw.polygon(pts, outline="#2f7d32", fill="#86bf6a")
|
||||
|
||||
|
||||
def main() -> None:
|
||||
data = read_json(SOURCE_NODES)
|
||||
width = int(data["design_resolution"]["width"])
|
||||
height = int(data["design_resolution"]["height"])
|
||||
img = Image.new("RGB", (width, height), "#d7efff")
|
||||
draw = ImageDraw.Draw(img, "RGBA")
|
||||
|
||||
for node in data["background_nodes"]:
|
||||
draw_centered_rect(draw, node, (width, height), "#7a9f4b", "#b7d77a55")
|
||||
|
||||
for node in data["land_candidates"]["nodes"]:
|
||||
draw_land_cell(draw, node, (width, height))
|
||||
|
||||
for node in data["house_and_doghouse"]["doghouse_nodes"]:
|
||||
draw_centered_rect(draw, node, (width, height), "#7a3f16", "#b8753555")
|
||||
|
||||
for record in data["house_and_doghouse"]["skin_cfg_default_records"]:
|
||||
pos = record.get("position") or {"x": 0, "y": 0}
|
||||
cx, cy = cocos_to_image(pos, width, height)
|
||||
label = str(record.get("skin_name", record.get("id")))
|
||||
draw.rectangle([cx - 55, cy - 35, cx + 55, cy + 35], outline="#5c2d91", fill="#c7a5ff66", width=2)
|
||||
draw.text((cx - 48, cy - 8), label, fill="#2b1545")
|
||||
|
||||
for node in data["bottom_menu_nodes"]:
|
||||
draw_centered_rect(draw, node, (width, height), "#1f4f99", "#6fa8ff55")
|
||||
|
||||
draw.rectangle([0, 0, width - 1, height - 1], outline="#222222", width=2)
|
||||
draw.text((12, 12), "Stage1 diagnostic preview - source evidence only", fill="#111111")
|
||||
draw.text((12, 34), f"land candidates: {data['land_candidates']['source_count']} / visible 24 blocked", fill="#8a1f11")
|
||||
|
||||
OUT_DIR.mkdir(parents=True, exist_ok=True)
|
||||
png = OUT_DIR / "stage1_source_preview.png"
|
||||
report = OUT_DIR / "stage1_source_preview_report.json"
|
||||
img.save(png)
|
||||
report.write_text(json.dumps({
|
||||
"status": "generated",
|
||||
"image": str(png),
|
||||
"resolution": {"width": width, "height": height},
|
||||
"land_candidates_rendered": data["land_candidates"]["source_count"],
|
||||
"visible_land_selection": data["land_candidates"]["selection_status"],
|
||||
"note": "Diagnostic rendering only; it does not define final Cocos coordinates.",
|
||||
}, indent=2) + "\n", encoding="utf-8")
|
||||
print(png)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
50
tools/verify_cocos4_project.py
Normal file
50
tools/verify_cocos4_project.py
Normal file
@ -0,0 +1,50 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Verify the Cocos 4 project and record current toolchain status."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
PROJECT = Path(__file__).resolve().parents[1]
|
||||
|
||||
|
||||
def run(cmd: list[str]) -> dict[str, object]:
|
||||
proc = subprocess.run(cmd, cwd=PROJECT, text=True, capture_output=True)
|
||||
return {
|
||||
"cmd": cmd,
|
||||
"returncode": proc.returncode,
|
||||
"stdout_tail": proc.stdout[-4000:],
|
||||
"stderr_tail": proc.stderr[-4000:],
|
||||
}
|
||||
|
||||
|
||||
def main() -> None:
|
||||
package = json.loads((PROJECT / "package.json").read_text(encoding="utf-8"))
|
||||
checks = {
|
||||
"generated_at": datetime.now(timezone.utc).isoformat(),
|
||||
"package": {
|
||||
"type": package.get("type"),
|
||||
"version": package.get("version"),
|
||||
"creator_version": package.get("creator", {}).get("version"),
|
||||
},
|
||||
"cocos_version": run(["zsh", "-lc", "cocos --version"]),
|
||||
"node_abi": run(["zsh", "-lc", "~/.local/tools/node-v24.14.1-darwin-arm64/bin/node -p 'process.version + \" abi=\" + process.versions.modules'"]),
|
||||
"build": run(["zsh", "-lc", "rm -rf temp library build && cocos build --project . --platform web-mobile"]),
|
||||
}
|
||||
checks["status"] = "passed" if checks["build"]["returncode"] == 0 else "blocked"
|
||||
checks["blocker"] = None if checks["status"] == "passed" else "Cocos 4 alpha CLI native gl module expects NODE_MODULE_VERSION 140; local Node 24 reports ABI 137."
|
||||
|
||||
out = PROJECT / "artifacts/cocos_capture"
|
||||
out.mkdir(parents=True, exist_ok=True)
|
||||
path = out / "stage1_cocos_verify.json"
|
||||
path.write_text(json.dumps(checks, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
|
||||
print(path)
|
||||
raise SystemExit(0 if checks["status"] == "passed" else 1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Loading…
x
Reference in New Issue
Block a user