feat(chat): retail text style — two-plane glyph outlines, authored SpewBox/chat styles
Campaign CH round 4, user-gate items 1+2. Root cause: retail ships a second (background) glyph atlas per font, dilated 2px on every side, plus two border-pixel scalars (Font.NumHorizontalBorderPixels/ NumVerticalBorderPixels) that acdream's font reader never read — so even the pre-existing outline parameter drew almost nothing once enabled. Landed together (either half alone is a no-op or a regression): - UiDatFont carries BorderX/BorderY from the DAT font resource. - UiRenderContext.DrawStringDat inflates the background blit's source and destination rect by that margin and restructures into retail's exact two-pass whole-string outline-then-fill model (UIElement_Text::DrawSelf), plus the 8-neighbour +-1px fallback for fonts with no background atlas. Corrects the stale "property 0xd" comment to the real ids, 0x21 (Outline) / 0x22 (OutlineColor). - LayoutDesc property 0x21/0x22 import (ElementInfo.Outline/ OutlineColor, LayoutImporter.ReadState, ElementReader.Merge/ ApplyCanonicalLegacyProjection, DatWidgetFactory.BuildText) so every authored-outline element across the DAT set is correct at once. - SpewBox: RetailFontId corrected from a round-3 heuristic (0x40000025) to the actually-authored 0x40000001 (18px bold serif), Outline=true set on the controller's UiText. Fill colour stays the user-gate-round-1-pinned yellow — font atlases are alpha-only (PFID_A8), so there is no baked shading that could explain the screenshot's gold as anything other than the outline itself. - Chat transcript: default fill now seeds from its authored ARGB(255,204,204,204) instead of an unrelated color-table slot (ChatTranscriptRenderer.BuildLines takes the transcript's own DefaultColor as a parameter); the 34-entry LogTextType table is untouched, and every existing CH1 conformance test stays green unmodified. Regenerated the committed chat_2100006f.json fixture from the real installed DAT, confirming end to end (not by missing-field default) that the transcript carries no outline. Tests: font-reader border fields + inflation math pinned against the real DAT font, two-pass draw ordering/tint/inflation via a new TextRenderer.DebugSpriteSegmentVerts test seam, property 0x21/0x22 import at both the ElementReader.Merge and StateDesc-property layers, SpewBox font/outline, and the chat default-shade seed with the color table proven untouched. Full Release suite: 12,610 passed / 4 skipped / 0 failed (AcDream.slnx, complete solution). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
5b54387b8e
commit
bcc34ee301
22 changed files with 1995 additions and 105 deletions
|
|
@ -52,15 +52,23 @@ shell is now CODE-COMPLETE. **User gate round 4 ran 2026-08-10 and found
|
|||
six findings; see "User gate — round 4" below.** Items 3 (user-visible
|
||||
`/help` meta-markers leaking into live output, closing #364) and 5 (the
|
||||
main window's 1/2/3/4 indicator buttons now toggle their floating window
|
||||
on click, per the user's retail memory) are fixed in this round's commit;
|
||||
item 4 passed with no action needed; items 1+2 (text-style findings) were
|
||||
under parallel read-only research this session, concurrent with this
|
||||
commit's item 3+5 work; item 6 is deferred to the settings track. Status
|
||||
stays CODE-COMPLETE pending the next user gate round (still needed for
|
||||
CH6a's own visual confirmation, CH6b's keybind/mirror/filter behavior,
|
||||
CH6c's focus-driven fade and Settings slider, round 3's fixes, round 4's
|
||||
item 3+5 fixes, and a final in-client visual pass on everything fixed so
|
||||
far).
|
||||
on click, per the user's retail memory) are fixed at `5b54387b`; item 4
|
||||
passed with no action needed; item 6 is deferred to the settings track.
|
||||
**Items 1+2 (text-style findings) landed CODE-COMPLETE this commit**, off
|
||||
the parallel read-only research agent's findings
|
||||
(`docs/research/2026-08-10-retail-ui-text-style.md`): the retail two-plane
|
||||
glyph-outline mechanism (background atlas inflated by the font's
|
||||
border-pixel margin, a bug that made "enable the outline flag" alone a
|
||||
visual no-op), property 0x21/0x22 import so every authored-outline element
|
||||
gets it for free, the SpewBox's authored font/size/outline (retired two of
|
||||
AP-178's four open sub-claims), and the chat transcript's authored
|
||||
default-fill seed (`ARGB(255,204,204,204)`, wired without touching the
|
||||
34-entry `LogTextType` color table). Status stays CODE-COMPLETE pending the
|
||||
next user gate round (still needed for CH6a's own visual confirmation,
|
||||
CH6b's keybind/mirror/filter behavior, CH6c's focus-driven fade and
|
||||
Settings slider, round 3's fixes, round 4's item 3+5 fixes, round 4's item
|
||||
1+2 text-style fixes, and a final in-client visual pass on everything fixed
|
||||
so far).
|
||||
|
||||
**Why now:** first track of the alpha-release program (chat is the most
|
||||
visible daily surface for the friend-alpha). User-directed 2026-08-09.
|
||||
|
|
@ -298,7 +306,8 @@ implementer per slice against a pinned contract (per
|
|||
| CH6c opacity | `a819687c` | 12,459 passed / 4 skipped / 0 failed | APPROVE-WITH-FIXES; fixed this commit — BLOCKER (out-of-box `DefaultOpacity` 0.5→1.0), AP-190 reworded + two new decomp-verified clauses (retail's per-tick ease, retail's entry-field-specific focus predicate), NITs (`UiElement.cs` stale comment, `WindowUnregistered` detach, post-Dispose `Set*` guards, `DrawString`/outline-pass alpha tests) | pending — needs the next connected round for visual confirmation (window fade on focus change, Settings slider live-apply) |
|
||||
| Goal-window #363/#367 interface-text seam | `09453eca` | 12,542 passed / 4 skipped / 0 failed | implementer-only, no subagent review this session (hard constraint) | pending — needs the next connected round to confirm the SpewBox now flashes for the reclassified refusals (see "Goal-window follow-up" below) |
|
||||
| Consolidated review — retail `/help` Detail extraction, seam wiring test | `f7a6f46b` | 12,553 passed / 4 skipped / 0 failed | APPROVE-WITH-FIXES; fixed this commit — SHOULD-FIX 1 (42 of 47 catalog leaf verbs given retail Detail_HelpType text, 4 confirmed-null, 1 honest UNVERIFIED, retiring the class doc's overclaim), SHOULD-FIX 2 (`ComposedChatViewModelWiresOnInterfaceTextToSpewBox` — the a5a7eb4f defect class had no test), SHOULD-FIX 3 (AP-113 RETIRED — Lifestone's and Marketplace's own bespoke bad-args refusal text recovered byte-exact), SHOULD-FIX 4 (register header's stale 0.5/1.0 sentence corrected), NITs (a)-(d) (`HeadlessDiagnosticWriter` instead of `Console.WriteLine`, bounded non-quiescent-pump liveness diagnostic, hydration test doc-comment contradiction, 0x26 fallback dispatches on its own `Type`) | pending — needs the next connected round to confirm `/help <verb>` now shows retail's exact wording (see "Consolidated review" below) |
|
||||
| User gate round 4 — items 3+5 (no meta text, indicator click-toggle) | this commit | 12,579 passed / 4 skipped / 0 failed | implementer-only, no subagent review this session (hard constraint) | pending — needs the next connected round to confirm `/help channels`/`chatting`/`commands`/`messagetypes` show complete retail text and clicking each indicator button toggles its floating window (see "User gate — round 4" below) |
|
||||
| User gate round 4 — items 3+5 (no meta text, indicator click-toggle) | `5b54387b` | 12,579 passed / 4 skipped / 0 failed | implementer-only, no subagent review this session (hard constraint) | pending — needs the next connected round to confirm `/help channels`/`chatting`/`commands`/`messagetypes` show complete retail text and clicking each indicator button toggles its floating window (see "User gate — round 4" below) |
|
||||
| User gate round 4 — items 1+2 (retail two-plane glyph outline, authored SpewBox/chat styles) | this commit | 12,610 passed / 4 skipped / 0 failed | implementer-only, no subagent review this session (hard constraint) | pending — needs the next connected round to confirm the SpewBox's heavy black border and the chat transcript's softer default shade (see "User gate round 4, items 1+2" below) |
|
||||
|
||||
### CH4 closeout (2026-08-09)
|
||||
|
||||
|
|
@ -1085,13 +1094,17 @@ SpewBox.
|
|||
|
||||
The user tested the goal-window build live and reported six findings. A
|
||||
parallel read-only research agent investigated items 1+2 (text-style
|
||||
presentation) concurrently with this session's items 3+5 fix work; this
|
||||
session owned all builds/commits (hard constraint: one commit).
|
||||
presentation) concurrently with the session that fixed items 3+5
|
||||
(`5b54387b`); that session owned its own build/commit (hard constraint:
|
||||
one commit). Items 1+2 landed CODE-COMPLETE in a separate follow-up
|
||||
session/commit off the research agent's findings
|
||||
(`docs/research/2026-08-10-retail-ui-text-style.md`) — see the dispositions
|
||||
below and the new ledger row.
|
||||
|
||||
| # | User finding (condensed) | Disposition |
|
||||
|---|---|---|
|
||||
| 1 | Text-style/presentation finding under the on-screen interface-text and/or `/help` surfaces. | **Research in flight** — a parallel read-only research agent investigated this concurrently with items 3+5; not fixed in this commit. Follow up in the next session once its findings land. |
|
||||
| 2 | A second text-style/presentation finding, same surface family as item 1. | **Research in flight** — same parallel agent as item 1. |
|
||||
| 1 | Both the chat-window transcript text AND the on-screen SpewBox text differ from retail in face, size, and colour shade. | **FIXED in the round-4 items-1+2 follow-up commit** (see the new ledger row below — a separate commit from items 3+5's `5b54387b`, per this session's one-parallel-agent/one-commit-per-session-slice pattern). Face/size for BOTH surfaces resolve to the actual authored fonts (chat: `0x40000000`/16px, already correct; SpewBox: `0x40000001`/18px, corrected from a round-3 heuristic). The transcript's default fill now seeds from its authored `ARGB(255,204,204,204)` instead of an unrelated color-table slot, without touching the 34-entry `LogTextType` table. See `docs/research/2026-08-10-retail-ui-text-style.md` §5. |
|
||||
| 2 | Retail's SpewBox text carries a heavy black border around every glyph that acdream's does not. | **FIXED in the same round-4 items-1+2 follow-up commit as item 1.** Root cause: retail ships a SECOND ("background") glyph atlas per font, dilated 2px on every side, plus two border-pixel scalars (`NumHorizontalBorderPixels`/`NumVerticalBorderPixels`) that acdream's font reader dropped entirely (zero repo hits for `BorderPixel` before this fix) — so even the pre-existing `outline` parameter drew almost nothing once enabled. Both the missing border-pixel read AND the un-inflated background blit rect are fixed together (either alone is a no-op), `UiRenderContext.DrawStringDat` now runs retail's exact two-pass whole-string outline-then-fill model, and property 0x21/0x22 (Outline/OutlineColor) import onto every DAT-authored text element — not just the SpewBox — so this class of bug cannot recur element-by-element. The SpewBox's own line template authors outline ON with no colour (ctor black default), matching the user's screenshot. |
|
||||
| 3 | User-visible meta-markers ("IMPLEMENTED", "acdream has not yet extracted…"-style notices) leaking into live `/help` output. | **FIXED this commit, closes ISSUES.md #364.** Every honesty marker is now gone from user-visible text: `AllegianceOverview`/`HouseOverview`'s `[IMPLEMENTED]` tags and trailing "Subcommands NOT marked…" sentences, and `Day`/`Log`/`Render`/`Motd`'s appended "NOT YET IMPLEMENTED in acdream" tails are all removed, with the underlying retail text corrected/completed against the pseudo-C's own pristine consolidated data dumps (`Log` and `Motd` had also been silently truncated; `Render` had been entirely acdream-authored and is replaced with the real retail usage string). The three PARTIAL `/help` group topics (channels/chatting/commands) are now COMPLETE verbatim listings — `ClientCommunicationSystem::HelpStupidChannelHack @0x0056f290`'s three "vtable slot" operands, previously believed undecodable, are the same pooled/mislabeled-data artifact this campaign has hit before (AP-113's precedent); reading the function's own disassembly for the `push imm32` preceding each constructor call resolves all three directly. `messagetypes` is now a real ported construction (`LogTextTypeEnumMapper::IsLegalChannel`'s 14-id whitelist + `LogTextTypeToString`'s name table + the exact join/wrap format) instead of an acdream summary. Register row AP-184 RETIRED. See `RetailCommandHelpTable`'s class remarks and `RetailCommandHelpTableTests` (51 tests, all passing) for the full citation trail. |
|
||||
| 4 | (Not detailed to this session — reported as passed.) | **User-passed**, no action needed this round. |
|
||||
| 5 | The main window's 1/2/3/4 indicator buttons don't open/close the floating chat windows on click — the user's retail memory says clicking should toggle them. | **FIXED this commit.** CH6b's decomp grep (`gmMainChatUI::ListenToElementMessage @0x004CDA80` has no click case for these ids) was TRUE but incomplete — it never checked `UIElement_Button`'s own generic click handler. `UIElement_Button::HandleButtonClick @0x00471E50` reads an Enum property (`0x12`) off the button itself and, if present, routes through `ICIDM`'s action map to `UIElementManager::DoVisibilityToggleAction @0x0045B660` (the SAME function the `Alt+1..4` keybinds reach), which broadcasts element message `0x31` to every element registered as a listener for that action id (via property `0x24`, read once by `UIElement::Initialize`) — the receiving element's generic `UIElement::ListenToElementMessage` base-class handler then toggles its own visibility per its OWN property `0x58`. The committed fixture (`chat_2100006f.json`) confirms the button HALF is genuinely armed: all four indicators carry a real Enum-kind property `0x12` = `0x10000514`-`0x10000517`. But the floating-window fixture (`chat_floaty_2100005b.json`) authors NO matching property `0x24`/`0x58` anywhere, so nothing in the shipped DAT registers a floating chat window as that action's listener — the generic mechanism is real and armed on the button side but has no proven target in the data available to us. Per CLAUDE.md, the user's retail memory is the axiom regardless: `ChatWindowController.BindIndicatorClicks` (new) wires each indicator's click to the SAME `ToggleFloatingChatWindow(windowId)` chokepoint the keybinds use, explicitly as USER-DIRECTED retail behavior. `SetIndicatorOpen` stays the sole writer of the `Selected` mirror (`SuppressSelfToggle` stays `true`) so the visual stays consistent through the click round trip. Full reconciliation in `docs/research/2026-08-09-chat-retail-window-shell.md` §1.4 (the `@0x004CDA80` citation stays true as a statement about that one function; the CONCLUSION is corrected). New tests in `ChatLayoutConformanceTests.cs` exercise the click round trip and confirm keybind and click drive the same chokepoint. |
|
||||
|
|
@ -1109,3 +1122,65 @@ constraint — no client launches) — the next connected round should confirm
|
|||
show complete retail text with no meta-notice, and that clicking each of the
|
||||
four chat-window indicator buttons now opens/closes its floating window
|
||||
while the button's lit/unlit state stays correct.
|
||||
|
||||
### User gate round 4, items 1+2 — text style follow-up (2026-08-10)
|
||||
|
||||
Off the parallel research agent's findings
|
||||
(`docs/research/2026-08-10-retail-ui-text-style.md`): retail's outline is a
|
||||
SECOND ("background") glyph atlas per font, dilated 2px on every side, plus
|
||||
two border-pixel scalars acdream's font reader never read (zero repo hits
|
||||
for `BorderPixel`) — so even flipping the pre-existing `outline` parameter
|
||||
was a visual no-op. Landed together (either half alone is a no-op or a
|
||||
regression):
|
||||
|
||||
1. **`UiDatFont`** carries `BorderX`/`BorderY` from the DAT's
|
||||
`NumHorizontalBorderPixels`/`NumVerticalBorderPixels`
|
||||
(`Font::Serialize @0x00443650`).
|
||||
2. **`UiRenderContext.DrawStringDat`** inflates the background blit's source
|
||||
AND destination rect by that margin, and restructures into retail's
|
||||
exact two-pass model — the WHOLE STRING's outline pass, then the WHOLE
|
||||
STRING's fill pass (`UIElement_Text::DrawSelf @0x00467aa0`), plus the
|
||||
8-neighbour ±1px fallback for the rare 0-border font family. The stale
|
||||
"LayoutDesc property 0xd" comment (actually the `OnSetAttribute`
|
||||
switch-case index, not the property id) is corrected to 0x21/0x22.
|
||||
3. **Property 0x21 (Outline) / 0x22 (OutlineColor) import**:
|
||||
`ElementInfo.Outline`/`OutlineColor`, read in `LayoutImporter.ReadState`
|
||||
and `ElementReader.ApplyCanonicalLegacyProjection`/`Merge` with the same
|
||||
"derived wins" convention as `FontDid`, wired onto `UiText.Outline`/
|
||||
`OutlineColor` by `DatWidgetFactory.BuildText`. Every one of the ~100
|
||||
authored-outline elements across 15 layouts is correct at once, not
|
||||
fixed controller-by-controller.
|
||||
4. **SpewBox**: `RetailFontId` corrected from the round-3 heuristic
|
||||
(`0x40000025`) to the actually-authored `0x40000001` (18px bold serif,
|
||||
base style `0x10000377`), `Outline = true` set directly on the
|
||||
controller's `UiText` (it is synthesized, not DAT-imported). Fill colour
|
||||
stays the user-gate-round-1-pinned yellow `(1,1,0.247,1)` — font atlases
|
||||
are `PFID_A8` (alpha-only), so there is no baked shading that could
|
||||
explain the screenshot's gold as anything other than the outline itself
|
||||
making a bright fill read warmer. Register row AP-178 updated: font,
|
||||
size, outline, and position are now AUTHORED; only fill-colour
|
||||
calibration and the AP-177 line-lifetime timeout remain open.
|
||||
5. **Chat transcript**: default fill now seeds from the authored
|
||||
`ARGB(255,204,204,204)` (style `0x10000372` property 0x1B) instead of
|
||||
the color table's own unrelated index-0x00 slot — `ChatTranscriptRenderer.BuildLines`
|
||||
takes the transcript's own `UiText.DefaultColor` as an explicit
|
||||
parameter. The 34-entry `LogTextType` table (the per-message color
|
||||
authority) is untouched — every existing CH1 conformance test
|
||||
(`RetailChatColorTableTests.cs`, `ChatWindowControllerTests.cs`) stays
|
||||
green unmodified. No outline on the transcript, matching retail (style
|
||||
`0x10000372` authors no property 0x21 anywhere in its chain) — pinned
|
||||
against the real installed DAT via a regenerated `chat_2100006f.json`
|
||||
fixture, not a JSON-missing-field default.
|
||||
|
||||
Suite: 12,610 passed / 4 skipped / 0 failed (Release, complete solution —
|
||||
`AcDream.slnx`), up from the round-4 items-3+5 baseline 12,579/4/0 — net
|
||||
+31 tests, zero regressions (one `LandblockPresentationPipelineTests`
|
||||
failure reproduces identically on the pristine pre-this-session baseline —
|
||||
pre-existing run-order flakiness in an unrelated streaming test, confirmed
|
||||
via `git stash` before touching any code; it did not reproduce at all
|
||||
during this round's own full-solution runs). No subagent review this session
|
||||
(hard constraint); no connected user gate for this commit's own changes
|
||||
(hard constraint — no client launches) — the next connected round should
|
||||
confirm the SpewBox now shows a heavy black border in the authored 18px
|
||||
face, and that the chat transcript's default text shade reads slightly
|
||||
softer than pure white.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue