Prototype Lua-authored protected action routing
Discuss design options for known issue 305 (https://git.project-rk.com/prk/spiritech-known-issues/issues/305): combat blocks macro creation, Inventory/Backpack resizing and Perks navigation/removal. User authorizes a fast opt-in implementation slice, with short focused checks only; no deep review or long test suites. Implement a Lua-authored controller inventory browser and four-way radial hotbar with keyboard equivalents, reusing native item validation and hotbar capture. Keep default UI/combat behavior unchanged. Lua owns presentation and declares routes; native code owns physical-input selection/captured gameplay intent. No commit or client launch requested. Preserve native physical-input provenance and prevent scripts from selecting/remapping gameplay commands in response to state. Compare narrower native-owned navigation/layout, declarative secure controls and broader input-authority designs. Acceptance: identify relevant current gates, explain automation threats/tradeoffs and propose a direction with explicit unresolved policy questions. Acceptance for this prototype: opt-in package works with real native game data and declared physical routes, Lua cannot execute/reselect/rebind actions after initialization, selected items/gestures cannot silently substitute subjects, focus loss cancels pending gestures, focused build and a few essential checks pass. User performs live UI/controller validation; explicitly record unverified behavior. No full security claim or production replacement of lockdown. Source findings: LuaWidgetHost.Security.cs freezes root layout and broadly refuses UI mutations during combat; native action dispatch captures the exact command/reference on pointer down and runs before nonactivating Lua observers. LuaWidgetHost.Windows.cs delegates resize policy to Lua, whose size/layout writes are blocked. PerksPresenter explicitly blocks local tab/line selection; Perks/main.lua pins rows and cannot update protected remove bindings/enabled state. CharacterInterface macro handler and ShortcutBarsController.CanConfigure/CreateMacro independently reject combat configuration. Skills/Friends already opt out of layout lockdown while retaining native action dispatch; this is precedent, not proof that unrestricted Perks/hotbar mutation is safe. Existing SecureInteractionTests cover command/hit-region stability and observer ordering; tests were read, not run. Design constraint clarified by user: move substantially more ownership into Lua; packages must be powerful enough to implement a controller-specific UI and own nearly all UI behavior. Earlier recommendation of native-owned navigation/reflow is not an agreed direction and is too restrictive as a default. Discuss Lua-owned navigation/layout/input composition with a narrow native command-authority boundary; distinguish player-selected action routing from state-driven action selection. Consider Lua-authored constrained action descriptions, host-captured physical input and immutable command/subject identity, without moving each UI interaction into C#. Do not assume a generic click-scoped token prevents automation. Must address pre-click state-driven remapping, mutable selection context, press/release changes, overlays/ancestor routing and out-of-combat automation. Implemented uncommitted on feature/lua-action-routing-slice. Opt-in PRK_LUA_ROUTING_SLICE=1 hosts UI/Packages/RoutingPrototype; Lua declares immutable input bindings and renders a six-column inventory browser and four-way wheel (bar 1 slots 1–4). Y/F6 toggles inventory; D-pad/arrows select; A/Enter activates; hold LB/F7 and select with D-pad/left stick/arrows, release to activate; B/Escape cancels. Native DeclaredActionRoutes owns selection/captured closures, has no Lua execute/selection setter, and seals through LuaWidgetHost.CompleteInitialization. Host grants routes explicitly; default windows have no grant. Existing combat lockdown/default UI unchanged. Input adapter polls mapped gamepads and selects the device with fresh routed button activity rather than the first enumerated device. Device changes cancel pending gestures; initial/disabled held inputs are not replayed. It handles fresh presses, cancels on focus/text/capture/session restrictions, preserves ordinary key releases, and displays/logs selected controller identity. CapturedItem and shortcut/macro context validation reject replacement subjects; no fallback or automatic initial selection. Views refresh source membership only on reopening. Equipment-item wheel shortcuts are unavailable. No paging/layers, pointer gameplay routing or general addon distribution yet. Verified: client warning-as-error build succeeds with NU1903 explicitly exempt, using prepared host font/audio packages because first-build font dependency bootstrap failed with HTTP 504. Final 11 focused tests pass (3 routing, 8 existing keyboard-feed), no skips. Native Lua package test demonstrates failed remapping when sealing is deliberately removed and passes after restoration. Native Vulkan specimen inventory/wheel captures rendered and visually inspected at normal scale under .dev-data/lua-routing-slice; not live gameplay evidence. API generator self-test, Lua/XML syntax and diff whitespace checks pass. No full suites, deep reviews, client launches, commits or PRs. Build log /tmp/lua-routing-build.log; final focused test log /tmp/lua-routing-final.log. Built client at PRK.Client/PRK.Client/bin/Debug/net10.0/PRK.Client.dll; README in prototype package gives launch/controls/limitations. Controller follow-up: user reported controller did not work. Native GLFW probe found index 0 is a recognized idle Streamify virtual Xbox controller, whereas index 1 is the physical Microsoft Xbox Controller with GUID 060000005e040000120b000001050000, unrecognized by built-in GLFW mappings. Added the exact upstream SDL_GameControllerDB mapping as an attributed/licensed reduced subset in the prototype package; native adapter loads it before polling. Probe using the built output proves physical controller changes from unmapped to mapped (Microsoft Xbox Series Controller), without launching the game. Selection now follows fresh physical button activity and names the controller in the panel. Client build and all 11 short focused tests pass again; Lua syntax/diff checks pass; refreshed native wheel capture inspected. These checks do not exercise real button presses through the running client. Follow-up log: /tmp/lua-routing-controller-fix.log. No client launch, broad review, commit or PR. User confirms after the controller follow-up: fully tested and all slice features work as expected. This satisfies the prototype's live validation gate; individual live scenarios were not independently observed by the assistant. Prototype scope is complete. Changes remain uncommitted; no PR or production migration authorized. This remains a feasibility slice, not a full security audit or a fix for issue 305. Broader adoption, pointer action routing, live source reconciliation and migration away from blanket combat lockdown are separate follow-up scope.
Checklist
2 of 2 complete- Trace reported restrictions and discuss security-preserving alternatives with the user.
- Build opt-in inventory/controller wheel slice and verify immutable routing, captured intent, cancellation and native Lua rendering with short focused checks.
- Area
- Project Rubi-Ka
- Project
- engines
- Kind
- Feature
- Task ID
tsk_kz5tyac4t2- Updated