Commit Graph
9 Commits
Author SHA1 Message Date
lennartandClaude Opus 5 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]>
2026-08-25 21:14:13 +02:00
lennartandClaude Opus 5 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]>
2026-08-25 21:01:27 +02:00
lennartandClaude Opus 5 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]>
2026-08-25 20:50:25 +02:00
lennartandClaude Opus 5 f1fadf7909 add a writer-facing content pipeline under writing/
Dialogue was already plain text, so the gap was never the .yarn files. It was
that the character material a writing session needs was either missing or stored
somewhere a writer could not comfortably work.

Three things were wrong. The writing handbook was not in the repo and was cited
by SC101.yarn as though it were. The best voice material — register, verbal tics,
success/failure/passive samples — was a \n-escaped string inside a JSON field.
The named NPCs had no sheets at all, existing only as their Yarn lines.

writing/ now holds the dialogue-facing layer, at the repo root so it gets no
.meta files and is not a Unity asset:

  STYLE.md          register, the five tone moves, the ban list, branching
                    shapes, the Wrong Truth rule, flag families, candidate rules
  YARN-PRIMER.md    the one page of syntax needed to write a scene
  GLOSSARY.md       in-world and project vocabulary
  voices/           the eleven skill voices, one readable sheet each
  characters/       Bartender, Chevalier Cassian Thal, Bradford Kane
  scenes/           SC-101's brief: intent, beats, checks, constraints
  lore/             the three identity readings and the rules that bind them

STYLE.md is a digest of the Mystery Writing Handbook in the Obsidian vault, with
pointers rather than copies. The vault stays the authoring home for design work,
and Ground Truth — the solution document — deliberately stays out of this repo.

The voice sheets are generated from skill_bible.json but are the source of truth
for the prose. tools/writing/sync_voices.py folds edits back; voicelib.py
guarantees notes -> dict -> notes is identity for all eleven, so --to-json on
unchanged sheets is byte-identical. VoiceSheetSyncTests fails the build on drift
in either direction, and was verified to fail on real drift rather than merely
to pass.

SC101.yarn's header is trimmed from prose rationale to the six rules that bind
while editing that file, with the reasoning moved to the scene brief.

EditMode 42/42. YarnCheck compiles 9 files / 35 nodes.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-25 20:23:42 +02:00
lennartandClaude Opus 5 6bf22f2d6e fix two wrong expectations in the locomotion math tests
Both were test bugs; MotionInputMath itself is correct.

WorldToCameraRelativeInput_Yaw90 expected +1 for the camera-relative x. A camera
yawed +90 degrees faces +X, so world +Z is to its left and the value is -1. The
conversion applies Quaternion.Euler(0, -cameraYaw, 0) and Unity's Y rotation is
clockwise viewed from above, so forward maps to -right. The round-trip test
already pinned this convention and passes precisely because of it.

ScreenDeltaToWorldPan compared Vector3 with Assert.AreEqual, which is exact.
-10f * 0.02f lands one ulp from the -0.2f literal, so a correct result failed a
comparison that printed as identical at two decimals. Now compared per component
with a tolerance.

EditMode suite is 39/39.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-25 19:50:25 +02:00
lennartandClaude Opus 5 932cd0582f add camera rig, click-to-move locomotion, and click interaction
Camera: Cinemachine-based rig with an anchor, a state director, point-of-
interest framing, pan input, and dialogue framing volumes.

Player: click-to-move over the NavMesh, a pointer input layer, and a motion
arbiter that reconciles direct stick input with navigation-driven movement.
The pure math is isolated in NightclubArcadia.Locomotion.Math with an EditMode
suite, so the arbitration rules are testable without a scene.

Interaction: IClickInteractable plus a bridge that routes pointer clicks to it.

Supporting project settings: adds the Cinemachine package, the Interactable and
Ground tags the raycasts depend on, and NavMesh agent dimensions matched to the
player capsule (radius 0.3, height 1.8, climb 0.25).

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-25 19:03:18 +02:00
lennart 57bc10ba79 updated Candidate System with Voice System 2026-08-15 13:25:04 +02:00
lennart 9e5c3277bf refactor the skill system to adhere to the lore handbook 2026-08-15 11:13:15 +02:00
lennart 063e94f6eb implemented skill system according to designdocuments 2026-08-15 08:09:29 +02:00