WorldGraph Node Editor
A standalone visual node editor for the WorldGraph procedural generation system, built with Dear ImGui and imnodes. Every node displays a live 64×64 preview of its output, ShaderGraph-style.
Building & Running
make world-editor
This configures, builds, and launches the editor in one step.
Interface
Layout
| Area | Description |
|---|---|
| Left sidebar | Preview settings, World Output status, help |
| Main canvas | Node graph — pan with middle-mouse, zoom with scroll |
Adding Nodes
Right-click anywhere on the empty canvas to open the node menu, grouped by category. The node spawns at the click position.
Connecting Nodes
Drag from an output pin (right side of a node) to an input pin (left side). Dragging in either direction works. Connecting to an already-wired input replaces the existing connection. Cycles are rejected automatically.
Disconnecting
Click an existing link to select it, then press Delete. Or drag a new connection onto the same input slot to replace it.
Deleting Nodes
Select one or more nodes and press Delete. The World Output node cannot be deleted.
Keyboard Shortcuts
| Key | Action |
|---|---|
Ctrl+S |
Save |
Ctrl+O |
Open |
Delete |
Delete selected nodes or links |
World Output Node
The World Output node (blue title bar) is the fixed endpoint of the graph. It is always present and cannot be moved off-canvas or deleted.
Each input slot represents one generation pass. Passes execute in order — pass 1 can read the tile output of pass 0 via QueryTile, QueryRange, and QueryDistance nodes.
- Connect a pass: drag any node's output pin into a
Pass Nslot. - Add a pass slot: click
+ Passinside the node. - Remove the last pass slot: click
- Pass.
The World Output preview shows the result of running GenerateChunk() with all connected passes over a 64×64 tile region starting at the preview origin. Each pixel equals one world tile.
Per-Node Previews
Every node in the graph renders its own 64×64 preview by evaluating the subgraph rooted at that node across a grid of world coordinates.
| Output type | Preview color |
|---|---|
Float |
Grayscale, clamped to [0, 1] |
Bool |
White (true) / black (false) |
Int (tile ID) |
Hashed to a distinct hue; tile 0 (AIR) = near-black |
Scale in the sidebar controls how many world units one pixel represents in per-node previews. This lets you zoom in on high-frequency noise or zoom out to see large-scale structure.
Query nodes (
QueryTile,QueryRange,QueryDistance) always preview as blank in the per-node view because no previous-pass data is available at that stage. They work correctly in the World Output preview when used in a later pass.
Preview Settings (Sidebar)
| Setting | Effect |
|---|---|
| Origin X / Y | World-space top-left corner of all previews |
| Scale | World units per pixel (per-node previews only; World Output is always 1 tile/pixel) |
| Seed | World seed passed to every EvalContext |
Node Types
Source
| Node | Output | Description |
|---|---|---|
Constant |
Float | Fixed float value (drag to edit) |
TileID |
Int | Fixed tile ID integer (drag to edit) |
PositionX |
Int | World X coordinate of the current cell |
PositionY |
Int | World Y coordinate of the current cell |
Math
Add, Subtract, Multiply, Divide, Modulo, Sin, Cos
Compare
Less, Greater, LessEqual, GreaterEqual, Equal — all output Bool
Logic
And, Or, Not
Control
| Node | Inputs | Description |
|---|---|---|
Branch |
condition (Bool), true, false | Passes through whichever branch the condition selects |
Query (previous pass)
These nodes read from the previous generation pass. They have no input pins — their parameters are edited inline by dragging.
| Node | Output | Parameters |
|---|---|---|
QueryTile |
Bool | offsetX, offsetY, expectedID — true if prev-pass tile at offset equals ID |
QueryRange |
Int | minX..maxX, minY..maxY, tileID — count of matching tiles in rectangle |
QueryDistance |
Int | tileID, maxDistance — Chebyshev distance to nearest matching tile |
File Format
Graphs are saved as .wge JSON files containing both the graph data and editor layout:
{
"graph": { ... },
"editor": {
"nodePositions": { "1": [x, y], "__worldOutput": [x, y] },
"worldOutputPasses": [3, 7],
"seed": 0,
"previewOriginX": 0,
"previewOriginY": 0,
"previewScale": 1.0
}
}
worldOutputPasses is an array of graph node IDs, one per pass slot (0 = empty slot).