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]>
67 lines
2.9 KiB
Makefile
67 lines
2.9 KiB
Makefile
# Nightclub Arcadia — common commands.
|
|
#
|
|
# Everything here is documented in CLAUDE.md; this file exists so the exact
|
|
# invocations live in one place instead of being retyped from memory.
|
|
|
|
UNITY_CLI ?= /Users/lennart/.unity/bin/unity
|
|
UNITY ?= /Applications/Unity/Hub/Editor/6000.5.8f1/Unity.app/Contents/MacOS/Unity
|
|
PROJECT ?= $(CURDIR)/NightclubArcadia
|
|
RESULTS ?= $(CURDIR)/.test-results
|
|
SMARTMERGE ?= /Applications/Unity/Hub/Editor/6000.5.8f1/Unity.app/Contents/Helpers/UnityYAMLMerge
|
|
|
|
.DEFAULT_GOAL := help
|
|
|
|
.PHONY: help check yarn yarn-play voices voices-sync test test-play build lock clean-results merge-driver
|
|
|
|
help: ## Show this help
|
|
@grep -hE '^[a-z-]+:.*?## ' $(MAKEFILE_LIST) \
|
|
| awk 'BEGIN {FS = ":.*?## "} {printf " \033[36m%-14s\033[0m %s\n", $$1, $$2}'
|
|
@echo ""
|
|
@echo " Unity must be CLOSED for test/build — run 'make lock' to check."
|
|
|
|
check: yarn voices test test-play ## Everything a change should pass before commit
|
|
|
|
yarn: ## Compile every Yarn script (seconds, no Unity)
|
|
@cd tools/YarnCheck && DOTNET_CLI_TELEMETRY_OPTOUT=1 dotnet run -- ../../NightclubArcadia/Assets/Dialogue
|
|
|
|
yarn-play: ## Play a node: make yarn-play NODE=Bartender_Talk PICKS="2 2 0 0"
|
|
@cd tools/YarnCheck && DOTNET_CLI_TELEMETRY_OPTOUT=1 \
|
|
dotnet run -- ../../NightclubArcadia/Assets/Dialogue $(NODE) $(PICKS)
|
|
|
|
voices: ## Check writing/voices/*.md against skill_bible.json
|
|
@python3 tools/writing/sync_voices.py --check
|
|
|
|
voices-sync: ## Fold edited voice prose into skill_bible.json
|
|
@python3 tools/writing/sync_voices.py --to-json
|
|
|
|
test: lock ## Run the EditMode suite
|
|
@mkdir -p $(RESULTS)
|
|
@$(UNITY_CLI) test $(PROJECT) --no-banner --mode EditMode \
|
|
--output $(RESULTS)/editmode.xml --timeout 900 || true
|
|
@python3 tools/ci/report_tests.py $(RESULTS)/editmode.xml
|
|
|
|
test-play: lock ## Run the PlayMode suite (bootstrap + scene split)
|
|
@mkdir -p $(RESULTS)
|
|
@$(UNITY_CLI) test $(PROJECT) --no-banner --mode PlayMode \
|
|
--output $(RESULTS)/playmode.xml --timeout 900 || true
|
|
@python3 tools/ci/report_tests.py $(RESULTS)/playmode.xml
|
|
|
|
build: lock ## Build a macOS player into build/
|
|
@$(UNITY_CLI) build $(PROJECT) --no-banner --target StandaloneOSX -o $(CURDIR)/build/NightclubArcadia.app
|
|
|
|
lock: ## Fail if the Unity Editor has the project open
|
|
@if pgrep -fl "Unity.app/Contents/MacOS/Unity" | grep -v AssetImportWorker | grep -q .; then \
|
|
echo "The Unity Editor is running — close it first (only one instance per project)."; \
|
|
exit 1; \
|
|
fi
|
|
|
|
merge-driver: ## One-time: teach git to merge Unity YAML with UnityYAMLMerge
|
|
@test -x "$(SMARTMERGE)" || { echo "UnityYAMLMerge not found at $(SMARTMERGE)"; exit 1; }
|
|
@git config merge.unityyamlmerge.name "Unity SmartMerge"
|
|
@git config merge.unityyamlmerge.driver "'$(SMARTMERGE)' merge -p --force --fallback none %O %B %A %A"
|
|
@git config merge.unityyamlmerge.recursive binary
|
|
@echo "configured: $$(git config merge.unityyamlmerge.name)"
|
|
|
|
clean-results: ## Remove local test results
|
|
@rm -rf $(RESULTS)
|