World Graph Node Editor
A standalone visual node editor for authoring world generation graphs. Built with Dear ImGui and imnodes, styled after Blender's geometry nodes.
What it does
Graphs describe how tiles are generated for each chunk in the world. Each node is a mathematical or contextual operation — noise functions, arithmetic, comparisons, tile queries — and they connect together into a tree that evaluates to a float value per tile. The game uses this value to decide what tile type to place.
Graphs are saved as Flecs JSON (graph.json) and loaded by the game at runtime, where they are compiled into an efficient memory-pooled runtime graph and evaluated per-tile during chunk generation.
Controls
| Action | How |
|---|---|
| Add a node | Add Node menu in the menu bar |
| Connect nodes | Drag from an output pin to an input pin |
| Disconnect a link | Right-click the link |
| Pan the canvas | Middle-click drag, or Alt + left-click drag |
| Zoom | Scroll wheel |
| Mark output node | Right-click a node → Set as Output |
| Delete a node | Right-click a node → Delete Node |
| Save graph | File → Save or Ctrl+S (writes graph.json) |
| Load graph | File → Load or Ctrl+O (reads graph.json) |
The output node (highlighted in orange) is the root of evaluation — it must be set before the graph can be compiled by the game.
Node types
Math (binary, float → float)
Add Subtract Multiply Divide Modulo Pow Max Min
Math (unary, float → float)
Negate Abs Ceil Floor Sin Cos Tan Exp Log Square Round OneMinus
Math (ternary, float → float)
Lerp Clamp
Comparison (float → bool)
Equal Smaller Greater SmallerEqual GreaterEqual
Logic (bool → bool)
And Or
Control flow
Branch — inputs: condition (bool), true value (float), false value (float)
Noise (no inputs, float output)
Simplex OpenSimplex Perlin Value ValueCubic
Parameters: Frequency — controls the scale of the noise.
Leaf nodes
| Node | Parameters | Output |
|---|---|---|
Constant |
Value (float) | The constant value |
IsTile |
RelativeX, RelativeY, TileType | bool — true if the tile at the offset matches the type |
TileDistance |
Range (1–3), TileType | float — distance to the nearest tile of that type |
Graph file format
Graphs are stored as Flecs JSON. Example of a simple graph that outputs Perlin noise:
{
"entities": [
{
"name": "Graph",
"children": [
{
"name": "Perlin_0",
"components": {
"VisualNodeType": {"kind": "Perlin"},
"VisualNodePos": {"x": 100.0, "y": 100.0},
"NodeParam_Noise": {"frequency": 0.01},
"VisualNodeOutput": {}
}
}
]
}
]
}
Connections between nodes are stored as Flecs relationships (InputPin0, InputPin1, InputPin2) on the destination node, referencing the source node by name. This makes the JSON human-readable and easy to hand-edit.
Building
Built automatically as part of the main CMake project:
cmake -B build
cmake --build build --target node-editor
./build/tools/node-editor/node-editor
Dependencies (fetched automatically via FetchContent): GLFW, Dear ImGui, imnodes.