> For the complete documentation index, see [llms.txt](https://docs.nursultan.fun/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.nursultan.fun/game-data/entities-and-filters.md).

# Entities and filters

An entity is anything living in the world: players, mobs, boats, dropped items, arrows. You get them from the [world](/game-data/world-and-blocks.md), from a [ray](/game-data/rays-and-the-crosshair.md), or from an event.

## What any entity can tell you

```kotlin
entity.id()              // numeric id in this world
entity.uuid()
entity.name()
entity.typeId()          // "minecraft:zombie"

entity.position()
entity.renderPosition()  // smoothed, for drawing
entity.previousPosition()
entity.box()
entity.width()  entity.height()

entity.rotation()
entity.yaw()  entity.pitch()
entity.velocity()

entity.alive()
entity.onGround()
entity.sneaking()
entity.sprinting()
entity.invisible()
entity.glowing()
entity.onFire()
entity.inWater()
entity.pose()
entity.fallDistanceBlocks()

entity.distanceTo(other)
entity.distanceTo(point)
```

## Who it is

```kotlin
entity.isSelf()          // that is me
entity.isPlayer()
entity.isLiving()
entity.isBot()           // looks like a bot
entity.isFriend()        // on the friends list
entity.isParty()         // in my party
entity.isAlly()          // friend or party
```

`isAlly()` is usually the one you want so you do not hit your own people.

## Living entities

If an entity is alive it has health, effects and items. The cast returns `null` when it is, say, a boat:

```kotlin
val living = entity.asLiving() ?: return

living.health()
living.maxHealth()
living.absorption()
living.armorPoints()
living.bypassedHealth()   // health accounting for armor and resistance
living.dead()
living.hurtTicks()

living.blocking()         // holding a shield
living.usingItem()
living.isNaked()          // no armor

living.headYaw()
living.bodyYaw()

living.hasEffect("speed")
living.effect("speed")?.amplifier()
living.effects()

living.mainHandItem()
living.offHandItem()
living.armorItem(ArmorSlot.HELMET)
living.armorItems()
```

Players have their own cast, which adds ping and game mode:

```kotlin
val target = entity.asPlayer() ?: return
target.pingMs()
target.gameMode()
```

## Filters

`filters` is a convenient way to pick entities by the traits you care about instead of writing the conditions out by hand:

| Filter         | What it picks          |
| -------------- | ---------------------- |
| `alive()`      | living ones            |
| `self()`       | you                    |
| `player()`     | players                |
| `mob()`        | mobs                   |
| `monster()`    | hostile ones           |
| `animal()`     | animals                |
| `villager()`   | villagers              |
| `item()`       | dropped items          |
| `friend()`     | friends                |
| `party()`      | party members          |
| `ally()`       | friends and party      |
| `bot()`        | bots                   |
| `attackable()` | anything worth hitting |

Every filter is an ordinary `Predicate<Entity>`, so you can combine them:

```kotlin
val targets = world.entitiesNear(
    player.position(), 6.0,
    filters.player().and(filters.ally().negate())
)
```

And mix in your own conditions:

```kotlin
val weak = filters.attackable().and { it.asLiving()?.health() ?: 0f < 8f }

val victim = world.nearestEntity(player.position(), 5.0, weak)
```

## Spawning and despawning

```kotlin
on<EntitySpawnEvent> { e ->
    if (filters.monster().test(e.entity())) {
        notify("mob nearby", NotifyKind.WARN)
    }
}

on<EntityRemoveEvent> { e ->
    chat.print(e.entity().name() + " went away")
}
```

## Careful with holding on to them

Entities come and go. If you keep a reference across ticks, check it is still alive:

```kotlin
var target: Entity? = null

on<ClientTickEvent> {
    val current = target
    if (current == null || !current.alive()) {
        target = world.nearestEntity(player.position(), 6.0, filters.attackable())
        return@on
    }
}
```

Keeping the `id()` and looking the entity up again with `world.entityById(...)` is safer.
