
# `vec3`

```lua
local pos = player:position()
local above = pos + vec3(0, 2, 0)
local eye = player:eye_position()
local hit = world:raycast(eye, eye + player:velocity() * 20)
```

`vec3(x?, y?, z?)` builds one, missing components default to `0`. It is a plain table with
`x`, `y`, `z` fields you can read and write, and any table carrying numeric `x`/`y`/`z` works
where the API expects a vec3.

## Arithmetic

`+`, `-`, `*` and `/` work componentwise against another vector, or uniformly against a
number (`v * 2`, `2 * v`). Unary `-` negates, `==` compares components, `tostring(v)` prints
`vec3(x, y, z)`. Every operation returns a new vector.

## Methods

| Method | Returns |
|--------|---------|
| `v:length()`, `v:length_sq()` | Length; squared length is cheaper for comparisons |
| `v:distance(u)`, `v:distance_sq(u)` | Distance to another vector, and its square |
| `v:normalized()` | Unit-length copy |
| `v:dot(u)`, `v:cross(u)` | Dot and cross product |
| `v:lerp(u, t)` | Interpolation, `t = 0` gives `v` and `t = 1` gives `u` |
| `v:floor()` | Componentwise `math.floor`, so a block position |
| `v:copy()` | Independent copy |
| `v:unpack()` | Components as three return values |

```lua
local target = enemy:position():lerp(enemy:position() + enemy:velocity(), client.tick_delta())
rotation.look_at(target + vec3(0, enemy:height() / 2, 0))
```
