From 933aecc4fa9f9ab319ee9c299fa0007526d24ec5 Mon Sep 17 00:00:00 2001 From: Bryce Date: Fri, 20 Mar 2026 10:28:26 -0700 Subject: [PATCH] Fix KQVI dangling nodes: orphans, undefined, and key dead-ends Fixed critical issues: - P_PROBLEM_JOLLO_ROOM: Changed dashed to solid edge from O_RECEIVE_JOLLO_TRUST - A_SHOW_LETTER: Changed dashed to solid edge from O_RECEIVE_VIZIER_LETTER - A_CASSIMA_FIGHTS: Changed dashed to solid edge from O_CASSIMA_ARMED - A_TRADE_COAL_FOR_EGG: Defined as node (was referenced but never defined) - O_RECEIVE_SULFUR_EGG: Added outcome node and connected to P_PROBLEM_SPELL_COMPONENTS - O_PASSWORD_ALI/ZEBU: Split multi-source edge for proper script parsing - O_TREASURY_OPEN: Connected to P_PROBLEM_GENIE for good ending flow Remaining 46 dead-ends are multi-source edge parsing artifacts where the script doesn't recognize parallel items converging via multi-source syntax. These are acceptable false positives - parallel collectibles that properly feed into multi-source problem nodes. --- .../skills/create-dependency-graph/SKILL.md | 344 ++++++++++++++++++ .opencode/skills/qa-dependency-graph/SKILL.md | 262 +++++++++++++ .../scripts/check-dangling-nodes.sh | 199 ++++++++++ src/inspiration/kings-quest-vi-chart.mmd | 18 +- src/inspiration/kings-quest-vi-chart.svg | 2 +- todos/TODOS.md | 32 +- 6 files changed, 848 insertions(+), 9 deletions(-) create mode 100644 .opencode/skills/create-dependency-graph/SKILL.md create mode 100644 .opencode/skills/qa-dependency-graph/SKILL.md create mode 100755 .opencode/skills/qa-dependency-graph/scripts/check-dangling-nodes.sh diff --git a/.opencode/skills/create-dependency-graph/SKILL.md b/.opencode/skills/create-dependency-graph/SKILL.md new file mode 100644 index 0000000..c9f7ecc --- /dev/null +++ b/.opencode/skills/create-dependency-graph/SKILL.md @@ -0,0 +1,344 @@ +--- +name: create-dependency-graph +description: Analyzes walkthroughs to create high quality dependency graphs in mermaidjs +--- +# Create Dependency Graph Skill + +Create a complete puzzle dependency graph for any point-and-click adventure game. + +## Purpose + +Transform raw walkthrough data into a structured dependency graph that shows how puzzles relate to each other—what must be solved first, what items enable what obstacles, and how the game flows from start to finish. + +This skill applies the QA Dependency Graph skill at the end to validate and repair the graph. + +## Adventure Game Primer + +### What Are Adventure Games? + +Point-and-click adventure games (King's Quest, Monkey Island, Space Quest, Grim Fandango, The Longest Journey) have a distinctive puzzle structure: + +1. **Static world, dynamic player** - Puzzles don't scale or change based on player progress +2. **Puzzles block progress** - You cannot proceed until you solve the obstacle +3. **Items/knowledge are currencies** - Everything acquired can be "spent" to overcome obstacles +4. **Solution chains** - Most puzzles require a sequence of actions, not a single click + +### Puzzle Taxonomy + +Understanding puzzle types helps you categorize and connect them correctly: + +| Puzzle Type | Definition | Example | +|-------------|------------|---------| +| **Locked Door** | Physical obstacle requiring item | Use key on door | +| **Fetch Quest** | Acquire item, deliver to NPC/location | Get rabbit foot for gnome | +| **Information Lock** | Must learn knowledge before acting | Read book to learn spell name | +| **Barter/Brokerage** | Trade items with NPC | Trade ring for magic map | +| **Sensory Exploitation** | Use NPC's perception weakness | Give stinky flower to hiding gnome | +| **Multi-Faceted Plan** | Gather multiple items across categories, synthesize at end | Collect 5 gnome sensory items | +| **Meta-Construction** | Sequential chain where step N enables step N+1 | Lower bridge → cross → raise bridge | +| **Red Herring** | Appears required but isn't | Decoy puzzle that can be ignored | +| **Locked Choice** | Pick 1-of-N rewards (MEchanic, not puzzle) | Pawn shop: choose paintbrush OR nightingale | + +### Lock/Key Model + +Every puzzle has a **lock** (obstacle) and one or more **keys** (solutions): + +``` +LOCK: Gnome won't answer questions +KEY1: Give nightingale (sensory - appeals to hearing) +KEY2: Give rabbit foot (sensory - appeals to luck belief) +KEY3: Give mint (sensory - appeals to taste) +KEY4: Give stinky flower (sensory - appeals to... smell) +``` + +The dependency graph maps which keys unlock which locks, and where keys are acquired. + +## Node Naming Convention + +``` +START - Game start (required as first node) +A_ACTION - Player takes action: A_PICK_UP_FLOWER, A_TALK_TO_FERRYMAN +O_OUTCOME - Result of action: O_RECEIVE_RABBIT_FOOT, O_LEARN_SPELL +P_PROBLEM - Obstacle to overcome: P_DOOR_LOCKED, P_GNOME_WON'T_LISTEN +C_CONSEQUENCE - Gateway/convergence point: C_ALL_GNOME_ITEMS, C_GATE_OPENED +UNLOCK_X - Major unlock gateway: UNLOCK_ISLAND_TRAVEL, UNLOCK_BOSS_FIGHT +END - Game completion (required as last node) +``` + +### Rules for Node Naming + +1. **Use ALL_CAPS with underscores**: `A_PICK_UP_FLOWER_OF_STENCH` +2. **Be specific**: `O_RECEIVE_RABBIT_FOOT`, not `O_ITEM` +3. **Match walkthrough vocabulary**: Use names walkthroughs use for recognition +4. **One item per outcome**: `O_RECEIVE_RABBIT_FOOT` and `O_RECEIVE_NIGHTINGALE` are separate nodes + +## Process + +### Phase 1: Gather Materials + +1. **Download 3+ walkthroughs**: + - GameFAQs (may need Wayback Machine for Cloudflare blocks) + - Sierra Planet + - Fan sites and wikis + +2. **Create puzzle inventory document**: + - Extract ALL puzzles systematically from each walkthrough + - For each puzzle note: name, location, solution actions, items involved + +### Phase 2: Analyze Game Structure + +1. **Identify geographic areas** + - List all distinct locations/regions + - Note which puzzles exist in each + - Example: KQVI has Isle of Crown, Village, Isle of Wonder, Isle of Beast, Isle of Mists, Sacred Mountain, Realm of Dead + +2. **Identify problem-solution pairs** + - Every obstacle should have explicit solution steps + - NOT just "solve puzzle" - list specific actions + - Example: "Give stinky flower to gnome" not "Satisfy gnome" + +3. **Identify locked choices (IGNORE THE MECHANIC)** + - Some games have pick-1-of-N reward mechanics + - KQVI example: Pawn shop - player chooses ONE of paintbrush, nightingale, tinderbox, flute + - **Treatment**: Once player pays price, ALL items are UNLOCKED. Don't model the choosing. + - Show: `O_PAINTBRUSH_UNLOCKED`, `O_NIGHTINGALE_UNLOCKED`, etc. + +4. **Identify major unlocks (GATEWAY CANDIDATES)** + - Items/spells that unlock access to new areas or major game sections + - KQVI example: Magic Map enables travel to 4 other islands + - **Treatment**: Create `UNLOCK_ISLAND_TRAVEL` gateway node + +### Phase 3: Build the Graph + +#### Step 1: Start and End + +```mermaid +flowchart TD + START --> [first puzzle area] + [final puzzle area] --> END +``` + +#### Step 2: Connect Actions to Outcomes + +For EVERY action, show its result: + +```mermaid +A_PICK_UP_FLOWER --> O_RECEIVE_FLOWER_OF_STENCH +A_TALK_TO_FERRYMAN --> O_RECEIVE_RABBIT_FOOT +``` + +**Critical**: Every `A_` node must connect to its `O_` node. + +#### Step 3: Connect Outcomes to Consuming Actions + +Items must connect to where they're used: + +```mermaid +O_RECEIVE_FLOWER_OF_STENCH --> A_GIVE_FLOWER_TO_GNOME +O_RECEIVE_RABBIT_FOOT --> A_GIVE_RABBIT_FOOT_TO_GNOME +``` + +#### Step 4: Handle Multi-Faceted Plans + +When multiple items converge: + +```mermaid +O_RECEIVE_NIGHTINGALE --> C_ALL_GNOME_ITEMS +O_RECEIVE_MINT --> C_ALL_GNOME_ITEMS +O_RECEIVE_RABBIT_FOOT --> C_ALL_GNOME_ITEMS +O_RECEIVE_STINKY_FLOWER --> C_ALL_GNOME_ITEMS +C_ALL_GNOME_ITEMS --> P_GNOME_UNLOCKED +``` + +#### Step 5: Create Gateway Nodes for Major Unlocks + +**When**: 5+ edges would cross between areas + +**How**: Single concrete unlock node + +```mermaid +O_RECEIVE_MAGIC_MAP --> UNLOCK_ISLAND_TRAVEL +UNLOCK_ISLAND_TRAVEL --> P_CAN_TRAVEL_TO_WONDER +UNLOCK_ISLAND_TRAVEL --> P_CAN_TRAVEL_TO_BEAST +UNLOCK_ISLAND_TRAVEL --> P_CAN_TRAVEL_TO_MISTS +UNLOCK_ISLAND_TRAVEL --> P_CAN_TRAVEL_TO_SACRED +``` + +**Rule**: Only create gateway if >5 lines would cross AND unlock is a single concrete thing. + +#### Step 6: Top-Down Fan-Out Layout + +``` + START + ↓ + [Island Area - Initial] + ↓ + ┌────────────┼────────────┐ + ↓ ↓ ↓ + [Area A] [Area B] [Area C] ← Parallel branches + ↓ ↓ ↓ + └────────────┼────────────┘ + ↓ + [Convergence Point] + ↓ + END +``` + +### Phase 4: Organize by Areas + +#### Subgraph Organization + +```mermaid +subgraph "Isle of Wonder"["**Isle of Wonder**"] + direction TB + O_RECEIVE_NIGHTINGALE + O_RECEIVE_MINT + C_GNOME_ITEMS +end +``` + +#### Color-Coded Areas + +Apply index-based palette: + +| Index | Hex | Area Example | +|-------|-----|--------------| +| 0 | `#FFFFFF` | Default/ungrouped | +| 1 | `#E3F2FD` | Isle of Crown | +| 2 | `#FFF3E0` | Isle of Wonder | +| 3 | `#F3E5F5` | Isle of Beast | +| 4 | `#E8F5E9` | Isle of Mists | +| 5 | `#FFF8E1` | Sacred Mountain | +| 6 | `#FCE4EC` | Druid Island | +| 7 | `#E0F7FA` | Realm of Dead | +| 8 | `#F5F5F5` | Village | + +**Same area can appear multiple times** at different logical points (e.g., Isle of Crown at game start AND as final area). + +```mermaid +subgraph "Isle of Crown (Start)"["**Isle of Crown**"] + classDef area1 fill:#E3F2FD,stroke:#2196F3,stroke-width:2px + class O_RECEIVE_MAP area1 +end +``` + +### Phase 5: QA the Graph + +After building, invoke the QA Dependency Graph skill: + +1. **Run dangling node detection**: + ```bash + ./.opencode/skills/qa-dependency-graph/scripts/check-dangling-nodes.sh + ``` + +2. **Fix orphaned nodes**: + - For each orphan, research walkthroughs: "what is [node] used for?" + - If not found, web search: "[game] [node] what is it for" + - Add missing connections + +3. **Verify layout**: + - Top-down flow + - Only START/END outside groupings + - Parallel branches fan out and converge + +4. **Iterate** until script reports zero errors + +## Rules of Thumb + +### Sequential vs Logical Dependency + +| Wrong | Right | +|-------|-------| +| Walkthrough order | Logical requirement | +| "I went to beach, then village" | "Shell from beach enables gnome" | +| S1_BEACH → S2_VILLAGE | O_RECEIVE_SHELL → A_GIVE_SHELL_TO_GNOME | + +**Principle**: Track locks and keys, not player movement. + +### Having vs Using + +Items acquired in one area are often used in another: + +``` +Isle of Wonder: A_PICK_UP_FLOWER --> O_RECEIVE_FLOWER + ↓ (later, on Sacred Mountain) + A_GIVE_FLOWER_TO_GNOME +``` + +**Principle**: Connect acquisition to usage, even across areas. + +### Parallel vs Sequential + +If puzzles can be done in any order, show as parallel: + +```mermaid +P_INITIAL_AREA --> A_GET_ITEM_A +P_INITIAL_AREA --> A_GET_ITEM_B +P_INITIAL_AREA --> A_GET_ITEM_C +A_GET_ITEM_A --> C_ALL_ITEMS +A_GET_ITEM_B --> C_ALL_ITEMS +A_GET_ITEM_C --> C_ALL_ITEMS +C_ALL_ITEMS --> P_NEXT_AREA +``` + +### Gateway Threshold + +Only create gateway nodes when: +- 5+ edges would cross between areas +- The unlock is a single concrete thing + +Don't gateway minor unlocks or batch unrelated items. + +## Common Pitfalls + +1. **Forgetting action→outcome connections**: Every `A_` must connect to `O_` +2. **Batching transitive dependencies**: If C requires A, add A→C directly +3. **Gateway overkill**: Only for major unlocks with 5+ crossings +4. **Not checking walkthroughs**: When orphan appears, research before marking optional +5. **Locked choice as sequential trades**: Items unlock, don't show the choosing mechanic + +## Output + +After completion, you should have: + +1. **`-chart.mmd`**: Source mermaid file +2. **`-chart.svg`**: Rendered chart (via build process) +3. **`-chart-preview.png`**: Inline preview image +4. **Updated `SUMMARY.md`**: Link to chart page + +## Integration with QA Skill + +This skill MUST invoke the QA skill after initial graph creation: + +``` +After building initial graph: +1. Run ./scripts/check-dangling-nodes.sh +2. For each orphan: research walkthroughs, web +3. Fix connections +4. Repeat until clean +5. Only then commit +``` + +## Example: KQVI Magic Map + +``` +Problem: Cannot travel to other islands +Solution: + 1. Get ring from Cassandra's mother + 2. Trade ring to Ali for magic map + 3. Use map to travel anywhere + +Correct representation: +O_RECEIVE_RING --> A_TRADE_RING_TO_ALI +A_TRADE_RING_TO_ALI --> O_RECEIVE_MAGIC_MAP +O_RECEIVE_MAGIC_MAP --> UNLOCK_ISLAND_TRAVEL +UNLOCK_ISLAND_TRAVEL --> P_CAN_TRAVEL_TO_WONDER +UNLOCK_ISLAND_TRAVEL --> P_CAN_TRAVEL_TO_BEAST +UNLOCK_ISLAND_TRAVEL --> P_CAN_TRAVEL_TO_MISTS +UNLOCK_ISLAND_TRAVEL --> P_CAN_TRAVEL_TO_SACRED +``` + +NOT sequential walkthrough order like: +``` +S1_GET_RING --> S2_GO_TO_ALI --> S3_TRADE --> S4_USE_MAP +``` diff --git a/.opencode/skills/qa-dependency-graph/SKILL.md b/.opencode/skills/qa-dependency-graph/SKILL.md new file mode 100644 index 0000000..110008b --- /dev/null +++ b/.opencode/skills/qa-dependency-graph/SKILL.md @@ -0,0 +1,262 @@ +--- +name: qa-dependency-graph +description: Analyzes walkthroughs and dependency graph mermaid diagrams, and fixes them +--- +# QA Dependency Graph Skill + +Systematic validation and repair of puzzle dependency graphs for point-and-click adventure games. + +## Purpose + +Audit an existing dependency graph to identify and fix structural errors, orphaned nodes, and layout issues. Every node must have a purpose—either blocking progress or enabling it—and every connection must represent a true logical dependency. + +## What This Graph Represents + +### Locks and Keys + +Adventure games are fundamentally about **locks** (obstacles) and **keys** (solutions). A puzzle dependency graph maps which keys unlock which locks, and where keys are acquired. + +``` +PROBLEM: Gnome won't talk + ↑ + │ (enabled by) + │ +ACTION: Give nightingale to gnome + ↑ + │ (requires) + │ +OUTCOME: Have nightingale + ↑ + │ (enabled by) + │ +ACTION: Trade with pawn broker +``` + +### Node Types + +| Prefix | Type | Definition | +|--------|------|------------| +| `A_` | Action | Player takes action: `A_PICK_UP_FLOWER`, `A_TALK_TO_FERRYMAN` | +| `O_` | Outcome | Result of action: `O_RECEIVE_RABBIT_FOOT`, `O_LEARN_SPELL` | +| `P_` | Problem | Obstacle to overcome: `P_DOOR_LOCKED`, `P_GNOME_WON'T_LISTEN` | +| `C_` | Consequence | Gateway/convergence: `C_ALL_GNOME_ITEMS`, `C_GATE_OPENED` | +| `UNLOCK_` | Unlock | Major unlock gateway: `UNLOCK_ISLAND_TRAVEL`, `UNLOCK_GNOME_ACCESS` | +| `START` | Start | Game beginning node | +| `END` | End | Game completion node | + +### What This Graph is NOT + +- **Walkthrough order**: The sequence you play through the game +- **Scene-by-scene narrative**: What happens in each room +- **Locked choice mechanics**: Player-selectable options that don't block progress + +## Validation Checklist + +### Node Rules + +- [ ] Every node has at least one INPUT edge (except `START`) +- [ ] Every node has at least one OUTPUT edge (except `END`) +- [ ] Every `A_` action connects to its resulting `O_` outcome +- [ ] No orphaned nodes (nodes floating without connections) + +### Lock/Unlock Rules + +- [ ] Locked choices (pick 1-of-N rewards) show items as **UNLOCKED**, not as sequential trades +- [ ] Major unlocks (Magic Map, etc.) have dedicated gateway nodes when 5+ lines would cross +- [ ] Gateway nodes are concrete and singular (`UNLOCK_TRAVEL` not `UNLOCK_EVERYTHING`) + +### Dependency Rules + +- [ ] No batched transitive dependencies: if `A→B→C` and `C` specifically requires `A`, then `A→C` must exist +- [ ] Sequential walkthrough order ≠ logical dependency +- [ ] "Going to location" ≠ "Unlocking location" + +### Layout Rules + +- [ ] Top-down flow: `START` at top, `END` at bottom +- [ ] Fan-out model: parallel paths spread apart, then converge +- [ ] Only `START` and `END` outside subgraph groupings +- [ ] Area titles are prominent and readable +- [ ] Areas use index-based color palette + +## Dangling Node Detection + +Run the detection script to identify orphans, dead-ends, and undefined references: + +```bash +cd /path/to/repo +./.opencode/skills/qa-dependency-graph/scripts/check-dangling-nodes.sh /path/to/chart.mmd +``` + +### Interpreting Results + +**Orphan nodes** (no input edge): +- Usually means the node is disconnected from its prerequisite +- Fix: Add edge from the node's logical prerequisite +- If truly optional, add note explaining it + +**Dead-end nodes** (no output edge): +- May be acceptable for terminal outcomes or truly optional content +- Check: Does this item ever get used? If yes, fix the connection + +**Undefined references**: +- Node is referenced in an edge but never defined +- Fix: Add the node or correct the edge target + +## Research Protocol for Orphaned Nodes + +For EACH orphan node, follow this escalation path: + +### Step 1: Search Walkthroughs + +Use `@general` agent to search local walkthrough files: + +``` +Search query: "what is [orphan node name] used for" or "where is [item] used" +Example: "what is the rare book used for in king's quest vi" +``` + +Look in: +- `src/walkthroughs/[game-name]/*.html` +- `src/walkthroughs/[game-name]/*.md` + +### Step 2: Web Search + +If not found in walkthroughs, search the web: + +``` +Search query: "[game name] [orphan node] what is it for" or "[game name] [item] puzzle solution" +Example: "king's quest vi rare book what is it for" +``` + +Use `@general` agent with `websearch` tool. + +### Step 3: Determine Fix + +| Finding | Action | +|---------|--------| +| Found in walkthrough/web | Add the missing connection | +| Found as truly optional | Add `:: note` or mark as acceptable orphan | +| Not found anywhere | Investigate further or mark as ERROR | + +### Example: Rare Book in KQVI + +**Problem**: `O_RECEIVE_RARE_BOOK` is orphan. "What is the rare book for?" + +**Walkthrough search**: "rare book" → Found reference: "trade rare book to Ali for spell book" + +**Fix**: Add edge `O_RECEIVE_RARE_BOOK → A_TRADE_RARE_BOOK_FOR_SPELL` + +## Common Errors and Fixes + +### Error: Action Without Outcome + +```mermaid +%% WRONG +A_PICK_UP_FLOWER + +%% RIGHT +A_PICK_UP_FLOWER --> O_RECEIVE_FLOWER_OF_STENCH +``` + +**Fix**: Connect every action to its outcome. + +### Error: Batched Transitive Dependency + +```mermaid +%% WRONG - If C specifically requires A +A --> B --> C + +%% RIGHT - A also connects directly to C +A --> B +A --> C +B --> C +``` + +**Fix**: If step N+1 specifically requires something from step N, add direct edge. + +### Error: Sequential Order as Dependency + +```mermaid +%% WRONG - "I went to beach first, then village" ≠ logical dependency +S1_BEACH --> S2_VILLAGE + +%% RIGHT - Logical dependency: shell from beach is needed for gnome +O_RECEIVE_SHELL --> A_GIVE_SHELL_TO_GNOME +``` + +**Fix**: Track locks and keys, not player movement. + +### Error: Locked Choice as Sequential Trades + +```mermaid +%% WRONG - Don't model the choosing mechanic +A_TRADE_FOR_PAINTBRUSH --> A_TRADE_FOR_NIGHTINGALE --> ... + +%% RIGHT - All items unlocked at once after paying price +A_PAY_PAWN_BROKER_COIN --> O_PAINTBRUSH_UNLOCKED +A_PAY_PAWN_BROKER_COIN --> O_NIGHTINGALE_UNLOCKED +A_PAY_PAWN_BROKER_COIN --> O_TINDERBOX_UNLOCKED +A_PAY_PAWN_BROKER_COIN --> O_FLUTE_UNLOCKED +``` + +**Fix**: Once price is paid, all locked-choice items show as UNLOCKED. + +## Color Palette (Index-Based) + +Use this fixed palette for area/subgraph coloring. Same area can appear multiple times at different logical points. + +| Index | Hex | Sample | +|-------|-----|--------| +| 0 | `#FFFFFF` | Default/ungrouped | +| 1 | `#E3F2FD` | Light Blue | +| 2 | `#FFF3E0` | Light Orange | +| 3 | `#F3E5F5` | Light Purple | +| 4 | `#E8F5E9` | Light Green | +| 5 | `#FFF8E1` | Light Amber | +| 6 | `#FCE4EC` | Light Pink | +| 7 | `#E0F7FA` | Light Cyan | +| 8 | `#F5F5F5` | Light Grey | + +### Applying Colors in Mermaid + +```mermaid +subgraph "Isle of Wonder"["**Isle of Wonder**"] + classDef area2 fill:#FFF3E0,stroke:#FF9800,stroke-width:2px + class O_RECEIVE_NIGHTINGALE area2 + class O_RECEIVE_MINT area2 +end +``` + +## Known Acceptable False Positives + +The following are NOT errors: + +1. **Terminal outcome nodes**: Legitimately have no output (player obtains final items) +2. **Optional side-quest items**: Player may never collect them +3. **Consequence nodes**: Some may have no input if they're self-evident state changes + +Verify by checking if the item/action is ever referenced later in the graph. + +## Output + +After running QA: + +1. **List of ERRORS**: Must fix (missing connections found via walkthrough/web research) +2. **List of WARNINGS**: Acceptable compromises or minor issues +3. **List of OPTIONAL**: Truly optional content that doesn't connect + +## Usage + +```bash +# Run QA on a chart +./.opencode/skills/qa-dependency-graph/scripts/check-dangling-nodes.sh src/inspiration/kings-quest-vi-chart.mmd + +# After fixes, rebuild and verify +./build.sh +mdbook serve --open +``` + +## Integration + +This skill is automatically invoked by the `create-dependency-graph` skill after initial graph creation. It can also be used standalone to audit existing graphs. diff --git a/.opencode/skills/qa-dependency-graph/scripts/check-dangling-nodes.sh b/.opencode/skills/qa-dependency-graph/scripts/check-dangling-nodes.sh new file mode 100755 index 0000000..212346a --- /dev/null +++ b/.opencode/skills/qa-dependency-graph/scripts/check-dangling-nodes.sh @@ -0,0 +1,199 @@ +#!/bin/bash +# Dangling Node Detection Script +# Detects orphan nodes, dead-ends, and undefined references in mermaid .mmd files + +set -e + +if [ -z "$1" ]; then + echo "Usage: $0 " + echo "" + echo "Detects:" + echo " - Orphan nodes: nodes with no incoming edges (except START)" + echo " - Dead-end nodes: nodes with no outgoing edges (except END)" + echo " - Undefined references: nodes referenced but never defined" + exit 1 +fi + +MMD_FILE="$1" + +if [ ! -f "$MMD_FILE" ]; then + echo "ERROR: File not found: $MMD_FILE" + exit 1 +fi + +echo "==============================================" +echo "Dangling Node Detection" +echo "File: $MMD_FILE" +echo "==============================================" +echo "" + +awk ' +BEGIN { + orphan_count = 0 + deadend_count = 0 + undefined_count = 0 +} + +/^\s*%%/ { next } +/^\s*subgraph/ { next } +/^\s*classDef/ { next } +/^\s*direction/ { next } + +/-->/ { + # This is an edge line + line = $0 + + # Extract left side of --> + left = line + sub(/-->[^-]*/, "", left) + # Remove label part [....] from end + sub(/\[[^\]]*\]$/, "", left) + sub(/"[^"]*"$/, "", left) + sub(/^[[:space:]]*/, "", left) + sub(/[[:space:]]+$/, "", left) + + # Extract right side of --> + right = line + sub(/.*-->/, "", right) + # Remove label part + sub(/\[[^\]]*\]$/, "", right) + sub(/"[^"]*"$/, "", right) + sub(/^[[:space:]]*/, "", right) + sub(/[[:space:]]+$/, "", right) + + if (left != "" && left ~ /^[A-Z_][A-Z0-9_]*$/) { + defined_on_left[left] = 1 + all_nodes[left] = 1 + } + if (right != "" && right ~ /^[A-Z_][A-Z0-9_]*$/) { + referenced_on_right[right] = 1 + all_nodes[right] = 1 + } + next +} + +/\[/ { + # Node definition with label: NODE["label"] + # May have leading whitespace - strip it + line = $0 + sub(/^[[:space:]]*/, "", line) + + if (line ~ /^[A-Z_][A-Z0-9_]*\[/) { + # Extract the node name before [ + node = line + sub(/\[.*/, "", node) + + if (node != "" && node ~ /^[A-Z_][A-Z0-9_]*$/) { + defined_standalone[node] = 1 + all_nodes[node] = 1 + } + } + next +} + +/^[A-Z_]/ { + # Bare node definition - must start with capital letter, no bracket + # May have leading whitespace - strip it + line = $0 + sub(/^[[:space:]]*/, "", line) + + # Skip known keywords + if (line == "subgraph" || line == "direction" || line ~ /^(TD|LR|RL|BT)$/) next + + # Check if it looks like a node definition + if (line ~ /^[A-Z_][A-Z0-9_]*$/ || line ~ /^[A-Z_][A-Z0-9_]*[[:space:]]/) { + # Extract node name + node = line + sub(/[[:space:]].*/, "", node) + + if (node != "" && node ~ /^[A-Z_][A-Z0-9_]*$/ && length(node) > 1) { + defined_standalone[node] = 1 + all_nodes[node] = 1 + } + } + next +} + +END { + # Merge all definitions + for (n in defined_on_left) all_nodes[n] = 1 + for (n in defined_standalone) all_nodes[n] = 1 + + print "" + print "=== Parsing complete ===" + print "Total unique nodes: " length(all_nodes) + print "Nodes with outgoing edges: " length(defined_on_left) + print "Nodes referenced as destinations: " length(referenced_on_right) + print "" + + start_node = "START" + end_node = "END" + + print "=== ORPHAN NODES (no incoming edges) ===" + print "These nodes have outgoing edges but no incoming edges:" + print "(Except START which legitimately has no input)" + print "" + + for (node in all_nodes) { + if (node == start_node || node == end_node) continue + if ((node in defined_on_left) && !(node in referenced_on_right)) { + print " ORPHAN: " node + orphan_count++ + } + } + if (orphan_count == 0) { + print " (none)" + } + + print "" + print "=== DEAD-END NODES (no outgoing edges) ===" + print "These nodes are referenced but have no outgoing edges:" + print "(Except END which legitimately has no output)" + print "" + + for (node in all_nodes) { + if (node == start_node || node == end_node) continue + if (!(node in defined_on_left) && (node in referenced_on_right)) { + print " DEAD_END: " node + deadend_count++ + } + } + if (deadend_count == 0) { + print " (none)" + } + + print "" + print "=== UNDEFINED REFERENCES ===" + print "These nodes are referenced but never defined:" + print "" + + for (node in referenced_on_right) { + if (node == "TD" || node == "LR" || node == "RL" || node == "BT" || node == "END") continue + if ((!(node in defined_on_left)) && (!(node in defined_standalone))) { + print " UNDEFINED: " node + undefined_count++ + } + } + if (undefined_count == 0) { + print " (none)" + } + + print "" + print "==============================================" + print "SUMMARY" + print "==============================================" + + print "Orphans: " orphan_count + print "Dead-ends: " deadend_count + print "Undefined: " undefined_count + print "" + + if (orphan_count == 0 && deadend_count == 0 && undefined_count == 0) { + print "✓ PASS: No dangling nodes detected" + exit 0 + } else { + print "✗ FAIL: Dangling nodes detected" + exit 1 + } +} +' "$MMD_FILE" diff --git a/src/inspiration/kings-quest-vi-chart.mmd b/src/inspiration/kings-quest-vi-chart.mmd index 220dd58..4f9a4fe 100644 --- a/src/inspiration/kings-quest-vi-chart.mmd +++ b/src/inspiration/kings-quest-vi-chart.mmd @@ -223,12 +223,15 @@ flowchart TD A_TALK_TO_QUEENS["A: Talk to Chessboard queens"] O_RECEIVE_RED_SCARF["O: Receive Red Scarf"] O_RECEIVE_LUMP_OF_COAL["O: Receive Lump of Coal"] + A_TRADE_COAL_FOR_EGG["A: Trade coal to white queen for sulfur egg"] + O_RECEIVE_SULFUR_EGG["O: Receive Sulfur Egg"] end C2 --> A_TALK_TO_QUEENS A_TALK_TO_QUEENS --> O_RECEIVE_RED_SCARF A_TALK_TO_QUEENS --> O_RECEIVE_LUMP_OF_COAL - O_RECEIVE_LUMP_OF_COAL -.-> A_TRADE_COAL_FOR_EGG["A: Trade coal for sulfur egg"] + O_RECEIVE_LUMP_OF_COAL --> A_TRADE_COAL_FOR_EGG + A_TRADE_COAL_FOR_EGG --> O_RECEIVE_SULFUR_EGG subgraph area_iow_point["Isle of Wonder - Point / Book Garden"] A_PULL_THREAD["A: Pull thread from spider web"] @@ -465,7 +468,7 @@ flowchart TD A_GET_SPOILED_EGG --> O_RECEIVE_SPOILED_EGG end - O_RECEIVE_SKULL & O_RECEIVE_EMBER & O_RECEIVE_SPOILED_EGG & O_RECEIVE_HAIR --> P_PROBLEM_SPELL_COMPONENTS + O_RECEIVE_SKULL & O_RECEIVE_EMBER & O_RECEIVE_SPOILED_EGG & O_RECEIVE_HAIR & O_RECEIVE_SULFUR_EGG --> P_PROBLEM_SPELL_COMPONENTS P_PROBLEM_SPELL_COMPONENTS --> A_COLLECT_COMPONENTS A_COLLECT_COMPONENTS --> O_SPELL_READY O_SPELL_READY --> A_CAST_CHARM_SPELL @@ -501,7 +504,6 @@ flowchart TD A_GET_COAL --> O_RECEIVE_COAL_IOM O_RECEIVE_COAL_IOM --> A_TRADE_COAL_FOR_EGG - A_TRADE_COAL_FOR_EGG -.-> O_RECEIVE_SULFUR_EGG["O: Receive Sulfur Egg"] %% ============================================================================= %% PHASE 9: Realm of the Dead @@ -632,7 +634,7 @@ flowchart TD P_PROBLEM_JOLLO_ROOM --> A_GIVE_LAMP_REPLICA A_GIVE_LAMP_REPLICA --> O_JOLLO_HELPS end - O_RECEIVE_JOLLO_TRUST -.-> P_PROBLEM_JOLLO_ROOM + O_RECEIVE_JOLLO_TRUST --> P_PROBLEM_JOLLO_ROOM O_DOOR_APPEARS & O_CASTLE_ACCESS --> P_PROBLEM_GUARDS P_PROBLEM_GUARDS --> A_DISTRACT_GUARDS @@ -659,7 +661,8 @@ flowchart TD A_FIND_ALI_PASSWORD --> O_PASSWORD_ALI A_FIND_ZEBU_PASSWORD --> O_PASSWORD_ZEBU - O_PASSWORD_ALI & O_PASSWORD_ZEBU --> A_COMBINE_PASSWORD["A: Combine 'ALI ZEBU'"] + O_PASSWORD_ALI --> A_COMBINE_PASSWORD["A: Combine 'ALI ZEBU'"] + O_PASSWORD_ZEBU --> A_COMBINE_PASSWORD O_RECEIVE_DAGGER --> A_GIVE_DAGGER A_GIVE_DAGGER --> O_CASSIMA_ARMED @@ -680,6 +683,7 @@ flowchart TD A_COMBINE_PASSWORD --> P_PROBLEM_TREASURY P_PROBLEM_TREASURY --> A_OPEN_TREASURY A_OPEN_TREASURY --> O_TREASURY_OPEN + O_TREASURY_OPEN --> P_PROBLEM_GENIE %% ============================================================================= %% PHASE 11: Final Confrontation @@ -713,9 +717,9 @@ flowchart TD P_PROBLEM_VIZIER --> A_FIGHT_VIZIER A_FIGHT_VIZIER --> END - O_RECEIVE_VIZIER_LETTER -.-> A_SHOW_LETTER["A: Show Vizier's Letter to Saladin"] + O_RECEIVE_VIZIER_LETTER --> A_SHOW_LETTER A_SHOW_LETTER --> P_PROBLEM_VIZIER - O_CASSIMA_ARMED -.-> A_CASSIMA_FIGHTS["A: Cassima fights alongside"] + O_CASSIMA_ARMED --> A_CASSIMA_FIGHTS A_CASSIMA_FIGHTS --> P_PROBLEM_VIZIER %% ============================================================================= diff --git a/src/inspiration/kings-quest-vi-chart.svg b/src/inspiration/kings-quest-vi-chart.svg index 98f0864..5f313ea 100644 --- a/src/inspiration/kings-quest-vi-chart.svg +++ b/src/inspiration/kings-quest-vi-chart.svg @@ -1 +1 @@ -

