User: Read this issue, download the images, understand the game design, and make a tool for designing levels: https://linear.app/notabot/issue/GDD-345/game-for-work-energy-and-force
Game concept: An isometric-view 2D physics puzzle game where:
- An invisible character has an energy meter (vertical bar: blue = current energy, green arrow = target)
- Goal: reach a specific target energy level through actions that are energy sinks or sources
- Core physics: Work = Force x Distance, and friction requires more force
Level designs from the mockups:
- Level 1: Box near wall. Pushing into wall = no work (blocked). Pulling away = energy decreases. Teaches that work requires displacement.
- Level 2: Two surfaces (blue=smooth, red=rough). Pulling over smooth doesn't drain enough energy; rough surface does. Teaches friction.
- Level 3: Adding a ramp as a third path. Ramp requires more Force x Distance = more work = more energy drain. Teaches combined concepts.
Claude: What form should this level design tool take?
- Interactive HTML canvas tool
- Extend the existing matplotlib approach
- Both
User: Interactive HTML canvas
Claude: What objects should the level designer be able to place?
User: Let's keep to box, wall, start point, destination point, and friction surfaces for now. Starting energy level is the target energy to finish (so reach destination point at 0 energy left). No max moves beyond that.
Claude: How should the isometric grid work?
- Top-down 2D grid (simpler, more usable)
- Isometric grid in the editor
User: Top down is fine for level design
Claude: What should the output format look like? (proposed JSON structure)
User: Sure
Claude: Presented the full design summary.
User: Looks good
Built the initial level designer as a single HTML file with:
- Left palette (Select, Start Point, Destination, Box, Wall, Friction Surface, Eraser)
- Center canvas grid
- Right properties panel
- JSON export/import
- LocalStorage persistence
User: Wall should have been a barrier between vertices (should delete an edge in the graph), and X (forbidden cell, should delete a vertex in the graph). Make friction surface be represented by vertex weight of integers 1 to 5. Add a Calculate button that produces the histogram showing number of paths available by total energy used. Don't need a box separately, start is where box is placed. This is just a weighted graph walking problem.
Claude: Rewrote the entire tool with the new graph-based model:
- Cells = vertices with weight 1-5 (energy cost to traverse)
- Adjacencies = edges (removable via walls)
- Forbidden (X) = deleted vertices
- Total energy = sum of vertex weights along path
- Wall tool detects clicks near grid lines between cells (edge detection)
- Calculate Paths runs DFS to find all simple paths, shows histogram
User: Calculation seems off by 1. Include only S in the path weights, not E.
Claude: Fixed — destination vertex weight excluded from path cost.
User: Turn the histogram oriented sideways (joules on the bottom, bar height as number of paths).
Claude: Rewrote histogram to vertical bars with energy on X-axis, path count on Y-axis.
User: Provide a way to see the paths themselves, maybe allow clicking on the histogram bars which opens a horizontally scrollable panel of visual icons showing the different paths, clicking on whom would update the main grid with that path (arrows to show motion through the vertices).
Claude: Added three-level drill-down:
- Histogram — click a bar to select an energy bucket
- Path browser — horizontally scrollable panel of mini canvas thumbnails showing each path
- Main grid overlay — gold arrows showing the selected path's route through vertices
User: Call the forbidden X — obstacles instead. So walls (edge barriers) and obstacles (deleted vertices).
Claude: Renamed "Forbidden (X)" to "Obstacle (X)" in all UI text.
User: Color the histogram bars with smallest value as greenest and largest value as reddest going through yellow for the middle.
Claude: Implemented continuous green-yellow-red gradient based on path count:
- Green = fewest paths (hardest for player)
- Yellow = middle
- Red = most paths (easiest)
User: Need to scale up histogram bar height more, they're all showing as a thin bar.
Claude: Switched from percentage-based heights to pixel heights (8px min, 90px max).
User: Move the level-designer.html file to ~/src/website/public/tools/work-energy-level-designer.html
Claude: Moved the file.
User: Commit, pull, push ~/src/website
Claude: Committed as "Add work energy level designer tool", rebased on latest main, pushed.
User: Update the linear issue with a link to the tool and a screenshot.
Claude: Posted comment on GDD-345 with link to https://notabot.ai/tools/work-energy-level-designer.html, features list, and technical description.
Renamed "Start Energy" to "Target Work" in the tool's UI labels, committed and pushed.
Deployed at: notabot.ai/tools/work-energy-level-designer.html
-
Weighted graph model — The entire game reduces to a graph problem: cells are vertices with integer weights, adjacencies are edges. Walls delete edges, obstacles delete vertices. Energy cost = path weight.
-
Edge click detection — The wall tool detects mouse proximity to internal grid lines (within 12px threshold), determining which two cells a line separates. This gives a natural "click between cells" interaction.
-
All-paths DFS — Enumerates all simple paths (no revisiting vertices) via DFS with backtracking. For typical level sizes (up to 8x8) this is tractable. Capped at 50k paths for safety.
-
Green-to-red histogram — Colors encode difficulty: green bars (fewest paths) represent energy values that are hardest for the player to achieve, making them ideal targets for level design.
-
Single-file HTML — No dependencies, no build step. Vanilla JS + Canvas API. Runs anywhere, instantly shareable.