How I Use AI With Unreal Engine Blueprints Without Burning Tokens

On this page
  1. The real problem is not the engine, it is the file format
  2. What Epic shipped, and the catch
  3. The fix: stop paying a genius to move wires
  4. The workflow, step by step
  5. What this actually changes
  6. Lessons that make this work
  7. Why I still pick Unreal
  8. FAQ
  9. Try it

Quick summary

  • Most AI-agents-for-games advice ends with “use Unity or Godot”, because their scripts are plain text an LLM can read and write. Unreal Blueprints are binary .uasset files, which an agent can only read by reverse engineering the package format, at a token cost that makes it impractical. The problem is not the engine, it is the file format.
  • Epic’s experimental Unreal MCP plugin lets any AI agent drive the editor, but it has a hidden bill: every tool call dumps verbose node and pin data into the context window, and a frontier model pays for all of it, on every turn.
  • My fix is to split the work. An expensive model reads a GraphScribe export and writes a Markdown spec. A cheap, even local, model executes that spec over Unreal MCP and validates its own work by exporting the Blueprint again and comparing it to the spec.
  • Result: the smart model makes roughly one call per feature instead of hundreds of tool-calling turns, the loop that iterates is nearly free, and the work is verifiable instead of hopeful.

I build games in Unreal Engine, and I use AI to help me do it. Every time I say that publicly, someone tells me I picked the wrong engine.

The advice is always the same: if you want AI to build your game, use Unity or Godot. Their code is text, C# and GDScript, and large language models are very good at text. Unreal is the wrong choice because Blueprints are binary files an AI cannot read, and Unreal C++ is a fight you do not need to have.

That advice is not stupid. It is just aimed at the wrong problem.

The real problem is not the engine, it is the file format

An AI agent cannot read a Blueprint the way it reads code. A Blueprint is a .uasset, a binary package holding nodes, pins, wires, defaults, and component templates. Your agent can open the file, and there is nothing in it for the agent to read. It cannot grep it, diff it, review it in a pull request, or answer “who calls this function?”.

Strictly speaking, “cannot” is too strong, and I should be honest about that. The package format is documented well enough to reverse engineer: name tables hold plain strings, K2 node classes carry recognisable names like K2Node_CallFunction, properties use the engine’s tagged serialization, pin links are GUID references you can resolve, and the compiled function bytecode sitting in the package can be disassembled. Plugins and standalone parsers exist that do exactly that, which is how you can inspect a Blueprint without opening the editor.

So an agent can read a Blueprint, if you are willing to pay for it. It has to infer structure from hex dumps and GUID cross-references, version by version, file by file. A 200 KB Blueprint becomes roughly a megabyte of hex before the model can start reasoning, and it pays that cost again every time it re-reads the graph. That is a research project, not a workflow you can run fifty times a day.

Which is the real point: the information is not locked away, it is just expensive enough to unlock that it never pays for itself inside a normal task.

Unity and Godot do not solve AI-assisted development. They just happen to store gameplay logic in a format that was already text, so nobody had to solve anything.

Change the format, and the argument disappears. That is what GraphScribe does: it exports Blueprints, Widget Blueprints, and DataAssets into Markdown, Mermaid, JSON, an Obsidian vault, and Graphify, which is a project-wide knowledge graph of how your Blueprints call each other. Your graphs stop being binaries and become text an agent can actually read.

With that in place, Unreal stops being the hard case. It becomes a case with a bridge.

What Epic shipped, and the catch

Epic’s Unreal MCP plugin (still marked experimental in UE 5.8) embeds an MCP server inside the editor process. Any MCP-compatible agent, Claude Code, Cursor, VS Code, Codex, Gemini, connects to http://127.0.0.1:8000/mcp and starts calling tools: spawn actors, configure lighting, create material instances, inspect Slate widgets, run automation tests. One console command writes the client config for you:

ModelContextProtocol.GenerateClientConfig ClaudeCode

It is genuinely good, and it is the missing piece that made “AI does Unreal work” possible instead of theoretical. I use it every day now.

But it has a structural flaw, and it is not a bug anyone can patch: MCP is chatty, and chat is billed by the token.

Here is what actually happens when you ask a frontier model to “add a coin pickup Blueprint” through MCP alone:

  1. The agent loads tool schemas so it knows what it can call.
  2. It calls a tool to find the asset, which returns a list.
  3. It calls a tool to read the graph, which returns nodes with GUIDs, pin arrays, defaults, and metadata as JSON.
  4. It decides on one small change, then calls a tool to make it.
  5. It re-reads the graph to check, and the full JSON comes back again.
  6. It repeats that loop until the graph looks right.

Every one of those tool results stays in the context window for the rest of the conversation, and the whole conversation is re-sent on every turn. A task a human would finish in four minutes becomes thirty tool calls, each one carrying data the model already saw. Tool calls also run serially on the game thread, so the agent cannot even parallelize the loop away.

None of this matters if you are using a cheap model. It matters enormously when the only model that can reason about a messy graph is the expensive one, because you are paying frontier prices to re-read the same pin dumps over and over.

