main
10
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
9a0618fd31 |
replace the NPC scaffold with data-driven prefabs, and retire the builders
NPCStandIn was written to be dropped on a sphere and carried its identity in per-instance public fields. The cost of that showed up in the scene itself: of the two spheres, one was the Bartender and the other was named "Bartender (1)" in the hierarchy while being configured as the Chair — data changed, name never was. Nothing outside the scene could see what existed, and two copies could disagree. Identity now lives in an InteractableDefinition asset and the scene only places a prefab. The migration matched the old objects by yarn node rather than by name, which is the only reason the chair ended up as the chair. InteractableDefinition rather than the planned "character definition": it covers a character and a talkable object equally, so Bartender.prefab sits under Prefabs/Characters and Chair.prefab under Prefabs/Interactables. Three components collapse into one. DialogueInteractable was in no scene at all — a dead trigger-zone variant of the same idea. ClickInteractableBridge existed only to adapt NPCStandIn without modifying it, a constraint that died with NPCStandIn; DialogueInteractor implements IClickInteractable itself. The parts worth keeping were lifted out rather than discarded: WorldSpaceLabel and InteractionPrompt are now normal components on prefab children, so a label can be seen and positioned in the Editor instead of existing only at runtime. InputDeviceTracker moved into NightclubArcadia.Core and gained a namespace, leaving no global-namespace runtime types. Characters get the same pipeline as Skills and Candidates: Assets/Characters/characters.json is the source of truth, CharacterSetup regenerates the definition assets on script reload and removes orphans. Adding an NPC is a JSON entry plus a prefab — no code, and no Unity for the data half. Phase 5.4 deletes the one-shot builders rather than disabling them. UILayerSetup, PlayerControlSetup, UILayerSetupAutoRun and YarnDemoSetup assumed the single-scene layout, had already destroyed a level scene and turned Systems binary once each, and after NPCStandIn went they no longer compiled. The prefabs they used to generate are authored and committed; the wiring knowledge is in those prefabs and in git history. The asset generators — Skill, Candidate, Character — are untouched and still work. EditMode 42/42, PlayMode 7/7, YarnCheck 9 files / 35 nodes. All three scenes still text. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
ec4619d9dc |
resolve cross-scene dependencies at the point of use, not in Awake
Fixes "[SceneServices] Bartender: could not resolve dialogueRunner". Resolving a cross-scene dependency in Awake is a race by construction. The dialogue runner lives in Systems; an NPC lives in the level. Open the level on its own, or let the scenes load in the other order, and the NPC wakes with no Systems scene in sight. Worse, the failed lookup was cached into the serialized field, so it stayed broken for the rest of the session rather than recovering once Systems appeared. NPCStandIn and DialogueInteractable now resolve lazily through a property and cache only a successful result, so any load order works. Awake still does a silent best-effort pass, which keeps the common case free. SceneServices splits in two accordingly. TryResolve is silent and is what speculative callers use; Resolve logs an error and belongs only where the dependency is genuinely required. Both now include inactive objects — a system parked inactive is still the object we mean, and excluding it reported "not found" for something sitting in the hierarchy. The error text now says where the runner lives and how to open the scenes, instead of asking a question. BootstrapTests only ever covered the happy order, which is why it stayed green while this was broken. SceneOrderTests loads the level BEFORE Systems and holds that NPCs still reach the runner. It also asserts it is reproducing the race — it counts the NPCs whose Awake-time resolution failed and fails if that is zero, so the test cannot quietly start passing for the wrong reason. It currently reports 2 of 2, which is the bug this commit fixes. EditMode 42/42, PlayMode 7/7, YarnCheck 9 files / 35 nodes. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
2a20bd68fe |
add an Open Game Scenes menu, and fix the Editor-lock check
The scenes were never destroyed. Pressing Play with only Bootstrap open means GameBootstrap loads Systems and the level at runtime, and Unity discards runtime-loaded scenes when Play ends, restoring whatever the Editor had open — Bootstrap alone. The Hierarchy comes back nearly empty. Every scene file was byte-identical to HEAD throughout, still text. Tools > Nightclub Arcadia > Open Game Scenes opens all three with the level active, which is the authoring setup. With them already open, GameBootstrap's LoadIfNeeded skips them and they survive Play. GameSceneWorkflow also captures the scene setup before Play and restores it afterwards as a safety net, skipping the restore when Unity already got it right and ignoring scenes deleted meanwhile — an exception in that callback would leave the Editor in a worse state than the problem it fixes. Toggleable under the same menu. Also fixes `make lock`, which had a self-matching bug since Phase 1: `pgrep -f` on the full binary path matched the very shell running the check, because the pattern appears in its own command line. It reported the Editor as running when nothing was, and would have blocked every make test/build once anything else matched. Now `pgrep -x Unity`, which matches the process name and cannot match the shell. EditMode 42/42, PlayMode 6/6, YarnCheck 9 files / 35 nodes. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
4f48d258b5 |
disable the pre-split scene builders instead of retargeting them
Fixes the "no Yarn Project has been configured" error coming back after running the setup menus. Last commit fixed the wrong layer. Retargeting YarnDemoSetup at a sandbox stopped it destroying the level, but left the deeper problem: all of these builders assume the single-scene layout, and after the split there is no target path that makes them correct. Two failures, both observed rather than reasoned about. Running the Yarn setup left a generated scene open whose DialogueRunner had no project and auto-started — that is the error the user kept seeing, coming from Dev/YarnSandbox.unity, not from Systems. And retargeting the other three at Systems made PlayerControlSetup pull navigation in with it; the baked NavMeshData is embedded rather than an asset, so Systems.unity silently turned binary, 61KB text to 109KB binary. That is trap 1 recurring on a scene that had just been fixed. So the three scene builders now return early through LegacySceneSetup.Blocked, with a message saying what they would have done and what to do instead. They are not deleted: UILayerSetup alone is 818 lines that still record how the UI layer is wired, and that record matters until prefabs replace it in Phase 5. Set Up Skill System keeps its useful half. It regenerates the SkillDefinition assets from JSON, which touches no scene; only the WireWorkingLevelScene call is dropped, because those objects already exist in Systems.unity. Set Up Candidate System was always asset-only and is untouched. While diagnosing, YarnDemoSetup's own bug was found and fixed even though the menu is now blocked: it set yarnProject through a SerializedObject on a prefab instance without recording the override, so the assignment was dropped on save. It now records the modification and refuses to save a scene whose runner has no project. Verified by running all five menus headlessly: the two asset generators run and produce no diff, the three builders refuse, and no scene or asset changes. Systems.unity restored to text, the level scene intact at 5 roots. EditMode 42/42, PlayMode 6/6, YarnCheck 9 files / 35 nodes. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
46160d86dc |
stop the Yarn setup menu from overwriting a real scene
Fixes "Can't start dialogue: no Yarn Project has been configured." Cause, and it was mine. Phase 3.7 said "retarget YarnDemoSetup.cs or retire it"; I retargeted it. But that menu does not modify a scene — it builds one from scratch and calls SaveScene over its target. Pointing it at SC101_ConferenceHall.unity armed it at the real level, and running it replaced the scene with a bare Yarn demo: ten of fourteen roots gone, including the player, the lighting and the navmesh. The leftover Dialogue System prefab instance it left behind had no yarnProject override, auto-started, and produced the error. The scene was committed, so nothing was lost; it is restored from HEAD at 14 roots with its sun reference intact. The menu now targets Assets/Scenes/Dev/YarnSandbox.unity and refuses to run if its target is not under Scenes/Dev, via ScenePaths.IsDisposable. It is renamed to "Set Up Yarn Sandbox Scene" so the menu says what it does. The other three setup menus open and modify their target rather than regenerating it, so they were never affected and are unchanged. The test suite could not have caught this, because it asserted only that a DialogueRunner existed. TheDialogueRunner_HasItsYarnProject now asserts there is exactly one runner across the loaded scenes and that its project is set and compiled — which reproduces the failure exactly when the scene is broken. Also here: four UI prefabs pick up m_EditorClassIdentifier changes from Assembly-CSharp to NightclubArcadia.Game, written by Unity after the assembly split in the previous commit. Expected and correct. EditMode 42/42, PlayMode 6/6, YarnCheck 9 files / 35 nodes. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
bb0f2b760c |
give the runtime code assemblies, a build entry point, and fix two names
No project code is in Assembly-CSharp any more. Five assemblies: Core (no dependencies), Locomotion.Math, Skills, Game (everything else under Scripts), and StarterAssets. Game is one assembly rather than one per area, which is what the plan assumed. Measuring the dependency graph first found three cycles, all through UI — CharacterPanelView reaches into Dialogue, PlayerControlLock into Player, and UILayerBootstrap into Cinematics — plus two edges a using-scan cannot see, because NPCStandIn is in the global namespace. Assemblies cannot be circular, so splitting further means relocating those three files. That is a code-movement task, not an asmdef task, and nothing needs it yet. StarterAssets had to get an assembly of its own. It had none, so it lived in Assembly-CSharp, and an asmdef assembly cannot reference the predefined assemblies — four runtime files use it, and all four would have stopped compiling. The payoff is immediate: BootstrapTests no longer needs reflection to reach NPCStandIn and CinemachineFollowsPlayer, which is exactly why Phase 3 wanted this. Assets/Editor/PlayerBuild.cs is the headless build entry point. It reads the enabled scenes, asserts Bootstrap is scene 0 because the player opens scene 0 on launch, honours the -buildOutput the CLI forwards from -o, and calls EditorApplication.Exit(1) on anything short of Succeeded — without which Unity exits 0 on a build that produced nothing and CI goes green on it. Verified end to end: a 172MB .app in about two minutes. Two renames, both different from what the plan described. DialougueSkillComparison.cs contains a class called SkillFunctions — the filename never matched the type, so it is now SkillFunctions.cs. The two .yarn files with spaces in their names lost the spaces rather than becoming kebab-case, which would have made them inconsistent with Bartender.yarn and SC101.yarn; spaces were the actual problem. Both renames preserved their .meta GUIDs, and the yarnproject graph keys and the two character sheets were updated. EditMode 42/42, PlayMode 5/5, YarnCheck 9 files / 35 nodes, make build green. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
40b4547c71 |
split the scene into Bootstrap, Systems and Level
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]> |
||
|
|
f5b302b3e3 |
add a Makefile for the common commands, and a test reporter
The invocations in CLAUDE.md were correct but long, and retyping them is how flags get dropped. `make check` is the gate a change should pass: Yarn compiles, voice sheets are in sync, EditMode is green. `make test` and `make build` depend on a `lock` target that fails if the Editor has the project open, which removes the most common confusing failure. It filters out AssetImportWorker children, which are not a second Editor. tools/ci/report_tests.py parses the NUnit results and exits non-zero on failure, because Unity documents no common exit-code definition across the components under test — the XML is the authority, not $?. `make merge-driver` configures UnityYAMLMerge for the .gitattributes rules added earlier. Note the binary lives in the Editor bundle under Contents/Helpers, not Contents/Tools as most guides say; there is no Tools directory in Unity 6 on macOS. Also ignores the local .test-results/ and build/ output. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
ed28763017 |
document the writing pipeline and record Phase 2
CLAUDE.md gains the writing/ layout, the voice-sheet pipeline and its direction of truth, the sync commands, and a pointer that Ground Truth must never be copied into this repo. The writer-owned/code-owned table now covers writing/. The restructure plan records Phase 2 as executed, and closes its first open question: the writing handbook does exist, in the Obsidian vault, so STYLE.md became a digest with pointers rather than the reconstruction the plan assumed. Also noted there: the vault's opening-scene spec records SC-101's tone check as BLOCKED on a one-page Voice Sheet that was never written. STYLE.md now holds that sheet with four fields explicitly unset. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
5da782d21b |
add agent reference and restructure plan
CLAUDE.md documents repository layout, the Unity command line, the dialogue content pipeline, validation, conventions, and known traps. AGENTS.md points at it for non-Claude agents. docs/restructure-plan.md covers both halves of the restructure: moving character and voice prose out of JSON string fields into a writer-facing writing/ tree, and migrating off the single-scene DialogueTest scaffold into Bootstrap/Systems/Level scenes. Phase 0 is recorded as executed; everything from Phase 1 on is proposal. Two findings in it were corrected after first being got wrong: the Unity CLI is installed (just not on PATH for non-interactive shells) and does have build and test commands, and the binary scene is not a stale save but a standing Unity behaviour where Force Text converts only when the setting changes. Co-Authored-By: Claude Opus 5 <[email protected]> |