Tracking issue for cli's engine-agnostic boundary
cli is structured around an explicit engine-agnostic / engine-scoped split:
| Location |
Intent |
src/command/, src/model/, src/logic/, src/middleware/ |
Engine-agnostic core |
src/command-options/unity-options.ts, src/logic/unity/, src/model/unity/, src/command/build/unity-build-command.ts |
Unity-scoped extensions |
src/command-options/android-options.ts |
Android-scoped (target platform within Unity) |
The intent is clean: adding support for a new engine (or removing Unity) should touch only the engine-scoped directories, never the core.
Current violations
Several files live in the engine-agnostic location but contain only Unity-specific code:
| File |
Violation |
src/model/platform-setup.ts |
The whole PlatformSetup class writes Unity's services-config.json and dispatches to Unity-specific Mac/Windows/Android setup modules. Should live in src/logic/unity/platform-setup/. |
src/model/image-environment-factory.ts |
Hardcodes UNITY_LICENSE, UNITY_LICENSE_FILE, UNITY_SERIAL, UNITY_LICENSING_SERVER env-var names. Should accept an engine-supplied env-var list. |
src/model/docker.ts |
Hardcodes --env UNITY_SERIAL in the docker invocation string. Should be engine-supplied. |
These were carried in unchanged from the unity-builder extraction; the boundary was set up correctly but the migration of files is incomplete.
Why this matters for adding fields
unity-builder#739 surfaced the cost: adding one Unity field today touches ~13 places across three repos. orchestrator#25 cleaned the boundary on the orchestrator side. The same cleanup is needed in cli, otherwise every new Unity field continues to be added to engine-agnostic locations and the boundary drifts further.
Phased plan
| Phase |
Scope |
PR |
| Phase 1 (this issue, scoped to PR #50) |
Move src/model/platform-setup.ts → src/logic/unity/platform-setup/. Single caller updated. Adding unityLicensingToolset lands in the correct (Unity-scoped) location. |
#50 |
| Phase 2 |
Refactor image-environment-factory.ts to accept engine-supplied env-var list. Engine modules register their secrets/env vars; the factory composes them generically. |
TBD |
| Phase 3 |
Refactor docker.ts so engine-specific --env flags come from the engine module, not hardcoded strings. |
TBD |
| Phase 4 (in the future per game-ci ecosystem plan) |
cli becomes the top-level entry, delegates Unity build runtime to unity-builder, dispatch to orchestrator. The engine-scoped Unity dirs in cli either retire or shrink to thin caller layers. |
far future |
Non-goals
- Inventing a "shared core package" between cli and unity-builder. Domain ownership is preferred — cli owns its own Unity-scoped logic; future migration to delegating-to-unity-builder is a separate project.
- Generalizing
cli to multi-engine NOW. The boundary cleanup makes adding a second engine possible; we don't need to actually add one.
Definition of done for Phase 1
Tracking issue for cli's engine-agnostic boundary
cli is structured around an explicit engine-agnostic / engine-scoped split:
src/command/,src/model/,src/logic/,src/middleware/src/command-options/unity-options.ts,src/logic/unity/,src/model/unity/,src/command/build/unity-build-command.tssrc/command-options/android-options.tsThe intent is clean: adding support for a new engine (or removing Unity) should touch only the engine-scoped directories, never the core.
Current violations
Several files live in the engine-agnostic location but contain only Unity-specific code:
src/model/platform-setup.tsPlatformSetupclass writes Unity'sservices-config.jsonand dispatches to Unity-specific Mac/Windows/Android setup modules. Should live insrc/logic/unity/platform-setup/.src/model/image-environment-factory.tsUNITY_LICENSE,UNITY_LICENSE_FILE,UNITY_SERIAL,UNITY_LICENSING_SERVERenv-var names. Should accept an engine-supplied env-var list.src/model/docker.ts--env UNITY_SERIALin the docker invocation string. Should be engine-supplied.These were carried in unchanged from the unity-builder extraction; the boundary was set up correctly but the migration of files is incomplete.
Why this matters for adding fields
unity-builder#739 surfaced the cost: adding one Unity field today touches ~13 places across three repos. orchestrator#25 cleaned the boundary on the orchestrator side. The same cleanup is needed in cli, otherwise every new Unity field continues to be added to engine-agnostic locations and the boundary drifts further.
Phased plan
src/model/platform-setup.ts→src/logic/unity/platform-setup/. Single caller updated. AddingunityLicensingToolsetlands in the correct (Unity-scoped) location.image-environment-factory.tsto accept engine-supplied env-var list. Engine modules register their secrets/env vars; the factory composes them generically.docker.tsso engine-specific--envflags come from the engine module, not hardcoded strings.Non-goals
clito multi-engine NOW. The boundary cleanup makes adding a second engine possible; we don't need to actually add one.Definition of done for Phase 1
src/logic/unity/platform-setup/.src/model/platform-setup.tseither deleted or reduced to a generic dispatcher that picks an engine module.unityLicensingToolsetinjection lives in the Unity-scoped location.