admin chat: sub-group expanded scenes by participant thread#185
Merged
Conversation
When the chronicler dispatches multiple attend_to calls (the common
case at arrival, shift-boundary, and buffered-flush cascades), each
attended villager's tick lands in the same scene_id as the
chronicler's perception. Pre-fix, the expanded-scene view rendered
all of those messages chronologically by sub-second sent_at, which
interleaved chronicler turns with each villager's turn:
12:01:42 engine → chronicler "perception..."
12:01:45 chronicler → engine [set_environment]
12:01:45 engine → chronicler [Atmosphere noted]
12:01:47 chronicler → engine [attend_to Prudence]
12:01:47 engine → chronicler [...attend...]
12:01:47 engine → Prudence "You are Prudence Ward..."
12:01:50 chronicler → engine [attend_to Josiah]
12:01:50 engine → chronicler [...attend...]
12:01:50 engine → Josiah "You are Josiah Thorne..."
12:01:53 prudence → engine [move_to PW Apothecary]
12:01:53 engine → prudence [OK]
12:01:55 josiah → engine [consume]
... etc
Reads as a jumble — eyes can't track which villager is doing what
without scanning timestamps and From/To columns line by line.
Sub-group within each scene by the non-engine participant:
Scene 019dfcf3-… · 4 participants · 18 messages
├── salem-chronicler · 5
│ ├── 12:01:42 engine → chronicler perception
│ ├── 12:01:45 chronicler → engine [set_environment]
│ └── ...
├── zbbs-prudence-ward · 4
│ ├── 12:01:47 engine → Prudence "You are Prudence..."
│ └── ...
└── zbbs-josiah-thorne · 4
├── 12:01:50 engine → Josiah "You are Josiah..."
└── ...
Each thread renders chronologically internally; threads are ordered
by their first message so the chronicler's perception (which always
opens a cascade) sits first, then each villager in the order
attended. salem-engine is always one endpoint in Salem flows, so the
"non-engine participant" picks out the thread cleanly. Fallback for
the rare PC-to-NPC speech with no engine in the pair: sorted "from
↔ to" pair, so direction-flipped rows still group together.
Source-only change; deploy rebuilds the SPA bundle via
infrastructure/roles/memory-api/tasks/main.yml.
— Home
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
When the chronicler dispatches `attend_to` to multiple villagers, all attended NPCs' ticks share the chronicler's `scene_id`. The pre-fix expanded-scene view rendered every row chronologically by sub-second `sent_at`, interleaving chronicler turns with multiple villagers' turns into a jumble.
This sub-groups within each scene by the non-engine participant, producing one thread per villager (and one for the chronicler) ordered by first-message time.
Why this approach
Jeff flagged the readability issue this morning and weighed display-fix vs pacing-fix; he greenlit the display fix. Pacing would have been an engine change with no game-side benefit, just a viewer-side workaround.
`salem-engine` is always one endpoint in Salem flows, so "non-engine participant" identifies the thread cleanly. Fallback to a sorted `from ↔ to` pair handles the rare case where neither side is the engine (PC-to-NPC speech).
Test plan
— Home
🤖 Generated with Claude Code