The editor panel
The MifBridge panel is a live window inside the Unreal Editor with eight tabs: a transcript of every bridge call, three project views, an AI and character view, and a setup checklist. Read this to see what each tab shows, what its numbers do and do not mean, and how to use it.
Opening it
The panel opens by itself about a second after the editor starts. You can also open it under Window, or from Tools, Mif Bridge: Live Panel. The console variable mif.BridgeAutoOpen 0 turns the automatic opening off.
The panel only reads the bridge. It writes nothing back, and the bridge does not depend on it. The server starts at editor startup with no reference to any widget, so closing the panel, or running an editor with no UI (a commandlet), changes nothing about how the bridge answers.
The one control in the panel's header that changes anything is WRITE MODE, which sets read, scratch or full. See Safety and write modes for the rules around raising it.
The eight tabs
| Tab | What it answers |
|---|---|
| ACTIVITY | What did the assistant just do? |
| BRAINMAP | How are my assets connected? |
| HEATMAP | Which assets are the most connected? |
| PERFORMANCE | Which actors are the heaviest in the open level? |
| INHERITANCE | How are my Blueprints derived from native classes? |
| BEHAVIOR | What do my behavior trees do? |
| SKELETAL SPLIT | Which bones drive which material section? |
| SETUP | Is the bridge working, and what is left to do? |
ACTIVITY: the transcript
Every bridge call appears as a card, newest first, colored by kind of work:
| Pill | Meaning |
|---|---|
READ (blue) |
a read |
WRITE (purple) |
a change |
BLOCKED (amber) |
refused by the safety gate |
REFUSED (gray) |
the caller asked for something invalid, such as an unknown parameter, a missing required one or an asset that does not exist. This is the contract working, not a defect |
FAILED (red) |
the handler tried and could not |
REFUSED is separate from FAILED on purpose. A test run deliberately sends bad input to prove it is refused, and showing those as red failures would make the whole transcript untrustworthy. A failure whose reason begins unrecognised parameter, contains is required, or begins no gets the quiet gray pill. Anything else stays red, so a real breakage stands out.
Each card shows the endpoint, its duration (slow calls color themselves), a live age and the subject of the call, read from its payload: for example find_assets /Game/FX/NS_Fire instead of a bare find_assets. When the subject is an asset path, clicking it reveals the asset in the Content Browser. A failed card shows the reason on its second line.
A live banner appears while a handler is running. Handlers run on the editor's game thread, so if that banner stays up, the endpoint it names is the one holding the editor.
The flag button
One click writes a structured report into Saved/MifBridge/reports/ describing what was flagged. The button writes a file and runs nothing.
BRAINMAP: the dependency graph
A custom-painted canvas of your assets and what references what. Zoom with the wheel (toward the cursor), drag with the right or middle mouse button, and click a node to reveal that asset in the Content Browser.
- Color is the asset type.
- Size is the number of referencers, so a hub looks like a hub.
- Zoomed out you read shape: clusters and hubs. Zoomed in the nodes become the engine's own type icons and names appear. The icons are looked up by class name, so reading them loads no assets, which also keeps the view safe on cooked content.
The layout is solved once when the data is fetched. Zoom and pan are only a transform, so the editor stays responsive.
A rail of chips beside the graph lists the asset types. A chip is a button: clicking one dims that type. A dimmed type fades but keeps its place and loses its labels, so the layout you built a mental map of does not shift. If you open the tab while the asset registry is still scanning, it waits and rebuilds when the scan finishes.
HEATMAP: what is most connected
Every package under a prefix, ranked: a rank chip, the name, the split, a bar and the total, in one scrolling list. The scan is capped at 400 packages.
- The bar is the package's connections as a fraction of the busiest package, so a third of the connections is visibly a third.
- The color follows rank. In a project where the busiest package has hundreds of referencers and the median has a few, coloring by absolute count would paint nearly everything the same color.
- Each row shows both halves, never only the sum. Many in and few out is a shared foundation, and deleting it breaks the world. Few in and many out is an asset that depends on everything. The two are opposite problems with similar totals.
PERFORMANCE: cost, and the limits of it
Read this before you trust a number here. The editor's frame-time numbers describe the editor drawing its own viewport, gizmos and selection outlines. They are not your game's frame rate, and ranking actors by "FPS cost" measured that way would be false precision. This tab reports a census of static content cost instead: properties of the content that are reproducible and that an artist can act on.
Three tiles come first, each stating its own denominator:
- total triangles, summed across actors that have geometry;
- how much of the level ticks, with the Blueprint share called out;
- the heaviest actor, shown as a share of the level total. A level whose worst actor is 3% has no heaviest-actor problem.
Then the list:
| Column | Meaning |
|---|---|
| triangles | LOD0 triangles across the actor's mesh components |
| components | primitive components it drags along |
| materials | material slots, a proxy for draw calls |
[BP TICK] |
the actor runs Blueprint code every frame |
[BP TICK] is the closest static proxy for Blueprint cost. It is not a measurement: a cheap tick and an expensive one look identical here, and the tab says so on screen. Bar length is relative to the heaviest actor, because there is no universal triangle budget to measure against.
The tab rebuilds every time you open it, because it describes the open level and a stale number gets acted on. The same census is available as perf_heavy_actors.
For real frame attribution
trace_start -> do the thing you want to measure -> trace_stop
This writes a .utrace file into Saved/MifBridge/Traces on the cpu,frame,bookmark,stats channels. Open it in UnrealInsights.exe (in Engine/Binaries/Win64), where a Blueprint's Tick appears by name with its real cost. That is what the census cannot give you.
trace_stop reports the file size, because a zero-byte trace means the channels captured nothing and otherwise looks like success. Stopping when nothing was started answers stopped: false instead of failing, so the call is safe to repeat. stopped: true means the trace system has released the file, so the size is final. Every trace gets its own file name, to the millisecond.
INHERITANCE: the class hierarchy
This tab groups your Blueprints under the native classes they derive from (Actor, ActorComponent, AnimInstance and the project's own C++ classes), with each Blueprint tree hanging off its root.
It loads nothing. A Blueprint publishes its parent class as an asset registry tag, so the whole hierarchy is metadata the registry already holds. Building it by loading every Blueprint would be slower and, on a cooked project, dangerous. Native roots are synthesized, because a C++ class is not an asset and has no registry entry.
- One plate per native root, folded except the biggest. The plate header shows two facts before you open it: the blueprint count under that root, and the depth of the longest inheritance chain, counting the native class as level 1. 200 Blueprints at depth 2 is a list. 20 at depth 6 is a problem.
- Each row shows its direct child count, with the subtree total in the tooltip. Roots are sorted by descendant count.
- The filter keeps a node if it or any descendant matches, then expands what survived. A root with matches is drawn open even if you folded it, and returns to how you left it when the filter clears.
- The summary carries
registryStillScanningwhile the registry scan runs, so a partial tree at startup is not mistaken for a small project. - Double-click opens the asset. That is the only place the view loads anything.
It is built once on first use and has a refresh button, because it describes the project's assets, which do not change while the editor idles.
BEHAVIOR: behavior trees
Lists the project's behavior trees and draws one at a time with its blackboard. It calls the same code as describe_behavior_tree, so the panel and the endpoint cannot disagree about your project's AI.
- Nodes are colored by kind, because kind says how a node behaves: a composite routes, a task acts, a decorator gates, a service ticks.
- Decorators and services are named on the row rather than drawn as children. They attach to a node and gate or tick it, and drawing them as children would show a tree the AI does not have. "Gated by HasMoney" tells you more than a count.
- A tree with no blackboard says outright that every blackboard decorator in it does nothing.
- The flow strip along the top shows the selected node's path from the root, left to right, with kind over name. Only the last box is lit. It answers "how did execution get to this node?", which an indented tree makes hard to read.
- The blackboard plate marks a key
read herewhen a node, one of its decorators or one of its services names it. The keys are read from the nodes' own key selectors, so no title matching is involved.
describe_behavior_tree returns this for every node: services (a count), decoratorNames[], serviceNames[] and blackboardKeys[]. list_blackboard_keys lists a blackboard's keys.
SKELETAL SPLIT: bones and material sections
Pick a skeletal mesh and the tab answers two questions an artist splitting a character asks: which bones drive which material section, and which of those bones could be split out cleanly.
- The bind pose as a figure you can click. Every bone is a dot at its real projected position, joined to its parent and colored by the section it drives. Clicking a joint shows the sections it touches, its split verdict, its child bone count and its weighted vertices.
- A split preview. With a bone selected, the mesh shows as the part that stays and the part that leaves, each with its vertex count and the sections it keeps.
- The character is rendered behind the figure in a real preview scene, and every bone is projected through that frame's own view, so the overlay cannot drift from the picture.
The bones come from list_bones, composed up the parent chain. Nothing in the tab knows what an arm or a spine is, so a prop, a door or a creature draws as itself. The tab calls the same code as analyze_skeletal_split and list_bones.
SETUP: a checklist that knows its own state
SETUP answers "I just installed this, what do I do" and also "why is nothing happening". Every step reads the editor's live state and has a full answer when the check fails, for example "the listener is not bound: start it from Tools, MifBridge, or check whether another editor holds the port".
| Step | Reads |
|---|---|
| Bridge listening | whether the server is running, and its port |
| Endpoints registered | how many endpoints are registered |
| An assistant has called it | the total call count |
| Write mode | the current mode. full shows amber, as a prompt to confirm it was chosen deliberately |
| Its knowledge is current | whether self_audit, describe_endpoint or mif_help appears among the recent calls |
| Generative mode (this project) | the project's setting, from MifBridgeProject.json beside the .uproject, which mif_project_mode writes when you answer. "not chosen" shows amber |
Two of the steps you might expect, such as "MCP server registered" and "endpoint snapshot is current", are facts about the MCP server, a separate process the editor has no handle on, so the tab does not print them.
The knowledge step states its own window on screen: it looks at the last fifty calls, because that is all the panel keeps. It says "nothing in the last N calls", which is true, instead of "the agent never checked", which would not be. The header's count of ready steps comes from running the same checks, so it cannot disagree with the steps beneath it.
SETUP also has a one-button setup for Claude Code, and two copy-paste prompts: what to paste at the top of a new conversation, and what to paste after the plugin is updated.
The endpoints behind the tabs
These work without any widget:
| Endpoint | Answers |
|---|---|
project_dependency_graph |
nodes and edges under a prefix. Each node reports dependsOn and referencedBy |
project_asset_distribution |
counts by class and folder |
perf_heavy_actors |
the static cost census, sortable |
trace_start and trace_stop |
an Unreal Insights capture |
describe_behavior_tree and list_blackboard_keys |
what the BEHAVIOR tab draws |
analyze_skeletal_split and list_bones |
what the SKELETAL SPLIT tab draws |
Everything here is bounded, and says so when it bounded something. Finding referencers runs per asset, so on a project with tens of thousands of assets an unbounded graph would stop the game thread for as long as it ran. project_dependency_graph therefore refuses a prefix shallower than two path segments and points you at project_asset_distribution, which accepts a bare /Game because it never touches referencers. Every capped result reports both the cap and the true total, so a truncated answer never reads as a complete one.