Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Layer 3 — New Player Pipeline

The first-launch flow (see 17-PLAYER-FLOW.md) includes a self-identification step:

Theme Selection (D032) → Self-Identification → Controls Walkthrough (optional) → Tutorial Offer → Main Menu

Self-Identification Gate

┌──────────────────────────────────────────────────┐
│  WELCOME, COMMANDER                              │
│                                                  │
│  How familiar are you with real-time strategy?   │
│                                                  │
│  ► New to RTS games                              │
│  ► Played some RTS games before                  │
│  ► Red Alert veteran                             │
│  ► OpenRA / Remastered player                    │
│  ► Skip — just let me play                       │
│                                                  │
└──────────────────────────────────────────────────┘

This sets the experience_profile used by all five layers. The profile is stored in player.db (D034) and changeable in Settings → QoL → Experience Profile.

SelectionExperience ProfileDefault HintsTutorial Offer
New to RTSnew_to_rtsAll on“Would you like to start with Commander School?”
Played some RTSrts_playerEconomy + Controls“Commander School available in Campaigns”
Red Alert veteranra_veteranEconomy onlyBadge on campaign menu
OpenRA / Remasteredopenra_playerMod-specific onlyBadge on campaign menu
SkipskipAll offNo offer

Controls Walkthrough (Phase 3, Skippable)

A short controls walkthrough is offered immediately after self-identification. It is platform-specific in presentation and shared in intent:

  • Desktop: mouse/keyboard prompts (“Right-click to move”, Ctrl+F5 to save camera bookmark)
  • Tablet: touch prompts with sidebar + on-screen hotbar highlights
  • Phone: touch prompts with build drawer, command rail, minimap cluster, and bookmark dock highlights

The walkthrough teaches only control fundamentals (camera pan/zoom, selection, context commands, control groups, minimap/radar, camera bookmarks, and build UI basics) and ends with three options:

  • Start Commander School
  • Practice Sandbox
  • Skip to Game

This keeps D065’s early experience friendly on touch devices without duplicating Commander School missions.

Canonical Input Action Model and Official Binding Profiles

To keep desktop, touch, Steam Deck, TV/gamepad, tutorials, and accessibility remaps aligned, D065 defines a single semantic input action catalog. The game binds physical inputs to semantic actions; tutorial prompts, the Controls Quick Reference, and the Controls-Changed Walkthrough all render from the same catalog.

Design rule: IC does not define “the keyboard layout” as raw keys first. It defines actions first, then ships official binding profiles per device/input class.

Semantic action categories (canonical):

  • Camera — pan, zoom, center-on-selection, cycle alerts, save/jump camera bookmark, minimap jump/scrub
  • Selection & Orders — select, add/remove selection, box select, deselect, context command, attack-move, guard, stop, force action, deploy, stance/ability shortcuts
  • Production & Build — open/close build UI, category navigation, queue/cancel, structure placement confirm/cancel/rotate (module-specific), repair/sell/context build actions
  • Control Groups — select group, assign group, add-to-group, center group
  • Communication & Coordination — open chat, channel shortcuts, whisper, push-to-talk, ping wheel, chat wheel, minimap draw, tactical markers, callvote, and role-aware support request/response actions for asymmetric modes (D070)
  • UI / System — pause/menu, scoreboard, controls quick reference, console (where supported), screenshot, replay controls, observer panels

Official profile families (shipped defaults):

  • Classic RA (KBM) — preserves classic RTS muscle memory where practical
  • OpenRA (KBM) — optimized for OpenRA veterans (matching common command expectations)
  • Modern RTS (KBM) — IC default desktop profile tuned for discoverability and D065 onboarding
  • Gamepad Default — cursor/radial hybrid for TV/console-style play
  • Steam Deck Default — Deck-specific variant (touchpads/optional gyro/OSK-aware), not just generic gamepad
  • Touch Phone and Touch Tablet — gesture + HUD layout profiles (defined by D059/D065 mobile control rules; not “key” maps, but still part of the same action catalog)