The fix: stop paying a genius to move wires

The insight is simple. Deciding what a graph should be is hard and worth a smart model. Typing that decision into the editor is mechanical, and mechanical work belongs to a cheap model.

So I split the job:

The two-model workflow: a smart planner writes a Markdown spec, a cheap executor builds it through Unreal MCP, and GraphScribe exports are the read-back that closes the loop

My folder layout is boring on purpose:

Docs/AI/
Exports/ <- folder batch export from GraphScribe (Markdown + Graphify)
Specs/ <- the smart model writes one spec per task here
Reports/ <- the executor writes its validation result here

The workflow, step by step

Step 1: Export the Blueprint so the smart model can read it

Right-click the content folder that owns the feature, choose Export Blueprints with GraphScribe…, set the format to Markdown and include subfolders, and point the output at Docs/AI/Exports. You get one clean text file per Blueprint: variables, components, events, functions, and a walk of every graph in execution order with pins and values inline. Run it again with Graphify and you also get ProjectLinkage.graphify.json, one file describing which Blueprint calls which function and uses which class across the whole project. Both are covered in Ways to Export.

This step is where the cost saving is born. The same Blueprint that an agent would accumulate node by node through MCP tool results, GUIDs, pin arrays, and JSON envelopes included, arrives as a compact document. On the graphs I have measured, the Markdown export that fully describes a graph is roughly 50x smaller in characters than the data an agent pulls to understand the same graph through MCP calls. Same content, a fraction of the context. (Do not take my number: export one of your own graphs, count the characters, then ask an agent to describe the same graph over MCP and count what comes back. The ratio is the whole business case, so it is worth checking once.)

Step 2: The smart model writes a spec, not code

The expensive model gets one prompt: here is the export, here is what I want, write the spec. The spec is not vague prose. It is a plan precise enough that a mediocre model cannot get it wrong, written in the vocabulary Unreal already uses:

# Spec: BP_CoinPickup
Target asset: /Game/Gameplay/Pickups/BP_CoinPickup
Parent class: BP_PickupBase
Baseline export: Exports/Markdown/Gameplay/Pickups/BP_CoinPickup.md
## Variables to add
- CoinValue (int32) = 10, Instance Editable, Category "Pickup"
- bCollected (bool) = false, Private
## EventGraph
### Event BeginPlay
- #1 Set (v)bCollected = false
- #2 --Exec-> Play Sound at Location (Sound = S_Pickup, Location = GetActorLocation)
### Event ActorBeginOverlap (OtherActor)
- #3 Cast To BP_PlayerCharacter (Object = OtherActor)
- As BP_PlayerCharacter:
- #4 Call AddCoins (Amount = (v)CoinValue)
- then -> #5 Set (v)bCollected = true
- then -> #6 Destroy Actor (Target = Self)
## Done when
- The export contains exactly these nodes with these pins and this order.
- AddCoins is called with the CoinValue variable, not a literal.
- No orphan nodes, no unconnected exec pins, no compile warnings.
- The re-export diff shows no other graph changed.

That example is close to real output, and it is exactly the shape a GraphScribe Markdown export uses, so the executor never has to translate between two notations.

Notice what the smart model did not do: it did not open a socket, call a tool, or re-read a graph. It thought once, wrote a file, and stopped. I review that file in two minutes, which is the other half of the win. Reading a spec is cheap; auditing three hundred tool calls is not.

Step 3: A cheap model executes it over MCP

Now the executor. Any model that can follow instructions and call tools will do: a small local model through Ollama, or the cheapest hosted model you can find. It needs no architectural judgement, because the thinking is already done and written down.

Its prompt is short:

Read Docs/AI/Specs/BP_CoinPickup.md and build it using Unreal MCP.
Follow the spec exactly. Do not invent node or function names.
If a node in the spec does not exist, stop and write the problem to Reports/.

This is the part people find hard to believe, so it is worth being blunt about why it works: the task is no longer “design a pickup system”. It is “create these variables, place these nodes, connect these pins”. That is transcription plus tool calls, and small models are fine at it when the spec is deterministic.

Step 4: The executor validates its own work with the same bridge

An agent that cannot check its own work is a liability at any price. This is where the loop closes, and it is my favourite part of the setup.

The executor is told that the task is not done when it thinks it is done. The task is done when the export matches the spec:

1. Re-export BP_CoinPickup with GraphScribe to Docs/AI/Exports/.
2. Compare it against the spec: nodes, pins, values, order.
3. Write the result to Reports/BP_CoinPickup.md.
4. If anything does not match, fix only that difference and repeat.

Because GraphScribe gives the graph a readable form, the check is a text comparison rather than a judgement call, and Graphify’s stable IDs (bp:, fn:, evt:, cls:, see Graphify: AI-Ready Graphs) mean the comparison survives re-exports: the same function keeps the same ID tomorrow, so a diff means a real change and not a reshuffled file.

