SOURCE / PINNED RELEASE
Made of little things.
Pickle Rustlers
- Release
- 039e51f55e34…
- Author-recorded commit
- 40608586a8a1…
- License
- LICENSE
- Author’s source reference
- nostr://npub12lm3rxsva8kfempyjkxupt09e02n3fezurkyadyqfejdc5e0r2kscqty6r/wss%3A%2F%2Fgit.napplet.soy%2F/n-bad44e7ab35
Archive hash verified: f38e99afa0992052…. The source-to-build association is the author’s claim; it has not been independently rebuilt.
# Keyboard integration
Pickle Rustlers uses optional NAP-KEYS for three stable actions:
`pickle-rustlers.shoot` (shoot/confirm, default literal Space),
`pickle-rustlers.lasso` (default `e`), and `pickle-rustlers.pause` (default `p`).
The shell owns these bindings. Successfully registered actions do not retain
fixed aliases, even when the shell leaves them unbound. Failed registrations
retain the original local aliases; touch and gamepad always remain available.
WASD/arrows remain local held controls because NAP-KEYS has no release operation.
Escape and Tab are never suggested bindings or prevented by the app.
The app uses SDK registration/subscription helpers, closes handles on disposal,
cleans up late registration results, and lets the injected shim handle forwarding
and binding updates. It filters repeat actions, editable targets, IME and
unrelated modified raw shortcuts. It honors consumed events and clears held state
on blur, visibility changes and pause/resume. Shell actions require a focused,
visible game in an applicable state, preventing background menu confirmation.
Pagehide releases input unless the page is entering the browser's back/forward cache.
## Compatibility checked on 2026-10-22
| Component | Result |
| --- | --- |
| [NAP-KEYS draft](https://github.com/napplet/naps/blob/8869a4cf77b023f4b049f47c546910a0280dc1a6/naps/NAP-KEYS.md) | Registration, actions, automatic forwarding and reserved-key rules reviewed |
| SDK 0.24.4 / NAP 0.28.0 | `registerAction`, `onAction`, `unregisterAction` used; document-capture shim marks consumed keydowns |
| soyLI 0.29.0 preview | Keys domain/methods injected; three registrations observed; Space/E/P handled locally while unbound W forwards with key/code/modifiers |
| Live binding display | No public SDK binding-change subscription; instructions label defaults and defer remapping to the shell |
The pinned package shim orders modifiers `Alt+Ctrl+Meta+Shift`, while the draft
specifies `Alt+Ctrl+Shift+Meta`. Our default hints use no modifiers and are
unaffected. Combined Shift+Meta remapping needs an upstream shim correction;
this app does not replace the injected shim. No shell keybinding editor was
available in the inspected preview; rebind/unbind behavior was verified with
full binding replacements in the real-shim browser fixture instead.
## Verification evidence
`pnpm test:keyboard` builds the application adapter with the actual package shim
into a Chromium-only test fixture. The injected namespace and host responses in
that fixture are test infrastructure, not shipped napplet code. The test runs
under `pnpm verify`, using the browser dependency supplied by conformance.
| Requirement | Evidence |
| --- | --- |
| No duplicate actions or bound-key forwarding | Real-shim test; trusted browser Space presses and repeats; hosted Space/E/P |
| Shell remapping and unbound actions | Complete binding-list replacement, old aliases stop, new key works |
| Known/unknown shell action IDs and game-state gate | Real-shim callbacks, unknown ID ignored, disabled state rejects action |
| Editable/IME/modified input | Browser fixture tests text/nested editable, forwarding suppression, composition and raw modifiers |
| Reserved keys | Fixture pushes reserved bindings; Tab/Shift+Tab/Escape retain defaults and do not trigger registered actions |
| Held movement/release/reset | Simultaneous keys, changed modifier/case on release, blur and visibility reset; existing pause/resume clearing retained |
| Optional failures | Absent domain, synchronous throw, rejection, partial success, listener failure |
| Lifecycle | Idempotent disposal, unsubscribe/unregister counts, reinitialization and late registration completion |
| Forward wire fields | Actual shim emits key, code and all four modifiers without correlation ID |
| Registration/unregistration | Actual shim correlation handling and unregister messages observed in fixture |
| Built artifact | Single-file HTML inlined by the existing plugin; type-check/build/guidance pass |
| Reference conformance | 5 passed, 0 failed, 5 skipped (manifest ×3, wire and lifecycle unmeasured) |
| Target host | `soyli check` passes; gameplay start, shooting/lasso and keyboard pause/resume exercised without page errors |
| Frames | Actual hosted iframe sized to 200×160, 320×560, 900×600 and 1400×850 with test-only frame style overrides; gameplay/HUD inspected |
| Touch | Chromium emulation: 390×844, 360×640, 844×390 outer viewports; actual frames 390×709, 360×505, 844×300; shoot/lasso taps succeed |
App-owned scene/HUD colors remain independent of the optional theme domain; no
NAP-THEME subscription is installed. Physical phone/controller behavior and the
publicly deployed host were not certified by these local keyboard checks.
