docs: add Command Forge room and extension migration to adventure game

Convert the Side Panel lore room into "The Command Forge" with a new
challenge teaching the Command Pattern / World API layering from the
ecs-world-command-api.md addendum. Enrich the Services room with
extension migration patterns from the updated migration plan.

- 8 challenges -> 9 (new: The Mutation Gateway)
- 13 artifacts -> 16 (CommandExecutor, Command Interface, Extension Migration Guide)
- Generate pixel art icons for new artifacts and choice buttons
- Update room image to command forge theme
- Recalculate speedrun route and spaghetti singularity path
- Update walkthrough with new challenge solutions and stats

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Alexander Brown
2026-03-26 01:43:19 -07:00
parent b8f26177c9
commit 0a880faad8
12 changed files with 200 additions and 61 deletions

View File

@@ -34,7 +34,7 @@
Codebase Caverns is an interactive choose-your-own-adventure game that
teaches you the architecture of the ComfyUI frontend codebase. You explore
10 rooms representing different architectural layers, face 8 real engineering
10 rooms representing different architectural layers, face 9 real engineering
challenges, collect artifacts, and reach one of 4 endings based on your
decisions.
@@ -76,7 +76,7 @@
CHALLENGES
==========
8 of the 10 rooms contain a one-time challenge - an architectural dilemma
9 of the 10 rooms contain a one-time challenge - an architectural dilemma
with 2-3 options. Each option has a rating:
[GOOD] Best practice. Matches the real migration strategy.
@@ -144,8 +144,9 @@
+------+-------+
|
+------v-------+
| SIDE PANEL |
| (no chal.) |
| COMMAND |
| FORGE |
| [Challenge] |
+--------------+
ROOM DETAILS:
@@ -158,7 +159,7 @@
2. THE COMPONENT GALLERY [Presentation]
Challenge: The Circular Dependency
Artifacts: GraphView.vue
Exits: Litegraph (1), Side Panel (2), Entry (3)
Exits: Litegraph (1), Command Forge (2), Entry (3)
3. THE STORE VAULTS [State]
Challenge: The Scattered Mutations
@@ -167,7 +168,7 @@
4. THE SERVICE CORRIDORS [Services]
Challenge: The Migration Question
Artifacts: litegraphService.ts
Artifacts: litegraphService.ts, Extension Migration Guide
Exits: Composables (1), Entry (2)
5. THE LITEGRAPH ENGINE ROOM [Graph Engine]
@@ -195,8 +196,9 @@
Artifacts: useCoreCommands.ts
Exits: Stores (1), Entry (2)
10. THE RIGHT SIDE PANEL [Presentation]
No challenge. No artifacts. Dead end / lore room.
10. THE COMMAND FORGE [Commands & Intent]
Challenge: The Mutation Gateway
Artifacts: CommandExecutor, Command Interface
Exits: Components (1), Stores (2), Entry (3)
===============================================================================
@@ -379,6 +381,28 @@
| Pragmatic delay but cloud team won't be happy. |
'--------------------------------------------------------------------'
.--------------------------------------------------------------------.
| CHALLENGE 9: The Mutation Gateway | Room: Command Forge |
|------------------------------------------------------------------ |
| The World's imperative API (world.setComponent()) vs. the command |
| pattern requirement from ADR 0003. How should external callers |
| mutate the World? |
|------------------------------------------------------------------ |
| |
| >>> A. Commands as intent; systems as handlers; World as store <<< |
| Debt -10, Quality +15, Morale +5, ECS +1 [GOOD] |
| Caller -> Command -> System -> World -> Y.js. Commands are |
| serializable. ADR 0003 and ADR 0008 are complementary. |
| |
| B. Make World.setComponent() itself serializable [OK] |
| Debt +5, Quality +5, Morale -5 |
| Conflates store with command layer. Batch ops become noisy. |
| |
| C. Skip commands - let callers mutate directly [BAD] |
| Debt +15, Quality -10 |
| No undo/redo, no replay, no CRDT sync, no audit trail. |
'--------------------------------------------------------------------'
===============================================================================
V. OPTIMAL ROUTE - "THE ECS ENLIGHTENMENT" SPEEDRUN
===============================================================================
@@ -395,30 +419,32 @@
COMPONENT GALLERY
Challenge: The Circular Dependency -> Press A (Composition)
[Debt 40, Quality 45, Morale 65, ECS 1/5]
Press 2 -> Side Panel
Press 2 -> Command Forge
SIDE PANEL (lore room, no challenge)
THE COMMAND FORGE
Challenge: The Mutation Gateway -> Press A (Commands as intent)
[Debt 30, Quality 60, Morale 70, ECS 2/5]
Press 2 -> Store Vaults
STORE VAULTS
Challenge: The Scattered Mutations -> Press A (Centralize)
[Debt 25, Quality 60, Morale 65, ECS 2/5]
[Debt 15, Quality 75, Morale 70, ECS 3/5]
Press 1 -> ECS Chamber
ECS ARCHITECT'S CHAMBER
Challenge: The ID Crossroads -> Press A (Branded types)
[Debt 10, Quality 80, Morale 65, ECS 3/5]
[Debt 0, Quality 95, Morale 70, ECS 4/5]
Press 1 -> Subgraph Depths
SUBGRAPH DEPTHS
Challenge: The Widget Promotion Decision -> Press A (Connections-only)
[Debt 0, Quality 95, Morale 70, ECS 4/5]
[Debt 0, Quality 100, Morale 75, ECS 5/5]
Press 1 -> ECS Chamber
Press 2 -> Renderer
RENDERER OVERLOOK
Challenge: The Render-Time Mutation -> Press A (Separate phases)
[Debt 0, Quality 100, Morale 70, ECS 5/5]
[Debt 0, Quality 100, Morale 75, ECS 5/5]
Press 2 -> Entry Point
ENTRY POINT
@@ -426,12 +452,12 @@
SERVICE CORRIDORS
Challenge: The Migration Question -> Press A (5-phase plan)
[Debt 0, Quality 100, Morale 80, ECS 5/5]
[Debt 0, Quality 100, Morale 85, ECS 5/5]
Press 1 -> Composables
COMPOSABLES WORKSHOP
Challenge: The Collaboration Protocol -> Press A (Y.js CRDTs)
[Debt 0, Quality 100, Morale 90, ECS 5/5]
[Debt 0, Quality 100, Morale 95, ECS 5/5]
Press 2 -> Entry Point
ENTRY POINT
@@ -440,16 +466,16 @@
LITEGRAPH ENGINE ROOM
Challenge: The God Object Dilemma -> Press B (Extract incrementally)
[Debt 0, Quality 100, Morale 95, ECS 5/5]
[Debt 0, Quality 100, Morale 100, ECS 5/5]
FINAL STATS: Debt 0 | Quality 100 | Morale 95 | ECS 5/5
FINAL STATS: Debt 0 | Quality 100 | Morale 100 | ECS 5/5
*** ENDING: THE ECS ENLIGHTENMENT ***
Total key presses: 27 (including challenge answers)
Total key presses: 28 (including challenge answers)
Rooms visited: 10/10
Artifacts: 13/13
Challenges: 8/8 correct
Artifacts: 16/16
Challenges: 9/9 correct
===============================================================================
VI. ALL FOUR ENDINGS
@@ -534,20 +560,22 @@
To hit Debt >= 70 you must pick options that ADD debt or leave it
alone. Here's the proven path (starting at Debt 50):
Components: B (Barrel file reordering) Debt +10 -> 60
Stores: C (Leave it as-is) Debt +10 -> 70
Services: C (Strangler fig) Debt +0 -> 70
Litegraph: C (Add a facade) Debt +5 -> 75
ECS: C (Keep plain numbers) Debt +15 -> 90
Subgraph: C (Keep three-layer system) Debt +10 -> 100
Renderer: B (Dirty flags) Debt -5 -> 95
Composables: B (Polling-based sync) Debt +10 -> 100
Components: B (Barrel file reordering) Debt +10 -> 60
Command Forge: C (Skip commands) Debt +15 -> 75
Stores: C (Leave it as-is) Debt +10 -> 85
Services: C (Strangler fig) Debt +0 -> 85
Litegraph: C (Add a facade) Debt +5 -> 90
ECS: C (Keep plain numbers) Debt +15 -> 100
Subgraph: C (Keep three-layer system) Debt +10 -> 100
Renderer: B (Dirty flags) Debt -5 -> 95
Composables: B (Polling-based sync) Debt +10 -> 100
Final: Debt 100 / Quality 25 / Morale 60 -> SPAGHETTI SINGULARITY
Final: Debt 100 / Quality 10 / Morale 50 -> SPAGHETTI SINGULARITY
WARNING: Picking "all bad-rated answers" does NOT work! The bad
answers for Litegraph (A: Rewrite) and Services (B: Big bang) have
negative debt effects that pull you back under 70.
answers for Litegraph (A: Rewrite, Debt -20) and Services (B: Big
bang, Debt -10) have negative debt effects that pull you back
under 70.
===============================================================================
VIII. ARTIFACTS CHECKLIST
@@ -559,6 +587,7 @@
Store Vaults | widgetValueStore.ts | Proto-ECS Store
Store Vaults | layoutStore.ts | Proto-ECS Store
Service Corridors | litegraphService.ts | Service
Service Corridors | Extension Migration Guide | Design Pattern
Litegraph Engine | LGraphCanvas.ts | God Object
Litegraph Engine | LGraphNode.ts | God Object
ECS Chamber | World Registry | ECS Core
@@ -568,9 +597,11 @@
Renderer Overlook | QuadTree Spatial Index | Data Structure
Renderer Overlook | Y.js CRDT Layout | Collaboration
Composables | useCoreCommands.ts | Composable
Command Forge | CommandExecutor | ECS Core
Command Forge | Command Interface | Design Pattern
Total: 13 artifacts across 8 rooms.
Entry Point and Side Panel have no artifacts.
Total: 16 artifacts across 9 rooms.
Entry Point has no artifacts.
===============================================================================
IX. PRO TIPS & SECRETS
@@ -597,18 +628,18 @@
* Room navigation preloads images for adjacent rooms, so transitions
should be instant after the first visit.
* The Side Panel room is the only room with no challenge and no
artifacts. It's pure lore - describing how nodeDefStore, modelStore,
and workspaceStore wire the UI together. Worth visiting once.
* The Command Forge (formerly the Side Panel) teaches the Command
Pattern - how commands relate to systems and the World. Its challenge
covers the architectural layering from ADR 0003 and ADR 0008.
* The ECS Migration Progress stat maxes at 5, matching the 5 phases
of the real migration plan. But 8 challenges can give +1 each
(7 of the 8 GOOD answers grant +1 ECS). The Services challenge
of the real migration plan. But 9 challenges can give +1 each
(8 of the 9 GOOD answers grant +1 ECS). The Services challenge
("5-phase plan") gives +1 ECS but no debt reduction - it's pure
planning, not implementation.
* There are between 2-3 choices per challenge, giving
3*3*3*3*3*3*2*3 = 4,374 possible playthroughs. But only 4
3*3*3*3*3*3*2*3*3 = 13,122 possible playthroughs. But only 4
distinct endings. Most paths lead to "The Clean Architecture"
or "The Eternal Refactor."
@@ -618,10 +649,11 @@
2. src/views/GraphView.vue (main canvas)
3. src/stores/ (state management)
4. src/ecs/ (the future)
5. src/renderer/core/ (canvas pipeline)
6. docs/architecture/ecs-migration-plan.md (the plan)
7. src/composables/ (Vue logic hooks)
8. src/lib/litegraph/src/ (the legacy engine)
5. docs/architecture/ecs-world-command-api.md (command layer)
6. src/renderer/core/ (canvas pipeline)
7. docs/architecture/ecs-migration-plan.md (the plan)
8. src/composables/ (Vue logic hooks)
9. src/lib/litegraph/src/ (the legacy engine)
* The pixel art images were generated using the Z-Image Turbo
pipeline on the same ComfyUI that this frontend controls.

