# @ferret/zones: API

A zone grid and named zones with occupancy, enter/exit events and name hashing.

9 exports. Generated from the source (`packages/zones/src`), so it matches the code.

## Classes

### ZoneService

*class* · `packages/zones/src/zones.ts:63`

```ts
class ZoneService implements Service
```

Named zones and who is in them. A member is in exactly one zone at a time: the highest-priority named zone that contains it,
else its cell of the zone grid (if there is one), else none. Entering and leaving fire `zone:enter` / `zone:exit` with
{ zone, entity, from? }. Zone names go to backends as `hashOf(name)`, never as text.

- `readonly name: "zones"`
- `constructor(readonly opts: ZoneOptions = {})`
- `init(world: World)`
- `add(def: ZoneDef): this`
- `remove(name: string)`
- `clear()`
- `get zones(): readonly ZoneDef[]`
- `def(name: string): ZoneDef | undefined`
- `track(e: Entity)` — Count another entity as a member (an NPC whose zone matters).
- `untrack(e: Entity)`
- `at(x: number, y: number, z: number): string | null` — The zone a point is in.
- `zoneOf(e: Entity): string | null`
- `occupants(zone: string): Entity[]`
- `hashOf(zone: string): string` — What to tell a backend instead of the zone's name.
- `occupancy(hashed = false): Record<string, number>` — Zone name -> number of members, for the occupancy report. Only zones with someone in them.
- `fixedUpdate()` — Called before the components' fixed update, at the fixed rate.

## Functions

### sha256

*function* · `packages/zones/src/hash.ts:10`

```ts
function sha256(data: Uint8Array): Uint8Array
```

### sha256Hex

*function* · `packages/zones/src/hash.ts:42`

```ts
function sha256Hex(text: string): string
```

SHA-256 of a string (UTF-8), as hex.

### zoneHash

*function* · `packages/zones/src/hash.ts:45`

```ts
function zoneHash(name: string, salt = ''): string
```

The name a backend sees for a zone: the hash of `salt:name`. The same name and salt always give the same value.

## Interfaces

### ZoneDef

*interface* · `packages/zones/src/zones.ts:9`

```ts
interface ZoneDef
```

- `name: string`
- `shape: ZoneShape`
- `priority?: number` — higher wins where zones overlap (default 0; later definitions win ties)
- `tags?: string[]`
- `data?: Record<string, unknown>`

### ZoneEvent

*interface* · `packages/zones/src/zones.ts:33`

```ts
interface ZoneEvent
```

- `zone: string`
- `entity: Entity`
- `from?: string`

### ZoneGridOptions

*interface* · `packages/zones/src/zones.ts:18`

```ts
interface ZoneGridOptions
```

- `cell: number` — cell size in metres; positions outside every named zone are in the cell zone "<prefix>x_z"
- `prefix?: string`
- `origin?: [number, number]`

### ZoneOptions

*interface* · `packages/zones/src/zones.ts:25`

```ts
interface ZoneOptions
```

- `salt?: string` — salt for `hashOf`: games choose it so a backend cannot match names across games
- `grid?: ZoneGridOptions`
- `memberTag?: string` — members are the entities with this tag (default "player"); more can join with `track`

## Types

### ZoneShape

*type* · `packages/zones/src/zones.ts:4`

```ts
type ZoneShape = | { kind: 'box'; centre: [number, number, number]; size: [number, number, number]; /** rotation about y, radians */ yaw?: number } | { kind: 'cylinder'; centre: [number, number, number]; radius: number; height: number } | { kind: 'polygon'; /** x,z pairs, in order */ points: [number, number][]; minY?: number; maxY?: number }
```