D070 role actions: Asymmetric mode actions (e.g., support_request_cas, support_request_recon, support_response_approve, support_response_eta) are additional semantic actions layered onto the same catalog and surfaced only when the active scenario/mode assigns a role that uses them.

Binding profile behavior:

  • Profiles are versioned. A local profile stores either a stock profile ID or a diff from a stock profile (Custom).
  • Rebinding UI edits semantic actions, never hardcodes UI-widget-local shortcuts.
  • A single action may have multiple bindings (e.g., keyboard key + mouse button chord, or gamepad button + radial fallback).
  • Platform-incompatible actions are hidden or remapped with a visible alternative (no dead-end actions on controller/touch).
  • Tutorial prompts and quick reference entries resolve against the active profile + current InputCapabilities + ScreenClass.

Official baseline defaults (high-level, normative examples):

ActionDesktop KBM default (Modern RTS)Steam Deck / Gamepad defaultTouch default
Select / context commandLeft-click / Right-clickCursor confirm button (A/Cross)Tap
Box selectLeft-dragHold modifier + cursor drag / touchpad dragHold + drag
Attack-MoveA then targetCommand radial → Attack-MoveCommand rail Attack-Move (optional)
GuardQ then target/selfCommand radial → GuardCommand rail Guard (optional)
StopSFace button / radial shortcutVisible button in command rail/overflow
DeployDContext action / radialContext tap or rail button
Control groups1–0, Ctrl+1–0D-pad pages / radial groups (profile-defined)Bottom control-group bar chips
Camera bookmarksF5–F8, Ctrl+F5–F8D-pad/overlay quick slots (profile-defined)Bookmark dock near minimap (tap/long-press)
Open chatEnterMenu shortcut + OSKChat button + OS keyboard
Controls Quick ReferenceF1Pause → Controls (optionally bound)Pause → Controls

Controller / Deck interaction model requirements (official profiles):

  • Controller profiles must provide a visible, discoverable path to all high-frequency orders (context command + command radial + pause/quick reference fallback)
  • Steam Deck profile may use touchpad cursor and optional gyro precision, but every action must remain usable with gamepad-only input
  • Text-heavy actions (chat, console where allowed) may invoke OSK; gameplay-critical actions may not depend on text entry
  • Communication actions (PTT, ping wheel, chat wheel) must remain reachable without leaving combat camera control for more than one gesture/button chord

Accessibility requirements for all profiles:

  • Full rebinding across keyboard, mouse, gamepad, and Deck controls
  • Hold/toggle alternatives (e.g., PTT, radial hold vs tap-toggle, sticky modifiers)
  • Adjustable repeat rates, deadzones, stick curves, cursor acceleration, and gyro sensitivity (where supported)
  • One-handed / reduced-dexterity viable alternatives for high-frequency commands (via remaps, radials, or quick bars)
  • Controls Quick Reference always reflects the player’s current bindings and accessibility overrides, not only stock defaults

Competitive integrity note: Binding/remap freedom is supported, but multi-action automation/macros remain governed by D033 competitive equalization policy. Official profiles define discoverable defaults, not privileged input capabilities.

Official Default Binding Matrix (v1, Normative Baseline)

The tables below define the normative baseline defaults for:

  • Modern RTS (KBM)
  • Gamepad Default
  • Steam Deck Default (Deck-specific overrides and additions)

Classic RA (KBM) and OpenRA (KBM) are compatibility-oriented profiles layered on the same semantic action catalog. They may differ in key placement, but must expose the same actions and remain fully documented in the Controls Quick Reference.

Controller naming convention (generic):

  • Confirm = primary face button (A / Cross)
  • Cancel = secondary face button (B / Circle)
  • Cmd Radial = default hold command radial button (profile-defined; Y / Triangle by default)
  • Menu / View = start/select-equivalent buttons

Steam Deck defaults: Deck inherits Gamepad Default semantics but prefers right trackpad cursor and optional gyro precision for fine targeting. All actions remain usable without gyro.

