Files
factory-hole-core/tools/node-editor
2026-02-20 22:50:05 +09:00
..
2026-02-20 22:50:05 +09:00
2026-02-20 22:50:05 +09:00
2026-02-20 22:50:05 +09:00

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 (13), 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.