# 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: ```json { "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: ```sh cmake -B build cmake --build build --target node-editor ./build/tools/node-editor/node-editor ``` Dependencies (fetched automatically via FetchContent): GLFW, Dear ImGui, imnodes.