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]>
89 lines
4.1 KiB
Markdown
89 lines
4.1 KiB
Markdown
---
|
|
id: chevalier-cassian-thal
|
|
name: Chevalier Cassian Thal
|
|
chr: —
|
|
yarn_file: Assets/Dialogue/Characters/ChevalierCassianThal.yarn
|
|
status: drafted
|
|
scenes: [SC101]
|
|
---
|
|
|
|
# Chevalier Cassian Thal
|
|
|
|
## Who they are
|
|
|
|
A knight, of Basel and Cyprus, seated at the table nearer the head than the protagonist is. He
|
|
introduces himself with a bow and a half-open fist to the forehead — an old form, performed
|
|
without irony. Old money, and comfortable in it. He is here as part of something ("the Knight's
|
|
compromise", "our friends of the Vaselian Concordat") and he speaks about it as though everyone
|
|
at the table already knows, because in his world everyone does.
|
|
|
|
He is the scene's mirror: whatever the protagonist has been leaning toward, he names it back at
|
|
them, gently, and waits. He is rarely wrong in matters like these, as he will tell you.
|
|
|
|
## How they speak
|
|
|
|
Courteous, archaic, warm. Slightly too familiar too quickly — "old chap", "my boy" — which reads
|
|
as class rather than affection. He uses `{$player_name_full}`, the formal form, when he is being
|
|
precise. He laughs easily and often, including at things that are not jokes.
|
|
|
|
## Verbal tics
|
|
|
|
1. Slips into the institutional "we" and "us" without noticing, then does not correct it.
|
|
2. Deflects with courtesy rather than refusal — "I am of no right to reveal this."
|
|
|
|
## What they never say or do
|
|
|
|
He never threatens and never withholds coldly; every evasion is dressed as politeness. He does
|
|
not name the Concordat's business outright, and he never breaks the fiction that the protagonist
|
|
already belongs at this table.
|
|
|
|
## What they know
|
|
|
|
| They know | True? | Reveals when | Records |
|
|
|---|---|---|---|
|
|
| He is of Basel and Cyprus | true | on introduction | `$spoke_to_chevalier_cassian_thal` |
|
|
| Cyprus connects to something he won't name | true | `<<check provenance Hard>>` succeeds, then the player inquires | `$inquired_about_cyprus` |
|
|
| Mr. Doss can explain the Cyprus connection | believed | on inquiring about Cyprus | `$looking_for_doss` |
|
|
| Something is about to happen at the table | true | after the protagonist declares a reading | `$declared_candidate_to_chevalier_cassian_thal` |
|
|
|
|
## What they are wrong about
|
|
|
|
He is certain he knows what the protagonist is. He is working from whatever the protagonist has
|
|
been projecting — which is to say from the lean, which is belief rather than truth. His
|
|
confidence is sincere and is not evidence. When he says "I am rarely wrong in matters like
|
|
these", that is characterisation, not a hint from the author.
|
|
|
|
## Their read on the protagonist
|
|
|
|
He is the game's first mirror mechanic. `SC101_Asks_Candidate_Chevalier_Cassian_Thal_Talk`
|
|
computes `top_skill(...)` over the three leans and asks the matching question:
|
|
|
|
| Leading reading | What he asks |
|
|
|---|---|
|
|
| Made Asset | whether they observe on behalf of the Vaselian Concordat |
|
|
| Journalist | whether he will read his answers in tomorrow's paper |
|
|
| Inheritor | whether they are here to settle a parent's debts |
|
|
|
|
Agreeing reinforces that lean. Denying adds to *both other* leans — a refusal is not neutral, it
|
|
is a push toward the alternatives. Denial routes to `SC101_Deny_Candidate`, which recomputes the
|
|
winner and, if it has not changed, offers the player the chance to reverse; if it has changed,
|
|
he simply asks the new question. The player can be walked around this loop.
|
|
|
|
`made_asset` is passed first to `top_skill`, which returns its first argument on a tie — so an
|
|
even score reads as Made Asset. That bias is deliberate.
|
|
|
|
## One line that is 100% them
|
|
|
|
> "Well, then let us hope the ... others follow the Knight's compromise."
|
|
|
|
## Open threads
|
|
|
|
The Atlantean cross on the place card (`$saw_knights_atlantean_cross_on_place_card`, found via a
|
|
`Hard` PROVENANCE check) is never connected to him in dialogue, though he is a knight and the
|
|
symbol is a knight's. That connection is available and unwritten.
|
|
|
|
His faction, the Vaselian Concordat, and "the Knight's compromise" are named but not explained.
|
|
Before writing more of him, confirm his faction row against `[[Lorebook]]` §2 — the vault's
|
|
`[[Character Sheet Handbook]]` exists specifically because figures drifting from the faction
|
|
tables is a logged, repeated failure in this project.
|