Wiki 9Minecraft Wiki 9Minecraft

Assign Unique Scoreboard IDs to Entities and Players

Give every player or entity a permanent, non-repeating scoreboard number for linking and tracking.

6Sections
5Code examples
4Known errors

Assigning a unique scoreboard integer to each player or entity is the foundation of advanced command logic in Minecraft Bedrock. Because selectors cannot natively store dynamic references between two separate entities, a shared ID number is the standard way to link a player to a personal pet, a custom projectile, or a floating text display. You reach for this pattern whenever you need to pair entities together or track join order across sessions.

How the Global Counter Pattern Works

Scoreboards in Bedrock Edition only store 32-bit signed integers, meaning you cannot copy an entity's internal UUID string into a score. To work around this limitation without using Script API, you maintain a single global counter on a fake player name and increment it every time an entity needs a new ID. That entity copies the current counter value into its own score, ensuring no two entities ever receive the same number.

The critical requirement of this pattern is that the increment and the assignment must happen one at a time, even if twenty entities spawn on the exact same tick. If you run a plain `/scoreboard players operation` across `@e` without restricting the target count, every unindexed entity will copy the same counter value before the counter has a chance to tick up.

By combining the `/execute as` subcommand with the `c=1` target selector argument, you force the game to process unindexed entities individually, or you let each entity drive its own assignment in sequence. In Bedrock, when `/execute as @e[...]` runs a `.mcfunction` file, the entire function executes from top to bottom for the first matched entity before starting over for the second matched entity. This execution order makes single-tick batch assignment completely reliable.

ComponentIdentifier / SyntaxRole in the Pattern
ObjectiveidThe dummy scoreboard objective that holds both the global counter and individual entity IDs.
Fake Player#next_idHolds the master counter. Prefixed with # so it never collides with a real Xbox Live gamertag.
Unassigned Filterscores={id=!1..}Matches any entity that does not yet have a positive ID score (including entities with no score at all).
Tag Guardtag=!has_idA secondary fast filter to prevent re-evaluating scoreboard ranges on every entity every tick.

Setting Up the Scoreboard Objective

Before any IDs can be handed out, your behavior pack must create the scoreboard objective and initialize the fake player counter. Using a fake player name that begins with a hash symbol, such as `#next_id` or `.global_id`, guarantees that a real player with that name can never join the world and corrupt your counter. Furthermore, names starting with `#` are hidden from the sidebar display if you temporarily set the objective to `sidebar` while debugging.

Place the initialization commands inside a setup function that runs on world load, or wire it into `BP/functions/tick.json` alongside your main loop. Running `scoreboard objectives add` repeatedly is safe because Bedrock simply ignores the command if the objective already exists, though keeping it in a one-time setup function keeps your content log clean.

BP/functions/id/setup.mcfunction
# Create the dummy objective for storing unique IDs
scoreboard objectives add id dummy "Unique ID"

# Ensure the global counter exists and starts at 0 if not already set
scoreboard players add #next_id id 0

Assigning Unique IDs to Players Automatically

To automatically assign a unique ID to every player the moment they join the world, you need two small functions: a router function registered in `tick.json` and a worker function that performs the math. The router checks for any player who lacks the `has_id` tag and runs the worker function `as` that player.

Inside the worker function, `@s` refers to the single player currently being processed. The function first adds `1` to `#next_id`, then uses the `=` operator in `scoreboard players operation` to copy the value of `#next_id` onto `@s`. Finally, it applies the `has_id` tag so the player is skipped on all future ticks.

Because Bedrock executes the entire called function for the first player matched by `@a[tag=!has_id]` before moving to the next player in the selector list, even ten players joining simultaneously on a fresh server will receive clean, sequential numbers from `1` to `10` within the same game tick.

BP/functions/id/assign_single.mcfunction
# Increment the master counter by 1
scoreboard players add #next_id id 1

# Copy the new counter value to the current entity or player
scoreboard players operation @s id = #next_id id

# Mark this target so it never receives a second ID
tag @s add has_id

Registering the Tick Loop

To make the assignment automatic, create a main tick function that invokes `id/assign_single` for any unindexed player or specific custom entity, and register that main function in `BP/functions/tick.json`. Avoid running the assignment across `@e[tag=!has_id]` without a `type` or `family` filter; otherwise, every dropped item, arrow, and experience orb in the world will consume an ID and bloat the world's scoreboard database.

Instead, target players directly with `@a[tag=!has_id]` and target only the custom entities that actually need linking by using a dedicated request tag such as `tag=needs_id`. When your custom entity spawns, you can grant it the `needs_id` tag through a spawn event in its behavior file, and the tick function will immediately assign its score and remove the request tag.

