How Bedrock counts entities
Unlike Java Edition, Minecraft Bedrock does not have a store subcommand inside its execute syntax to capture the return value of a query directly. Instead, counting is done by zeroing a counter score and then forcing every matching entity to add 1 to that same score within a single game tick.
Because a function file executes all of its lines sequentially inside the exact same tick before the world advances, resetting a score on line one and incrementing it on line two produces no visual flicker on sidebar displays and leaves no window where another command could read an incomplete total. The score goes from its previous value to zero and straight to the new live count instantaneously.
Rather than creating a dummy armor stand in the world to hold global variables—which risks being killed, unloaded inside a distant chunk, or caught in an @e selector by mistake—Bedrock lets you assign scores to arbitrary string names known as fake players. Prefixing a fake player name with a hash symbol, such as #total, is a common convention because no real Xbox Live account can start with that character, guaranteeing a real player joining the server will never collide with your counter.
One-time scoreboard setup
Before any counting function can run, the world needs a dummy scoreboard objective to hold the numbers. You only need to create this objective once per world, though running the creation command repeatedly is harmless if you wrap it in a setup function or run it on world initialization.
A single objective can hold dozens of distinct counters at once by giving each counter its own fake player name. For example, an objective named counters can simultaneously track #zombies, #alive_players, and #arena_enemies without needing three separate scoreboard objectives.
scoreboard objectives add counters dummy "Entity Counters"
scoreboard players set #zombies counters 0
scoreboard players set #players_in_zone counters 0
scoreboard players set #dropped_items counters 0The three-line counting recipe
The core recipe takes two commands to compute the count, plus a third command if you want to trigger an outcome based on the result. First, set the fake player's score to 0. Second, use execute as with your target selector to run scoreboard players add on that same fake player. If twenty entities match the selector, the add command runs twenty times in that tick, leaving the score at 20. If no entities match, the execute command simply does nothing and the score remains 0.
When selecting entities by type in a behavior pack, always include the namespace—such as type=minecraft:zombie or your custom pack namespace—and restrict the volume if you only care about a specific room. Remember that Bedrock can only count entities inside currently ticking areas (around players or inside regions marked with the tickingarea command). Entities sitting in unloaded chunks do not exist to target selectors and will not be counted.
| Range Syntax | What it matches | Example Use |
|---|---|---|
| 0 | Exactly zero entities | Detecting when a boss room or wave is completely cleared |
| 1.. | One or more entities | Checking if at least one player is still alive in an arena |
| ..5 | Five or fewer entities | Permitting a custom spawner to summon more mobs while under a cap |
| 4..8 | Between four and eight inclusive | Scaling trap difficulty for medium-sized party groups |
# 1. Reset the counter to zero at the start of the check
scoreboard players set #zombies counters 0
# 2. Every matching entity adds 1 to the fake player score
execute as @e[type=minecraft:zombie] run scoreboard players add #zombies counters 1
# 3. Act on the final count in the same tick
execute if score #zombies counters matches 0 run title @a actionbar All zombies cleared!
execute if score #zombies counters matches 10.. run say Warning: 10 or more zombies are active.Running the counter automatically
If your add-on needs a continuously updated count—for example, to display remaining enemies on the HUD or to open a gate the exact moment a room is cleared—register your counting function inside BP/functions/tick.json. Functions listed in this file are executed by the game engine every single tick (20 times per second) from the world origin.
Because tick.json runs at the world origin (0, 0, 0) with no entity context, any volume-based counter using radius (r) or box dimensions (dx, dy, dz) must explicitly anchor its coordinates inside the execute chain or inside the selector itself. If you only need to count entities when a button is pressed or when an entity dies, skip tick.json and call the function directly from an entity event, block component, or command block instead.
{
"values": [
"counter/count_zombies"
]
}Spatial and multi-category counters
In real projects, you rarely want to count every entity across the entire loaded world. You can combine multiple counters in a single function file to inspect specific rooms, filter by entity families, or compare two populations against each other.
The family selector argument is particularly useful for add-on creators because a single check like family=monster covers zombies, skeletons, creepers, and any custom entities to which you assigned the minecraft:type_family component containing monster. When checking a rectangular room with dx, dy, and dz, place x, y, and z right in the target selector to define the lower northwest corner of the box.
# Reset all arena counters
scoreboard players set #arena_players counters 0
scoreboard players set #arena_monsters counters 0
# Count survival players inside a 21x11x21 box starting at 100, 64, 100
execute as @a[x=100,y=64,z=100,dx=20,dy=10,dz=20,m=s] run scoreboard players add #arena_players counters 1
# Count all hostile monsters within 32 blocks of the arena center
execute as @e[x=110,y=64,z=110,r=32,family=monster] run scoreboard players add #arena_monsters counters 1
# Trigger a reward if players are present and all monsters are dead
execute if score #arena_players counters matches 1.. if score #arena_monsters counters matches 0 run function arena/spawn_reward
# Compare two counters: trigger an alert if monsters outnumber players
execute if score #arena_monsters counters > #arena_players counters run title @a[x=100,y=64,z=100,dx=20,dy=10,dz=20] actionbar You are outnumbered!Counting in Script API
If your behavior pack already uses the @minecraft/server Script API module, you do not need scoreboards to count entities. The Dimension.getEntities method returns an array of Entity objects matching an EntityQueryOptions filter, and reading the .length property of that array gives you the exact count immediately in JavaScript.
This approach is cleaner when your surrounding logic is already written in TypeScript or JavaScript, and it avoids cluttering the world's scoreboard table when players open the pause menu or sidebar.
import { world, system } from "@minecraft/server";
system.runInterval(() => {
const overworld = world.getDimension("overworld");
const zombies = overworld.getEntities({
type: "minecraft:zombie",
location: { x: 110, y: 64, z: 110 },
maxDistance: 32
});
const count = zombies.length;
if (count === 0) {
overworld.runCommand("title @a actionbar Arena cleared!");
}
}, 20);Which versions this applies to
Applies to Minecraft Bedrock 1.19.50 and newer (using the modern execute syntax). Make sure format_version in your behavior pack manifest.json is set to 2 and min_engine_version is at least [1, 19, 50] so the game parses the new execute syntax inside .mcfunction files. No experimental toggles are required for either the function recipe or the stable @minecraft/server Script API alternative.
When it does not work
| What you see | Why | The fix |
|---|---|---|
| Function counter/count_zombies failed to load: Syntax error: Unexpected "as": at "execute >>as<< @e" | Your behavior pack's manifest.json has a min_engine_version lower than 1.19.50 (or is missing it), causing Bedrock to parse your .mcfunction files using the legacy pre-1.19.50 execute command syntax. | Open BP/manifest.json and set "min_engine_version": [1, 19, 50] or higher inside the header object, then reload the world. |
| No error message is shown, but the counter climbs infinitely into the thousands every second | The scoreboard players set <name> <objective> 0 line at the top of the function is missing, misspelled, or writing to a different fake player name than the add command. | Verify that the exact same fake player string and objective name are reset to 0 on the line immediately before the execute as ... run scoreboard players add line. |
| No targets matched selector, or the counter stays at 0 even though entities exist in the world | Either the entities are located in unloaded chunks outside any player's simulation distance, or a custom entity's identifier was written in the selector without its namespace. | Ensure the area is loaded (using a player or /tickingarea) and always include the full namespace in type=namespace:identifier. |
| Objective 'counters' does not exist | The counting function is running in tick.json before the setup function has created the scoreboard objective in that world. | Run your setup function once via /function counter/setup, or place scoreboard objectives add counters dummy at the top of your function file. |
Reference, straight from the game files
Read out of the game itself, so the ids match the version you are building for.