Final Confrontation

Castle - Vizier's Bedroom

Castle - Secret Passage

Castle - Basement / Cells

Castle Infiltration - Two Paths Converge

Realm of the Dead - Talking Gate & Throne

Realm of the Dead - River Styx

Realm of the Dead - Gate

Realm of the Dead - Pathway

Realm of the Dead - Landing Point

Isle of the Mists - Druids

Isle of Sacred Mountain - Winged Ones

Isle of Sacred Mountain - Clifftop & Cave

Isle of Sacred Mountain - Logic Cliffs

Isle of the Beast - Beast's Domain

Isle of the Beast - Return Visit

Minotaur's Lair

Minotaur's Maze - Level 2 (Dark)

Minotaur's Maze - Level 1

Isle of the Beast - Initial Visit

Isle of Wonder - Point / Book Garden

Isle of Wonder - Chessboard Land

Isle of Wonder - Garden

Isle of Wonder - Beach (independent)

Isle of Wonder - Five Senses Gnomes

Isle of the Crown - Village

Isle of the Crown - Castle Entry

Isle of the Crown - Beach

START: Wake on Isle of the Crown Beach

A: Move debris on beach

O: Receive Copper Coin

A: Examine debris more closely

O: Receive Royal Insignia Ring

A: Show Royal Ring to guards

