MSIR
A MetaSound is a binary node graph — oscillators, envelopes, mixers and math operators wired
together, plus the graph inputs, outputs, variables and interfaces that shape it — that you can
normally only read by opening the MetaSound editor and tracing the canvas by eye. MSIR decompiles that
whole graph into one flat, node-and-wire text document you can read top to bottom, diff, and paste into
an assistant as context. It is read-only: audio.authoring.decompile_metasound renders a
MetaSound Source or Patch to text; compiling text back into the asset is a planned follow-up, not a
current capability.
Why it matters
Diffable in version control
The same text is written to the asset-dump cache as msir.txt, so a signal-chain change shows up as a handful of changed lines in a pull request instead of an opaque binary .uasset diff. git log -p and grep both work on it.
Reviewable like code
You read exactly which node feeds which, what a graph input defaults to, and where each wire lands — in plain text. Reviewing a procedural-audio graph becomes reviewing a diff, not squinting at a canvas screenshot.
Context an AI can actually read
An assistant cannot see a node graph, but it can read text. Decompiled MSIR is a compact whole-graph snapshot you can hand it so it reasons about your real audio wiring instead of guessing from asset names.
Faithful and deterministic
The live RPC and the msir.txt dump sidecar both call the same BuildMetaSoundIrText builder, so prompt context never drifts from the dump. Class refs carry their v=Major.Minor version, node positions travel in an @(x, y) suffix, and anything the decompiler cannot resolve — a missing dependency class ref, an unresolved wire endpoint — is surfaced in the returned warnings rather than dropped.
A taste
A small motor-loop source: one graph input driving a sine oscillator into a gain multiply, wired out to the graph’s audio output.
metasound MS_MotorLoop kind=MetaSoundSource {
interface `UE.Source.OneShot` v=1.0
input Float RPM = 5000.0
output Audio Out
node n1 = `UE.Sine` v=1.0 @(-320, 16) { Frequency: 220.0 }
node n2 = `UE.Multiply` v=1.0 @(-96, 32)
wire $RPM -> n1.Frequency
wire n1.Audio -> n2.PrimaryOperand
wire n2.Output -> $Out
}
Graph I/O uses $Name sigils, the decompiler assigns n1, n2…
locals to nodes, and each class ref is a backtick-quoted Namespace.Name token with its
version.
How your assistant uses it
Your assistant decompiles the graph to MSIR, reads the wiring for context, and answers or plans from it — a read-only inspection, no canvas walking and no edit to the asset.
You: In MS_MotorLoop, what drives the Sine node's frequency and where does the mix go?
call("audio.authoring.decompile_metasound", {assetPath:"/Game/Audio/MS_MotorLoop"})
→ {ir:"metasound MS_MotorLoop kind=MetaSoundSource { ... wire $RPM -> n1.Frequency ... }", warnings:[]}
The RPM graph input drives n1 (Sine).Frequency, and n1's audio runs through
n2 (Multiply) out to the graph's $Out audio output.
audio.authoring.decompile_metasound reads a MetaSound
Source or Patch out as text for review and AI context; round-trip authoring (compile_msir)
is a future follow-up, so there is no compile-text-back path yet. To change a graph, drive it directly
with the other audio.authoring.* MetaSound editing methods. MetaSound support is Early
Access; verify against a decompile of your own asset before relying on the output.