Wiki 9Minecraft Wiki 9Minecraft

Entity Properties Reference

Store typed, network-synced state variables on custom entities without abusing vanilla data components.

6Sections
5Code examples
3Known errors

Entity Properties are typed state variables declared directly inside an entity's behavior file. They replace the older practice of hijacking components like `minecraft:variant`, `minecraft:mark_variant`, or `minecraft:skin_id` just to store custom numbers, booleans, or string states. You reach for Entity Properties whenever your entity needs to track custom state across ticks, share that state with client-side animations or render controllers, or expose data to Molang filters and the Script API.

Declaring properties in the description block

Properties are defined inside the `description` object of your server-side entity JSON file, right alongside `identifier` and `is_spawnable`. Each property key must include a namespace—never use the `minecraft:` namespace for your own custom properties. An entity can hold up to 32 properties in total.

When an entity spawns, every property initializes to its `default` value. That value can be a literal matching the property's type, or a Molang expression evaluated at spawn time (for example, `Math.random(0, 3)` to pick a random starting integer). If `client_sync` is set to `true`, the server automatically replicates changes to all nearby clients so resource pack animations, particle effects, and render controllers can read the property.

BP/entities/crystal_golem.json
{
  "format_version": "1.20.40",
  "minecraft:entity": {
    "description": {
      "identifier": "my_pack:crystal_golem",
      "is_spawnable": true,
      "is_summonable": true,
      "properties": {
        "my_pack:charge_level": {
          "type": "int",
          "range": [0, 10],
          "default": 0,
          "client_sync": true
        },
        "my_pack:heat_ratio": {
          "type": "float",
          "range": [0.0, 1.0],
          "default": 0.0,
          "client_sync": false
        },
        "my_pack:is_awakened": {
          "type": "bool",
          "default": false,
          "client_sync": true
        },
        "my_pack:stance": {
          "type": "enum",
          "values": ["idle", "guard", "berserk"],
          "default": "idle",
          "client_sync": true
        }
      }
    },
    "components": {
      "minecraft:health": {
        "value": 40
      }
    }
  }
}

Property types and constraints

Every property requires a `type` and a `default` field. Numerical properties (`int` and `float`) also require a `range` array of two numbers specifying the inclusive minimum and maximum values. If an event or script attempts to push a number outside its declared range, the game clamps the value or rejects the change.

For discrete named states, `enum` is usually cleaner than an integer code because the values are self-documenting strings. An `enum` property allows up to 16 distinct strings in its `values` array, and each string must be between 1 and 32 characters long.

FieldWhat it doesNotes
typeSets the data type: "int", "float", "bool", or "enum".Required on all properties.
defaultInitial value assigned when the entity is created.Accepts a literal value or a Molang string.
rangeTwo-element array [min, max] defining valid bounds.Required for "int" and "float" types only.
valuesArray of allowed string states (up to 16 entries).Required for "enum" type only.
client_syncBoolean controlling whether the client receives updates.Defaults to false. Set true if RP needs the value.

Modifying properties inside entity events

On the server side, you mutate properties inside the `events` block of your behavior entity file using the `set_property` action. Unlike component groups, changing a property does not add or remove heavy component trees—it just updates the stored value in place, which is much lighter when you only need to flip a flag or increment a counter.

For numeric properties, `set_property` accepts Molang strings. This lets you read the current value with `query.property()` and perform arithmetic on it within the same event.

BP/entities/crystal_golem.json
{
  "format_version": "1.20.40",
  "minecraft:entity": {
    "description": {
      "identifier": "my_pack:crystal_golem",
      "is_spawnable": true,
      "is_summonable": true,
      "properties": {
        "my_pack:charge_level": {
          "type": "int",
          "range": [0, 10],
          "default": 0,
          "client_sync": true
        },
        "my_pack:stance": {
          "type": "enum",
          "values": ["idle", "guard", "berserk"],
          "default": "idle",
          "client_sync": true
        }
      }
    },
    "components": {},
    "events": {
      "my_pack:add_charge": {
        "set_property": {
          "my_pack:charge_level": "math.min(10, query.property('my_pack:charge_level') + 1)"
        }
      },
      "my_pack:enter_berserk": {
        "set_property": {
          "my_pack:stance": "berserk",
          "my_pack:charge_level": 0
        }
      }
    }
  }
}

