nodeCreate кладёт узел на слой DEFAULT, а камера Canvas рисует только UI_2D. Поэтому сборка показывала цвет очистки камеры и больше ничего. В редакторе это не видно вообще: камера вида сцены рисует все слои, так что сцена выглядит правильной, а билд — пустым. - 45 узлов в обеих сценах и префабе переведены на слой UI_2D - scripts/check-scenes.mjs: headless-проверка сцен и префабов — слои, наличие камеры у Canvas, видимость UI_2D у камеры, незаполненные ссылки в наших компонентах. Проверено, что она действительно падает на подсунутом неверном слое - npm run check — всё разом (чистота core, сцены, типы, тесты) - Bootstrap теперь докладывает каждый шаг в лейбл и в консоль и через 10 секунд уходит в лобби даже если арт не догрузился: молча висящий загрузчик — худший вид бага в отчёте - ловушка со слоями описана в docs/CODE_MODE_SETUP.md Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
5.8 KiB
Code Mode setup
The cocos-code-mode extension (in extensions/cocos-code-mode)
runs an HTTP server inside the Cocos Creator editor and exposes scene, asset and
inspector operations as UTCP tools. That is how the editor
is driven from outside the UI — see CODE_MODE_TOOLS.md for
the tool reference.
Prerequisites
- Cocos Creator 3.8.8 must be running with this project open. The tool server lives inside the editor process; if the editor is closed, there are no tools.
- The extension registers itself in
~/.utcp_config.jsonon startup.
The port changes on every editor restart
The server binds to 127.0.0.1 on an OS-assigned port, and rewrites
~/.utcp_config.json each time. Always read the config file rather than
remembering a port:
cat ~/.utcp_config.json
Running a tool chain
Pass the config path via UTCP_CONFIG_FILE. The script body runs as an async
function; tool calls look synchronous and return gives back the result.
UTCP_CONFIG_FILE="$USERPROFILE/.utcp_config.json" npx -y @utcp/code-mode-cli run <<'EOF'
const tree = CocosEditor.nodeGetTree({});
return { name: tree.name, children: (tree.children || []).map(c => c.name) };
EOF
Discover tools by task instead of guessing names:
UTCP_CONFIG_FILE="$USERPROFILE/.utcp_config.json" npx -y @utcp/code-mode-cli search "add a sprite to a node"
Working discipline
The tools are built around discover, then act:
nodeGetTree/assetGetTree— find the thing.inspectorGetInstanceDefinition— get its real TypeScript class.inspectorSetInstanceProperties— set properties by confirmed name.
inspectorSetInstanceProperties states it outright: if a property path or type
has not been confirmed via an inspectorGet* call, do not call a setter. Property
names differ from the engine docs often enough that guessing corrupts scenes.
Batch reads and writes into one run script — each npx invocation re-registers
the manual, which costs a few seconds.
Regenerating the tool reference
After updating the extension:
curl -s "$(node -p "require(require('os').homedir()+'/.utcp_config.json').manual_call_templates[0].url")" -o manual.json
node docs/scripts/gen-tool-reference.js manual.json docs/CODE_MODE_TOOLS.md
Known issue: sharp / libvips conflict on Windows
Symptom. The editor logs The plug-in main process failed to load with either
Could not load the "sharp" module using the win32-x64 runtime or
TypeError: Cannot read properties of undefined (reading 'output') at
node_modules/sharp/lib/utility.js. No ~/.utcp_config.json appears and no tools
are reachable.
Cause. Two things stacked:
- The released extension zip was packaged on macOS, so its bundled
sharpships onlydarwin-arm64binaries. - More fundamentally, Cocos Creator already has its own
sharp0.32.6 (libvips 8.14) resident in the same process. On Windows a second libvips cannot be loaded beside the first, so the extension'ssharp0.34.x binds against the editor's older DLL. That DLL has no JPEG 2000 support,format.jp2kcomes back undefined, and the module throws while initialising — taking the whole plugin with it.
Fix. asset-tools.js
now loads sharp lazily, prefers the editor's own resident build under
process.resourcesPath/app.asar.unpacked/node_modules/sharp, and tolerates it
being unavailable. sharp is only a fast path for assetGetPreview, which
already had a renderer-based fallback, so a missing image library no longer stops
the tool server from starting.
That file is tracked by git, so the fix survives — but re-importing the extension from a release zip will overwrite it. If the extension is ever re-imported, re-apply the patch and, on Windows, also install the matching native binaries:
cd extensions/cocos-code-mode && npm install --no-save --os=win32 --cpu=x64 --include=optional sharp@0.34.5
(extensions/cocos-code-mode/node_modules is gitignored, so that install does not
survive a clean checkout either.)
Known issue: the setter tools take arrays, not a single path
CODE_MODE_TOOLS.md is generated from the manual the
extension serves, and for inspectorSetInstanceProperties /
inspectorSetSettingsProperties that manual advertises a singular
propertyPath + value pair. The implementation actually loaded
(set-properties-tool.js)
expects parallel arrays, and the singular form fails with the unhelpful
Cannot read properties of undefined (reading 'length').
Use:
CocosEditor.inspectorSetSettingsProperties({
settingsType: 'ProjectSettings',
propertyPaths: ['general.designResolution.width', 'general.fitWidth'],
values: [1080, true],
});
Known issue: nodeCreate puts nodes on the wrong layer for UI
A node created with nodeCreate lands on the DEFAULT layer
(1073741824). A Canvas camera is normally set to render UI_2D
(33554432) only, so every node authored through the tools is invisible at
runtime — the camera draws its clear colour and nothing else, which looks like
the game has frozen on a blank coloured screen.
The editor's own "create node" menu assigns UI_2D, so this only bites automation, and nothing in the editor viewport reveals it: the scene-view camera renders every layer, so the scene looks perfectly fine while the build does not.
Always set the layer after creating a UI node:
const UI_2D = 33554432;
CocosEditor.inspectorSetInstanceProperties({
reference: newNode, propertyPaths: ['layer'], values: [UI_2D],
});
To check a whole scene, walk nodeGetTree and assert every node's layer.