acdream/tests/AcDream.Runtime.Tests
Erik e62aaebda0 feat(chat): CT-B2 — "/r " expands to a tell at whoever last told you
Campaign CT slice B2, and the autocomplete the user asked about directly.

Typing "/r " now rewrites the chat entry to "@tell {LastTeller}, " the moment
the space lands, matching ChatInterface::HandleTextReplacements @0x004F50D0 ->
SetReplyTextInChatBox @0x004F4760.

This is display sugar rather than routing: "/r hello" already SENT correctly
through ChatInputParser's reply aliases. What was missing is that the player
could not SEE who they were about to reply to before pressing enter.

The trigger strings came out of the constant pool, not the decompiled listing —
Binary Ninja renders them as bare data_* references with no preview:

    data_7C4C70 = "r "      data_7C4C68 = "rp "      data_7C4C58 = "reply "

Retail stores them WITHOUT the leading prefix and tests the first character
separately against '/' (0x2F) or '@' (0x40), which is why both prefixes work.
The research summary for this area listed the triggers as "/t ", "/tell " and
"reply " — reading the pool corrected that.

Three boundaries, each pinned by test because each is a way to get this subtly
wrong:

  - The trailing space is PART of the trigger. "/r" alone must be left alone —
    the player may still be typing "/roleplay", and expanding early would
    hijack a different command mid-word.
  - Only on space. Running the replacer per keystroke would rewrite text out
    from under someone mid-word; retail keys on 0x20 specifically.
  - Only with the caret at the end. Otherwise the player is editing existing
    text, and expanding would corrupt a sentence they are part way through
    fixing.

With nobody to reply to, nothing is rewritten — retail leaves the text alone
rather than producing a tell addressed to nobody, and the ordinary submit path
still reports "Someone must @tell you first!".

Solution builds clean; full hermetic gate green.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 08:10:39 +02:00
..
CharGen fix(chargen): Campaign CC CC5 review fix round — F1-F14 2026-08-16 01:13:52 +02:00
Chat feat(chat): CT-B2 — "/r " expands to a tell at whoever last told you 2026-08-21 08:10:39 +02:00
Entities fix(review): close the C5b architecture-review findings (D2/D3/D4, L1-L5, S1) 2026-08-05 22:08:46 +02:00
Gameplay fix(ui): restore retail vitals and window interactions 2026-08-20 13:26:35 +02:00
Physics test: stabilize load-sensitive release contracts 2026-08-18 11:50:23 +02:00
Session feat(session): the in-world logoff — LogOut animation, reverse wormhole, live return to character select 2026-08-17 14:02:40 +02:00
Support fix: retail text and golden-string tests must not follow the machine's locale 2026-08-19 19:56:09 +02:00
World feat(session): the in-world logoff — LogOut animation, reverse wormhole, live return to character select 2026-08-17 14:02:40 +02:00
AcDream.Runtime.Tests.csproj build: make release restore reproducible 2026-08-18 10:29:00 +02:00
GameRuntimeContractTests.cs test: replace campaign labels with behavior names 2026-08-18 12:25:00 +02:00
GameRuntimeTests.cs feat: secure trade with other players - wire, RuntimeTradeState, the 2026-08-14 11:49:13 +02:00
NoWindowGameRuntimeHostTests.cs fix(chat): CH1 review fixes — sbb-idiom channel catch-all, command-output typing 2026-08-09 16:03:13 +02:00
packages.neutral.lock.json build: make release restore reproducible 2026-08-18 10:29:00 +02:00
RuntimeDependencyBoundaryTests.cs feat(platform): Campaign LA LA0 — extract ApplicationPathSet to AcDream.Platform 2026-08-14 15:19:02 +02:00
RuntimeGenerationResetTests.cs fix(net,runtime): FA2 fix-round MUST-FIX -- allegiance clears at reset, 0x027C stops seeding 2026-08-12 02:17:04 +02:00
RuntimeSimulationFixtureHostTests.cs fix: retail text and golden-string tests must not follow the machine's locale 2026-08-19 19:56:09 +02:00