BP/functions/tick.json
{
  "values": [
    "id/tick"
  ]
}

Tick Router and Entity Linking Recipe

Once both a player and a secondary entity have scoreboard capability, you can link them together by copying the player's unique ID into a separate objective on the child entity, such as `owner_id`. When you want the child entity to teleport to its owner or apply an effect to them, you compare their scores using `scoreboard players operation`.

Because target selectors cannot evaluate a dynamic variable inside `scores={id=...}`, the standard Bedrock recipe for finding a linked partner is the subtraction test. You copy the child entity's `owner_id` to a temporary score on every candidate player, subtract each player's own `id` from that temporary score, and select the one player whose result equals `0`.

The function below shows both the tick router that triggers `id/assign_single` and the subtraction pattern used to locate the matching owner during gameplay.

BP/functions/id/tick.mcfunction
# Ensure the objective exists
 scoreboard objectives add id dummy
scoreboard objectives add temp_match dummy

# Assign unique IDs to any new players
execute as @a[tag=!has_id] run function id/assign_single

# Assign unique IDs to custom entities that requested one
execute as @e[tag=needs_id,tag=!has_id] run function id/assign_single
tag @e[tag=needs_id,tag=has_id] remove needs_id

# Example link check: executed AS a pet or marker that has an 'id' score matching its owner's 'id'
# Copy this entity's ID to all players on the temp_match objective
# execute as @e[type=minecraft:armor_stand,tag=linked_marker] run scoreboard players operation @a temp_match = @s id
# Subtract each player's own ID from their temp_match score
# execute as @e[type=minecraft:armor_stand,tag=linked_marker] as @a run scoreboard players operation @s temp_match -= @s id
# Whoever has temp_match == 0 is the owner of this marker
# execute as @e[type=minecraft:armor_stand,tag=linked_marker] at @a[scores={temp_match=0}] run tp @s ~ ~2 ~

Triggering ID Assignment from an Entity File

If you are creating a custom entity in your behavior pack and want it to receive a unique ID the instant it enters the world, you do not even need to wait for the global tick loop. You can invoke `id/assign_single` directly inside the `minecraft:entity_spawned` event using a `queue_command` response.

When `queue_command` runs on an entity event, the execution context `@s` is already set to the newly spawned entity. It queues the function to run on the upcoming tick with `@s` bound to that exact instance, guaranteeing it gets a unique score before your gameplay systems interact with it.

BP/entities/custom_drone.json
{
  "format_version": "1.20.40",
  "minecraft:entity": {
    "description": {
      "identifier": "example:custom_drone",
      "is_spawnable": true,
      "is_summonable": true
    },
    "components": {
      "minecraft:physics": {},
      "minecraft:health": {
        "value": 20,
        "max": 20
      }
    },
    "events": {
      "minecraft:entity_spawned": {
        "queue_command": {
          "command": [
            "function id/assign_single"
          ]
        }
      }
    }
  }
}

Which versions this applies to

Applies to Minecraft Bedrock 1.19.50 and newer (uses the modern /execute syntax). No experimental toggles are required.

When it does not work

What you seeWhyThe fix
Multiple entities receive the exact same ID number when spawned on the same tick.You placed the `scoreboard players add #next_id id 1` and `scoreboard players operation` commands directly inside the same function using `@e[tag=!has_id]` instead of calling a sub-function via `execute as @e[tag=!has_id] run function ...`. Without the sub-function call, the first line runs once, and the second line copies that single number to every matching entity at once.Move the increment, operation, and tag commands into a separate `.mcfunction` file and call it with `execute as @e[tag=!has_id] run function id/assign_single` so the sequence completes per entity.
Content Log error: "No targets matched selector" or "Objective 'id' does not exist" on first world load.`tick.json` starts running your assignment loop before the `id` objective has been created in the world.Place `scoreboard objectives add id dummy` at the top of your tick function or run your setup function before the assignment check.
A player's ID resets or changes when they die and respawn.You used a death-clearing mechanic or manually removed tags on respawn, or you tested on a non-player entity that despawned and was replaced by a new instance.Player scoreboard values and tags persist through death automatically in Bedrock. Ensure none of your respawn functions run `tag @s remove has_id` or `scoreboard players reset @s id`.
Command output says: "Failed to execute 'scoreboard' as [Entity]" when using `queue_command` in `minecraft:entity_spawned`.The `format_version` of your entity file or the `min_engine_version` in `BP/manifest.json` is set below 1.19.50 while your function uses the new `/execute as` syntax, or the function path has a leading slash.Remove any leading slash from the function call (use `function id/assign_single`, not `/function /id/assign_single`) and set `min_engine_version` in `BP/manifest.json` to at least `[1, 19, 50]`.

Reference, straight from the game files

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