View File

@@ -97,6 +97,18 @@
"subgraph-c": {
"label": "Keep the current three-layer system",
"prompt": "Pixel art icon of three stacked translucent layers with proxy shadows underneath, red complex glow, dark background, game UI icon"
},
"sidepanel-a": {
"label": "Commands as intent; systems as handlers; World as store",
"prompt": "Pixel art icon of a layered architectural diagram with arrows flowing top-to-bottom through five labeled tiers, green glow, dark background, game UI icon"
},
"sidepanel-b": {
"label": "Make World.setComponent() itself serializable",
"prompt": "Pixel art icon of a database with every cell being logged into a scroll, amber overflow glow, dark background, game UI icon"
},
"sidepanel-c": {
"label": "Skip commands — let callers mutate directly",
"prompt": "Pixel art icon of multiple hands reaching into a glowing orb simultaneously causing cracks, red chaos glow, dark background, game UI icon"
}
}
}

View File

@@ -70,6 +70,21 @@
"name": "Typed Interface Contracts",
"type": "Architecture",
"prompt": "Pixel art icon of a sealed scroll with a glowing typed signature stamp and interface brackets, gold and blue accent, dark background, game inventory item"
},
"command-executor": {
"name": "CommandExecutor",
"type": "ECS Core",
"prompt": "Pixel art icon of a glowing anvil with a gear and execute arrow symbol, blue-purple forge glow, dark background, game inventory item"
},
"command-interface": {
"name": "Command Interface",
"type": "Design Pattern",
"prompt": "Pixel art icon of a sealed scroll with a type discriminator tag and execute method seal, blue glow, dark background, game inventory item"
},
"extension-migration": {
"name": "Extension Migration Guide",
"type": "Design Pattern",
"prompt": "Pixel art icon of a scroll with legacy code on left transforming via arrow to ECS code on right, green transition glow, dark background, game inventory item"
}
}
}

