Unity ML-Agents Inference Not Running in Build - Agent Configuration Fix
Your ML-Agents characters or vehicles behave correctly when you press Play in the Unity Editor during or after training, but in a development build, release build, or executable they freeze, drift with no decisions, or fall back to idle / zero actions. Training and Python are not involved anymore. You only need embedded inference.
This guide walks through the configuration that differs between Editor sessions (where a trainer or default behavior can hide mistakes) and a standalone player where only your Behavior Parameters and model matter.
Bookmark this page if you ship demos or Steam builds with pretrained policies. The checks are fast once you know the pattern.
If your issue is training never starting or hanging while connected to Python, start with Unity ML-Agents Training Hangs or Crashes - Environment Fix.
Problem Statement
You may see one or more of the following:
- In a built player, agents never change actions (always zeros, or heuristic idle pose).
- No errors in the console because inference fails silently or actions are clamped to default.
- Same scene in the Editor Play mode still works because Behavior Type is Default and something external supplies actions during development.
- Logs (if you enable them) mention no model, wrong behavior type, or Academy not stepping.
Why This Happens
Behavior Type still targets training-time expectations
- Default often assumes a connection to an external policy or trainer workflow that does not exist in a shipped game. In the Editor you may not notice if you always launch with
mlagents-learnor cached policy. - Player builds need an explicit Inference Only (or Heuristic Only for hand-authored logic) path that reads from an assigned Model ( ONNX / NN model asset depending on package version).
No model assigned or wrong brain name
- After exporting a policy, you must assign the Model on Behavior Parameters (or the component your ML-Agents version uses for policy assets).
- A mismatched Behavior Name between trained checkpoint and agent configuration can yield a model that never loads for that behavior.
Decision stepping never runs
- Decision Requester missing, disabled, or Decision Period set inconsistently can mean
DecisionRequestednever fires in builds the way you expect. - Time scale zero, paused
Academy, or script execution order differences between Editor and player can mask the issue until you build.
Package / backend mismatch
- Recent ML-Agents packages use Sentis (formerly Barracuda path) for inference. If the Sentis (or inference) package is missing, outdated, or fails on a target platform, inference can fail only in certain builds (for example IL2CPP vs vanilla Mono).
Step-by-step fix
Step 1: Set Behavior Type for shipping
- Select the GameObject with your Agent (or child that holds Behavior Parameters).
- Find Behavior Parameters in the Inspector.
- Set Behavior Type to Inference Only for trained policies you want in the final game.
- If you are still smoke-testing without a network, use Heuristic Only temporarily to confirm the rest of the loop runs in a build.
Verification: In the Editor, switch to Inference Only with your Model assigned. You should see normal behavior without starting Python training.
Step 2: Assign the exported model
- Locate your exported Model asset (policy) from the training pipeline your ML-Agents version documents (for example
.onnxor the asset type your Inspector expects). - Drag it into the Model field on Behavior Parameters (when Inference Only is selected).
- Confirm Behavior Name matches what you trained against (YAML / config used during training).
Common mistake: Assigning a model trained for a different observation or action space (different vector sizes). That often works in Editor tests if an older component caches state; in a clean build, actions collapse. Re-export after changing Vector Observation or Action Size.
Step 3: Confirm Decision Requester
- Ensure a Decision Requester component exists on the Agent (or equivalent setup for your version).
- Set a sensible Decision Period (for example
5physics steps, depending on your game loop). - If you replaced decisions with custom code, confirm you still call
RequestDecision()on the schedule you expect.
Verification: Add a temporary log or UI counter in OnActionReceived during a development build only. You should see it increment when decisions run.
Step 4: Academy and global settings
- Ensure your scene includes a valid Academy setup for your ML-Agents major version (automatic Academy instance or explicit object, per current package docs).
- Check Project Settings → ML-Agents: confirm options match between Editor and build (communicator off for pure inference, reasonable time scale).
- Confirm nothing disables stepping in builds (custom pause menus setting time scale to zero before agents initialize).
Step 5: Build settings and stripping
- Create a Development Build with Autoconnect Profiler and logging enabled first.
- If you use IL2CPP, and you see runtime exceptions involving inference or native plugins, review link stripping / Managed Stripping Level for your Unity version. Start with minimal stripping on a test build to isolate the problem.
- Confirm Script Compilation includes all assemblies that register ML-Agents / Sentis types (no optional define that is Editor-only).
Step 6: Platform-specific checks
- Standalone Windows / Mac / Linux: Verify antivirus or path casing is not blocking StreamingAssets or model loading if you load policies from disk manually.
- Mobile / console: Confirm Sentis and ML-Agents support your target per Unity documentation; reduce observation size if you hit memory or initialization failures.
Verification checklist
- [ ] Behavior Type is Inference Only (or Heuristic Only for tests) in the prefab or scene you actually ship.
- [ ] Model field is non-null and references the policy trained for this behavior.
- [ ] Decision Requester present and Decision Period > 0 (or equivalent manual requests).
- [ ] OnActionReceived runs in a Development Build (temporary logging).
- [ ] Academy stepping is not blocked by time scale or pause logic.
Alternative fixes
- Heuristic Only path: For boss fights or scripted segments, bypass the model and write explicit actions until you finish integration.
- Hybrid: Use Inference Only for NPCs but Heuristic Only for the player-controlled tutorial drone while you iterate.
- Separate prefabs: Keep a Training prefab (Default / training-friendly) and a Shipping prefab (Inference Only + model) to avoid accidentally building the wrong one.
Prevention tips
- Add a build preflight script or checklist item that asserts all agents in shipping scenes have Inference Only and a non-null Model before you tag a release.
- Store exported policies next to versioned training configs so observation sizes cannot drift silently.
- After upgrading ML-Agents or Sentis, run one clean player build on each target before demo day.
Related links
- Unity ML-Agents documentation for Behavior Parameters, inference, and package requirements.
- Unity ML-Agents Training Hangs or Crashes - Environment Fix when the problem is Python / training, not the player build.
- Unity learning track that covers ML-Agents in context: Unity Game Development (AI integration module).
If this article saved you a long night of “works in Editor, dead in build,” share it with teammates who are wiring their first inference-only agents. It keeps the same mistakes from spreading across branches.