The game now starts from Bootstrap.unity, which additively loads Systems (the
dialogue runner, skills, UI layer, camera rig and the player) and then a level
(geometry, light, navmesh, reveal cameras). The level becomes the active scene so
new objects and lighting land there.
The player moved into Systems. It had been parented under Room_101 — under level
geometry — and it is persistent content, not level content. Moving it also
removes most of the cross-scene breakage on its own.
Unity nulls any serialized reference that crosses a scene boundary. Measured
rather than guessed: the pre-split scene was pulled from git and its null
references diffed against the split result. Exactly seven were lost — both NPCs'
dialogueRunner, dialogueUI and player, plus the reveal camera's tracking target.
A first naive audit reported 210, which turned out to be pre-existing Unity
defaults like Image.m_Material; the baseline diff is what separated the two.
Each of the seven now resolves at runtime. SceneServices.Resolve fills in a null
Inspector reference by searching the loaded scenes, keeping an assigned value if
there is one; CinemachineFollowsPlayer binds the reveal camera once the player
exists. Both follow the pattern already used by CameraFramingVolume and by
NPCStandIn's player lookup, rather than introducing a new one.
Assets/Tests/PlayMode is new, and it immediately paid for itself. BootstrapTests
loads Bootstrap and asserts the whole game comes up; on its first run it caught a
real bug the split had introduced. The player's NavMeshAgent lives in Systems
while the NavMesh is baked into the level, so during load the agent exists
off-mesh and ResetPath logs an error. ClickToMoveController now guards on
agent.isOnNavMesh rather than a bare null check. No EditMode test could have seen
that, because none of it has run yet.
Two of those checks reach their types by name through reflection: NPCStandIn and
the Cinematics namespace live in Assembly-CSharp, and an asmdef test assembly
cannot reference the predefined assemblies. Per-area asmdefs remove the need.
Build settings list all three scenes with Bootstrap at index 0, which
LoadSceneAsync by name requires.
EditMode 42/42, PlayMode 5/5, YarnCheck 9 files / 35 nodes.
Co-Authored-By: Claude Opus 5 <[email protected]>
The scene is now Assets/Scenes/Levels/SC101_ConferenceHall.unity, serialized as
TEXT: 101KB of YAML, diffable and mergeable for the first time.
Root cause of the binary problem, which four earlier approaches had failed to
fix: the NavMeshSurface on the Navigation root held its baked NavMeshData
*embedded in the scene* rather than as an asset. NavMeshData prefers binary
serialization, and one such object forces the whole scene file to binary
regardless of the project's Force Text setting — which is why toggling that
setting, re-saving, and saving to a new path all did nothing.
Bisecting the roots one at a time found it: thirteen roots each saved as text on
their own, Navigation did not. Extracting the data to
Scenes/Levels/SC101_ConferenceHall/NavMesh-Navigation.asset — which is what
baking from the NavMeshSurface inspector produces anyway — lets the scene
serialize as text. The embedded copy was the anomaly.
The scene was rebuilt rather than copied, because saving the binary scene to a
new path reproduces binary. All 14 roots were moved into a fresh scene and
verified: roots 14 -> 14, cross-root references 25 -> 25, zero missing scripts.
Render settings were carried across by hand, since they do not travel with
GameObjects.
Nothing is split yet — every object is still in one scene, so no reference
crosses a scene boundary. That split is the next step.
Also here: the four Editor setup menus no longer each hardcode the scene path;
they share NightclubArcadia.EditorTools.ScenePaths, which is what made renaming
the scene a four-file edit. Build settings point at the new scene, the URP
template leftovers (SampleScene, Readme.asset, TutorialInfo) are deleted, and
.gitattributes drops the binary exception that existed only for the old file.
EditMode 42/42, YarnCheck 9 files / 35 nodes.
Co-Authored-By: Claude Opus 5 <[email protected]>