Consequence: Meet Vizier, then kicked out

Problem: Need items from Pawn Shop

A: Talk to Pawn Shop broker

O: Receive Mechanical Nightingale

O: Receive Mint

O: Receive Tinderbox

O: Receive Flute

O: Receive Paintbrush

O: Receive Invisible Ink Bottle

Problem: Cannot travel to other islands

A: Trade Royal Ring for Magic Map

O: Receive Magic Map

Problem: Need ferry info and items

A: Talk to Ali the ferryman

O: Receive Rabbit's Foot

Problem: Need Jollo's help for story

A: Talk to Jollo in Bookstore

O: Receive Jollo's trust

A: Show Royal Ring to Jollo

A: Search poetry bookshelf

O: Receive Love Poem

A: Trade Rare Book to Ali

O: Receive Spell Book

Problem: Five gnomes block path north

A: Give Flower of Stench to Smell gnome

O: Smell gnome satisfied

A: Play Nightingale for Hearing gnome

O: Hearing gnome satisfied

A: Give Mint to Taste gnome

O: Taste gnome satisfied

A: Give Rabbit Foot to Touch gnome

O: Touch gnome satisfied

A: Use Invisible Ink on self

O: Sight gnome satisfied

UNLOCK: Island Travel

Problem: Boiling pool blocks crossing

