acdream/tests/AcDream.App.Tests
Erik 35454a9f58 fix #436: combat no-target refusal reaches the SpewBox with retail's exact text
Attacking with no valid target has told the player nothing since Campaign V
slice V11 orphaned the DebugVM toast the message was wired to (#434 found
the drop; this closes it retail-faithfully).

Ground truth from the Ghidra decompile of
ClientCombatSystem::ExecuteAttack (0x0056bb70): retail writes
"You must select a valid combat target before attacking" via
ClientSystem::AddTextToScroll(..., 0x1A, true, 0) — the ClientLocal
SpewBox channel this codebase already routes every other client-local
refusal through. And retail has ONE message, not the two we carried:
attacking outside melee/missile modes is silent (ExecuteAttack is
unreachable there), so the invented "Enter melee or missile combat first"
text is deleted rather than rerouted, and the invented "No monster
target" is replaced by the retail string, which joins ClientTextRefusals
with its decomp citation.

Wiring: CombatFeedbackSlot gains the sibling BindOwned session-lifetime
shape, and SessionPlayerComposition.CompleteSessionPlayer binds it to
RuntimeCommunicationState.AddText(ClientLocal) with session-owned
teardown — a torn-down session's slot returns to its silent unbound
state. A binding-seam test
(CompleteSessionPlayerBindsCombatFeedbackToTheClientLocalSpewBoxRoute)
inspects the compiled composition for the BindOwned call and its
AddText-routing lambda, so the slot can never again pass its unit tests
while production leaves it unbound — the exact failure mode that hid
this defect. The two tests that pinned the invented strings now pin the
retail contract (exact string; silence for the unsupported-mode case).

Full hermetic suite 15,325 passed / 0 failed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-24 12:53:11 +02:00
..
Architecture test: replace gameplay owner source freezes 2026-08-18 16:49:38 +02:00
Audio feat(audio): Campaign A slice A2 — retail's 2D pan+gain mixer replaces AL 3D 2026-08-08 21:58:50 +02:00
Combat fix #436: combat no-target refusal reaches the SpewBox with retail's exact text 2026-08-24 12:53:11 +02:00
Composition fix #436: combat no-target refusal reaches the SpewBox with retail's exact text 2026-08-24 12:53:11 +02:00
Configuration fix(app): Campaign LA gate round 2 — session-config launches force the retail UI on 2026-08-15 08:42:33 +02:00
Credentials test: make prerequisite lanes fail honestly 2026-08-18 12:09:41 +02:00
Diagnostics fix #435 (part 2, closes it): attribute the unowned probes — delete 7, reclassify 8, restore 1 2026-08-24 12:32:42 +02:00
Input fix(input): free-fly is unreachable, and Escape no longer answers to it 2026-08-21 09:55:16 +02:00
Interaction fix: social panel completion batch (user gate 2026-08-13, "fix all") 2026-08-13 19:30:51 +02:00
Net feat(chat): CT-B4 — @log, and the research block that was a wrong question 2026-08-21 11:28:20 +02:00
Physics test: replace input and physics source freezes 2026-08-18 15:31:57 +02:00
Platform feat(platform): Campaign LA LA0 — extract ApplicationPathSet to AcDream.Platform 2026-08-14 15:19:02 +02:00
Plugins feat(render): implement Campaign AR and terrain fidelity 2026-08-22 13:13:29 +02:00
Rendering fix #435 (part 1): delete 17 probes that outlived their closed investigations 2026-08-24 11:41:20 +02:00
Runtime test: replace gameplay owner source freezes 2026-08-18 16:49:38 +02:00
Settings feat(render): implement Campaign AR and terrain fidelity 2026-08-22 13:13:29 +02:00
Spells feat(headless): share immutable gameplay content 2026-07-27 09:00:48 +02:00
Streaming feat(render): implement Campaign AR and terrain fidelity 2026-08-22 13:13:29 +02:00
UI test(gates): sequence the two-client remote-shadow gate with harness signals 2026-08-22 17:44:13 +02:00
World test: replace create authority source pin 2026-08-18 16:52:22 +02:00
AcDream.App.Tests.csproj feat(render): implement Campaign AR and terrain fidelity 2026-08-22 13:13:29 +02:00
BoundedTestDatCollection.cs perf(content): remove exception-driven setup probes 2026-07-24 15:12:21 +02:00
FramePhaseTestDoubles.cs refactor(runtime): move session lifetime and ordered transport 2026-07-25 19:39:24 +02:00
FrameProfilerReportTests.cs perf(diag): complete trustworthy Slice A capture tooling 2026-07-24 12:46:51 +02:00
FrameStatsBufferTests.cs fix(pipeline): MP0 - profiler toggle-path hygiene + Max() seed (review follow-up) 2026-07-05 19:26:28 +02:00
GameRuntimeTestFactory.cs refactor(runtime): cut graphical host over to canonical root 2026-07-26 19:06:09 +02:00
GlobalUsings.cs feat(runtime): share chat commands and run login sequence 2026-08-14 20:27:45 +02:00
LiveEntityRuntimeFixture.cs test(runtime): restore the world-frame precondition across first-entry fixtures 2026-08-03 13:32:28 +02:00
LiveEntitySpawnFixture.cs feat(runtime): C3c - production placement cutover: both hosts on the residence conductors (routes 1+8) 2026-08-02 18:10:33 +02:00
packages.neutral.lock.json build: make release restore reproducible 2026-08-18 10:29:00 +02:00
RuntimeDatAccessArchitectureTests.cs feat(headless): share immutable process content 2026-07-27 08:37:24 +02:00
RuntimeDatCollectionFactoryTests.cs feat(headless): share immutable process content 2026-07-27 08:37:24 +02:00
RuntimeOptionsRetailUiTests.cs test(runtime): add deterministic world gate artifacts 2026-07-20 22:37:16 +02:00
RuntimeOptionsTests.cs fix #435 (part 2, closes it): attribute the unowned probes — delete 7, reclassify 8, restore 1 2026-08-24 12:32:42 +02:00
RuntimeWorldTransitTestDriver.cs refactor(runtime): own teleport destination correlation 2026-07-26 17:52:34 +02:00
ZeroAllocationProbe.cs test(app): measure the warmed path, not the path being warmed (#250) 2026-07-29 03:42:08 +02:00
ZeroAllocationProbeTests.cs test(app): measure the warmed path, not the path being warmed (#250) 2026-07-29 03:42:08 +02:00