Filtering by property in AI goals and sensors

To test a property inside entity filters (such as `minecraft:environment_sensor`, `minecraft:interact`, or target filters on AI goals), use the filter test that corresponds to your property's data type: `int_property`, `float_property`, `bool_property`, or `enum_property`.

In each filter, `domain` specifies the full namespaced name of the property you are inspecting, `value` is the target value you are comparing against, and `operator` (such as `==`, `!=`, `<`, `>`, `<=`, `>=`) defines the comparison.

BP/entities/crystal_golem.json
{
  "format_version": "1.20.40",
  "minecraft:entity": {
    "description": {
      "identifier": "my_pack:crystal_golem",
      "is_spawnable": true,
      "is_summonable": true,
      "properties": {
        "my_pack:charge_level": {
          "type": "int",
          "range": [0, 10],
          "default": 0,
          "client_sync": true
        }
      }
    },
    "components": {
      "minecraft:environment_sensor": {
        "triggers": [
          {
            "filters": {
              "test": "int_property",
              "domain": "my_pack:charge_level",
              "operator": ">=",
              "value": 10
            },
            "event": "my_pack:enter_berserk"
          }
        ]
      }
    }
  }
}

Reading properties in Molang and Resource Packs

In Molang expressions—whether in server-side behavior packs or client-side animation controllers and render controllers—you access properties with two functions: `query.property('namespace:name')` (or the alias `q.property()`) and `query.has_property('namespace:name')`.

Remember that a resource pack runs on the client. If you call `q.property('my_pack:stance')` inside a render controller to swap textures, that property must have `"client_sync": true` in the behavior pack definition. If `client_sync` is omitted or `false`, the client has no record of the server's value.

RP/render_controllers/crystal_golem.render_controllers.json
{
  "format_version": "1.10.0",
  "render_controllers": {
    "controller.render.crystal_golem": {
      "geometry": "Geometry.default",
      "materials": [
        {
          "*": "Material.default"
        }
      ],
      "textures": [
        "q.property('my_pack:stance') == 'berserk' ? Texture.berserk : Texture.default"
      ]
    }
  }
}

Reading and writing from the Script API

If your add-on uses `@minecraft/server`, you can read and mutate entity properties directly on any `Entity` instance without firing JSON events. The `getProperty(identifier)` method returns a `boolean`, `number`, `string`, or `undefined` if the property does not exist on that entity.

To update a value, call `setProperty(identifier, value)`. The value passed must match the declared type and fall within the defined `range` or `values` list. You can also reset a property back to its JSON-defined default by calling `resetProperty(identifier)`, which returns the restored default value.

BP/scripts/main.js
import { world } from "@minecraft/server";

world.afterEvents.entityHurt.subscribe((event) => {
  const entity = event.hurtEntity;
  if (entity.typeId !== "my_pack:crystal_golem") return;

  const currentCharge = entity.getProperty("my_pack:charge_level");
  if (typeof currentCharge === "number" && currentCharge < 10) {
    entity.setProperty("my_pack:charge_level", currentCharge + 1);
  }
});

Which versions this applies to

Stable in format_version 1.20.0 and higher; no experimental toggle is required. Originally introduced behind the Upcoming Creator Features toggle in 1.19.x.

When it does not work

What you seeWhyThe fix
Content Log Error: [Entity][error]-my_pack:crystal_golem | Property 'charge_level' must have a namespace.You declared a property key without a namespace prefix, or you tried to use the reserved 'minecraft:' prefix.Prefix every property identifier with your own custom namespace, such as 'my_pack:charge_level', both in the declaration and everywhere you reference it.
Client-side animations or render controllers never react when the property changes on the server.Entity properties default to server-only (`"client_sync": false`) to save network bandwidth, so the client always reads the default or fails the check.Add `"client_sync": true` to the property's definition inside the behavior pack entity JSON.
Content Log Error when loading the world: default value or range is invalid on an int or float property.Either the `range` array is missing on a numeric property, or the `default` literal falls outside the `[min, max]` bounds.Ensure every `int` and `float` property has a two-element `range` array (for example, `"range": [0, 10]`) and that `default` is between those two numbers inclusive.

Reference, straight from the game files

Read out of the game itself, so the ids match the version you are building for.