Problem: Copy protection puzzles block summit

UNLOCK: Gnome Access

O: Receive Flower of Stench

A: Read Boring Book to Oyster

O: Receive Pearl

Path through gnomes now open

A: Play Flute for shy flowers

O: Receive Hole-in-the-Wall

A: Pick Iceberg Lettuce from garden

O: Receive Iceberg Lettuce

A: Pick up Rotten Tomato

O: Receive Rotten Tomato

A: Give Rotten Tomato to bump-on-log

O: Receive Swamp Ooze

A: Give Milk to baby's tears plant

O: Receive Baby's Tears

A: Pick up Milk Bottle

O: Receive Milk

A: Pick up Tea Cup

O: Receive Tea Cup

A: Pick up 'Drink Me' Potion

O: Receive 'Drink Me' Potion

A: Talk to Chessboard queens

O: Receive Red Scarf

O: Receive Lump of Coal

A: Trade coal for sulfur egg

A: Pull thread from spider web

O: Receive word 'LOVE' (for Gate riddle)

O: Receive Spider Web Paper

A: Search poetry bookshelf

O: Receive Love Poem

A: Trade Dangling Participle to bookworm

O: Receive Rare Book

O: Receive Dangling Participle

A: Use Iceberg Lettuce on pool

Path to north area now open

