Text IRs
Unreal's most powerful assets — Blueprints, materials, animation graphs, control rigs —
are visual node graphs locked inside binary .uasset files. You can only really read them
by opening the editor and tracing wires by hand. PinWright's text IRs turn those graphs into clean,
readable text: something you can diff, review, and hand to an AI to author.
Why a text IR changes what your assistant can do
An AI assistant is good at exactly one representation: text. Ask it to wire a node graph blind, through dozens of “create node / connect pin” calls, and small mistakes compound. Give it the same graph as a compact, line-based language, and it reads the whole thing, edits a few lines, and hands it back. That is what an IR (intermediate representation) is here: a faithful text form of the graph, on the way in and on the way out.
A Blueprint BeginPlay graph: a Print, an IsValid check, a Branch, two exec paths reconverging at the end — a dozen nodes and wires you read by following pins across the canvas.
entry event BeginPlay() {
call PrintString(InString: "Hello")
%valid = call IsValid(Object: $MyRef)
%b = branch(%valid) [true -> @ok, false -> @end]
@ok:
set Score = 100
@end:
call PrintString(InString: "Done")
}
Diffable in version control
A change to a graph becomes a few changed lines in a pull request, instead of an opaque binary blob you cannot review.
Reviewable like code
You read what changed and why in plain text, so an AI edit to a Blueprint or material is as auditable as an edit to your source.
The format an AI can author
One consistent, line-based language per graph type — the assistant learns it from a handful of examples and writes whole graphs reliably.
Faithful, with a stated boundary
Graph structure is the guarantee: nodes, connections, property values and node positions all survive — on the round-trip IRs, back into the asset too. Editor cosmetics do not: node colors and editor list order are out of scope by design, and most IRs drop comment boxes. The per-IR table below gives the exact boundary.
Two kinds of IR
Every IR reads a graph out to text. Some also compile text back in, so your assistant can author and edit those graphs as text; the rest are read-only for now.
- Round-trip — read the graph as text and compile edited text back into the asset. Full authoring.
- Read as text — decompile the graph to text for review and context. Compile-back is a future follow-up.
Round-trip — author as text
Read the graph out, edit the text, compile it back in.
Blueprint graph logic — events, functions, and control flow as line-based text.
Material and Material Function graphs — the shader node network as text.
Animation Blueprint graphs — state machines and blend logic as text.
Control Rig (RigVM) graphs and rig hierarchy — procedural rigging as text.
Read as text — decompile for review
Turn the graph into readable text for inspection and AI context.
Behavior Trees — composites, decorators, services, and tasks as text.
Niagara systems, emitters, and module scripts — VFX graphs as text.
MetaSound Source and Patch graphs — the audio node network as text.
SoundCue graphs — the classic sound node tree as compact text.
PCG graphs — procedural-generation nodes and edges as text.
Per-IR fidelity
The shared guarantee above is the floor; each IR sits slightly differently against it. This is the exact boundary per format — what node identity survives, what layout survives, whether comments come along, and what is still out of scope.
| IR | Direction | Node identity | Layout | Comments | Known unsupported |
|---|---|---|---|---|---|
BPIR |
Round-trip | Preserved across a compile | Authored @(x, y) kept |
Dropped | Unusual composite and plugin-defined nodes ride a generic form — review after a compile |
MGIR |
Round-trip | Expressions keyed by qualified class path | Authored @(x, y) kept |
Dropped | Node colors, editor list order, layout-only reroutes |
AGIR |
Round-trip | Node GUIDs travel in guid= |
Authored @(x, y) kept |
Dropped | Node colors; a narrower engine-version scope than the rest of PinWright — see the AGIR page |
CRIR |
Round-trip | Struct paths plus %localId |
Authored @(x, y) kept |
Comment nodes round-trip | Curve, connector and physics hierarchy elements decompile to a # TODO unsupported marker |
BTIR |
Read as text | Node names as the asset stores them | @(x, y) emitted |
Captured per node | No compile-back path yet; unreachable nodes emit as orphan plus a warning |
NIR |
Read as text | Node identity lines inside script graph bodies | @(x, y) recorded; equivalence is logical, not visual |
Not emitted | Referenced module scripts stay path references; unknown node classes become # unknown-node plus a warning |
MSIR |
Read as text | Decompile-local n1, n2… over the node GUIDs |
@(x, y) recorded |
Not emitted | Unresolved class refs and wire endpoints surface as warnings |
SCIR |
Read as text | Node names as the cue stores them | @(x, y) recorded |
Not emitted | Multiply-referenced and unreachable nodes surface as warnings |
PCGIR |
Read as text | N1, N2… follow GetNodes() order — not asset-stable |
@(x, y) recorded |
Not emitted | Subgraphs are flattened, not recursed |
On the read-as-text IRs, “survives” means the detail is represented in the decompiled text — there is no compile-back trip for it to survive yet. Byte-level determinism is claimed per IR, not across the board: where an IR guarantees it, its own page says so and in what scope.