4 min read
Gradientspace Graph

Gradientspace Graph (GSGraph) is a standalone NodeGraph Programming System that merges visual node-based workflows with embedded code capabilities. It’s inspired by systems like Unreal Engine’s Blueprints, but designed as an independent, general-purpose tool. Graphs are saved as very simple Json (.gg extension) and can be executed via command-line for automation workflows.

The project lives on the Gradientspace website at gradientspace.com/gsgraph. I wrote a blog post about the initial release here. Both these pages start with sections about the motivation for GSGraph, so I won’t repeat that here.

Similarly there are long descriptions of why I chose C#, if you are interested. Personally I think C# is the ideal language for a node graph, for lots of technical reasons. The GSEditor App uses the Avalonia UI Framework, this was the first time I have used a XAML-based UI thing. TBH I don’t love the XAML, but the framework is reasonably nice.

The main Graph Editor viewport uses a custom UI library which draws using SkiaSharp. I have always thought that NodeGraph Editors suffer when they try to adapt traditional box-model GUI frameworks & widgets. So naturally I wrote my own, which is meant for freeform layout based on a concept of hierarchical “anchors”. Someday I will have to write about this UI system.

The core GSGraph Engine and Node Libraries are open-source on GitHub (MIT license). The GSGraph Editor is not (currently) open-source. You can download installers on the project page above.

Code Nodes

One of the main pain points of NodeGraph Programming that I wanted to address with GSGraph was dealing with the situation where you need to wire up a whole bunch of nodes to do something that would be one line of text code. This happens most commonly with things like math and string manipulation.

To solve it, I added support for inline “Code Nodes” that have embedded C# code. Using C# dynamic reflection, I can extract the arguments to a C# static method and create a graph node that calls the method. This is similar to how static UFunctions work in UE’s Blueprint Function Libraries, but vastly better because using the Roslyn C# compiler, I can compile the C# code on-the-fly. So I can just launch VSCode with a temporary .cs file and watch for changes, and rebuild the graph node as you edit and save. *(Eventually I’ll integrate a text editor component so you can write code directly in the graph viewport…)

Once I had that working, I discovered Python.NET and realized I could easily turn Python functions into Nodes too. Typed Python makes it work even better. The images below-left show examples of C# and Python Code Nodes. Combining Code Nodes with C# Func<> objects make it even more powerful. The video below-right shows a Code Node that returns a function, which is passed to a node that evaluates that function for every vertex in a mesh. I haven’t really done a lot of experimentation with this so far, but it feels incredibly powerful.

Node Wizard

I spent a good chunk of 2025 working on GSGraph, and 2025 was also “the year of vibe coding”. I was pretty skeptical if vibe coding (although in 2026 I dove in and had some wild experiences). But I do feel like creating custom nodes for a node graph is an ideal usecase for code generation. Technically using Code Nodes and Copilot in VSCode it was already possible to vibe-code a Node. However I wanted to make it even easier, so I added a “Node Wizard” directly in the GSGraph Editor.

The Node Wizard has a detailed system prompt that helps to constrain the LLM, so that the static function it generates can easily be turned into a node. This worked out really well. The video below shows a simple demo of using the Node Wizard to generate a node that can query Github.