Camera & Navigation
Semantic actionModern RTS (KBM)Gamepad DefaultSteam Deck DefaultNotes
Camera panMouse to screen edge / Middle-mouse dragLeft stickLeft stickEdge-scroll can be disabled; drag-pan remains
Camera zoom inMouse wheel upRB (tap) or zoom radialRB (tap) / two-finger trackpad pinch emulation optionalProfile may swap with category cycling if player prefers
Camera zoom outMouse wheel downLB (tap) or zoom radialLB (tap) / two-finger trackpad pinch emulation optionalSame binding family as zoom in
Center on selectionCR3 clickR3 click / L4 (alt binding)Mode-safe in gameplay and observer views
Cycle recent alertSpaceD-pad DownD-pad DownIn replay mode, Space is reserved for replay pause/play
Jump bookmark slot 1–4F5–F8D-pad Left/Right page + quick slot overlay confirmBookmark dock overlay via R5, then face/d-pad selectQuick slots map to D065 bookmark system
Save bookmark slot 1–4Ctrl+F5–F8Hold bookmark overlay + Confirm on slotHold bookmark overlay (R5) + slot click/confirmMatches desktop/touch semantics
Open minimap focus / camera jump modeMouse click minimapView + left stick (minimap focus mode)Left trackpad minimap focus (default) / View+stick fallbackNo hidden-only path; visible in quick reference
Selection & Orders
Semantic actionModern RTS (KBM)Gamepad DefaultSteam Deck DefaultNotes
Select / Context commandLeft-click select / Right-click contextCursor + ConfirmTrackpad cursor + R2 (Confirm)Same semantic action, resolved by context
Add/remove selection modifierShift + click/dragLT modifier while selectingL2 modifier while selectingAlso used for queue modifier in production UI
Box selectLeft-dragHold selection modifier + cursor dragHold L2 + trackpad drag (or stick drag)Touch remains hold+drag (D059/D065 mobile)
DeselectEsc / click empty UI spaceCancelB / CancelCancel also exits modal targeting
Attack-MoveA, then targetCmd Radial → Attack-MoveR1 radial → Attack-MoveHigh-frequency, surfaced in radial + quick ref
GuardQ, then target/selfCmd Radial → GuardR1 radial → GuardQ avoids conflict with Hold G ping wheel
StopSX (tap)X (tap) / R4 (alt)Immediate command, no target required
Force Action / Force FireF, then targetCmd Radial → Force ActionR1 radial → Force ActionName varies by module; semantic action remains
Deploy / Toggle deploy stateDY (tap, context-sensitive) or radialY / radialFalls back to context action if deployable selected
Scatter / emergency disperseXCmd Radial → ScatterR1 radial → ScatterOptional per module/profile; present if module supports
Cycle selected-unit subtypeCtrl+TabD-pad Right (selection mode)D-pad Right (selection mode)If selection contains mixed types
Production, Build, and Control Groups
Semantic actionModern RTS (KBM)Gamepad DefaultSteam Deck DefaultNotes
Open/close production panel focusB (focus build UI) / click sidebarD-pad Left (tap)D-pad Left (tap)Does not pause; focus shifts to production UI
Cycle production categoriesQ/E (while build UI focused)LB/RBLB/RBContextual to production focus mode
Queue selected itemEnter / left-click on itemConfirmR2 / trackpad clickWorks in production focus mode
Queue 5 / repeat modifierShift + queueLT + queueL2 + queueUses same modifier family as selection add
Cancel queue itemRight-click queue slotCancel on queue slotB on queue slotContextual in queue UI
Set rally point / waypointR, then targetCmd Radial → Rally/WaypointR1 radial → Rally/WaypointModule-specific labeling
Building placement confirmLeft-clickConfirmR2 / trackpad clickGhost preview remains visible
Building placement cancelEsc / Right-clickCancelBConsistent across modes
Building placement rotate (if supported)RY (placement mode)Y (placement mode)Context-sensitive; only shown if module supports rotation
Select control group 1–01–0Control-group overlay + slot select (D-pad Up opens)Bottom/back-button overlay (L4) + slot selectTouch uses bottom control-group bar chips
Assign control group 1–0Ctrl+1–0Overlay + hold slotOverlay + hold slotAssignment is explicit to avoid accidental overwrite
Center camera on control groupDouble-tap 1–0Overlay + reselect active slotOverlay + reselect active slotMirrors desktop double-tap behavior
Communication & Coordination (D059)
Semantic actionModern RTS (KBM)Gamepad DefaultSteam Deck DefaultNotes
Open chat inputEnterView (hold) → chat input / OSKView (hold) or keyboard shortcut + OSKD058/D059 command browser remains available where supported
Team chat shortcut/team prefix or channel toggle in chat UIChat panel channel tabChat panel channel tabSemantic action resolves to channel switch
All-chat shortcut/all prefix or channel toggle in chat UIChat panel channel tabChat panel channel tabD058 /s remains one-shot send
Whisper/w <player> or player context menuPlayer card → WhisperPlayer card → WhisperVisible UI path required
Push-to-talk (PTT)CapsLock (default, rebindable)LB (hold)L1 (hold)VAD optional, PTT default per D059
Ping wheelHold G + mouse directionR3 (hold) + right stickR3 hold + stick or right trackpad radialMatches D059 controller guidance
Quick pingG tapD-pad Up tapD-pad Up tapTap vs hold disambiguation for ping wheel
Chat wheelHold V + mouse directionD-pad Right holdD-pad Right holdQuick-reference shows phrase preview by profile
Minimap drawAlt + minimap dragMinimap focus mode + RT drawTouch minimap draw or minimap focus mode + R2Deck prefers touch minimap when available
Callvote menu / command/callvote or Pause → VotePause → VotePause → VoteConsole command remains equivalent where exposed
Mute/unmute playerScoreboard/context menu (Tab)Scoreboard/context menuScoreboard/context menuNo hidden shortcut required
UI / System / Replay / Spectator
Semantic actionModern RTS (KBM)Gamepad DefaultSteam Deck DefaultNotes
Pause / Escape menuEscMenuMenuIn multiplayer opens escape menu, not sim pause
Scoreboard / player listTabView (tap)View (tap)Supports mute/report/context actions
Controls Quick ReferenceF1Pause → Controls (bindable shortcut optional)L5 (hold) optional + Pause → ControlsAlways reachable from pause/settings
Developer console (where supported)~Pause → Command Browser (GUI)Pause → Command Browser (GUI)No tilde requirement on non-keyboard platforms
ScreenshotF12Pause → Photo/Share submenu (platform API)Steam+R1 (OS default) / in-game photo actionPlatform-specific capture APIs may override
Replay pause/play (replay mode)SpaceConfirmR2 / ConfirmMode-specific; does not conflict with live match Space alert cycle
Replay seek step ±, / .LB/RB (replay mode)LB/RB (replay mode)Profile may remap to triggers
Observer panel toggleOY (observer mode)Y (observer mode)Only visible in spectator/caster contexts

