Skip to content

HashGrid2D

Defined in: src/modules/spatial/hash-grid-2d.ts:27

Grid-based spatial index mapping integer (x, y) cells to sets of entity IDs. Implements SpatialStructure with TPos = {x, y}.

Suitable for grid games (roguelikes, chess, tile strategy) and for continuous-position games when paired with Math.floor(pos / cellSize) cell hashing done by the caller.

Exposes the interface methods (queryAt/queryRect/queryNear/etc.) plus grid-specific extras (getAt, findAt, findFirstAt, getInRect, integer add(id, x, y) overloads). Cells live in a nested numeric Map<y, Map<x, Set>> (row-major). Numeric keys avoid the per-access string a flat Map<string, Set> would allocate on every cell touch — this index is read for every cell of every broadphase query, so that string churn dominated CPU and GC at high entity counts. The extras are honest about the structure — they aren’t part of the SpatialStructure contract.

new HashGrid2D(): HashGrid2D

HashGrid2D

add(id, posOrX, y?): void

Defined in: src/modules/spatial/hash-grid-2d.ts:32

Register an entity at a position. No-op if already present at that position.

EntityId

number | Pos

number

void

SpatialStructure.add


clear(): void

Defined in: src/modules/spatial/hash-grid-2d.ts:52

Remove all entries.

void

SpatialStructure.clear


findAt(x, y, predicate): EntityId[]

Defined in: src/modules/spatial/hash-grid-2d.ts:63

Collect every entity at (x, y) for which predicate(id) returns true. Returns an empty array when the cell is empty or no entity matches. The predicate is application-defined — typical uses are “is a blocker”, “is an item”, “is pickable up” — and carries the game-specific semantics, keeping the spatial index itself domain-neutral.

number

number

(id) => boolean

EntityId[]


findFirstAt(x, y, predicate): EntityId | undefined

Defined in: src/modules/spatial/hash-grid-2d.ts:81

Return the first entity at (x, y) for which predicate(id) returns true, or undefined if none match. Iteration order follows the underlying Set insertion order; callers needing a deterministic preference should use findAt and sort the result.

number

number

(id) => boolean

EntityId | undefined


getAt(x, y): ReadonlySet<EntityId> | undefined

Defined in: src/modules/spatial/hash-grid-2d.ts:98

Return all entity IDs at a given cell, or undefined if no entities are present. Exposes the backing Set directly for zero-alloc .has() / .size checks — a grid-specific escape hatch. Prefer queryAt when writing backend-agnostic code.

number

number

ReadonlySet<EntityId> | undefined


getInRect(x1, y1, x2, y2): EntityId[]

Defined in: src/modules/spatial/hash-grid-2d.ts:103

Collect all entity IDs within an axis-aligned rectangle (inclusive bounds) as an array.

number

number

number

number

EntityId[]


move(id, fromOrOldX, toOrOldY, newX?, newY?): void

Defined in: src/modules/spatial/hash-grid-2d.ts:112

Update an entity’s position. Accepts either the interface shape move(id, from, to) or the grid shorthand move(id, ox, oy, nx, ny). Skips work if the cell hasn’t changed.

EntityId

number | Pos

number | Pos

number

number

void

SpatialStructure.move


queryAt(pos): Iterable<EntityId>

Defined in: src/modules/spatial/hash-grid-2d.ts:134

All entity IDs at pos. Empty iterable if none.

Pos

Iterable<EntityId>

SpatialStructure.queryAt


queryNear(pos, radius): Iterable<EntityId>

Defined in: src/modules/spatial/hash-grid-2d.ts:141

All entity IDs within radius of pos (Euclidean, inclusive). radius is in the same units as the position coordinates.

Pos

number

Iterable<EntityId>

SpatialStructure.queryNear


queryRect(min, max): Iterable<EntityId>

Defined in: src/modules/spatial/hash-grid-2d.ts:163

All entity IDs within an axis-aligned region (inclusive bounds). min / max are the region corners.

Pos

Pos

Iterable<EntityId>

SpatialStructure.queryRect


remove(id, posOrX, y?): void

Defined in: src/modules/spatial/hash-grid-2d.ts:177

Unregister an entity from a position. No-op if not present.

EntityId

number | Pos

number

void

SpatialStructure.remove