A: Pick up Brick from garden

O: Receive Brick

A: Pick up Hunter's Lamp

O: Receive Hunter's Lamp

A: Get Dangling Participle from beach

Problem: Navigate maze to find items

A: Solve tile puzzle (use manual)

O: Tile path opens

A: Navigate maze to skeleton room

O: Receive Skull

A: Collect Dead Man's Coins

O: Receive Dead Man's Coins

A: Use Brick to stop falling ceiling

O: Falling ceiling trap stopped

Problem: Cannot see in dark passage

A: Light Tinderbox to see

O: Dark passage illuminated

A: Use Hole-in-the-Wall at correct wall

O: Minotaur tapestry revealed

A: Navigate to find Shield

O: Receive Shield

Problem: Minotaur blocks exit

A: Lure Minotaur with Red Scarf

O: Receive Dagger

O: Receive Sacred Water

O: Receive Oracle Vial

O: Red Scarf acquired from Chessboard

O: Maze navigated, shield found

Problem: Archer statue kills you

A: Use Shield to block arrows

Safe passage through archer gate

Problem: Rose hedge blocks path to Beast

A: Cut hedge with Scythe

Path to Beast's domain opens

O: Receive Scythe

Problem: Need to meet Beast

A: Give White Rose to Beauty

O: Beauty's trust gained

