Skip to content

t1k:cocos:playable:submodule-to-package

FieldValue
Moduleplayable
Version0.15.0
Effortmedium
Tools

Keywords: cocos, game-foundation, migration, package, parameter-tool, playable, playablelabs, submodule, vendored

/t1k:cocos:playable:submodule-to-package
[--verify-only]

Submodule → @playablelabs Package Migration

Section titled “Submodule → @playablelabs Package Migration”

Convert a Cocos 3.8.7 playable from the PLAGameFoundation / PlayableParamterTool git submodules to the vendored @playablelabs/game-foundation and @playablelabs/parameter-tool packages under assets/packages/.

IntentPath
Full migration (submodules still present)Run Migration steps 1→7
Packages already vendored, just check for bugs--verify-onlyStep 7 only
A toast/tutorial/layout call throws ReferenceError: X is not definedGotcha 1 → run the verifier, patch the flagged file

The .ts / .core.ts / .core.impl.ts triplet in each vendored package is generated at publish time by the cocos-package-manager editor extension (split + obfuscate) — it is NOT how the source repo looks (upstream is a single monolithic .ts). That obfuscator has a defect (Gotcha 1) and several call-site APIs changed between the submodule and the package (Step 4). Both must be handled or the game silently fails to start / throws at runtime.

Drop both [submodule …] blocks from .gitmodules (keep ConfigPath, optimize-size), then git rm --cached the two submodule paths (assets/PLAGameFoundation, assets/PlayableParamterTool). Remove their VCS root mappings from .idea/vcs.xml if present.

Place the published packages under assets/packages/@playablelabs/game-foundation/ and .../parameter-tool/ (with their .meta files). These carry the generated .core.impl.ts split form.

In <project>/package.json, add both to playableSync[]:

"playableSync": ["@playablelabs/warning", "@playablelabs/parameter-tool", "@playablelabs/game-foundation"]

Step 4 — Repoint imports + apply API changes

Section titled “Step 4 — Repoint imports + apply API changes”

Rewrite every db://assets/PLAGameFoundation/…db://assets/packages/@playablelabs/game-foundation/… and db://assets/PlayableParamterTool/…db://assets/packages/@playablelabs/parameter-tool/…. Then apply the known signature changes — these are not path-only:

Call siteChange
ParameterUtilsParameterReplacedAssetsHandler moved to assetParameterUtils/
PlayableConfig TableParameternow takes category after minItems/maxItems
VirtualJoystick TouchEndSignalnow requires (worldPosition, uiPosition)
ParameterControllergetTextureFromBase64 now resolves null (was: never resolves). Guard the null — an unguarded null yields a textureless SpriteFrame that throws in SpriteFrame.getHash
ParameterManagerparameter-tool is now standalone and no longer imports game-foundation. You MUST ParameterToolRuntime.register(SignalBus, AudioService) — without these seams it no-ops silently, ParametersReadySignal never reaches the bus, and the game flow never starts

Step 5 — Remap scene/prefab script uuids

Section titled “Step 5 — Remap scene/prefab script uuids”

The submodule scripts and the package scripts have different meta uuids. In MainScene.scene (and any prefab referencing a foundation component, e.g. AudioEmitter.prefab), remap __type__ / _componentId / __uuid__ from the old submodule-script uuid to the package-script uuid. Missing this = component silently detaches in the editor. Do this in the Cocos editor (drag-reassign) or by matching each old uuid to the new .ts.meta uuid.

Delete any .meta whose prefab no longer exists after the swap.

Run the splitter-defect scanner (also the entry point for --verify-only):

Terminal window
node "$HOME/.claude/skills/t1k-cocos-playable-submodule-to-package/scripts/scan-missing-sibling-imports.cjs" \
<project>/assets/packages/@playablelabs/game-foundation \
<project>/assets/packages/@playablelabs/parameter-tool

For each DEFECT: line, add the printed import { … } from './<Sibling>'; to that .core.impl.ts. Exit 0 = clean. Then open the project in the Cocos editor and confirm LOADING→FTUE→GAMEPLAY runs (the ParameterToolRuntime seams from Step 4 are what let the flow start).

  • Obfuscator drops enum sibling imports (the ReferenceError class). The publish-time obfuscator is the Cocos editor extension The1Studio/cocos-package-manager (ComponentExtractService), which extracts an @ccclass component’s method bodies into an obfuscated .core.impl sibling. Its topLevelLocalNames() gate — the set of module-scope declarations that keep a referencing method in the readable wrapper — enumerated const/let/var/function/class but omitted enum. So a method referencing a co-located enum got extracted anyway, leaving the enum a free identifier with no importReferenceError the instant that path fires (e.g. ToastPosition in ToastController on every toast; AspectFitMode, AspectRatioCategory, FingerAction on colder paths). // @ts-nocheck hides it from tsc. Root cause is in cocos-package-manager, NOT PLAGameFoundation (its source is a correct monolith) and NOT UPMAutoPublisher (that publishes to a different registry and does not obfuscate). Fixed in cocos-package-manager PR #10 (enums added to the gate). Until that ships and packages are republished, patch the vendored copy as a stopgap — a npm update @playablelabs/* reverts it — running the Step 7 scanner after any package update and re-patching with the same one-liner: append import{X}from'./<Sibling>'; after the existing from'cc'; import.
  • .core.impl.ts files trip the descriptive-name Edit/Write hook. Their PascalCase.core.impl.ts names are rejected by the naming hook on Edit/Write. Patch them with a Node fs one-liner via Bash (the hook only guards Edit/Write), or in the editor.
  • The bug is invisible to type-checking. Every .core.impl.ts carries // @ts-nocheck, so tsc / t1k-cocos-base-tsc-validate will NOT catch the missing import. Only runtime execution (or this scanner) does.
  • Do not confuse with t1k-cocos-base-migrate. That skill is the Cocos 2.4.15 JS→TS pipeline. This skill is Cocos 3.8.7 submodule→package and shares no code.