Workshop-Shareable Configuration Profiles (Optional)

Players can share configuration profiles via the Workshop as an optional, non-gameplay resource type. This includes:

  • control bindings / input profiles (KBM, gamepad, Deck, touch layout preferences)
  • accessibility presets (target size, hold/toggle behavior, deadzones, high-contrast HUD toggles)
  • HUD/layout preference bundles (where layout profiles permit customization)
  • camera/QoL preference bundles (non-authoritative client settings)

Hard boundaries (safety / trust):

  • No secrets or credentials (API keys, tokens, account auth data) — those remain D047-only local secrets
  • No absolute file paths, device serials, hardware IDs, or OS-specific personal data
  • No executable scripts/macros bundled in config profiles
  • No automatic application on install; imports always show a scope + diff preview before apply

Compatibility metadata (required for controls-focused profiles):

  • semantic action catalog version
  • target input class (desktop_kbm, gamepad, deck, touch_phone, touch_tablet)
  • optional ScreenClass / layout profile compatibility hints
  • notes for features required by the profile (e.g., gyro, rear buttons, command rail enabled)

UX behavior:

  • Controls screen supports Import, Export, and Share on Workshop
  • Workshop pages show the target device/profile class and a human-readable action summary (e.g., “Deck profile: right-trackpad cursor + gyro precision + PTT on L1”)
  • Applying a profile can be partial (controls-only, touch-only, accessibility-only) to avoid clobbering unrelated preferences

