Crushline needed a node graph, but I did not want every production recipe and game consequence baked into the graph library. That question drove Whacky Node-Graph Layer. The platform layer below it would provide windows, input, and drawing; the game above it would decide what a material, machine, or connection meant. I kept testing that boundary whenever a convenient feature threatened to move game rules into the reusable core.
The result was a series of ownership decisions, patches, and reviews rather than one big graph engine appearing fully formed. The library could know about nodes, ports, references, constraints, and edits. It could let an application construct a strange or inefficient factory without refusing the graph itself. Crushline remained the demanding example that exposed gaps, while WNG became a place to solve the graph problems that other applications might also have. This page follows how I tried to keep those responsibilities from collapsing into one codebase.
Let a bad factory still be a valid graph
For Crushline, I wanted players to be allowed to fail. Connecting an unsuitable material, creating a bottleneck, or producing something unintended could be part of the puzzle. If the editor refused every poor production choice, it would remove the experimentation.
That required a distinction between structural validity and domain behavior. The graph core can know whether a referenced node or port exists and whether a connection satisfies its structural contract. The game decides what a liquid means, whether a recipe can use it, and what the production result should be.
My requested port description was deliberately small: a port number, side, direction, and optional metadata. The approved side discussion used left, bottom, and right, with input, output, or two-way direction. Machine-specific meaning could then live in the attached definition or metadata.
References without execution
Another question concerned attaching something such as a JSON definition or a script to a node. I clarified that I did not mean the node should store a whole file or execute code. I wanted the framework to be able to express that the node has a reference.
That distinction keeps the core from becoming a file loader or scripting runtime simply because an application needs to associate a node with external data. The host can interpret the reference and decide what to do with it.
The graph-core shape
A later status description I supplied characterized WNG as a standalone C++17 core. Its original milestone included strong NodeId, PortId, and LinkId types, graph-space vectors and rectangles, result-based public APIs, node/port/link records, mutations, connection validation, deterministic mutation summaries, and unit tests.
It explicitly excluded rendering, WPL integration, platform code, hit testing, selection, and editor state. The next serialization work used in-memory data-transfer objects for import and export. That did not define JSON, a binary format, or file I/O.
The same description covered a broader set of subsequent graph facilities:
| Facility | Purpose described in the snapshot |
|---|---|
| Schema | Define node and port types and offer host validation callbacks |
| Traversal | Find upstream/downstream nodes and topological order |
| Dependency analysis | Determine affected nodes from a change |
| Execution planning | Build an ordered plan without evaluating nodes |
| Mutation preview | Show consequences of deleting nodes, ports, or links |
| Snapshots and diffs | Capture, restore, and compare graph or schema state |
| History | Order normal graph edits and schema migrations for undo/redo |
| GraphSession | Own graph, schema, history, revision, and dirty-state tracking together |
A plan is not a running node
Execution planning was a particularly useful boundary. WNG could describe dependencies and produce a deterministic order while leaving evaluation, threaded scheduling, and stored runtime execution state outside that scope. Likewise, a snapshot could be an in-memory object without implying a saved file, and an undo history could restore graph data without restoring a visual selection.
The supplied status text mixes an original milestone description with later implemented subsystems, so it is best read as a historical development snapshot rather than a clean release manifest. I have not turned it into a present-day API guarantee.
I had a cleaner ownership line at the end of this discussion. WPL could supply the canvas and platform services, WNG could hold reusable graph structure, and Crushline could decide what the graph did to a factory. Keeping those boundaries through implementation was the next test.