What runtime_identifier actually does
Every vanilla entity in Minecraft Bedrock is backed by a compiled C++ class that dictates its core behavior before any JSON components are applied. When you create a custom entity without specifying a runtime_identifier, the engine defaults to the standard living mob class. This gives your entity standard AI processing, health tracking, death animations, and turning red when hurt.
When you add a runtime_identifier to your entity description, your custom entity inherits the exact C++ mechanics of that target vanilla identifier. Your JSON components then override or layer on top of that base logic. Using non-mob identifiers strips away the overhead of a living creature and replaces it with specialized mechanics like projectile deflection, solid block-like collision, or instant removal of death smoke.
This inheritance is a double-edged sword. Because hard-coded C++ logic often runs after or completely ignores JSON components, certain non-mob runtime identifiers will refuse to run AI goals, ignore movement speed values, or force specific sounds to play when interacted with.
{
"format_version": "1.20.40",
"minecraft:entity": {
"description": {
"identifier": "my_pack:custom_dummy",
"runtime_identifier": "minecraft:armor_stand",
"is_spawnable": true,
"is_summonable": true,
"is_experimental": false
},
"components": {
"minecraft:physics": {
"has_gravity": true,
"has_collision": true
},
"minecraft:collision_box": {
"width": 0.6,
"height": 1.8
},
"minecraft:health": {
"value": 20,
"max": 20
}
}
}
}Useful non-mob identifiers and their quirks
Not every vanilla identifier works cleanly as a base for custom entities. Some will crash the game if spawned without internal engine data, while others are completely locked into specific trajectories. The table below lists the non-mob identifiers most frequently used by add-on developers and the exact engine behaviors they pass down to your custom entity.
| Runtime Identifier | What it does | Notes |
|---|---|---|
| minecraft:armor_stand | Disables the red hurt flash and death fall-over animation. Punches break the entity quickly. | Forces a right-click equip interaction unless carefully bypassed. Emits wooden hit sounds. |
| minecraft:snowball | Provides lightweight projectile tracking, smooth client-side flight interpolation, and no death smoke. | Also used as a tick-light base for invisible marker entities when physics and projectile components are omitted. |
| minecraft:arrow | Allows the projectile to stick into blocks and trigger wooden buttons or target blocks. | Hard-codes arrow pickup behavior unless overridden. Model rotation follows velocity automatically. |
| minecraft:boat | Gives the entity a solid, standable collision box (like a block) rather than soft entity pushing. | Inherits weird buoyant physics in water and custom paddling controls if ridden by a player. |
| minecraft:minecart | Allows the custom entity to snap onto and ride vanilla rail blocks. | Strictly locks movement to rail axes when touching rails; normal AI navigation will not work. |
| minecraft:ender_crystal | Triggers an immediate death/destruction response on any single point of damage. | Hovers in place by default and cannot use standard navigation components. |
Building a custom projectile
When creating custom thrown items, spells, or bullets, omitting the runtime_identifier causes the entity to stutter in mid-air because the client treats its movement like a walking mob rather than a fast-moving object. Setting the runtime_identifier to a vanilla projectile like minecraft:snowball or minecraft:thrown_trident enables the engine's client-side projectile interpolation.
Pair the runtime identifier with the minecraft:projectile and minecraft:physics components. The runtime identifier handles the smooth rendering and prevents the entity from leaving behind a puff of white death smoke upon impact, while the minecraft:projectile component lets you define exact gravity, velocity, and on-hit behavior in JSON.
{
"format_version": "1.20.40",
"minecraft:entity": {
"description": {
"identifier": "my_pack:pebble_projectile",
"runtime_identifier": "minecraft:snowball",
"is_spawnable": false,
"is_summonable": true,
"is_experimental": false
},
"components": {
"minecraft:collision_box": {
"width": 0.25,
"height": 0.25
},
"minecraft:projectile": {
"on_hit": {
"impact_damage": {
"damage": 2,
"knockback": true
},
"remove_on_hit": {}
},
"power": 1.3,
"gravity": 0.05,
"inertia": 0.99,
"uncertainty_base": 1.0
},
"minecraft:physics": {}
}
}
}Static props and marker entities
Custom furniture, statues, and technical marker entities should not behave like biological creatures. If you use a default mob base for a chair, hitting it will cause it to flash red, tilt sideways as it dies, and emit a burst of smoke particles. By assigning minecraft:armor_stand as the runtime_identifier, the entity skips the red tint and death tilt completely.
For invisible technical markers used to run commands or anchor animations, minecraft:snowball or minecraft:area_effect_cloud are preferred over armor stands. A snowball with its physics disabled has a much smaller server performance footprint than a mob base and will never trigger pressure plates, make noises, or display death particles when despawned or killed.
Client-side rendering implications
Choosing a non-mob runtime identifier also affects how the resource pack renders your entity. Certain vanilla identifiers apply hard-coded rotations or offsets to the geometry before your resource pack animations even run. For instance, using minecraft:arrow or minecraft:snowball may cause the engine to automatically pitch and yaw your geometry along its movement vector, or bill-board a 2D texture toward the camera if no 3D geometry is properly hooked up in a render controller.
Furthermore, vanilla identifiers carry built-in sound events. An entity using minecraft:armor_stand will play the wooden armor stand hit sound when struck, even if you do not define it in your sounds.json file. To silence this, you must override the sound defaults in your resource pack or intercept the hit mechanics entirely.
Which versions this applies to
Applies to all modern Bedrock versions (1.12.0 through 1.21+). Does not require any experimental toggles. Note that in newer format versions (1.16.100+), custom blocks and the minecraft:property system have replaced many older uses for non-mob runtime identifiers like boats and armor stands.
When it does not work
| What you see | Why | The fix |
|---|---|---|
| The custom entity spawns, does not move, and completely ignores all minecraft:behavior.* AI goals. | You assigned a non-mob runtime_identifier such as minecraft:boat, minecraft:armor_stand, or minecraft:snowball. Non-mob C++ classes do not run the Mob AI goal selector loop. | Remove the runtime_identifier so it defaults to a standard mob, or change it to a living mob identifier like minecraft:pig or minecraft:armor_stand only if AI is not needed. |
| Right-clicking the custom entity swaps the item in the player's hand onto the entity and makes it disappear or float strangely. | Using minecraft:armor_stand as a runtime_identifier forces the hard-coded armor stand equipment slot interaction whenever a player interacts with it. | Add a minecraft:interact component that intercepts the interaction, or stop using minecraft:armor_stand and instead use a standard mob base with a custom render controller that removes the hurt overlay color. |
| Content Log Error: [Entities][error]-my_pack:custom_entity | minecraft:entity | description | runtime_identifier: unrecognised or invalid identifier. | The runtime_identifier is missing the 'minecraft:' namespace, is misspelled, or points to another custom entity instead of a vanilla one. | Ensure the value is a valid, lowercase vanilla entity identifier including the namespace, such as "minecraft:snowball". You cannot use a custom entity identifier as a runtime_identifier. |
Reference, straight from the game files
Read out of the game itself, so the ids match the version you are building for.
