depgraph

Depgraph Rebuild Spec

What it is

Single-file HTML tool that visualizes the dependency graph of prototype/index.html. Parses the game’s JS via Acorn AST, combines with project_codemap.md sections, renders an interactive node graph.

Data Pipeline

Inputs

AST Analysis (analyzeCode)

Codemap Parsing

Multi-System Affinity Scoring

Each node gets affinities: Map<clusterId, weight> (normalized to sum=1.0) from 5 signals:

Signal Weight Source
Codemap section 5.0 Manual assignment (strongest)
Name tokens 1.5 each camelCase split → keyword lookup
Globals read/written 0.5 each underscore split → keyword lookup
Functions called 0.3 each Callee’s primary cluster
Called-by 0.2 each Caller’s primary cluster

Keyword table maps ~40 tokens to systems (e.g. terrain → Math/Noise/Terrain, ghost → Night/Combat).

Globals get affinities from naming (weight 2.0) + connected functions’ clusters (1.0 each).

Primary cluster = highest-weight affinity. Used for hull membership, node color, legend.

Layout Requirements

Clusters must have hard boundaries

No ambient physics

Sticky positions on file change

Live reload toggle

Interaction

Click

Drag

Press-and-hold (Attractor)

Semantic Zoom

Visual

Nodes

Edges

Hulls

Cluster Labels

Info Panel

View Modes

Toolbar Controls

Tech Stack

Key Files

Spatial Memory & Arrangement Navigation

The layout is not just a computed output — it’s a document that accumulates context over time. User interaction produces spatial knowledge that should persist, be navigable, and influence future layouts.

Three layers of layout input

Layer Source Persistence
Structure AST (calls, shared state) Recomputed from code
Semantics Codemap + affinity scoring project_codemap.md
Spatial memory User interaction over time depgraph-spatial.json

Spatial affinity edges

A new edge type that doesn’t come from the AST — it comes from interaction. When the user drags nodes together, clicks nodes in sequence, or uses the attractor to pull neighborhoods together, this creates spatial affinity between those nodes. Over time, nodes the user mentally associates become physically closer in the default layout, even if they’re in different codemap systems.

Signals that build spatial affinity:

These edges are stored and influence layout: nodes with strong spatial affinity get placed closer, potentially overriding pure cluster membership for positioning (while still keeping their cluster color/hull).

Arrangements as snapshots

Each meaningful layout state is an arrangement — a Map<nodeId, {x, y}> plus metadata:

Arrangements are pushed onto a navigation stack as the user interacts.

Arrangement navigation (Back/Forward)

Navigate between arrangements like browser history:

Transitions between arrangements are animated interpolations of node positions (lerp over ~300ms).

Layout merging & comparison view

When the user navigates back/forward repeatedly (oscillating between two arrangements), the system detects this pattern and enters a comparison mode:

This is analogous to how a diff highlights changes between two files — the comparison view highlights changes between two ways of looking at the same graph.

Detection heuristic: if the user does back→forward→back within ~3 seconds (oscillating), trigger comparison mode. A third arrangement navigation or clicking away exits it.

Persistence format

tools/depgraph-spatial.json:

{
  "arrangements": [
    {
      "id": "a1b2c3",
      "timestamp": "2026-03-21T...",
      "positions": {"getTerrainY": [120, 45], "moveNPC": [135, 50], ...},
      "focal": ["getTerrainY", "moveNPC"],
      "label": "terrain-npc interaction",
      "trigger": "attractor"
    }
  ],
  "spatialEdges": {
    "getTerrainY\u0000moveNPC": {"weight": 0.7, "lastSeen": "2026-03-21T..."},
    ...
  },
  "clickLog": [
    {"node": "getTerrainY", "t": 1711036800000},
    {"node": "moveNPC", "t": 1711036812000}
  ]
}

Spatial edges decay over time (half-life of ~1 week?) so stale associations fade. The click log can be truncated to last N entries. Arrangements could be capped (e.g. last 50) with older ones pruned.

How spatial memory influences layout

During the constraint-based layout step:

  1. Pack clusters into non-overlapping regions (structural)
  2. Within each cluster, place nodes by importance (semantic)
  3. Adjust positions by spatial affinity — nodes with strong spatial edges get pulled closer, potentially across cluster boundaries (the node stays in its hull but shifts toward the hull edge nearest its spatial neighbor)
  4. If a saved arrangement exists for the current node set, use it as the starting point instead of computing fresh

What went wrong with D3 force layout