This follows the same philosophy as the Controls Quick Reference and D065 prompt system: shared semantics, device-specific presentation, and no hidden behavior.

Controls Quick Reference (Always Available, Non-Blocking)

D065 also provides a persistent Controls Quick Reference overlay/menu entry so advanced actions are never hidden behind memory or community lore.

Rules:

  • Always available from gameplay (desktop, controller/Deck, and touch), pause menu, and settings
  • Device-specific presentation, shared semantic content (same action catalog, different prompts/icons)
  • Includes core actions + advanced/high-friction actions (camera bookmarks, command rail overrides, build drawer/sidebar interactions, chat/ping wheels)
  • Dismissable, searchable, and safe to open/close without disrupting the current mode
  • Can be pinned in reduced form during early sessions (optional setting), then auto-unpins as the player demonstrates mastery

This is a reference aid, not a tutorial gate. It never blocks gameplay and does not require completion.

Asymmetric Co-op Role Onboarding (D070 Extension)

When a player enters a D070 Commander & Field Ops scenario for the first time, D065 can offer a short, skippable role onboarding overlay before match start (or as a replayable help entry from pause/settings).

What it teaches (v1):

  • the assigned role (Commander vs Field Ops)
  • role-specific HUD regions and priorities
  • request/response coordination loop (request support ↔ approve/deny/ETA)
  • objective channel semantics (Strategic, Field, Joint)
  • where to find the role-specific Controls Quick Reference page

Rules:

  • skippable and replayable
  • concept-first, not mission-specific scripting
  • uses the same D065 semantic action prompt model (no separate input prompt system)
  • profile/device aware (KBM, controller/Deck, touch) where the scenario/platform supports the role

Controls-Changed Walkthrough (One-Time After Input UX Changes)

When a game update changes control defaults, official input profile mappings, touch gesture behavior, command-rail mappings, or HUD placements in a way that affects muscle memory, D065 can show a short What’s Changed in Controls walkthrough on next launch.

Behavior:

  • Triggered by a local controls-layout/version mismatch (e.g., input profile schema version or layout profile revision)
  • One-time prompt per affected profile/device; skippable and replayable later from Settings
  • Focuses only on changed interactions (not a full tutorial replay)
  • Prioritizes touch-platform changes (where discoverability regressions are most likely), but desktop can use it too
  • Links to the Controls Quick Reference and Commander School for deeper refreshers

Philosophy fit: This preserves discoverability and reduces frustration without forcing players through onboarding again. It is a reversible UI aid, not a simulation change.

Skill Assessment (Phase 4)

After Commander School Mission 01 (or as a standalone 2-minute exercise accessible from Settings → QoL → Recalibrate), the engine estimates the player’s baseline skill:

┌──────────────────────────────────────────────────┐
│  SKILL CALIBRATION (2 minutes)                   │
│                                                  │
│  Complete these exercises:                       │
│  ✓  Select and move units to waypoints           │
│  ✓  Select specific units from a mixed group     │
│  ►  Camera: pan to each flashing area            │
│  ►  Optional: save/jump a camera bookmark        │
│     Timed combat: destroy targets in order       │
│                                                  │
│  [Skip Assessment]                               │
└──────────────────────────────────────────────────┘

Measures:

  • Selection speed — time to select correct units from a mixed group
  • Camera fluency — time to pan to each target area
  • Camera bookmark fluency (optional) — time to save and jump to a bookmarked location (measured only on platforms where bookmarks are surfaced in the exercise)
  • Combat efficiency — accuracy of focused fire on marked targets
  • APM estimate — actions per minute during the exercises