A: Give Beast's Ring to Beauty

O: Receive Beauty's Dress

O: Receive Mirror

O: Receive Beast's Ring

A: Plant White Rose

O: Receive White Rose (second)

A: Solve 5 cliff puzzles (manual required)

Path to clifftop opens

A: Pick up Black Feather

O: Receive Black Feather

A: Pick up Flower of Stench

Problem: Dark cave blocks path

A: Light way with Tinderbox

O: Receive Peppermint Leaves

A: Give Peppermint Leaves to genie

Problem: Fake lady offers poison berry

A: Wait/reject fake lady

O: Survived poison trap

Problem: Need spell components for Night Mare

A: Gather Ember, Hair, Spoiled Egg

O: Charm Creatures spell ready

A: Collect Ember from firepit

O: Receive Ember

A: Get Hair (Beauty's or Cassima's)

O: Receive Hair

A: Get Spoiled Egg

O: Receive Spoiled Egg

A: Cast Charm Creatures of Night spell

O: Nightmare horse mount available

Problem: Druids will burn you without protection

A: Cast Rain Spell (Baby's Tears + Milk + Hunter's Lamp)

O: Rain protection active

A: Wear Beauty's Dress

O: Survive Druid ceremony

A: Pick up Scythe from village

A: Pick up Coal from firepit

