Docs
Runtime Editing
Letting players build and edit pipe networks in a running game.
Everything the editor tooling does to a pipe network goes through a Blueprint-callable API on the network’s graph component, and that API ships in your game. With it, a player can draw, re-route, decorate, and demolish pipe networks at runtime, with undo and save/load included.
This page covers the workflow. The node-by-node details are in the Blueprint API Reference.
Opting a network in
Runtime editing is off by default: a game’s interaction system should not be able to modify level-authored pipes by accident. Opt a network in by enabling Runtime Editable on the Pipe Network (details panel or Blueprint). While it is off, every runtime mutation (graph operations, imports, undo) is refused.
For networks the player edits, also consider forcing Render Mode to Authoring: edits re-render only the changed island, per-piece material overrides survive, and the network looks identical in the editor and in game. See Mesh Scale & Render Modes.
The edit loop
A runtime editing interaction usually looks like this:
- Trace from the camera or cursor into the world.
- Resolve the hit with Find Clicked Element. It tells you whether the player hit a junction node, a pipe edge, or a curved flexi edge (in either render mode) and returns the ids the mutation functions take.
- Preview while the player aims. The Begin Preview functions render a translucent ghost of exactly what the commit would do; they return false (and clear the ghost) when the operation would be rejected, so the player never aims at an invalid placement.
- Commit with the matching operation, passing the same arguments as the preview.
The main operations, all on the graph component:
| Interaction | Preview | Commit |
|---|---|---|
| Draw from an open end | Begin Preview Upgrade | Upgrade |
| Insert a junction on a pipe | Begin Preview Insert On Edge | Insert Node On Edge |
| Mount a bracket | Begin Preview Insert Bracket On Edge | Insert Bracket On Edge |
| Move / rotate a piece | none | Translate Node / Rotate Node |
| Delete a piece | none | Delete Node |
Use Is End Cap to decide whether a clicked node can be drawn from, and Clear Preview State when the player stops aiming. When an interaction has no natural draw distance (a single button press rather than a drag), the kit’s Get Default Edge Length returns a length that always passes spacing validation for that kit.
To change looks rather than layout, query the kit’s options with Get Mesh Variant Ids For Node / Get Pipe Mesh Variant Ids and apply with Set Node Mesh Id / Set Pipe Mesh Id. This is the same variant cycling the editor performs with Alt + Wheel. Set Pipe Kit re-skins the whole network with another kit.
Undo and redo
In game worlds, every committed edit is recorded automatically. Undo and Redo walk the history; Max Undo Depth caps it (oldest entries drop first). Because states share unchanged islands, an entry costs memory proportional to what the edit changed, not to the network size.
Two rules keep the history player-shaped:
- Batch continuous gestures. A drag that calls Translate Node every tick would record one entry per frame. Wrap the gesture in Begin Undo Batch / End Undo Batch and it becomes a single entry (batches nest; nothing is recorded if the state did not actually change).
- Automatic bracket re-traces and Set Pipe Kit never record entries, so undo stays about what the player did.
Undo history is transient: it is never saved and never replicated. In editor worlds the engine’s own transaction system owns undo, so nothing records there.
Reacting to changes
On Graph Changed fires after every committed change (player edits, undo, redo, and imports) with the reason: topology, transform, variant, and so on. It broadcasts after the renderer has synced, so the mesh accessors below already return the refreshed pieces. Previews never fire it.
Per-piece components exist on the Authoring render path: Get Junction Mesh Component, Get Pipe Mesh Components (one stretched mesh, or cap + tiles + cap for tiled variants), and Get Flexi Pipe Mesh Components. Components are torn down and recreated when their island changes, so re-resolve them (and re-apply dynamic material instances) from an On Graph Changed handler rather than caching them.
Saving and loading
Export Graph serializes the committed network into a self-contained byte array; store it in a USaveGame like any other property. Import Graph restores it.
The import is fail-closed: bytes written by a newer PipeIt version, or that fail validation, return false and leave the current network untouched, so a corrupt save slot cannot destroy a live network. Layout only: the kit assignment, render mode, and scale are actor properties and save with the actor as usual.
Brackets at runtime
The bracket surface tracking works in game worlds for runtime-editable networks: brackets re-trace when the actors they grip move, and when the pipe itself moves. Those automatic updates never pollute the player’s undo history.