Results stored in SQLite:

-- In player.db
CREATE TABLE player_skill_estimate (
    player_id        TEXT PRIMARY KEY,
    selection_speed  INTEGER,    -- percentile (0–100)
    camera_fluency   INTEGER,
    bookmark_fluency INTEGER,    -- nullable/0 if exercise omitted
    combat_efficiency INTEGER,
    apm_estimate     INTEGER,    -- raw APM
    input_class      TEXT,       -- 'desktop', 'touch_phone', 'touch_tablet', 'deck'
    screen_class     TEXT,       -- 'Phone', 'Tablet', 'Desktop', 'TV'
    assessed_at      INTEGER,    -- Unix timestamp
    assessment_type  TEXT        -- 'tutorial_01' or 'standalone'
);

Percentiles are normalized within input class (desktop vs touch phone vs touch tablet vs deck) so touch players are not under-rated against mouse/keyboard baselines.

The skill estimate feeds Layers 2 and 4: hint frequency scales with skill (fewer hints for skilled players), the first skirmish AI difficulty recommendation uses the estimate, and touch tempo guidance can widen/narrow its recommended speed band based on demonstrated comfort.

Layer 4 — Adaptive Pacing Engine

A background system (no direct UI — it shapes the other layers) that continuously estimates player mastery and adjusts the learning experience.

Inputs

  • hint_history — which hints have been shown, dismissed, or mastered
  • player_skill_estimate — from the skill assessment
  • gameplay_events (D031) — actual in-game actions (build orders, APM, unit losses, idle time)
  • experience_profile — self-identified experience level
  • input_capabilities / screen_class — touch vs mouse/keyboard and phone/tablet layout context
  • optional touch friction signals — misclick proxies, selection retries, camera thrash, pause frequency (single-player)

Outputs

  • Hint frequency multiplier — scales the cooldown on all hints. A player demonstrating mastery gets longer cooldowns (fewer hints). A struggling player gets shorter cooldowns (more hints).
  • Difficulty recommendation — suggested AI difficulty for the next skirmish. Displayed as a tooltip in the lobby AI picker: “Based on your recent games, Normal difficulty is recommended.”
  • Feature discovery pacing — controls how quickly progressive discovery notifications appear (Layer 5 below).
  • Touch tutorial prompt density — controls how much on-screen guidance is shown for touch platforms (e.g., keep command-rail hints visible slightly longer for new phone players).
  • Recommended tempo band (advisory) — preferred speed range for the current device/input/skill context. Used by UI warnings only; never changes sim state on its own.
  • Camera bookmark suggestion eligibility — enables/disables “save camera location” hints based on camera fluency and map scale.
  • Tutorial EVA activation — in the Allied/Soviet campaigns (not Commander School), first encounters with new unit types or buildings trigger a brief EVA line if the player hasn’t completed the relevant Commander School mission. “Construction complete. This is a Radar Dome — it reveals the minimap.” Only triggers once per entity type per campaign playthrough.

Pacing Algorithm

skill_estimate = weighted_average(
    0.3 × selection_speed_percentile,
    0.2 × camera_fluency_percentile,
    0.2 × combat_efficiency_percentile,
    0.15 × recent_apm_trend,           -- from gameplay_events
    0.15 × hint_mastery_rate            -- % of hints mastered vs shown
)

hint_frequency_multiplier = clamp(
    2.0 - (skill_estimate / 50.0),      -- range: 0.0 (no hints) to 2.0 (double frequency)
    min = 0.2,
    max = 2.0
)

recommended_difficulty = match skill_estimate {
    0..25   => "Easy",
    25..50  => "Normal",
    50..75  => "Hard",
    75..100 => "Brutal",
}

Mobile Tempo Advisor (Client-Only, Advisory)