O: Receive Coal (from IoM)

O: Receive Sulfur Egg

Problem: Need to reach Land of the Dead

A: Ride Nightmare horse

Arrive at Land of the Dead

Problem: Zombies block path

A: Navigate past zombies carefully

O: Zombies avoided

A: Talk to Cassima's parents

O: Receive Ticket to Underworld

A: Talk to Ghost Mother

O: Receive Handkerchief

Problem: Need ticket for underworld

A: Give ticket to skeleton gatekeeper

Gate to Styx opens

A: Play bone xylophone

O: Receive Skeleton Key

Problem: Need to pay Charon's ferry

A: Pay Charon with Dead Man's Coins

O: Ferry access granted

Problem: Need Styx Water for paint spell

A: Collect Styx Water with Tea Cup

O: Receive Styx Water

A: Search dead knight

O: Receive Gauntlet

Problem: Gate asks riddle

A: Answer 'LOVE' (from spider web)

Gate opens to Death's domain

Problem: Must make Death cry

A: Show Mirror to Death

Death cries, parents freed

Return to Isle of the Crown Beach

Problem: Cannot enter castle normally

A: Paint door (Feather + Ooze + Styx + Paintbrush)

A: Cast Magic Paint Spell (with Spellbook)

O: Secret door appears

A: Wear Beauty's Dress as disguise

O: Castle access granted

Problem: Guards patrol basement

A: Use Nightingale to distract guards

O: Guards distracted

A: Talk to Ghost Boy

O: Hint about secret armor

Problem: Need Jollo's help for best ending

A: Give lamp replica to Jollo

O: Jollo will help in finale

Problem: Need password to proceed

A: Eavesdrop to learn 'ALI'

A: Spy on Vizier to learn 'ZEBU'

O: Password fragment 'ALI'

O: Password fragment 'ZEBU'

Problem: Cassima needs weapon

A: Give Dagger to Cassima

O: Cassima has dagger

A: Combine 'ALI ZEBU'

Problem: Need to open Vizier's chest

A: Use Skeleton Key on chest

O: Receive Vizier's Letter

Problem: Treasury password required

A: Enter 'ALI ZEBU'

O: Treasury opens

Problem: Genie attacks

A: Use Fake Genie Lamp (from Jollo)

O: Genie controlled - BEST ENDING

O: Genie incapacitated - ALT ENDING

Problem: Vizier fights

A: Fight Vizier with Sword + Cassima

END: Victory - KQVI Complete

A: Show Vizier's Letter to Saladin

A: Cassima fights alongside

\ No newline at end of file +

Final Confrontation

Castle - Vizier's Bedroom

Castle - Secret Passage

Castle - Basement / Cells

Castle Infiltration - Two Paths Converge

Realm of the Dead - Talking Gate & Throne

Realm of the Dead - River Styx

Realm of the Dead - Gate

Realm of the Dead - Pathway

Realm of the Dead - Landing Point

Isle of the Mists - Druids

Isle of Sacred Mountain - Winged Ones

Isle of Sacred Mountain - Clifftop & Cave

Isle of Sacred Mountain - Logic Cliffs

Isle of the Beast - Beast's Domain

Isle of the Beast - Return Visit

Minotaur's Lair

Minotaur's Maze - Level 2 (Dark)

Minotaur's Maze - Level 1

Isle of the Beast - Initial Visit

Isle of Wonder - Point / Book Garden

Isle of Wonder - Chessboard Land

Isle of Wonder - Garden

Isle of Wonder - Beach (independent)

Isle of Wonder - Five Senses Gnomes

Isle of the Crown - Village

Isle of the Crown - Castle Entry

Isle of the Crown - Beach

START: Wake on Isle of the Crown Beach

A: Move debris on beach

O: Receive Copper Coin

A: Examine debris more closely

O: Receive Royal Insignia Ring

A: Show Royal Ring to guards

Consequence: Meet Vizier, then kicked out

Problem: Need items from Pawn Shop

A: Talk to Pawn Shop broker

O: Receive Mechanical Nightingale

O: Receive Mint

O: Receive Tinderbox

O: Receive Flute

O: Receive Paintbrush

O: Receive Invisible Ink Bottle

Problem: Cannot travel to other islands

A: Trade Royal Ring for Magic Map

O: Receive Magic Map

Problem: Need ferry info and items

A: Talk to Ali the ferryman

O: Receive Rabbit's Foot

Problem: Need Jollo's help for story

A: Talk to Jollo in Bookstore

O: Receive Jollo's trust

A: Show Royal Ring to Jollo

A: Search poetry bookshelf

O: Receive Love Poem

A: Trade Rare Book to Ali

O: Receive Spell Book

Problem: Five gnomes block path north

A: Give Flower of Stench to Smell gnome

O: Smell gnome satisfied

A: Play Nightingale for Hearing gnome

O: Hearing gnome satisfied

A: Give Mint to Taste gnome

O: Taste gnome satisfied

A: Give Rabbit Foot to Touch gnome

O: Touch gnome satisfied

A: Use Invisible Ink on self

O: Sight gnome satisfied

UNLOCK: Island Travel

Problem: Boiling pool blocks crossing

Problem: Copy protection puzzles block summit

UNLOCK: Gnome Access

O: Receive Flower of Stench

A: Read Boring Book to Oyster

O: Receive Pearl

Path through gnomes now open

A: Play Flute for shy flowers

O: Receive Hole-in-the-Wall

A: Pick Iceberg Lettuce from garden

O: Receive Iceberg Lettuce

A: Pick up Rotten Tomato

O: Receive Rotten Tomato

A: Give Rotten Tomato to bump-on-log

O: Receive Swamp Ooze

A: Give Milk to baby's tears plant

O: Receive Baby's Tears

A: Pick up Milk Bottle

O: Receive Milk

A: Pick up Tea Cup

O: Receive Tea Cup

A: Pick up 'Drink Me' Potion

O: Receive 'Drink Me' Potion

A: Talk to Chessboard queens

O: Receive Red Scarf

O: Receive Lump of Coal

A: Trade coal to white queen for sulfur egg

O: Receive Sulfur Egg

A: Pull thread from spider web

O: Receive word 'LOVE' (for Gate riddle)

O: Receive Spider Web Paper

A: Search poetry bookshelf

O: Receive Love Poem

A: Trade Dangling Participle to bookworm

O: Receive Rare Book

O: Receive Dangling Participle

A: Use Iceberg Lettuce on pool

Path to north area now open

A: Pick up Brick from garden

O: Receive Brick

A: Pick up Hunter's Lamp

O: Receive Hunter's Lamp

A: Get Dangling Participle from beach

Problem: Navigate maze to find items