In practice the executor runs three to six iterations on a medium graph, each one costing almost nothing, and stops when the export matches. When it cannot match, it does not guess. It writes what is missing to Reports/, and I read that instead of a 400 line chat log.

Step 5: Escalate only when the plan was wrong

Sometimes the spec is the problem: the node the planner asked for does not exist, or the parent class cannot do what the spec assumes. That is the one case where the smart model comes back, and it comes back cheaply, because I hand it three things: the spec, the current export, and the executor’s report. It rewrites section of the spec that was wrong. No frontier model ever sits in a tool-calling loop.

What this actually changes

DimensionSmart model over MCP onlyGraphScribe bridge
Context per taskTool schemas plus full JSON graph dumps, re-sent every turnOne Markdown export plus one Graphify graph, read once
Who iteratesThe expensive modelThe cheap or local model
Cost curveTokens x turns x frontier priceOne planning call plus near-free loops
Validation“The agent said it worked”Export diffed against the spec
Failure modeExpensive retries and silent driftA precise mismatch written to a report

The speed is a side effect worth mentioning. Folder exports take seconds, the executor loop is short, and the planner is not waiting on thirty round trips. On features I have built both ways, the bridged version finishes faster, mostly because it stops re-reading things it already knows.

Lessons that make this work

  1. Make the spec boringly explicit. Node names, pin names, values, order. Ambiguity is the only thing a small model cannot handle.
  2. One Blueprint per task. Multi-asset specs are where cheap models start improvising.
  3. Never let the executor invent API. Put it in the prompt, and make the validation step catch it.
  4. Define “done” as something an export can prove. If you cannot write the check, the task is not ready.
  5. Keep exports in version control. Committing Docs/AI/Exports turns “changed a binary file” into a readable diff, which is how you review AI work without reading chat logs.
  6. Re-export before every iteration. Stale exports are how an agent “fixes” something that is already correct.
  7. Use JSON when you need exactness. Markdown is the spec, JSON is the machine truth when a pin value really has to match.
  8. Cheapest model that passes the check, not the cheapest model that exists. Upgrade only the step that keeps failing.

Why I still pick Unreal

If your goal is to ship a small 2D game this month and you have no Unreal experience, use Godot. I am not going to pretend otherwise.

But if your goal is to ship a game in the engine you already know, with the rendering, animation, networking, and console support you actually need, then “AI works better with text” is not a reason to throw that away. It is a reason to make your engine produce text. Blueprints are the only part of Unreal that was ever truly opaque, and that part is solved by exporting them. Everything else in Unreal, C++, configs, data assets, build scripts, was already text, and agents handle it the same way they handle any other codebase.

The people telling you to switch engines are optimising for the demo. I am optimising for the project I have to maintain for the next three years.

FAQ

Does Unreal MCP really burn tokens that fast?

On its own, yes, for anything graph-shaped. Each tool result enters the context window and stays there for the rest of the session, and the whole conversation is re-sent every turn, so a task with many small calls and verbose JSON results is expensive even when the model is doing very little thinking. The fix is not fewer tools, it is putting the graph into the context once, in a compact form, instead of rebuilding it call by call.

Can a small local model really build Unreal Blueprints?

It can execute a precise spec through MCP, yes. It cannot design a system, and it should not be asked to. The workflow above is designed around that limit: the smart model decides, the cheap model types, and the export comparison decides whether the typing was right.

Do I need GraphScribe for this workflow?

You need something that turns Blueprints into text your agent can read and diff. That is the entire bridge. GraphScribe is what I built for it, because I wanted the export to be one click, to include widget trees and DataAssets, and to produce a project-wide graph instead of fifty unrelated files. The FAQ page covers what it does and does not do.

Does this work for C++ as well as Blueprints?

Yes, and C++ is easier. Your source is already text, so the planner can read it directly and the executor patches files. The bridge only earns its keep for Blueprint graphs, DataAssets, and widget trees, which is exactly the part of Unreal that agents otherwise cannot see without reverse engineering the package format.

What if the cheap model gets stuck in a loop?

Cap the iterations in the prompt, three to six is usually enough. When the cap is hit, the executor writes the mismatch to Reports/ and stops. A stuck loop that costs pennies and produces a clear failure report is a much better outcome than an expensive model improvising for twenty minutes.

Is this worth setting up for a small project?

It pays for itself the first time you change a system you built a month ago. The exports are the documentation, the specs are the change requests, and the validation loop is the review. That is useful whether or not an AI is doing the typing.

Try it

Install GraphScribe from Fab, enable Epic’s Unreal MCP plugin, and export one feature folder. Then ask your smartest model to write a spec from that export, and let the cheapest model you trust try to build it. If the export matches the spec at the end, you have the workflow.

If you are new to Unreal and AI, start with Why New Unreal Engine Developers Should Use GraphScribe and What is GraphScribe?. If you want the technical detail of what an export contains, read the Markdown and Graphify format pages, and the schema reference if you plan to validate exports with your own script.

The engine was never the problem. The file format was. Fix the format and Unreal becomes one of the better places to work with AI, because the graphs finally say what they mean.

Keep reading