The adaptive pacing engine also powers a Tempo Advisor for touch-first play. This system is intentionally non-invasive:

  • Single-player: any speed allowed; warnings shown outside the recommended band; one-tap “Return to Recommended”
  • Casual multiplayer (host-controlled): lobby shows a warning if the selected speed is outside the recommended band for participating touch players
  • Ranked multiplayer: informational only; speed remains server/queue enforced (D055/D064, see 09b-networking.md)

Initial default bands (experimental; tune from playtests):

ContextRecommended BandDefault
Phone (new/average touch)slowest-normalslower
Phone (high skill estimate + tutorial complete)slower-fasternormal
Tabletslower-fasternormal
Desktop / Deckunchangednormal

Commander School on phone/tablet starts at slower by default, but players may override it.

The advisor emits local-only analytics events (D031-compatible) such as mobile_tempo.warning_shown and mobile_tempo.warning_dismissed to validate whether recommendations reduce overload without reducing agency.

This is deterministic and entirely local — no LLM, no network, no privacy concerns. The pacing engine exists in ic-ui (not ic-sim) because it affects presentation, not simulation.

Implementation-Facing Interfaces (Client/UI Layer, No Sim Impact)

These types live in ic-ui / ic-game client codepaths (not ic-sim) and formalize camera bookmarks, semantic prompt resolution, and tempo advice:

#![allow(unused)]
fn main() {
pub struct CameraBookmarkSlot {
    pub slot: u8,                    // 1..=9
    pub label: Option<String>,       // local-only label
    pub world_pos: WorldPos,
    pub zoom_level: Option<FixedPoint>, // optional client camera zoom
}

pub struct CameraBookmarkState {
    pub slots: [Option<CameraBookmarkSlot>; 9],
    pub quick_slots: [u8; 4],        // defaults: [1, 2, 3, 4]
}

pub enum CameraBookmarkIntent {
    Save { slot: u8 },
    Jump { slot: u8 },
    Clear { slot: u8 },
    Rename { slot: u8, label: String },
}

pub enum InputPromptAction {
    Select,
    BoxSelect,
    MoveCommand,
    AttackCommand,
    AttackMoveCommand,
    OpenBuildUi,
    QueueProduction,
    UseMinimap,
    SaveCameraBookmark,
    JumpCameraBookmark,
}

pub struct TutorialPromptContext {
    pub input_capabilities: InputCapabilities,
    pub screen_class: ScreenClass,
    pub advanced_mode: bool,
}

pub struct ResolvedInputPrompt {
    pub text: String,             // localized, device-specific wording
    pub icon_tokens: Vec<String>, // e.g. "tap", "f5", "ctrl+f5"
}

pub struct UiAnchorAlias(pub String); // e.g. "primary_build_ui", "minimap_cluster"

pub enum TempoSpeedLevel {
    Slowest,
    Slower,
    Normal,
    Faster,
    Fastest,
}

pub struct TempoComfortBand {
    pub recommended_min: TempoSpeedLevel,
    pub recommended_max: TempoSpeedLevel,
    pub default_speed: TempoSpeedLevel,
    pub warn_above: Option<TempoSpeedLevel>,
    pub warn_below: Option<TempoSpeedLevel>,
}

pub enum InputSourceKind {
    MouseKeyboard,
    TouchPhone,
    TouchTablet,
    Controller,
}

pub struct TempoAdvisorContext {
    pub screen_class: ScreenClass,
    pub has_touch: bool,
    pub primary_input: InputSourceKind, // advisory classification only
    pub skill_estimate: Option<PlayerSkillEstimate>,
    pub mode: MatchMode,            // SP / casual MP / ranked
}

pub enum TempoWarning {
    AboveRecommendedBand,
    BelowRecommendedBand,
    TouchOverloadRisk,
}

pub struct TempoRecommendation {
    pub band: TempoComfortBand,
    pub warnings: Vec<TempoWarning>,
    pub rationale: Vec<String>,     // short UI strings
}
}

The touch/mobile control layer maps these UI intents to normal PlayerOrders through the existing InputSource pipeline. Bookmarks and tempo advice remain local UI state; they never enter the deterministic simulation.