Start hereBeginnerUnreal
Ask the bridge what it has
There are several hundred endpoints and their names are not guessable. The running plugin can also be older than any document, so the build you are talking to is the only authority.
Do thisCall self_audit for the live endpoint list, the engine version and the write mode, and describe_endpoint for one endpoint's real parameters, aliases and what it refuses.
POST /api/describe_endpoint
{
"name": "set_property"
}Start hereBeginner
A wrong parameter name is refused, not ignored
Endpoints reject keys they do not recognise instead of quietly dropping them, so a typo cannot turn into a call that does something else.
Do thisRead the refusal before retrying. It lists the parameters the endpoint accepts and usually names the spelling you meant.
Start hereBeginnerUnreal
Check the write mode before calling something broken
In scratch mode, saves, level loads, PIE and console commands refuse by name. A gated refusal and a real defect look alike if you only read ok.
Do thisself_audit reports writeMode. The refusal itself says how to unlock the gate and how to make the setting stick.
POST /api/self_audit
{}VerifyBeginnerUnreal
A write is not done until you read it back
An endpoint reporting success while the value did not change is exactly the bug worth catching, and it has been caught this way more than any other.
Do thisRead back with a different endpoint than the one that wrote, and compare with what you asked for, not with what the response echoed.
POST /api/get_property
{
"objectPath": "<object path>",
"propertyPath": "<property>"
}VerifyBeginner
Read the numbers, not just ok
A count of zero beside ok: true has been a real, shipped bug more than once. The response often carries the truth in a field nobody reads.
Do thisCheck the fields that say what happened, such as spawned, deleted, added, failed and remaining, before trusting ok.
VerifyIntermediateUnreal
Send numbers as numbers
A value of the wrong JSON type is an error, never a default. The refusal names the field path, so a half-applied write cannot happen.
Do thisOmit a field to leave it alone. Vectors take {x,y,z} or [x,y,z], rotators also take {pitch,yaw,roll}, and scale takes a bare number for uniform.
POST /api/set_actor_transform
{
"actorPath": "<actor path>",
"location": {
"x": 100,
"y": 0,
"z": 50
},
"rotation": {
"pitch": 0,
"yaw": 90,
"roll": 0
}
}VerifyIntermediateUnreal
Measure a captured image, do not trust its size
A capture can report a correct path, size and byte count and still be a stale or blank frame.
Do thiscapture_viewport redraws before reading and reports uniformity, dominantColour and distinctColours on every capture. Test uniformity rather than black, because a blank frame can be white.
POST /api/capture_viewport
{}SafetyBeginnerUnreal
Never silence a call that changes something
curl exits 0 on any HTTP response, including one that reports failure. A cleanup script that threw its output away once stacked three landscapes on top of each other.
Do thisParse ok from every call that changes state. Destructive calls also need an explicit confirm: true.
POST /api/delete_level_actor
{
"actorPath": "<actor path>",
"confirm": true
}SafetyBeginner
If the bridge stops answering, look for a dialog
Calls run on the editor's game thread. A modal dialog stops that thread, so the bridge goes silent while the editor itself is fine.
Do thisLook for a window behind the editor before assuming a crash. If the editor really did die, Saved/MifBridge/journal.jsonl records each call's start and end, and a start with no end names the call that was running.
SafetyIntermediateUnreal
Check for unsaved work before new_level or load_level
Both discard unsaved edits in the current map without asking, and there is no undo. A save prompt would freeze the editor and the bridge with it, so they do not show one.
Do thisCall list_dirty_packages first and decide deliberately.
POST /api/list_dirty_packages
{}SafetyIntermediateUnreal
Back up a Blueprint before deleting it
delete_asset asks for confirm: true and only works under /Game/, but it takes no backup of what it deletes.
Do thisCall backup_blueprint yourself first.
BlueprintsBeginnerUnreal
Graph edits take effect after a compile
An edit that reads back correctly and does nothing at runtime is usually a Blueprint that has not been compiled.
Do thisCompile after editing. Some endpoints remind you in their response; not all of them do.
BlueprintsIntermediateUnreal
Batch related edits into one undo
batch runs several ops in one transaction, so a single Ctrl-Z reverts the lot.
Do thisCompile-heavy ops are refused inside a batch, so use compileAtEnd instead; self_audit lists them as transactionBuckets.compileHeavy. A refused op does not stop the others, so read results[] per op: the batch's own ok only says something failed.
POST /api/batch
{
"ops": [
{
"op": "<first endpoint>"
},
{
"op": "<second endpoint>"
}
],
"compileAtEnd": true
}BlueprintsAdvancedUnreal
To change every instance, edit the component template
Setting a property on a placed actor's component reruns its construction scripts, which rebuilds the component. An instance edit the engine does not carry across that rebuild fails honestly rather than claiming success.
Do thisEdit the component template (the object ending in _GEN_VARIABLE) instead. That also makes the change apply to every instance.
Cooked projectsBeginnerUnreal
A cooked Blueprint has no graphs to read
Cooking strips the editor-only Blueprint and ships only the generated class. That is the nature of the asset, not a limit of the bridge.
Do thisRead what survives: list_components for the component tree, and describe_package for the objects a package holds and whether it is cooked.
POST /api/describe_package
{
"package": "/Game/<path>"
}Cooked projectsAdvanced
Pass graphId for double-loaded Blueprints
Some modded or cooked assets load as two copies whose nodes share identical GUIDs, so a GUID alone can resolve to the wrong copy.
Do thisPass graphId alongside the node GUID, so the node is looked up in the right graph.
BlenderBeginner
Check which addon copy Blender is running
Blender loads the addon from its own add-ons folder, not from the folder you are editing, and keeps what it imported at startup.
Do thisping reports addonPath and sourceChangedSinceStart. If addonPath is not your copy, you are running another one; if the source changed since start, restart Blender.
// MifBlender socket frame
{
"endpoint": "ping",
"token": "<token>",
"params": {}
}BlenderBeginner
run_python is on by default, so switch it off if you do not need it
It executes any Python the client sends, with your user's privileges. The socket only listens locally and is token-gated, but it is still an escape hatch.
Do thisUntick "Allow run_python" in the MifBlender add-on preferences if you do not need it.
BlenderIntermediate
Keep the scene's unit scale at 1.0 when exporting
Blender's unit scale silently rescales every export, and the FBX header does not show it. Only the magnitudes change.
Do thisscene_info reports unitSettings.scaleLength and warns when it is not 1.0. One Blender unit is 100 Unreal units.
// MifBlender socket frame
{
"endpoint": "scene_info",
"token": "<token>",
"params": {}
}BlenderIntermediate
Do not apply transforms to meshes that came from Unreal
Unreal exports a static mesh in its own local space. Applying all transforms bakes the round trip into the mesh, and anything that tiles then shears.
Do thisLeave the transform alone. import_mesh warns when an imported object has a non-identity transform precisely so nobody is tempted to fix it.
TokensBeginner
Load only the tool packs you need
Every tool definition is sent to the model on every turn, whether it is used or not.
Do thisSet MIF_TOOL_PACKS to what the session needs; core is always loaded. find_tools still searches the tools that are not loaded and names the pack that has them, and mif_enable_pack adds one mid-session.
MIF_TOOL_PACKS=world
TokensBeginner
Long tool help is one call away
Tool descriptions are trimmed in the tool list to keep it small.
Do thisCall mif_help for a tool's full description when you need it, instead of loading everything up front.