Skip to content

Rebuild modern controls and onboarding around semantic actions #14

Description

@zoeyrose

Important

This preserved product issue is now part of the fresh MIT replacement program. Final implementation owner: atrinik/client. Legacy C/SDL2, packet, global-state, and file-path details below are historical evidence only.

Replacement implementation contract

Build the preserved control/onboarding design directly on Rust semantic actions, SDL3 input contexts, focus routing, and generated prompt tokens. Keyboard, mouse, controller, accessibility, remapping, and automation dispatch the same action catalog.

New implementation and tests are independent MIT work unless an exact contribution by an approved MIT provenance grantor is admitted through the recorded file-level MIT grant. Preserve every player-facing, accessibility, disclosure, and performance design decision below.

Required verification

  • Test pure state/geometry/material/UI behavior headlessly where possible and run supported Linux/Windows integration paths.
  • Add bounded malformed, stale, lifecycle, resource-loss, and recovery cases appropriate to the owner.
  • Add shared Go/Rust protocol fixtures for authoritative fields; presentation never reconstructs hidden rules.
  • Use released shared renderer/protocol/toolkit contracts and wrapper-managed replacement scenarios.
Preserved product/design specification and historical implementation notes

Summary

Rebuild Atrinik's controls and first-player onboarding as one coherent system based on stable semantic actions rather than hard-coded keys, raw command strings, and isolated tutorial notes.

The current client already has configurable keybindings, a keybinding settings popup, help notifications, and the Deserted Island tutorial quest. The missing infrastructure is a shared action catalog, input contexts, prompt substitution, onboarding state, and repeatable playtest coverage.

This supersedes the idea of adding one bank tutorial (#39) or running an undirected tutorial test (#73) before the controls, UI, and combat interaction model stabilize.

Existing foundations

  • client/src/client/keybind.c loads settings/keys.dat and maps SDL key/modifier values to command strings.
  • client/src/gui/popups/settings_keybinding.c can add, edit, remove, and toggle repeat for bindings.
  • Existing ?ACTION commands already provide an informal semantic layer for movement, apply, get/drop, help, and UI actions.
  • Quest/interface XML can emit delayed notifications with action/shortcut fields.
  • The Deserted Island and Incuna content already form the opening tutorial path.
  • Add resolution-independent UI scaling and native display/frame pacing #20 owns scalable settings/UI presentation, while the client-session proposal owns renderer-independent semantic action execution.

Proposed design

Stable action catalog

Define one catalog of stable action IDs with:

  • display name and help text;
  • input contexts where the action is valid;
  • press/release/hold/repeat behavior;
  • whether it is bindable and its default keyboard/controller bindings;
  • the semantic action function it invokes;
  • optional tutorial category and icon.

SDL key codes, scancodes, controller buttons, and command strings are bindings/adapters, not persisted gameplay identities. The catalog should drive default bindings, the settings UI, help prompts, conflict checks, automation actions, and onboarding copy.

Input contexts and arbitration

Define explicit contexts such as gameplay, targeting, text entry, dialog, inventory/container, popup/menu, and spectator/editor. Resolve conflicts deterministically and show them in settings.

Held movement, run, fire, and repeated actions must have paired release/cancel semantics. Focus loss, popup transitions, rebind, disconnect, and controller removal must clear held state. atrinik/atrinik#128 should supply SDL3 keyboard/controller/text-input events without changing the action contract.

Support keyboard first, then ordinary gamepads. Do not embed controller-specific wording in quests.

Dynamic prompts

Add safe prompt tokens for authored help/interface text, for example an action reference that renders the player's current binding and falls back to the action's localized/display name if unbound.

Quest and tutorial content must say “use Apply [binding]” from the catalog rather than hard-code A, Q, mouse buttons, or legacy command names. Rebinding updates future prompts immediately.

Onboarding state and curriculum

Define a small, data-driven sequence of observable competencies rather than one linear modal tutorial:

  • movement, stop/run, camera/map reading;
  • inspect, target, apply/interact, get/drop, inventory/container;
  • combat intent, action timing, healing/recovery, death/savebed;
  • dialog, quests/journal, map markers, shops/bank;
  • party/support and advanced systems only when unlocked.

Completion should be triggered by authoritative semantic actions and resulting state transitions, not by opening a help page. Store bounded completion state with stable lesson IDs, allow replay/reset, and never permanently block progression because a notification was dismissed.

Keep content delivery contextual: early quest/dialog prompts, optional practice interactions, and a discoverable tutorial/help browser. Avoid a wall of controls at login.

Opening-content rewrite and audit

Audit the Deserted Island, Incuna, bank interactions, help pages, notifications, and default bindings against the catalog. Rewrite stale instructions and add narrowly scoped practice where a mechanic is otherwise introduced without feedback.

Use the current opening path as the pilot before adding later combat disciplines from atrinik/server#27 or wind-up-specific lessons from atrinik/server#25.

Playtest harness

Add a checklist and automated action/state smoke path that can run through the renderer-independent session/action layer:

  1. start with default settings;
  2. complete core movement/interaction/inventory/dialog lessons;
  3. rebind at least one core action and verify prompt substitution;
  4. reconnect/focus-loss during a held action;
  5. complete the bank/shop lesson;
  6. replay/reset lessons;
  7. finish the opening quest without external instructions.

Record only lesson IDs and outcomes needed to diagnose flow; do not add invasive player analytics by default.

Delivery plan

  1. Inventory commands/default bindings and define the action catalog.
  2. Route keybindings and UI input through semantic actions.
  3. Add contexts, conflict diagnostics, held-action cleanup, and SDL3 controller support.
  4. Add prompt tokens and lesson-state definitions.
  5. Rewrite the opening tutorial/help/bank content.
  6. Add automated and human playtest scenarios, then remove obsolete hard-coded help paths.

Acceptance criteria

  • One stable action catalog drives defaults, settings, help prompts, onboarding, and automation.
  • Input contexts and conflicts are explicit and user-visible.
  • Rebinding a core action changes subsequent authored prompts without editing content.
  • Focus loss, context change, disconnect, and device removal cannot leave movement/fire/run held.
  • Core lessons complete from actual actions and authoritative results, can be replayed/reset, and cannot soft-lock progression.
  • The opening path teaches movement, interaction, inventory, dialog/quests, combat recovery, and bank/shop use at the point of need.
  • Keyboard-only and controller-first playthroughs do not require hard-coded legacy keys.
  • Automated smoke and a concise human checklist cover default, rebound, reconnect, and replay paths.

Validation

Unit-test catalog uniqueness, binding serialization, contexts, conflicts, prompt substitution, held-action cleanup, and lesson transitions. Run the opening content through interface/quest validation and map checking. Exercise keyboard and controller input under SDL3 and run a fresh-character end-to-end playtest with no external guide.

Depends on atrinik/atrinik#128, #20, and the renderer-independent client session/action proposal. Related: atrinik/server#27 and atrinik/server#25. Supersedes atrinik/atrinik#39 and atrinik/atrinik#73.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Fields

    Priority

    None yet

    Start date

    None yet

    Target date

    None yet

    Effort

    None yet

    Projects

    Status
    Backlog

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions