> 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/actions/prediction.md).

# Prediction

Prediction answers "what happens if nothing changes": where I will be in a few ticks, and where a projectile will land.

## Where I will be

```kotlin
val soon = prediction.after(10)      // ten ticks from now

soon.position()
soon.velocity()
soon.box()
soon.onGround()
soon.inWater()
soon.sneaking()
soon.sprinting()
soon.jumping()
soon.fallDistanceBlocks()
```

It is worked out from your current velocity, input and world physics. Future player input is unknowable, so the further out you go the less it means. A dozen or two ticks is the practical ceiling.

For example, not jumping when you will end up in water five ticks from now anyway:

```kotlin
if (prediction.after(5).inWater()) return@on
```

## Where a projectile will go

```kotlin
val path = prediction.projectile(ProjectileKind.ARROW)

path.points()             // the trajectory as points
path.lands()              // will it get anywhere at all
path.landingPosition()    // where it lands
path.hitEntity()          // who it hits, or null
path.hitsBlock()
path.flightTicks()        // how many ticks it flies
```

Projectile kinds: `ARROW`, `TRIDENT`, `ENDER_PEARL`, `SPLASH_POTION`, `SNOWBALL`, `WIND_CHARGE`.

By default it uses your current angle and a full charge. You can give it your own:

```kotlin
prediction.projectile(ProjectileKind.ARROW, aim)
prediction.projectile(ProjectileKind.ARROW, aim, 0.7f)
```

## Only shoot when it lands

The most common use is not wasting a projectile:

```kotlin
fun willHitEnemy(kind: ProjectileKind): Boolean {
    val victim = prediction.projectile(kind).hitEntity() ?: return false
    return victim.alive() && !victim.isSelf() && !victim.isAlly()
}

on<ClientTickEvent> {
    if (!player.usingItem()) return@on
    if (!inventory.held().isA("trident")) return@on
    if (player.itemUseTicks() < 10) return@on
    if (!willHitEnemy(ProjectileKind.TRIDENT)) return@on
    interaction.stopUsingItem()
}
```

## Drawing the trajectory

`points()` is a ready-made list you can hand to the [3D render](/interface/3d-render.md):

```kotlin
on<Render3DEvent> { e ->
    val path = prediction.projectile(ProjectileKind.ENDER_PEARL)
    val points = path.points()
    for (i in 0 until points.size - 1) {
        e.render().line(points[i], points[i + 1], Colors.CYAN, true)
    }
    path.landingPosition()?.let {
        e.render().box(Box.around(it, 0.2), Colors.RED, true)
    }
}
```

## About the cost

Every call is a simulation, not a field read. Once or twice a tick is fine; inside a loop over every entity is not. If you need the result several times in a tick, compute it once and keep it in a variable.