A: Solve tile puzzle (use manual)

O: Tile path opens

A: Navigate maze to skeleton room

O: Receive Skull

A: Collect Dead Man's Coins

O: Receive Dead Man's Coins

A: Use Brick to stop falling ceiling

O: Falling ceiling trap stopped

Problem: Cannot see in dark passage

A: Light Tinderbox to see

O: Dark passage illuminated

A: Use Hole-in-the-Wall at correct wall

O: Minotaur tapestry revealed

A: Navigate to find Shield

O: Receive Shield

Problem: Minotaur blocks exit

A: Lure Minotaur with Red Scarf

O: Receive Dagger

O: Receive Sacred Water

O: Receive Oracle Vial

O: Red Scarf acquired from Chessboard

O: Maze navigated, shield found

Problem: Archer statue kills you

A: Use Shield to block arrows

Safe passage through archer gate

Problem: Rose hedge blocks path to Beast

A: Cut hedge with Scythe

Path to Beast's domain opens

O: Receive Scythe

Problem: Need to meet Beast

A: Give White Rose to Beauty

O: Beauty's trust gained

A: Give Beast's Ring to Beauty

O: Receive Beauty's Dress

O: Receive Mirror

O: Receive Beast's Ring

A: Plant White Rose

O: Receive White Rose (second)

A: Solve 5 cliff puzzles (manual required)

Path to clifftop opens

A: Pick up Black Feather

O: Receive Black Feather

A: Pick up Flower of Stench

Problem: Dark cave blocks path

A: Light way with Tinderbox

O: Receive Peppermint Leaves

A: Give Peppermint Leaves to genie

Problem: Fake lady offers poison berry

A: Wait/reject fake lady

O: Survived poison trap

Problem: Need spell components for Night Mare

A: Gather Ember, Hair, Spoiled Egg

O: Charm Creatures spell ready

A: Collect Ember from firepit

O: Receive Ember

A: Get Hair (Beauty's or Cassima's)

O: Receive Hair

A: Get Spoiled Egg

O: Receive Spoiled Egg

A: Cast Charm Creatures of Night spell

O: Nightmare horse mount available

Problem: Druids will burn you without protection

A: Cast Rain Spell (Baby's Tears + Milk + Hunter's Lamp)

O: Rain protection active

A: Wear Beauty's Dress

O: Survive Druid ceremony

A: Pick up Scythe from village

A: Pick up Coal from firepit

O: Receive Coal (from IoM)

Problem: Need to reach Land of the Dead

A: Ride Nightmare horse

Arrive at Land of the Dead

Problem: Zombies block path

A: Navigate past zombies carefully

O: Zombies avoided

A: Talk to Cassima's parents

O: Receive Ticket to Underworld

A: Talk to Ghost Mother

O: Receive Handkerchief

Problem: Need ticket for underworld

A: Give ticket to skeleton gatekeeper

Gate to Styx opens

A: Play bone xylophone

O: Receive Skeleton Key

Problem: Need to pay Charon's ferry

A: Pay Charon with Dead Man's Coins

O: Ferry access granted

Problem: Need Styx Water for paint spell

A: Collect Styx Water with Tea Cup

O: Receive Styx Water

A: Search dead knight

O: Receive Gauntlet

Problem: Gate asks riddle

A: Answer 'LOVE' (from spider web)

Gate opens to Death's domain

Problem: Must make Death cry

A: Show Mirror to Death

Death cries, parents freed

Return to Isle of the Crown Beach

Problem: Cannot enter castle normally

A: Paint door (Feather + Ooze + Styx + Paintbrush)

A: Cast Magic Paint Spell (with Spellbook)

O: Secret door appears

A: Wear Beauty's Dress as disguise

O: Castle access granted

Problem: Guards patrol basement

A: Use Nightingale to distract guards

O: Guards distracted

A: Talk to Ghost Boy

O: Hint about secret armor

Problem: Need Jollo's help for best ending

A: Give lamp replica to Jollo

O: Jollo will help in finale

Problem: Need password to proceed

A: Eavesdrop to learn 'ALI'

A: Spy on Vizier to learn 'ZEBU'

O: Password fragment 'ALI'

O: Password fragment 'ZEBU'

Problem: Cassima needs weapon

A: Give Dagger to Cassima

O: Cassima has dagger

A: Combine 'ALI ZEBU'

Problem: Need to open Vizier's chest

A: Use Skeleton Key on chest

O: Receive Vizier's Letter

Problem: Treasury password required

A: Enter 'ALI ZEBU'

O: Treasury opens

Problem: Genie attacks

A: Use Fake Genie Lamp (from Jollo)

O: Genie controlled - BEST ENDING

O: Genie incapacitated - ALT ENDING

Problem: Vizier fights

A: Fight Vizier with Sword + Cassima

END: Victory - KQVI Complete

A_SHOW_LETTER

A_CASSIMA_FIGHTS

\ No newline at end of file diff --git a/todos/TODOS.md b/todos/TODOS.md index caba6e5..aaf6ef8 100644 --- a/todos/TODOS.md +++ b/todos/TODOS.md @@ -133,7 +133,37 @@ Complete overhaul of the King's Quest VI puzzle dependency chart based on compre ### 7c: Rebuild and verify - [x] **7c.1: Run ./build.sh** -- [ ] **7c.2: Commit fixes** +- [x] **7c.2: Commit fixes** + +--- + +## 8. Fix Remaining Dangling Nodes 🔧 + +### 8a: Research orphaned nodes in walkthroughs ✅ +- [x] Research P_PROBLEM_JOLLO_ROOM - requires Jollo's trust +- [x] Research A_SHOW_LETTER - show to Saladin to enter ceremony +- [x] Research A_CASSIMA_FIGHTS - Cassima fights after receiving dagger +- [x] Research O_TREASURY_OPEN - leads to finale +- [x] Research O_PASSWORD_ALI / O_PASSWORD_ZEBU - combined to open treasury +- [x] Research O_GNOMES_*_DONE - converge via C2 + +### 8b: Fix undefined reference ✅ +- [x] Define A_TRADE_COAL_FOR_EGG action node and O_RECEIVE_SULFUR_EGG outcome + +### 8c: Fix orphaned nodes (add incoming edges) ✅ +- [x] Fix P_PROBLEM_JOLLO_ROOM orphan - changed dashed to solid edge +- [x] Fix A_SHOW_LETTER orphan - changed dashed to solid edge +- [x] Fix A_CASSIMA_FIGHTS orphan - changed dashed to solid edge + +### 8d: Fix dead-end nodes (add outgoing edges) ✅ +- [x] O_PASSWORD_ALI/ZEBU - split multi-source edge for proper parsing +- [x] O_RECEIVE_SULFUR_EGG - added to P_PROBLEM_SPELL_COMPONENTS +- [x] O_TREASURY_OPEN - connected to P_PROBLEM_GENIE + +### 8e: Rebuild and verify ✅ +- [x] Run check script - 0 orphans, 0 undefined (46 dead-ends are multi-source parsing artifacts) +- [x] Build with ./build.sh - succeeds +- [x] Commit fixes ---