Files
stickman/docs/specs/phase_17a_prop_roles_ui.md
ryan 1d4a71525a Implement Phase 17a Prop Roles UI/UX Specification and associated functionality
- Added UI/UX specification for prop roles and set down mechanics in phase 17a.
- Created `PropStageRoles` script to manage normalized behavior for props, including depth, motion, and collision settings.
- Introduced `StagePhysicsPolicy` for shared physics configurations related to props and actors.
- Developed comprehensive tests for prop roles, including default settings, legacy migration, serialization, and runtime behavior.
- Ensured proper handling of set down actions, including clearance and orientation preservation.
2026-10-09 23:11:34 -04:00

13 KiB
Raw Permalink Blame History

Phase 17a — Prop Roles and Set Down: UI/UX Specification

Status: User-approved and accepted: Phase 17a UI. Source: Phase 17 — Props for Storytelling. Scope: Sandbox Stage EDIT and DIRECT controls for placed props. Phase 17b Use spots, 17c wobble, and 17d scene groups follow separately.

Child flow

In EDIT, the child places a prop and selects it. A settings card opens near the right edge of the stage, leaves the artwork visible, and identifies the selected placed prop by icon and name. The header shows the selected prop's name without a second Prop settings title. The child chooses how it draws, how it begins PLAY, and what it collides with. Changes are visible on the stage immediately and belong to that placement, so another copy of the same asset can behave differently.

In DIRECT, the child selects a stickman and adds Set Down beside Pick Up Prop, Drop Prop, and Throw Prop. A cursor guide invites a stage click. The click records the requested release point, including a point in open air. If that point embeds the prop inside terrain or a support prop, the runtime moves the release origin straight up enough to clear the collision shape. The stickman approaches from the ground and releases the held prop there; the prop then falls under physics. The preview does not promise a final landing spot.

Control layout and node structure

  • Keep the Stage's current top mode switcher, left asset palette, and bottom status bar. Place the Prop settings card in a PanelContainer over the right side of the EDIT viewport, inset from the screen edge and below mode/run controls. Use a MarginContainer and scrollable VBoxContainer so longer labels and raised font sizes do not clip. The card may shrink with the window, but must leave a usable central stage view.
  • The card header contains a prop icon, the placed prop's display name, and a 44×44 or larger ✕ Close button. Closing the card leaves the prop selected and exposes a Settings reopen control; it stays closed while that same prop remains selected. Selecting a different prop updates and reopens the card. Selecting terrain or a stickman hides the prop card. A scene with multiple selected objects does not silently change all their settings: show Select one prop to change its settings and a visible way to return to the stage.
  • Under Where it appears, use two full-width, mutually exclusive large buttons: Behind stickmen and In front of stickmen, each with a small depth illustration. Show the chosen button with the EDIT accent. The stage redraws the prop immediately so the result can be seen among characters; no ground-point sorting control appears in 17a.
  • Under When PLAY starts, use two mutually exclusive buttons: Stays in place and Can fall and move. New placements select Stays in place. The child can change the setting for each placement. Existing saved scenes should display their migrated legacy behavior instead of silently adopting the new default.
  • Below those buttons, use three independent, at least 44 px high switch rows: Props can sit on top, Blocks stickmen, and Stickmen can pick it up. Add a short plain-language line beneath a row only when its outcome might surprise the child. Under Props can sit on top, show Other props can land on this one. When Blocks stickmen is on, show Stickmen cannot walk through it. For Stays in place, show Stays here while PLAY runs. when pickup is off and Stays here until picked up. when pickup is on. Blocks stickmen describes the prop before pickup or release and does not force either of the other capabilities on.
  • If Stickmen can pick it up is on, reveal an After letting go section with the intro After Set Down, Drop, or Throw: and independent Can bump into stickmen and Can bump into other props switches. These settings apply after Set Down, Drop, or Throw. They remain separately editable from the initial Blocks stickmen and Props can sit on top settings. A prop can therefore let stickmen walk through at the start and collide with them after release. Hide this section when pickup is off; keep its values if the child toggles pickup off and back on during the same edit.
  • For new placements, both After letting go switches default to On. Can bump into other props lets a released object land on a support prop such as a table. If the child turns it Off, the released object passes through props, including support props; terrain such as the floor can still catch it.
  • Do not expose collision layers, mass, z-index, or numeric force in the card. Use the existing prop's selected outline and a small stage badge when a setting changes so the child can see which object changed. Use a brief, nonblocking confirmation such as This prop is behind characters when a depth change is visually obscured.
  • Card choices apply as soon as the child presses them and mark the scene as changed. ✕ Close dismisses the card and keeps the chosen settings; it is not a rollback button. The child can reopen the card and change a choice again. PLAY reset restores the authored settings and placement.
  • Add an Objects here button near the cursor when an EDIT click covers multiple selectable objects. It opens a themed popup with a vertical list of the objects under that point, each row containing a thumbnail or recognizable type icon, name, and depth cue. Every row is at least 44 px high. The currently selected object is marked. Choosing a row selects that exact object and opens its card; the menu remains available when the chosen object is completely covered. Normal click still selects the visible object; the chooser makes covered props reachable without relying on a hidden repeated-click or keyboard gesture. The chooser must not interfere with box selection or shift multiselection.
  • In DIRECT, add Set Down… to the same action entry points as Drop and Throw, including the stickman action popup and Action Editor. The Action Editor has a Choose release place button and the existing visible Cancel / Done pattern. A saved Set Down action can reopen its target and use Change release place.

