<!-- https://minecraftdocs.dev/systems/commands/entity-selectors — this page as markdown. The book's index: https://minecraftdocs.dev/llms.txt; the whole book in one file: https://minecraftdocs.dev/llms-full.txt -->

# Entity selectors

> Verified against **Minecraft 26.3** · Part XIII · you type */kill @e[type=!player,distance=..8,sort=nearest,limit=1]*, and the characters inside the brackets decide, between them, which levels are searched and which of two entirely different data structures answers.

Put a command block at the Overworld origin and give it */tp @p 0 100 0*.
One player is two hundred blocks away across the Overworld; another is
standing on the Nether roof directly "above" the block, at the Nether's own
*0, 128, 0*. The command block teleports the one in the Nether. *@p* is not
"the nearest player in this world": it is the player whose raw *x*, *y* and
*z* are nearest, chosen from the list of everybody on the server, compared as
though the dimensions were stacked in the same coordinate space. (Type the
same command yourself and you always win it — a player's own source sits at
distance zero from a player's own position.) Nothing in a selector is confined to
one level unless you write one of **seven** options that says so — and four of those seven, *distance* and the three box deltas, are also what decides whether the game walks every entity in the level or asks the chunk sections for a box.

That is the shape of the whole subject. A selector looks like a filter
language, and it is one, but many of its twenty-one option names do more than filter: they write the query plan. This page is about which is which.

## The cast

| class | what it decides | when it runs |
|---|---|---|
| `EntitySelectorParser` | the reader, the grammar and thirty-one half-built fields besides it. It owns the selector's own syntax; the brace grammars of *scores* and *advancements* are read by the handlers themselves | parse time |
| `EntitySelectorOptions` | the name-to-handler map — twenty-one entries, filled once by `Bootstrap.bootStrap` and never again | bootstrap |
| `InvertableSetOptionState` | the three-state machine behind *type=!zombie,type=!skeleton*: one positive assertion **or** any number of negations and tags, never both | parse time |
| `SetOnceOptionState` | one boolean, for the four options with no parsed field to test for emptiness — *limit*, *sort*, *scores*, *advancements*. The other ten once-only options enforce it by checking their own field | parse time |
| `EntitySelector` | the compiled query: thirteen final fields, and no grammar left in them | built at parse time, run later |
| `EntityArgument` | four argument shapes (single or many, entities or players) and the parse-time rejections that enforce them | parse time and on the wire |
| `CommandSourceStack` | the only thing a selector can be resolved against — origin, level, server, permission set | resolve time |
| `LevelEntityGetterAdapter` | the fork in the road: an `EntityLookup` walk, or an `EntitySectionStorage` box query ([entity lifecycle](../entities/entity-lifecycle#findable-ticking-or-neither) owns both) | resolve time |

`net/minecraft/commands/arguments/selector` holds five classes, and every one of them is in the server jar *and* the client jar. That matters
later.

## Three stages, and the last one is not on the parser's clock

```mermaid
flowchart LR
    S["the argument text"]
    subgraph P["PARSE — at parse time"]
        direction TB
        P1["the head sets the defaults"]
        P2["each option name finds its handler"]
        P3["the handler writes a field or adds a test"]
        P1 --> P2 --> P3
    end
    subgraph C["COMPILE — at parse time"]
        direction TB
        C1["thirteen final fields"] ~~~ C2["a box, or none"] ~~~ C3["an origin"]
    end
    subgraph R["RESOLVE — per execution"]
        direction TB
        R1["which levels"]
        R2["which of two structures"]
        R3["order, then cut to the limit"]
        R1 --> R2 --> R3
    end
    S --> P
    P --> C
    C --> R
```

*The three stages a selector passes through — the first two while Brigadier parses, and the third on the Server thread each time a command asks for its argument; the three boxes under COMPILE are what it produces, not steps.*

The first two stages happen while Brigadier walks the command tree; the third
happens when the command's lambda asks for its argument. In between, the
selector is an ordinary immutable object sitting in a parsed context, which is
why an */execute* chain can resolve the same parsed selector once per source
and get a different answer each time
([the execution engine](the-execution-engine)).

## Parse: six heads and twenty-one names

`EntitySelectorParser.parseSelector` reads the character after the *@* and
sets four things — a result limit, whether non-players are in scope, an order,
and sometimes a type. There are six, and no more: the default branch of that
switch throws.

| head | limit | non-players | order | extras |
|---|---|---|---|---|
| *@a* | unbounded | no | arbitrary | typed to player |
| *@e* | unbounded | yes | arbitrary | adds an `Entity.isAlive` test |
| *@n* | 1 | yes | nearest | adds an `Entity.isAlive` test |
| *@p* | 1 | no | nearest | typed to player |
| *@r* | 1 | no | random | typed to player |
| *@s* | 1 | yes | arbitrary | resolves to the source's own entity |

Only *@e* and *@n* add that test, and only `LivingEntity.isAlive` makes it
mean anything — it is the override that adds "and has health left" to the
base class's "and has not been removed". So a player sitting on the death screen is invisible to *@e* and *@n*, and still a target for *@a*, *@p* and *@r* — though twenty ticks after death the body leaves the level's own player list, so a world-limited selector stops finding it.

Then the bracket. `EntitySelectorParser.parseOptions` reads a name, looks it
up through `EntitySelectorOptions.get`, and hands the reader to the handler it
finds. **Twenty-one** names are registered, counted by reading every
`EntitySelectorOptions.register` call in `EntitySelectorOptions.bootStrap`.

| option | what its handler does | repeatable? |
|---|---|---|
| *name* | compares `Nameable.getPlainTextName` | one positive, or many negatives |
| *team* | compares `Entity.getTeam` — the empty string means *no team* | one positive, or many negatives |
| *gamemode* | compares `ServerPlayer.gameMode`, **and drops non-players** | one positive, or many negatives |
| *type* | an id sets the `EntityTypeTest`; a tag only adds a test | one positive id, or many negatives and tags |
| *tag* | reads `Entity.entityTags` — empty means *no tags at all* | freely |
| *nbt* | serialises the candidate and compares with `NbtUtils.compareNbt` | freely |
| *predicate* | runs a loot condition in `LootContextParamSets.SELECTOR` ([contexts and predicates](../items/contexts-and-predicates)) | freely |
| *scores* | a brace map of objective to `MinMaxBounds.Ints` | once |
| *advancements* | a brace map of advancement to done-ness, **players only** | once |
| *limit* | sets the result cap, rejects anything below 1 | once, never on *@s* |
| *sort* | picks one of four orders | once, never on *@s* |
| *distance* | a `MinMaxBounds.Doubles`, rejects negatives, **world-limits** | once |
| *level* | a `MinMaxBounds.Ints`, rejects negatives, **drops non-players** | once |
| *x*, *y*, *z* | override one axis of the resolve origin, **world-limit** | once each |
| *dx*, *dy*, *dz* | build the box, **world-limit** | once each |
| *x_rotation*, *y_rotation* | angle ranges that wrap through 360 | once each |

Three of the twenty-one are freely repeatable — *tag*, *nbt* and *predicate* —
because they are the three registered as always available, with no state
object behind them at all. That is why *tag=a,tag=b* is the idiom for "has
both" and *type=zombie,type=skeleton* is a parse error rather than an empty
result: `InvertableSetOptionState` moves to a terminal state the moment a
positive id is accepted, and `EntitySelectorOptions.get` then refuses the
whole option by name before its handler ever runs. Its *other* terminal state
is the permissive one — after a negation or a tag, more negations and more
distinct tags are allowed, which is why *type=!zombie,type=!skeleton* works and why
two entity tags can be written together and AND.

## Compile: what a box is, and where it comes from

`EntitySelectorParser.getSelector` runs once, at the end of the parse, and
turns the pile of fields into thirteen final ones. Two of the thirteen are the
interesting decisions.

**The box.** If any of *dx*, *dy* or *dz* was written,
`EntitySelectorParser.createAabb` builds the box from those three, treating
the missing ones as zero and adding one to each maximum — a *dx=0* volume is
one block wide, not zero. Otherwise, if *distance* was written **and has a
maximum**, the box is a cube of that radius, again with one added to the
positive corner. Otherwise there is no box. So *distance=8..* — a minimum with
no maximum — produces no box at all, and *dx=3,distance=..64* ignores the
distance entirely when choosing the box, because the delta branch wins.

**The origin.** If any of *x*, *y* or *z* was written, the position becomes a
function that overrides those axes of the source's position and keeps the
rest. Otherwise it is the identity. This is applied per execution, which is what makes *x=0* mean the same thing everywhere while every axis left unwritten follows the source at each link of a chain.

Everything else that was written is already a test in a list, in written
order — with exceptions appended afterwards whatever order they appeared in.
`EntitySelectorParser.finalizePredicates` adds the two rotation tests and the
experience-level test last, and `EntitySelector.getPredicate` then appends up
to three more at resolve time: the feature-flag test, the exact box test and
the range test. `Util.allOf` evaluates them in that order and short-circuits,
so the range test, a few multiplications, runs **after** an *nbt*
comparison that serialised the whole entity.

## Resolve: which levels, which structure, which order

```mermaid
flowchart TD
    A["EntitySelector.findEntities"] --> C{"a bare name or a UUID?"}
    C -- name --> N["PlayerList.getPlayerByName"]
        C -- UUID --> UE["Level.getEntity, level by level"]
    C -- neither --> D{"is it the source itself?"}
    D -- yes --> S["the source's own entity, if it passes"]
    D -- no --> E{"world-limited?"}
    E -- "yes: this level" --> B2{"non-players in scope?"}
    E -- "no: every level" --> B2
    B2 -- no --> PL["a player list, walked"]
    B2 -- yes --> H{"is there a box?"}
    H -- yes --> I["EntitySectionStorage — only the sections near the box"]
    H -- no --> J["EntityLookup — every visible entity, one by one"]
    I --> K["sort unless arbitrary, then cut to the limit"]
    J --> K
    PL --> K
```

*How a compiled selector finds its entities — the players-only selector asks the same questions in the same order, so the figure asks whether non-players are in scope only where the two answers part; the three shortcuts at the top return at once, with no sort and no limit.*

**Three shortcuts come first.** A bare player name goes to `PlayerList.getPlayerByName`, since a name always takes non-players out of scope; a UUID is looked up with `Level.getEntity`, level by level, since a UUID always brings non-players into scope; and *@s* tests the
source's own entity against the selector's tests. None of the three is sorted
or cut.

**World-limited is a parse-time flag, not a runtime one.** Exactly seven
option handlers call `EntitySelectorParser.setWorldLimited`: *distance*, *x*,
*y*, *z*, *dx*, *dy* and *dz*. Write none of them and
`EntitySelector.findEntities` iterates every level the server has. */kill
@e[type=item]* is a three-dimension operation.

**The two structures are genuinely different.** With a box,
`Level.getEntities` goes through `EntitySectionStorage`, which visits only the accessible non-empty 16-cubes the box overlaps once widened by two blocks sideways and four below. Without one,
`ServerLevel.getEntities` goes through `EntityLookup`, which walks the level's
entire visible-entity map and calls `EntityTypeTest.tryCast` on each —
`EntityTypeTest` being the small "is this the type I asked for, and give it to me typed" interface the whole entity-fetching API is generic over. **There
is no index by entity type.** *type=zombie* narrows nothing structurally; it
is a cast applied one entity at a time, ahead of the tests. Of the seven, only *distance* and the three deltas narrow the entity walk within a level, and only when they add up to a box; *x*, *y* and *z* only confine it to one level and move the box.

**And the box path finds things the walk cannot.** `Level.getEntities` also
offers each ender dragon's eight `EnderDragonPart` sub-entities to the type
test and the predicate, and every part reports its parent's type. So a box
query in the End can return the dragon and up to eight more "ender dragons";
the same selector without a box returns one.

**Players never get a box.** Both player paths — `ServerLevel.getPlayers` for
one level, `PlayerList.getPlayers` for the whole server — are linear walks of
a list, and the box survives only as one more test. *@a[distance=..8]* costs
what *@a* costs.

**Sort is what takes the limit away.** `EntitySelector.getResultLimit` returns
the parsed limit **only when the order is arbitrary**, and the unbounded value
otherwise, because a sort has to see everything before it can know what comes
first. When it is the parsed limit, it reaches the level query as an early
abort. So *@e[limit=1]* stops at the first match, and *@e[limit=1,sort=nearest]*
collects every match in range, sorts the list and throws all but one away.
*@n* and *@p* live in the second mode unless told otherwise: their heads set the nearest order, so they collect first and cut afterwards, and only an explicit *sort=arbitrary* puts them back in the first.

**So the query plan is written by thirteen of the twenty-one names**: the seven above, which world-limit the search and build or place the box; *limit*, which aborts it early; *sort*, which un-decides part of it by taking the limit away; and the four that drop non-players, *level*, *gamemode*, *advancements* and a positive *type=player*, which send the whole search to a player list. The other eight only filter what the plan returns.

## One permission, checked in two places, for two different reasons

The gate is a single atom, `Permissions.COMMANDS_ENTITY_SELECTORS`, granted by
`LevelBasedPermissionSet` from gamemaster upward as the one hard-coded exception in that interface
([permissions](permissions#a-question-an-answer-and-a-check)). It is the
**only permission in the game checked in two different phases**, it is read in
seven places, all of them under `commands/arguments`, and they divide cleanly
in two.

**At parse time**, `EntitySelectorParser.allowSelectors` asks the source and
the answer becomes a constructor argument. If it is false, an *@* throws
`EntitySelectorParser.ERROR_SELECTORS_NOT_ALLOWED` immediately, and a bare
name or UUID still parses. This is the check that matters for the three
vanilla commands that take a selector-capable argument with **no permission
requirement at all** — `MsgCommand`, `EmoteCommands` and `TeamMsgCommand`, so
*/msg*, */tell*, */w*, */me*, */teammsg* and */tm*. For an ordinary player
this atom is the only gate on those.

`MessageArgument` alone treats a refusal as a formatting decision rather than
an error: without the permission the message is taken as literal text, so an
unopped */msg Bob @a* sends those two characters. With the permission, an *@*
that is not a valid selector head is skipped and the scan continues — which is how an address like *me@gmail.com* survives — but a *malformed* selector body throws, and
the whole command fails to parse.

**At resolve time**, `EntitySelector.checkPermissions` asks again, guarding on
`EntitySelector.usesSelector`, which only `EntitySelectorParser.parseSelector`
ever sets. A selector compiled from a bare player name is exempt. The second
check is not redundant, because there is a whole route into the machinery that
never passed the first one: `EntitySelector.COMPILABLE_CODEC` compiles a
selector out of a **text component** — the *selector* content type, the
*score* name field and the *entity* NBT data source — and does so with
selectors unconditionally allowed, because a codec has no source to ask. The
resolve-time check is what decides whether a */tellraw* written by a data pack may enumerate entities, and it asks the source the component is being
resolved *against*, never whoever wrote it.

## Two more argument types write the same fork by hand

`EntityArgument` is not the only argument type that will take an `@`.
`ScoreHolderArgument` and `GameProfileArgument` each reimplement the
selector-or-literal fork for a value that is not an entity, and what they do
on the *literal* side is the interesting half.

`GameProfileArgument` resolves to profiles, not entities. An `@` builds a
selector and is rejected outright if it includes non-players; anything else is
read to the next space and looked up in the server's name-to-id cache — so
`/ban`, `/whitelist` and `/op` name a player who has never joined this session
and may not exist on this server at all. That lookup is the only thing on this
page that leaves the game's own data.

`ScoreHolderArgument` resolves to `ScoreHolder`s, which need not be alive.
Its literal side has four branches in order — `*` for every tracked holder,
a `#`-prefixed name taken as a bare string, a UUID searched across every
level, and an online player — with the UUID and player branches falling back to a bare name and the wildcard alone throwing when there is nothing to return
([scores, teams and stored data](scoreboard-and-data#names-that-belong-to-nobody-and-the--that-hides-them)
for what those names are for).

Both take the permission the same way this page's own parse does, and both check the compiled selector rather than the text, as `EntityArgument` does — `ScoreHolderArgument` for its single-or-many shape, `GameProfileArgument` for players only.

## Four argument shapes, enforced on the query and not on the text

`EntityArgument` comes in four shapes — one entity or many, players only or
anything — and it enforces the difference on the *compiled selector*, during
the parse, before the world is touched. A limit above one in a single-target
slot is refused, and so are non-players in a players-only slot.

That is why */damage @e 1* complains before it has looked at anything:
`/damage`, `/ride` and `/data get entity` all take the single-target shape,
and *@e* is unbounded. */kill @e* is fine, because `/kill` takes the
many-entities shape and neither rejection can fire on it. And *@s* is exempt
from the players-only test, so */msg @s* parses and then finds nobody when
the source is not a player.

## The client parses selectors and cannot resolve one

This is what the cast's five-classes-in-both-jars is for. The client parses a
selector by two routes and can run neither.

`EntityArgument.listSuggestions` builds a real `EntitySelectorParser` against
the client's own permission set, parses as far as it can, swallows the
exception and asks the half-finished parser for its suggestions — which is why
completion inside a bracket knows which options are still legal; the tree it
parses against is a real one the server sent ([Brigadier and
commands](brigadier-and-commands#three-parsers-see-one-string)). And
`ComponentSerialization` decodes a *selector* content type on the client with
the same compiler the server uses.

What the client cannot do is run one: every find method takes a
`CommandSourceStack`, and the client's suggestion source is a
`ClientSuggestionProvider`. The one place a client resolves a component that
might contain a selector is `ServerStatusPinger`, whose `ResolutionContext`
deliberately carries no source, so a server-list description containing a
selector renders as nothing at all.

## Questions players ask

**Which dimension does */kill @e[type=item,limit=1]* kill in?** The
overworld, unless there is nothing to kill there. With no world-limiting
option the resolve walks `MinecraftServer.getAllLevels`, which iterates the
server's `LinkedHashMap` of levels in the order they were created — the
overworld put in first, the rest in registry order — and an arbitrary-order
limit reaches the level query as an early abort, so the walk stops at the
first match it finds. Write *sort=nearest* and the bias disappears, because
a sort has to see every level before it can rank anything.

**What does the client suggest for an entity argument?** Online player names,
plus — from `ClientSuggestionProvider.getSelectedEntities` — the UUID of
whatever your crosshair is on. Point at a cow, press tab, and it offers you
that cow.

**Is *sort=random* seeded?** No. It is the JDK's list shuffle, with no world
seed and no `RandomSource` anywhere near it, so *@r* is not reproducible from
a save.

**Why does *distance=..8* not return something 8.9 blocks away?** Because the
box is only a pre-filter. The cube built for a maximum of 8 spans −8 to +9 on
each axis, deliberately larger than the sphere it approximates, and the exact
test that follows is `MinMaxBounds.Doubles.matchesSqr`, which compares squared
distances against pre-squared bounds and so never takes a square root.

> **For a 1.21-era reader.** The parser's crowd of *hasNameEquals* /
> *hasNameNotEquals* / *hasGamemodeEquals* booleans is gone, replaced by
> eight state objects — four `InvertableSetOptionState` and four
> `SetOnceOptionState` — that enforce the same rules structurally.

## Where to look

`EntitySelector` first — thirteen fields and four find methods, and the design
is in them. Then `EntitySelectorParser.getSelector` for the one place those
thirteen are decided, and `EntitySelectorOptions.bootStrap` for the grammar players write. `LevelEntityGetterAdapter` is six methods long and is
where the cost of every selector is settled. Note that the name
`EntitySelector` is used twice in the game: this one, and an unrelated bag of
predicate constants in `world/entity` that the mob AI and the hoppers use.

---

*Rules: names, never code · how the system works, not how the code reads ·
newest version only · every backticked name passes `tools/verify_names.py`.*