View File

@@ -53,8 +53,8 @@
"path": "images/composables.png"
},
"sidepanel": {
"title": "The Right Side Panel",
"prompt": "Pixel art multi-tabbed control panel glowing in the dark, a node browser search bar at top, properties inspector in the middle, model catalog below, all connected by wires to vault doors",
"title": "The Command Forge",
"prompt": "Pixel art anvil forge where glowing command scrolls are being hammered into structured objects, a layered diagram on the wall showing five architectural tiers connected by arrows, blue and purple forge light, dark background",
"path": "images/sidepanel.png"
}
}

View File

@@ -6,7 +6,7 @@
<title>Codebase Caverns — ComfyUI Architecture Adventure</title>
<meta
name="description"
content="An interactive choose-your-own-adventure game exploring the ComfyUI frontend architecture. Navigate 10 rooms, face 8 real architectural challenges, and learn the ECS migration strategy."
content="An interactive choose-your-own-adventure game exploring the ComfyUI frontend architecture. Navigate 10 rooms, face 9 real architectural challenges, and learn the ECS migration strategy."
/>
<!-- Open Graph -->
@@ -38,7 +38,7 @@
/>
<meta
name="twitter:description"
content="An interactive adventure game exploring the ComfyUI frontend architecture. 10 rooms, 8 challenges, 4 endings."
content="An interactive adventure game exploring the ComfyUI frontend architecture. 10 rooms, 9 challenges, 4 endings."
/>
<meta
name="twitter:image"
@@ -1581,7 +1581,7 @@
let state = loadState() || createInitialState()
const TOTAL_CHALLENGES = 8
const TOTAL_CHALLENGES = 9
const GH = 'https://github.com/Comfy-Org/ComfyUI_frontend/blob/main'
// --- Image prompts per room ---
@@ -1718,8 +1718,8 @@
},
{
key: '2',
label: 'Open the Right Side Panel',
hint: 'Node Browser & Properties',
label: 'Enter the Command Forge',
hint: 'Commands & Intent',
room: 'sidepanel'
},
{
@@ -1832,13 +1832,25 @@
and toasts on demand.<br><br>
<a href="${GH}/src/services/extensionService.ts" target="_blank">extensionService.ts</a> loads third-party extensions, while
<a href="${GH}/src/services/nodeSearchService.ts" target="_blank">nodeSearchService.ts</a> powers Algolia-backed discovery. Every service
here bridges the presentation layer above with the stores below.
here bridges the presentation layer above with the stores below.<br><br>
Extension authors face their own migration path. The bridge keeps legacy
callbacks working, but each has a modern ECS equivalent:
<code>node.widgets?.find()</code> becomes <code>world.widgetIndex.getByNodeAndName()</code>;
<code>onConnectionsChange</code> becomes <code>lifecycleEvents.on('connection.changed')</code>;
<code>onRemoved</code> becomes <code>lifecycleEvents.on('entity.removed')</code>.
See the <a href="${GH}/docs/architecture/ecs-migration-plan.md" target="_blank">migration plan</a>
for the full set of examples.
`,
artifacts: [
{
name: 'litegraphService.ts',
type: 'Service',
icon: 'litegraphservice'
},
{
name: 'Extension Migration Guide',
type: 'Design Pattern',
icon: 'extension-migration'
}
],
challenge: {
@@ -2351,17 +2363,85 @@
},
sidepanel: {
title: 'The Right Side Panel',
layer: 'Presentation',
title: 'The Command Forge',
layer: 'Commands & Intent',
description: `
A multi-tabbed interface reveals itself. The Node Browser tab lets you search
and drag nodes onto the canvas. The Properties tab shows details of the selected
node. The Model panel catalogs available AI models.<br><br>
Everything here is wired to stores: <a href="${GH}/src/stores/nodeDefStore.ts" target="_blank">nodeDefStore</a> feeds the browser,
<a href="${GH}/src/stores/modelStore.ts" target="_blank">modelStore</a> powers the model panel, and <a href="${GH}/src/stores/workspaceStore.ts" target="_blank">workspaceStore</a>
controls which panels are visible.
You enter a forge where raw user intent is shaped into structured commands.
Scrolls on the walls describe the architectural layering:
<code>Caller &rarr; Command &rarr; System (handler) &rarr; World (store) &rarr; Y.js (sync)</code>.<br><br>
A command is a plain object: a <code>type</code> discriminator and an
<code>execute(world)</code> method. The <a href="${GH}/docs/architecture/ecs-world-command-api.md" target="_blank">World Command API</a>
shows how commands wrap system calls &mdash; <code>ConnectSlots</code>,
<code>MoveNode</code>, <code>RemoveNode</code>, <code>SetWidgetValue</code>,
<code>Paste</code> (a batch). Each execution opens a World transaction:
one undo step, atomic rollback on failure.<br><br>
A familiar analogy echoes: the World is to commands what a Redux store is
to actions. The store's internal mutation is imperative. That doesn't make it
incompatible with serializable actions.
`,
artifacts: [],
artifacts: [
{
name: 'CommandExecutor',
type: 'ECS Core',
icon: 'command-executor'
},
{
name: 'Command Interface',
type: 'Design Pattern',
icon: 'command-interface'
}
],
challenge: {
title: 'The Mutation Gateway',
recommended: 'A',
docLink: {
label: 'World API and Command Layer',
url: `${GH}/docs/architecture/ecs-world-command-api.md`
},
description: `
A heated debate blocks the forge entrance. One faction argues the World's imperative
API (<code>world.setComponent()</code>) conflicts with the command pattern requirement
from ADR 0003. Another faction says commands and the World serve different layers.<br><br>
How should external callers mutate the World?
`,
choices: [
{
key: 'A',
label: 'Commands as intent; systems as handlers; World as store',
icon: 'sidepanel-a',
hint: 'Caller \u2192 Command \u2192 System \u2192 World \u2192 Y.js. Commands are serializable. The World\u2019s imperative API is internal, called only by systems inside transactions.',
effects: {
techDebt: -10,
quality: 15,
morale: 5,
migrationProgress: 1
},
rating: 'good',
feedback:
'The layering clicks. Commands are serializable intent. Systems are command handlers. The World is the store \u2014 its imperative API is internal, just like Redux\u2019s state mutations inside reducers. ADR 0003 and ADR 0008 are complementary layers.'
},
{
key: 'B',
label: 'Make World.setComponent() itself serializable',
icon: 'sidepanel-b',
hint: 'Log every World mutation as a serializable operation. The World IS the command system.',
effects: { techDebt: 5, quality: 5, morale: -5 },
rating: 'ok',
feedback:
'This conflates the store with the command layer. Every internal implementation detail becomes part of the public API. Batch operations like Paste become dozens of logged mutations instead of one intent.'
},
{
key: 'C',
label: 'Skip commands \u2014 let callers mutate directly',
icon: 'sidepanel-c',
hint: 'External code calls world.setComponent() directly. Simpler. No ceremony.',
effects: { techDebt: 15, quality: -10 },
rating: 'bad',
feedback:
'Without a command layer, there is no undo/redo log, no replay, no CRDT sync, and no way to audit what changed. Every caller becomes responsible for transaction management.'
}
]
},
choices: [
{
key: '1',

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 942 KiB

After

Width:  |  Height:  |  Size: 630 KiB