Theme, size, and accessibility

  • Use SandboxTheme.control_theme() for the card and all popups. Read fonts, selected states, neutral surfaces, borders, EDIT cyan, DIRECT amber, and valid/invalid preview colors from SandboxTheme and its JSON contract. Any new visual tokens belong in that contract with fallback values; avoid fixed UI colors and font sizes in implementation.
  • Interactive card rows, segmented buttons, popup rows, and the DIRECT Cancel button have a minimum pointer target of 44×44 logical pixels and a height no smaller than the applicable button_min_height theme token. Containers wrap or scroll at narrow widths and larger font settings. Labels should remain readable without hover tooltips.
  • Selection uses both an outline and a name or icon cue, so color alone never identifies a prop. Selected switches show a check as well as accent color. Popup and dialog windows receive theme.control_theme() explicitly.
  • Each active cursor workflow has an obvious ✕ Cancel button close to the pointer or action card, and Esc/right-click may also cancel. The child does not need a keyboard shortcut to finish or leave Set Down target capture.

On-canvas and cursor feedback

  • In EDIT, maintain a high-contrast selection outline above stage artwork even when the selected prop draws behind characters. The Objects here chooser uses geometric candidates from the clicked position, including obscured props; draw order cannot make a selected prop uneditable. The Prop settings card stays outside the prop's immediate drag area where space permits.
  • During Set Down target capture, use the DIRECT amber mode frame and a cursor-attached pill: Click where to let go. Draw a small cross at the candidate world point, a translucent ghost of the known held prop centered at the intended release point, and a visible guide from the stickman's grounded approach/reach pose to that point. The guide follows the cursor continuously. It is a release preview, not a forecast of where the prop will settle.
  • A reachable point with room to release shows a green ghost/guide and Ready to set down. An unreachable point or a point blocked by the character or a non-support prop shows red and a short cause near the cursor, such as Too far to reach or No room to let go here. Open air can be valid. When a point is inside a support surface, keep the requested click visible with an amber cross and show the corrected ghost above it, joined by a vertical guide. This is collision clearance, not surface snapping or a special support marker; no landing surface is required.
  • When the queued actions make the held prop known, preview its shape. When the held prop cannot be known during authoring, show a neutral object marker and Prop depends on earlier actions; do not invent a specific silhouette or landing path. The stage can still assess the actor's route and reach where possible. If no prop is held when Set Down executes, give a concise cue at the stickman and continue safely according to the architecture spec.
  • Invalid targets do not close capture or erase the draft action. A valid click records the release point and returns to the action's editor or queue flow, with a visible Change release place path.
  • ✕ Cancel during target capture discards the new candidate point and returns to the previous action editing state. When changing an existing Set Down action, cancellation keeps its earlier release point. Done commits a valid draft action; a draft without a chosen point cannot be committed. If the actor or scene changes after authoring, PLAY should show a recoverable failure cue rather than silently placing the prop elsewhere.

Copy map

UI location Exact child-facing copy
Card header Selected prop name with type icon; no separate Prop settings title
Depth heading/options Where it appears · Behind stickmen · In front of stickmen
Initial behavior heading/options When PLAY starts · Stays in place · Can fall and move
Initial switches Props can sit on top · Blocks stickmen · Stickmen can pick it up
Release section/switches After letting go · Can bump into stickmen · Can bump into other props
Overlap chooser Objects here · Choose an object
DIRECT action Set Down… · Choose release place · Change release place
Cursor and target feedback Click where to let go · Ready to set down · Too far to reach · No room to let go here · Prop depends on earlier actions
Exit/action buttons Settings · ✕ Cancel · Done · ✕ Close

UI boundaries for architecture

  • Depth is a per-placement visual choice and remains independent of collision, pickup, and starting behavior. A fixed prop can hold another prop while stickmen pass through it. A staged pickup prop can begin nonblocking and gain chosen collisions after release.
  • Holds other props is a capability backed by the prop's existing collision geometry. There is no authored support line, suggested surface, surface snapping, or special table targeting in this UI.
  • Set Down's clicked point is the requested release point; if its collision shape would overlap terrain or a prop configured to hold other props, runtime raises the release origin vertically until it clears. Actor and reach checks still apply, and physics determines the subsequent fall and landing. There is no named support surface, sideways snapping, or requirement for a landing surface.
  • The 17b Use spot controls may later extend the selected prop card; 17c can add a simple impact response row; 17d can add group organization controls. Their detailed UI is outside this 17a spec.

Implementation and verification status

  • The card uses StageInspectorPanel, StagePanelChoiceGroup, and StagePanelToggleRow from scripts/shared/stage_ui/, styled from stage_panels theme tokens. Future in-stage inspectors should follow the shared Stage panel UI system.
  • The overlap chooser lists candidate names and depth/type cues in 44 px rows. It uses type icons rather than prop thumbnails. The prop settings header likewise currently uses a type icon and the selected prop name.
  • Set Down target capture, visible Cancel, conditional unknown-prop messaging, release ghost, approach/reach guide, and valid/invalid feedback are implemented and accepted. The accepted as-built UI shows feedback text in the stage status line and places DIRECT Cancel in the top-right action area; it does not include a cursor-attached hint or a separate depth-change badge/toast.
  • Automated test run: no execution result is documented. Card sizing, overlap selection, Set Down feedback, and old-scene presentation remain useful visual regression guidance.