# Phase 4: Triggers & Event System — Implementation Plan ## 1. Overview Phase 4 adds **reactive storytelling** to the Sandbox Stage. While Phase 3a gave directors _sequential_ control (actions in a fixed order), Phase 4 gives them _reactive_ control — **"When X happens, do Y."** This unlocks: - **Cross-stickman communication** (Stickman A arrives → Stickman B speaks) - **Environmental reactions** (Stickman reaches crate → crate explodes) - **Branching narratives** (Arrive at different waypoints → different reactions) **Crucially:** Phase 4 **does not** replace or duplicate the Phase 3a Action Queue. Sequential actions for a single stickman (Walk → Wait → Speak → Walk) remain unchanged. Phase 4 adds **cross-object reactivity**. --- ## 2. Core Distinction | Feature | Phase 3a (Already Works) | Phase 4 (New) | | ----------------------------------------------- | ------------------------ | -------------- | | Walk → Wait → Speak → Walk | ✅ Action Queue | ✅ (unchanged) | | Waypoint → next action | ✅ Action Runner | ✅ (unchanged) | | **Stickman A arrives → Stickman B speaks** | ❌ | ✅ NEW | | **Stickman collides with prop → prop explodes** | ❌ | ✅ NEW | | **Stickman enters area → all stickmen react** | ❌ | ✅ NEW | | **Multiple reactions per event** | ❌ | ✅ NEW | --- ## 3. The User's Mental Model The director should think of events as **"When → Then"** rules that exist _alongside_ the action queues. - **Action Queue:** "Stickman A walks to the crate, waits, then speaks." - **Event Rule:** "When Stickman A reaches the crate, Stickman B says 'Welcome!'" The event rule is **not** part of Stickman A's queue. It's a separate rule that watches Stickman A and reacts independently. --- ## 4. Milestone Breakdown | # | Milestone | Description | | --- | --------------------------- | ------------------------------------------------------- | | 4.1 | **Event Data Model** | Define rule structure and storage. | | 4.2 | **Trigger System** | Detect and emit events from stickmen, props, and areas. | | 4.3 | **Event Rule UI** | Visual rule builder (When → Then workflow). | | 4.4 | **Trigger Areas** | Placeable `Area2D` sensors. | | 4.5 | **Prop Interaction Events** | Prop collisions emit events. | | 4.6 | **Chain Reactions** | Multiple actions per rule, executed in sequence. | | 4.7 | **Integration & Polish** | Full end-to-end testing, bug fixes, UI polish. | --- ## 5. Milestone 4.3: Event Rule UI ### 5.1. The "When..." Option ``` The existing action popup is extended with a new section: ┌─────────────────────────────────────────────┐ │ 🚶 Walk To │ │ 💬 Speak │ │ ⏳ Wait │ │ 💥 Ragdoll │ │ 🔄 Recover │ │ ───────────────────────────────────────── │ │ ⚡ When... (opens trigger sub-menu) │ └─────────────────────────────────────────────┘ ``` **Design note:** The "When..." option is visually separated (line divider) to signal it creates a _rule_, not a direct action. ### 5.2. Trigger Sub-Menu ``` When "When..." is clicked, the popup expands/replaces with trigger types: ┌─────────────────────────────────────────────┐ │ 📍 Arrives at a waypoint │ │ ✅ Completes any action │ │ 💬 Finishes speaking │ │ 🎯 Enters trigger area │ │ 💥 Collides with something │ │ ⬅ Back to actions │ └─────────────────────────────────────────────┘ ``` Each trigger type corresponds to a signal emitted by stickmen or the stage. ### 5.3. The Rule Building Flow (6 Stages) ``` ┌──────────────┐ │ STAGE 1 │ → User clicks stickman → popup opens │ IDLE │ └──────┬───────┘ │ Click "When..." ▼ ┌──────────────┐ │ STAGE 2 │ → User selects trigger type │ SELECT_TRIGGER│ └──────┬───────┘ │ (If trigger needs a target: waypoint, area, prop) ▼ ┌──────────────┐ │ STAGE 3 │ → User clicks the specific target │ TARGET_ENTRY │ (e.g., a waypoint dot on the stage) └──────┬───────┘ │ ▼ ┌──────────────┐ │ STAGE 4 │ → User selects the action (Speak, Walk, etc.) │ SELECT_ACTION│ └──────┬───────┘ │ (If action needs a target: a stickman or prop) ▼ ┌──────────────┐ │ STAGE 5 │ → User clicks the target stickman/prop │ TARGET_ENTRY2│ └──────┬───────┘ │ (If action needs params: text, duration, etc.) ▼ ┌──────────────┐ │ STAGE 6 │ → User fills in params │ PARAMS │ └──────┬───────┘ │ ▼ ┌──────────────┐ │ STAGE 7 │ → Rule is stored. Visuals update. │ DONE │ └──────────────┘ ``` **Escape** at any stage cancels rule creation and returns to IDLE. --- ## 6. Complete UI Walkthrough: "A Reaches Waypoint → B Speaks" ### Step 0: Prerequisites (Edit Mode) - Stickman A and Stickman B are placed on the stage. - Stickman A already has a **"Walk To"** action queued (with a visible waypoint marker on the stage), OR the user is about to create one. ### Step 1: Create Stickman A's Walk (If Not Done) | # | User Action | System Response | | --- | -------------------------------------------------- | ------------------------------------------------------------------------ | | 1 | Click the **"Direct"** tool button in the palette. | Cursor changes to crosshair. | | 2 | Click **Stickman A** on the stage. | Action popup appears. | | 3 | Click **"🚶 Walk To"** in the popup. | Popup closes. Stage enters target placement mode. | | 4 | Click a spot on the stage. | Blue waypoint dot appears. `walk_to` action added to Stickman A's queue. | ### Step 2: Create the Reactive Event Rule | # | User Action | System Response | | --- | --------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | | 5 | Click the **"Direct"** tool again (if it was deselected). | Cursor changes to crosshair. | | 6 | Click **Stickman A** on the stage. | Action popup appears with new "When..." option. | | 7 | Click **"⚡ When..."** | Trigger sub-menu opens. | | 8 | Click **"📍 Arrives at a waypoint"** | Popup closes. Cursor changes to target selector. Status bar: _"Click the waypoint you want to trigger on."_ | | 9 | Click **the blue waypoint dot** on the stage. | Waypoint glows green briefly. Popup reappears with trigger confirmed. | | 10 | Click **"💬 Speak"** | Popup closes. Cursor changes to target selector. Status bar: _"Click the stickman who will speak."_ | | 11 | Click **Stickman B** on the stage. | Stickman B glows yellow. Text dialog appears. | | 12 | Type **"Hello there!"** and click **[OK]** | Dialog closes. Toast: _"Rule created!"_ | ### Step 3: Visual Feedback (Edit Mode) | Element | Appearance | Description | | ---------------- | ------------------------------------------- | --------------------------------------- | | **Dashed line** | White dashed line | Connects waypoint to Stickman B. | | **Label** | _"When arrives → Speak 'Hello there!'"_ | Centered on the line. | | **Color coding** | Green waypoint + orange badge on Stickman B | Shows trigger source and action target. | | **Rule badge** | ⚡ icon on the label | Hover shows full rule details. | | **Delete icon** | ✕ on the label | Click to remove rule. | ### Step 4: Test in Play Mode | # | User Action | System Response | | --- | ------------------------------------- | ----------------------------------------------------------- | | 13 | Click **"Play"** button. | All queues start executing. | | 14 | Stickman A walks to waypoint. | Normal Phase 3a behavior. | | 15 | When Stickman A arrives, event fires. | Stickman B says **"Hello there!"** (speech bubble appears). | --- ## 7. Visual Feedback (Edit Mode Only) ### 7.1. Rule Visualization Elements | Element | Color/Style | Position | | ------------------- | ----------------------------- | ---------------------- | | **Trigger badge** | Green, small, "⚡" | Near source object. | | **Action badge** | Orange, small, "→" | Near target object. | | **Connection line** | Dashed white, alpha 0.6 | From source to target. | | **Label** | White text on dark background | Centered on line. | | **Waypoint glow** | Green (if trigger source) | On the waypoint dot. | ### 7.2. Rule Interaction | Action | Behavior | | --------------------- | ----------------------------------------- | | **Click rule label** | Opens edit popup for that rule. | | **Click delete icon** | Removes the rule (confirmation optional). | | **Hover rule label** | Shows tooltip with full rule details. | ### 7.3. What the User Sees on the Stage ``` Stickman A Stickman B ┌──────┐ ┌──────┐ │ 🔵 │ │ 🔵 │ │ (A) │ │ (B) │ └──┬───┘ └──┬───┘ │ │ │ ════════════╗ │ │ (When arrives) │ │ │ ════════════╝ │ │ ── ── ── ── ── ── ── ── →│ │ (Then Speak "Got it!") │ │ │ ┌──┴──────────────────────────────────┐│ │ 📍 Waypoint 3 ││ └──────────────────────────────────────┘ ``` --- ## 8. Event Data Model ### 8.1. Rule Structure Rules are stored in the stage's event registry and have three parts: **Trigger** — The "When" part. | Trigger Type | Source | Target | Description | | --------------------- | ------------- | ------------ | ------------------------------------ | | `arrived_at_waypoint` | Stickman | Waypoint | Stickman completes a walk. | | `action_finished` | Stickman | Action type | Stickman finishes any action. | | `speech_finished` | Stickman | (none) | Stickman finishes speaking. | | `entered_area` | Stickman/Prop | Trigger Area | Object enters a trigger area. | | `collided` | Stickman/Prop | Object | Object collides with another object. | **Action** — The "Then" part. | Action Type | Target | Params | | -------------- | -------- | ----------------------------------- | | `walk_to` | Stickman | `target` (Vector2) | | `speak` | Stickman | `text` (String), `duration` (float) | | `wait` | Stickman | `duration` (float) | | `ragdoll` | Stickman | (none) | | `recover` | Stickman | (none) | | `explode_prop` | Prop | (none) — future | | `spawn_prop` | Stage | `type` (String) — future | ### 8.2. Rule Storage Rules are stored in `SandboxStage._event_rules` and persist across mode toggles (Play ↔ Edit). They are **not** saved to disk in Phase 4 (deferred to Phase 5). ### 8.3. Rule Evaluation Rules are evaluated **in order** when an event occurs. If a rule's trigger matches the event, its actions are executed. --- ## 9. What's NOT in Phase 4 | Feature | Why Excluded | | ----------------------------------------------------------- | -------------------------------------------------- | | "When Stickman A arrives → Stickman A speaks" | This is just a sequential queue action (Phase 3a). | | "When Stickman A finishes walking → Stickman A walks again" | Same as above. | | Conditions (AND/OR logic) | Too complex for Phase 4; deferred to future. | | Variables / counters | Deferred to future. | | Save/Load rules to disk | Phase 5. | | Edit/Delete actions | Phase 3c. | | Stickman/Prop selector grids | Phase 3b. | --- ## 10. Acceptance Criteria ### 10.1. Cross-Stickman Events - [ ] **"When..." option appears** in the action popup. - [ ] **Trigger sub-menu opens** when "When..." is clicked. - [ ] **Waypoint trigger works:** A arrives → B speaks. - [ ] **Action completion trigger works:** A finishes speaking → B walks. - [ ] **Speech completion trigger works:** A finishes speaking → B speaks. - [ ] **Multiple actions per rule work:** Trigger → B speaks AND C walks. ### 10.2. Cross-Object Events - [ ] **Area trigger works:** A enters area → B speaks. - [ ] **Prop collision trigger works:** A hits crate → crate explodes. - [ ] **Prop reaction works:** Trigger → prop explodes (disappears + particles). ### 10.3. UI & Visuals - [ ] **Rule label shows summary:** "When arrives → Speak" text appears. - [ ] **Delete icon works:** Click ✕ → rule removed. - [ ] **Clicking rule label opens edit popup:** Click label → popup re-opens. - [ ] **Rules persist across mode toggles:** Create rule → Play → Edit → rule still there. - [ ] **Rules are cleaned up** when source/target objects are deleted. ### 10.4. Backward Compatibility - [ ] **Sequential actions still work:** Walk → Wait → Speak → Walk works. - [ ] **Existing queues unchanged:** Any Phase 3a scene loads and runs. --- ## 11. File Changes Summary | File | Changes | | ----------------------------------- | ------------------------------------------------------------- | | `scripts/sandbox_stage.gd` | Add `_event_rules`, event evaluation, rule UI state machine. | | `scripts/stickman_rig.gd` | Emit `arrived`, `action_finished`, `speech_finished` signals. | | `scripts/stage_director_visuals.gd` | Draw rule lines, labels, and badges. | | `scripts/trigger_area.gd` | NEW: Placeable `Area2D` sensor. | | `scripts/prop_block.gd` | Emit `collided` signal. | ---