Files
stickman/docs/plans/action_reactions_design_brief.md
T

109 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Action Reactions — Product Design Brief
> **Status:** Accepted product decisions captured from the design conversation; not a final architecture or implementation specification.
> **Audience:** UI/UX, architecture, and implementation.
> **Purpose:** Preserve the agreed child-facing behavior and identify the remaining product and technical questions before implementation.
## Goal
Let a child connect a specific moment in an authored action to a purposeful response from one or more characters. A reaction can contain ordered steps, combine compatible actions such as walking and speaking, and itself become the source of another reaction. The same scene events can also be observed by stage-level handlers such as sound or lighting cues.
The child is directing a planned scene. Reaction links are intentional links to authored action instances, not broad reusable rules such as “whenever Milo walks.”
## Accepted child flow
1. In **DIRECT**, the child selects a character. The Director inspector appears only while a character is selected. Clicking outside dismisses it; there is no close button. This is an intentional departure from the shared Stage inspector shell’s fixed Close control. The Phase 20a **EDIT** naming inspector is a separate workflow and retains the shared shell's labeled Close control.
2. The inspector keeps the three quick actions **Move**, **Say**, and **Wait** visible.
3. An authored action card can be opened to reveal its management choices. From a specific action, the child chooses **Make someone react to this…**.
4. The **When** choice is contextual to that action. The child does not browse one long list of generic events.
5. The child chooses who responds from a visual, searchable character roster, with on-stage picking available where useful. Each additional responder has a separate **Then** lane.
6. **Then** is an ordered set of numbered steps. Actions placed together in one step start together; the next step waits until the current step’s actions finish.
7. Reactions to reactions use the same flow. They appear as separate linked cards, not as a nested graph. The source action shows that it starts reactions; browsing all reactions supports search and grouping by their **When** event.
Numbered steps and paired actions should fit the shared Stage inspector visual system, not introduce a parallel popup style. The shell should retain its safe placement and accessible, clearly labeled controls. The agreed outside-click dismissal is a deliberate exception to the shell’s usual Close button.
## Stage character names
- A placed character can be renamed from its inspector when selected in **Edit** mode. This is a new stickman inspector; the current Edit-mode inspector UI is for props and scenery.
- The name belongs to that character instance in the scene. Renaming it does not rename or modify the reusable stickman asset.
- Character and prop instance names share one scene-wide, case-insensitive uniqueness rule. Placing or duplicating characters that share an asset default name assigns a distinct suffix, such as **Milo**, **Milo 2**, and **Milo 3**.
- Action and reaction cards, event descriptions, and responder choices use the current stage-character name.
- A character’s saved identity is independent of its display name, so renaming it does not retarget its actions or reactions.
## Stage prop names
- A placed prop can be renamed from its selected-prop inspector in **Edit** mode using a **Name on stage** field. The name belongs to the scene instance and does not modify the reusable prop asset.
- Duplicate props receive a distinct default name, such as **Blue Door** and **Blue Door 2**. Renaming an instance does not change its saved identity or retarget existing links.
- Target choices and action/reaction descriptions show the instance name so a child can distinguish props of the same asset. Where helpful, target pickers should also show a thumbnail or highlight the exact prop on stage.
- A Move To action can be described as **Walk to Blue Door** only when it is linked to that specific prop instance. A free-position target remains a place, optionally described as **Place 2 · by Blue Door**. Do not infer prop identity from coordinate proximity.
## Choosing overlapping stage objects
- A normal click on one object selects it immediately. A click that hits multiple objects opens **Objects here** and lists only objects whose visible geometry is actually under the click; an object merely nearby or inside another object's bounding-box corner is not a candidate.
- Keep the previous selection and inspector as-is while the chooser is open. Hovering or keyboard-focusing a row previews that exact candidate on the stage without committing selection.
- Choosing a row commits that object and opens its inspector. Cancel, Escape, or outside dismissal closes the chooser and keeps the previous selection. The click that dismisses the popup must not also select an object behind it.
- Rows use the current scene instance name and a clear character/prop icon. The accompanying approved mockup is [Objects here overlap picker](action_reactions_mockups/06_edit_overlap_picker.png).
## DIRECT mode action previews
- A selected character’s route is labeled with its authored movement type, such as **Walk** or **Run**. The destination marker identifies the named target, such as **Blue Door**. Do not use a generic “planned walk” label; show only movement types the editor supports.
- A **Say** step is represented on the stage by a single speech-bubble marker at the action’s starting point. It signals that speech will happen without displaying a bubble count or keeping multiple dialogue bubbles on the stage. Any step number identifies the action’s place in the plan, not the number of speech bubbles.
- Tapping a numbered movement flag selects its existing plan step and reveals **Change place**; selecting alone never moves the destination, and flags are not draggable by default. **Change place** enters destination capture with a clear prompt and visible **Cancel**. The old flag stays faintly visible while the candidate route and flag follow the cursor. Choosing a new point or exact named prop commits the change; **Cancel** or **Esc** restores the original destination.
## Action moments
Only moments relevant to the selected authored action are shown. “Starts” is omitted from Drop and Set Down labels because the start timing is implied.
| Authored action or event | Reaction moment |
| --- | --- |
| **Move To** | When the character begins walking, or when they reach that action’s named endpoint. The endpoint is specific to that Move To action; there is no generic “walk finishes” choice. |
| **Say** | When that exact line begins (default), or after that line finishes. The line-start event occurs when the bubble/line appears, so a reaction can start while the speaker is still walking. |
| **Wait** | When that exact wait finishes (default), or when it begins. A “finished waiting” reaction only fires if the wait completes. |
| **Pick Up** | When the prop is successfully picked up and reaches the character’s hand. |
| **Use** | When the character successfully uses the selected prop/use spot. |
| **Drop** | When the character begins the authored Drop action. |
| **Set Down** | When the character begins the authored Set Down action. |
| **Throw action** | A separate event for when a character throws a prop. This is distinct from a prop touching a character. The event fires when the character begins the authored Throw action. |
| **Moving prop touches character** | A separate scene event for a moving prop touching a character, such as “When a prop touches Ava.” It is not tied back to, or tracked as, the authored Throw action that may have launched it. Fire once when contact begins, not every physics frame; if contact ends and a new touch occurs, that is a new event. |
| **Ragdoll** | **When Milo falls.** No separate settled/lying-still moment for now. Landing, bouncing, and prop contact are distinct physical events. |
| **Recover** | When Milo is back on his feet, after the Recover action completes. |
## Reaction priority and action flow
- A reaction begins as soon as its selected source moment occurs. It does not wait for the source character’s other action in the same step to finish. For example, Milo can **Walk to Red Door + Say “Help!”** together; Ava’s reaction starts when that exact Say line appears, while Milo keeps walking.
- A reaction takes priority for its responder. If Ava is doing an incompatible action, that action pauses. Compatible actions may continue together, such as adding speech while a walk continues.
- Ava completes all numbered steps in the reaction before returning to her paused authored plan. Actions grouped in one step start together; the step ends when all its actions finish. Ava resumes her paused action and then continues her original queue.
- A **Follow Milo** action tracks Milo’s live position. In the agreed example, Ava follows while Milo walks, and the follow ends when Milo reaches the door and Ava catches up.
- If a new reaction for Ava triggers while she is already reacting, the new reaction takes over and cancels the unfinished steps of the current reaction. Completed actions are not undone. The original authored plan remains paused and resumes after the new reaction finishes. The saved earlier reaction remains available for later plays; there is no queue of superseded reactions.
- The user does not want extra explanatory UI copy for the basic priority/resume behavior.
- Do not show loop warnings for ordinary authored reaction chains. Links refer to specific authored actions, so a finite chain remains finite unless the child deliberately authors more links. The moving-prop contact event is independently repeatable per distinct contact, as described above.
## Event listeners beyond characters
One scene event can start a linked character reaction and notify external handlers from the same occurrence. Handlers are not limited to characters: they may drive stage-wide effects such as a sound or lighting cue. For example, Milo’s specific “Help!” line can start Ava’s reaction and notify a stage handler.
## Editing and deletion
- Editing the destination of an existing Move To action keeps reactions attached to that authored action and updates the displayed trigger location.
- Deleting an action with dependent reactions warns that reactions will also be removed. Do not enumerate all affected reactions. Deleting it removes dangling reactions, including follow-up reactions downstream. If there are no dependent reactions, use a normal confirmation to delete the action.
- If editing an action removes the moment a reaction depends on (for example, changing a Walk to a Say), use the same confirmation style as deleting an action with reactions. Explain that reactions will also be removed; on confirmation, delete the dangling reactions and downstream reactions. Canceling keeps the original action and reactions. Never silently retarget a reaction to an unrelated moment.
## Existing visual guidance and intentional departures
- Use the established Stage inspector visual system and its shared theme tokens for the inspector shell and controls.
- The no-close-button, outside-click dismissal behavior is an intentional departure from the Stage panel system’s fixed Close button, chosen by the user for this inspector.
- The user chose a sparse reaction flow and simple delete warning. Do not add an itemized dependent-reaction list to the delete confirmation.
- A persistent actor-specific inspector context and actor-named reopen affordance were proposed during UI/UX review; their final layout is not part of the decisions captured here.
## Architecture follow-up before implementation
The product decisions require an architecture specification for:
- Stable authored action identity across save/load, so links remain attached to the exact action rather than row position or action type.
- Stable stage-character and prop-instance identities independent of display names, so renames do not retarget actions or reactions and duplicate instances remain distinct.
- A Move To target linked to a prop instance must retain that identity separately from its approach position; free-position targets remain distinct from prop-linked targets.
- Event routing that can notify both reactions and external/stage handlers from one event, including the moving-prop contact event.
- Grouped concurrent actions, multi-step Then execution, reaction priority, interruption and resumption, replacement of an active reaction, and live actor following.
- Distinguishing authored Drop and Set Down events from incidental prop release during ragdoll or other runtime behavior.
These are implementation constraints to carry into the architecture phase; this brief does not claim the current runtime already supports them.