Repository navigation
[compass] Fix: a refused gamepad_set leaves part of its change pending, so the next set or tap sends it - #49
Merged
Conversation
…ort (B-041) GamepadManager.Apply set each button, axis and trigger as it read them. The pads run with AutoSubmitReport off, so when a later name was unknown the call threw before SubmitReport and the earlier changes stayed in the pending report, for the agent's next gamepad_set or gamepad_tap to send. Every name is now resolved first; the changes are set and submitted together. A trigger passed as a button got "Unknown gamepad button 'lt'. Use ... lt or rt."; it is now told it is a trigger. gamepad_tap recognises the trigger names the triggers take (l2, r2). The stand-in pad in the quick checks now keeps what was set until a report sends it, and the new check "gamepad set all or nothing" covers all three. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
…r message From #49's second review: ViGEm's Equals(object) compares type and index, so the stand-in keys by control alone; it keeps each sent report so the check proves a tapped trigger was pulled to 255, and counts reports instead of an Unsent test that is always false after a submit; the trigger error says gamepad_set's triggers are an MCP option. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…6-10-15-gamepad-set-atomic
… behind Co-Authored-By: Claude Opus 5.5 <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.
Report
ANODE-BUGS.md B-041 (filed 2026-10-15 by compass-anode-fixer from a read-only code hunt in its nightly run): a rejected
gamepad_setleaves part of its change pending, so the next set or tap sends it.Root cause
GamepadManager.Apply(src/Anode/Core/Gamepad/GamepadManager.cs) resolved and set each button, axis and trigger as it read them, then calledSubmitReportonce at the end. Every pad runs withAutoSubmitReport = false(set inAttach), so a set only changes the pad's pending report. When a later name was unknown,ResolveButton,ResolveAxisorResolveTriggerthrew beforeSubmitReport, the agent got an error, and the changes made before it stayed pending. The agent's nextgamepad_setorgamepad_tapsent them (agamepad_resetor a detach clears the report first, so those threw them away). Example:gamepad_set {"buttons": {"a": true, "dpad_up": true}}fails ondpad_up, and A goes down with the agent's next call, so the game in the seat sees A held that the agent believes it never pressed. The MCP schema takes any button name, so a guessed name reaches this path.Two smaller faults in the same names:
gamepad_setbuttons{"lt": true}andanode gamepad hold ltwere told "Unknown gamepad button 'lt'. Use …, lt or rt."gamepad_taprecognisedlt,rt,lefttriggerandrighttriggeras triggers, but notl2andr2, whichResolveTriggeraccepts;gamepad_tap l2failed with that same error.Fix
Applyresolves every name and value first into a list of changes, then sets them and submits one report under the lock. A refused call changes nothing.TriggerNamedhelper now names the triggers forResolveTrigger,Tapand the button error. A trigger passed as a button hears "'lt' is a trigger, not a button: tap it, or, over MCP, set it from 0 to 1 under gamepad_set's triggers." (the CLI can tap a trigger but not hold one) The unknown-button list no longer offersltorrt.gamepad_tap's "lt or rt" stays true.Tests
gamepad set all or nothing(Cli/GamepadChecks.cs,SetAllOrNothing). The stand-inFakePadnow keeps what was set until a report sends it, like ViGEm's pad withAutoSubmitReportoff, and keeps each report it sent. Refused sets for an unknown button, an unknown axis after a good button and axis, an unknown trigger after a good axis and trigger, and a trigger named as a button leave nothing for the next report; the unknown-button error no longer offersltorrt; the next valid set sends only its own change, in one report; a full set sends buttons, axes and triggers together;gamepad_tap l2pulls the left trigger to 255 and releases it. No controller is plugged in.selftest --quick): 7 of 7 caught (buttons, axes or triggers set as they are read, which is the old code for each; the trigger message reverted;lt or rtback in the button list;Tap's old trigger test; a valid set never submitted). Every restore byte-identical.f2ef33fadds it there (and [compass] Fix: a refused Reconnect sets a running seat to error, so display reconnects answer "stopped" and the next disconnect drops the seat #48 did the same for itself), with the quick-check count now 110. Its P3s applied in714100f(the stand-in, the tap check, a vacuous assertion, the CLI-true trigger message, this description's reset/detach sentence); not taken:Tapresolving the trigger once (kept the diff small).6e0e297.f6e4c8c); the mutations were re-run on the final code: 7 of 7 caught.scripts\build.ps1 -QuickTest -OutputDirectory artifacts\pkg-build): passed on the final head with main merged in: Release publish, 110/110 quick checks, docs consistent.selftest --quick: 109/109 before main was merged in.Manual check in a real seat
None needed for the fix itself: the stand-in models the one ViGEm behaviour it relies on (sets wait for
SubmitReportwhenAutoSubmitReportis off). The full self-test's "virtual gamepad" check (a real ViGEm pad, machine-wide) still runs the sameApplycall when someone runs it with a gamepad; agents don't.CHANGELOG, release notes and the 0.11.3 validation record: one entry each, since 0.11.3 isn't released yet.
🤖 Generated with Claude Code