Merge op8-keyboard: Campaign OP slice OP8 — Configure Keyboard
Bringsb4edee97(slice),b1968ce9(M1/M2/M3 rework),f1d50207(round-2 residuals). Review chain: REJECT -> rework -> REOPEN-narrow -> coordinator third round; findings docs 2026-08-11-op8-review.md / -op8-rereview.md. The merge lands OP8's six ListBoxes on top of 057d8cd7's #372 viewport fix, which auto-heals the blank-pages hazard the re-review flagged — the OP8 connected gate was contracted to run post-merge for exactly this. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
commit
1c5cd969b4
23 changed files with 36178 additions and 12 deletions
File diff suppressed because one or more lines are too long
|
|
@ -424,5 +424,5 @@ before anything builds on them.
|
|||
| OP5 | CODE-COMPLETE, gate READY | `e71e5a96` (AP-195 retired) → fixes `6d0b0f92` → residuals `67b0815c` | combined APPROVE-WITH-FIXES (`2026-08-11-op5-review.md`) → re-check CLOSED (`2026-08-11-op5-recheck.md`) → coordinator drag residuals landed | connected gate OWED (script §OP5) |
|
||||
| OP6 | CODE-COMPLETE, gate READY | `f5ac1742` (REJECTED) → rework `472525b9` → doc residuals (coordinator) | REJECT (`2026-08-11-op6-review.md`) → re-review CLOSED, all six caption sites byte-decoded (`2026-08-11-op6-rereview.md`) | connected gate OWED (script §OP6) |
|
||||
| OP7 | CLOSED | `09cb548a` → fixes in `7b60e71b` (shared commit, see its message) | combined-lens APPROVE-WITH-FIXES (`2026-08-11-op7-review.md`); all nine findings closed | live bot-vs-ACE gate PASSED 2026-08-11 (coordinator; evidence in script §OP7) |
|
||||
| OP8 | — | | | |
|
||||
| OP8 | CODE-COMPLETE, gate READY | (this branch's commit) | not yet reviewed | connected gate OWED (script §OP8) |
|
||||
| OP9 | — | | | |
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
# Campaign OP connected-gate test script
|
||||
|
||||
**Status:** OP3, OP4, OP5, OP6, and OP7 sections. Later slices (OP8) append
|
||||
their own sections here as they land; the campaign's OP9 closeout gate is
|
||||
this document complete plus every slice code-complete.
|
||||
**Status:** OP3, OP4, OP5, OP6, OP7, and OP8 sections. The campaign's OP9
|
||||
closeout gate is this document complete plus every slice code-complete.
|
||||
|
||||
This document is the script the user runs against the live connected
|
||||
client (`ACDREAM_LIVE=1` against the local ACE server) to accept each
|
||||
|
|
@ -851,3 +850,168 @@ Three live runs against local ACE (`127.0.0.1:9000`, `+Acdream`,
|
|||
unmapped `[weenie-error] code=0x051D`, and the K4 resource envelope's
|
||||
`handle-count` violation (the `k4-linux-30-session` Linux profile
|
||||
evaluated on Windows).
|
||||
|
||||
---
|
||||
|
||||
## OP8 — Configure Keyboard
|
||||
|
||||
**Known, tracked behaviors — do NOT file as defects (read before testing):**
|
||||
|
||||
- **Shared combat keys prompt a false conflict (ISSUES #373).** Retail
|
||||
legitimately shares Insert/Delete/End/PageUp/PageDown across the three
|
||||
combat contexts (Melee/Missile/Magic) via the DAT's `ConflictingMaps`
|
||||
table, which acdream does not read yet. Rebinding any of those keys — or
|
||||
any chord one combat context already holds — will show a conflict
|
||||
confirmation retail would not. DECLINE the prompt and move on; the
|
||||
binding you declined stays untouched. Report only if declining CHANGES a
|
||||
binding anyway.
|
||||
- **Camera Alternate Controls rows are display/store-only (AP-203).** They
|
||||
show retail's authored arrow-key defaults and accept edits, but do not
|
||||
drive the camera — only the primary Camera scheme is live. Verify they
|
||||
RENDER (arrow keys visible); do not expect camera behavior from them.
|
||||
|
||||
|
||||
The screen is retail's own separate full-screen window (`gmKeyboardUI`,
|
||||
LayoutDesc `0x21000009`), NOT a fifth tab of the Options panel. It opens
|
||||
from the Gameplay tab's Configure Keyboard button — **the OP3 INERT
|
||||
contract for that button is retired as of this slice**; OP3's own script
|
||||
line calling it INERT no longer applies.
|
||||
|
||||
### Opening the screen
|
||||
|
||||
1. **Open the Options panel (F11), Gameplay tab, click "Configure
|
||||
Keyboard."** A separate full-screen window opens (not layered inside
|
||||
the Options panel) showing six tabs across the top: Movement, Camera,
|
||||
Combat, UI, CharacterSettings, Emote — Movement is the default/first
|
||||
tab. Each tab lists grouped rows: a bold-ish header naming the
|
||||
sub-category (e.g. "Movement Commands"), then one row per action —
|
||||
an action label on the left, up to three key-binding buttons to its
|
||||
right (retail's "Mapping 1/2/3" columns) showing the currently bound
|
||||
key(s) (e.g. "W", "Up").
|
||||
2. **Not every group has a visible header/rows.** Debug/dialog/system
|
||||
InputMaps (DialogBoxes, DebugConsole, ProfilerUI, UIDebugger,
|
||||
DebugCommands, and six further unnamed contexts) are 100% non-user-
|
||||
bindable in the shipped DAT and correctly show NOTHING — this is not
|
||||
a bug, it is retail's own shipped data (byte-verified against the
|
||||
live DAT, see `RetailActionMap.cs`'s class doc).
|
||||
3. **The bottom-row buttons:** Load File…, a current-keymap-name label,
|
||||
Save As…, Defaults, Revert, OK, Cancel. Load File / Save As are
|
||||
**INERT** (D4 — no `.keymap` file interchange, AP-202) — clicking
|
||||
them does nothing; this is correct, contracted behavior.
|
||||
|
||||
### Rebind a movement key live
|
||||
|
||||
4. **On the Movement tab, find "Move Forward"** (should show two bound
|
||||
keys, "W" and "Up"). Click the SECOND key button (currently "Up").
|
||||
The button should visually indicate it is listening for input
|
||||
(retail's own capture-prompt text is not wired to a tooltip in this
|
||||
port — a simple pressed/active state is enough to confirm capture
|
||||
started).
|
||||
5. **Press a different key**, e.g. `U`. The button should immediately
|
||||
update to show "U".
|
||||
6. **Move your character forward using W and U** (both should now work
|
||||
— this is the live-effect proof: the rebind reached the SAME
|
||||
`InputDispatcher`/`KeyBindings` every other input path uses, not a
|
||||
screen-local shadow copy). The original "Up" arrow should no longer
|
||||
move the character forward.
|
||||
7. **Right-click the "U" key button** you just set. It should clear
|
||||
back to blank/empty — right-click erases just that one slot
|
||||
(`EraseBinding`), distinct from a hypothetical "Clear all" (there is
|
||||
no Clear-all button on this screen — the shipped 2013 row template
|
||||
authors none; a real, DAT-verified fact, not a limitation of this
|
||||
port).
|
||||
|
||||
### Conflict on a taken chord
|
||||
|
||||
8. **Still on Movement, click "Move Backward"'s first key button**
|
||||
(currently "X"), then press **W** — the SAME key you just confirmed
|
||||
is bound to "Move Forward."
|
||||
9. **Expect**: a confirmation dialog opens (retail's own
|
||||
`OpenOverwriteBindingDialog`, ported through the same
|
||||
`RetailDialogFactory` confirm mechanism the game's other Yes/No
|
||||
prompts already use) naming "Move Forward" as the row that currently
|
||||
holds the key and asking whether to reassign it to "Move Backward."
|
||||
**Click Yes**: "Move Backward" takes W, and "Move Forward" loses its
|
||||
W slot (down to just "U" from step 5); both rows' key-button labels
|
||||
update to reflect the swap. Repeat steps 8-9 once more but **click
|
||||
No** this time: neither row should change at all — the capture is
|
||||
simply abandoned, exactly like Escape.
|
||||
|
||||
### Non-bindable refusal
|
||||
|
||||
10. **Click any key button, then press Ctrl+M** (acdream's own
|
||||
debug-only mute toggle — retail has no equivalent, so no DAT row on
|
||||
this screen owns it). **Expect**: the rebind is REFUSED — the key
|
||||
button you clicked keeps its previous value, and a system message
|
||||
appears reading "Could not overwrite " (retail's own byte-verified
|
||||
`ID_KeyMapCantOverwriteReadOnlyKeymap_Label` string, table
|
||||
`0x23000004` — it may read as an odd sentence fragment on its own;
|
||||
that is the literal stored string, not a truncation bug in this
|
||||
port). Confirm Ctrl+M still mutes/unmutes audio afterward — the
|
||||
acdream-only binding was NOT touched.
|
||||
|
||||
### Erase, then Reset to Defaults
|
||||
|
||||
11. **Erase a couple more bindings** via right-click (any tab).
|
||||
12. **Click Defaults.** Every row on EVERY tab should snap back to its
|
||||
retail-default key(s) LIVE — including the ones you just erased,
|
||||
the "Move Forward"/"Move Backward" pair from steps 5-9 (both back
|
||||
to their original W/Up and X/Down), and the Ctrl+M row from step 10
|
||||
is untouched (it has no DAT row, so Defaults cannot and does not
|
||||
touch it). The OK/Cancel/Revert buttons should now read as
|
||||
"changed" (retail never gates Defaults itself, but the page as a
|
||||
whole is dirty after it runs) — confirm by tabbing away and back:
|
||||
edits should still be there (Defaults applies live without
|
||||
committing, exactly like a manual edit would).
|
||||
13. **Click Revert** (not Cancel) with SOME rows still showing your
|
||||
Defaults-restored values. Expect every changed row to revert to
|
||||
whatever was bound when you last clicked OK (or, if you haven't
|
||||
clicked OK yet this session, back to what was loaded from
|
||||
`keybinds.json` at startup) — Revert and Cancel run the identical
|
||||
verb (`RestoreSavedValues`); Revert just doesn't also close the
|
||||
window.
|
||||
|
||||
### Persistence across relaunch
|
||||
|
||||
14. **Rebind one distinctive key** (e.g. change "Jump" from Space to
|
||||
some other free key) and **click OK.** The window closes.
|
||||
15. **Close acdream gracefully and relaunch it** (see CLAUDE.md's
|
||||
logout-before-reconnect discipline — wait for the graceful-close
|
||||
session-clear window before reconnecting). Open Configure Keyboard
|
||||
again: the rebind from step 14 should still be there — proof it
|
||||
persisted to `keybinds.json` on disk, not just the in-memory
|
||||
dispatcher.
|
||||
16. **Open a plain text editor on `%LOCALAPPDATA%\acdream\keybinds.json`**
|
||||
(or the platform-portable equivalent) and confirm the rebound
|
||||
action shows the new key. A sibling `keybinds-unmapped.json` should
|
||||
also exist if you rebound anything on the CharacterSettings or
|
||||
Emote tabs during this session (AP-203's store-only rows — e.g. try
|
||||
rebinding one "Bow Deep"-style Emote row and confirm it shows up in
|
||||
THAT file, not `keybinds.json`).
|
||||
|
||||
### Cancel discards uncommitted edits
|
||||
|
||||
17. **Rebind another key WITHOUT clicking OK**, then click **Cancel.**
|
||||
The window closes; reopen it — the rebind from this step should be
|
||||
GONE (reverted to the last-committed/loaded state), matching step
|
||||
13's Revert behavior plus the window closing.
|
||||
|
||||
### What to report
|
||||
|
||||
- Any row that shows a DIFFERENT key than what `keybinds.json` /
|
||||
`RetailDefaults()` says it should (a sign the DAT-vs-InputAction
|
||||
identity table mis-mapped a row — see
|
||||
`RetailActionIdentityRoundTripTests` for the automated half of this
|
||||
check).
|
||||
- Any tab/header that renders EMPTY where it should show rows, or vice
|
||||
versa (the page-scoped element-lookup trap this slice's controller
|
||||
explicitly guards against — a regression here would mean one page's
|
||||
rows leaked into another, or the six reused element ids resolved to
|
||||
the wrong page's instance).
|
||||
- Whether the confirm dialog's wording (step 9) or the refusal
|
||||
message's odd phrasing (step 10, the literal DAT string) reads
|
||||
awkwardly enough in practice to warrant a follow-up polish pass.
|
||||
- Any row whose Emote/CharacterSettings binding visibly DOES something
|
||||
in-game despite AP-203 saying it shouldn't (would mean acdream grew a
|
||||
consumer for it since this table was written, and the identity table
|
||||
should be updated to route it live).
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue