hex-world
    Preparing search index...

    Class HexMap

    Row-major rectangular hex map backed by a flat ArrayBuffer. Coordinates are offset (col, row) internally; all public API accepts either offset or cube (HexCoord) coordinates.

    Memory layout per cell (CELL_STRIDE bytes): [terrain: Uint8][elevation: Int8][flags: Uint8][reserved: Uint8]

    Index

    Constructors

    Properties

    width: number
    height: number
    featureLayerCount: number
    uint8: Uint8Array
    roadBits: Uint8Array
    riverInBits: Uint8Array

    Per-cell bitmask of incoming river edges (bit e = a river enters across edge e). Supports confluences — multiple tributaries entering one cell. The cell byte keeps only the primary (lowest) incoming for compatibility.

    featureData: Uint8Array<ArrayBufferLike> | null
    waterSurfaces: Int8Array

    Per-cell water surface elevation (elevation index, same units as getElevation). Populated by computeWaterSurfaces. World-space Y = getWaterSurface(col, row) * elevScale. Initialized to 0 (sea level). Non-water cells retain 0 and should not be queried.

    shoreDistances: Uint8Array

    Per-cell hex distance to the nearest land-adjacent cell of the same water body (0 = touches land, 255 = far open water / capped). Populated by computeWaterSurfaces alongside surfaces. Drives the shallow→deep color gradient in the water surface geometry. Non-water cells retain 0.

    cellData: Map<number, Record<string, unknown>>

    Sparse per-cell metadata channel: arbitrary JSON-serializable game data (ownership, yields, quest flags, grazing state…) keyed by flat cell index (row * width + col). Rides through save/load and .hexpack — values must survive JSON.stringify/JSON.parse round-trips (no functions, no class instances, no cycles). Prefer the getCellData/setCellData accessors; the raw map is exposed for serializers and bulk iteration.

    Accessors

    • get cellCount(): number

      Total number of cells (width × height).

      Returns number

    • get riverRevision(): number

      See the field doc: changes whenever map-wide river rendering could.

      Returns number

    Methods

    • Returns true if (col, row) is within the map boundaries.

      Parameters

      • col: number
      • row: number

      Returns boolean

    • Returns the feature density level (0–3) for the given cell and scatter layer. Returns 0 if the layer index is out of range or no feature layers were allocated.

      Parameters

      • col: number
      • row: number
      • layer: number

      Returns number

    • Sets the feature density level for the given cell and scatter layer. value is clamped to 0–3 (2-bit). No-op if the layer index is out of range.

      Parameters

      • col: number
      • row: number
      • layer: number
      • value: number

      Returns void

    • Returns the metadata value stored under key for the cell, or undefined if the cell has no entry for that key. Values are arbitrary JSON-serializable game data — see cellData.

      Parameters

      • col: number
      • row: number
      • key: string

      Returns unknown

    • Stores a metadata value under key for the cell. Passing undefined deletes the key (and drops the cell's record entirely once its last key is removed, keeping the store sparse). Values must be JSON-serializable — they ride through save/load and .hexpack via JSON.stringify. No-op for out-of-bounds cells.

      Parameters

      • col: number
      • row: number
      • key: string
      • value: unknown

      Returns void

    • Returns the cell's full metadata record, or undefined if the cell has none. The record is the live object — treat it as read-only and mutate through setCellData so sparse-store invariants hold.

      Parameters

      • col: number
      • row: number

      Returns Readonly<Record<string, unknown>> | undefined

    • Returns true if the cell has any metadata entries.

      Parameters

      • col: number
      • row: number

      Returns boolean

    • Removes all metadata entries for the cell.

      Parameters

      • col: number
      • row: number

      Returns void

    • Parameters

      • col: number
      • row: number

      Returns number

    • Parameters

      • col: number
      • row: number
      • elevation: number

      Returns void

    • Call after writing river, terrain, or elevation data through the raw arrays.

      Returns void

    • Returns the raw flag bitmask for a cell. Use hasFlag for individual flag checks.

      Parameters

      • col: number
      • row: number

      Returns number

    • Sets one or more flag bits on a cell (OR).

      Parameters

      • col: number
      • row: number
      • flag: number

      Returns void

    • Clears one or more flag bits on a cell (AND NOT).

      Parameters

      • col: number
      • row: number
      • flag: number

      Returns void

    • Returns true if all bits in flag are set on the cell.

      Parameters

      • col: number
      • row: number
      • flag: number

      Returns boolean

    • Returns true if the cell has any river data (incoming or outgoing).

      Parameters

      • col: number
      • row: number

      Returns boolean

    • Returns true if at least one river flows into this cell from a neighbour.

      Parameters

      • col: number
      • row: number

      Returns boolean

    • Returns true if a river flows out of this cell to a neighbour.

      Parameters

      • col: number
      • row: number

      Returns boolean

    • Returns true if the cell is a river source or terminus (has exactly one of incoming/outgoing).

      Parameters

      • col: number
      • row: number

      Returns boolean

    • Returns the PRIMARY incoming river edge index (0–5), or -1 if none. With multiple tributaries this is the lowest-indexed incoming edge; use hasRiverIncomingThroughEdge / getIncomingRiverMask for the full set.

      Parameters

      • col: number
      • row: number

      Returns number

    • Returns the outgoing river edge index (0–5), or -1 if none.

      Parameters

      • col: number
      • row: number

      Returns number

    • Bitmask of ALL incoming river edges (bit e = edge e).

      Parameters

      • col: number
      • row: number

      Returns number

    • Returns true if a river flows into this cell across the given edge.

      Parameters

      • col: number
      • row: number
      • edgeIndex: number

      Returns boolean

    • Parameters

      • col: number
      • row: number
      • edgeIndex: number

      Returns boolean

    • Set the outgoing river direction for this cell (does NOT update the neighbour).

      Parameters

      • col: number
      • row: number
      • edgeIndex: number

      Returns void

    • ADD an incoming river through the given edge (does NOT update the neighbour). Multiple incoming edges per cell are supported (confluences); adding an edge never disturbs existing ones. The primary incoming direction is kept as the lowest set edge.

      Parameters

      • col: number
      • row: number
      • edgeIndex: number

      Returns void

    • Remove one incoming river edge, keeping any others (does NOT update the neighbour).

      Parameters

      • col: number
      • row: number
      • edgeIndex: number

      Returns void

    • Clear the outgoing river direction, keeping incoming tributaries (does NOT update the neighbour).

      Parameters

      • col: number
      • row: number

      Returns void

    • Clear all river data for this cell.

      Parameters

      • col: number
      • row: number

      Returns void

    • Returns true if a road passes through the given edge (0–5) of the cell.

      Parameters

      • col: number
      • row: number
      • edgeIndex: number

      Returns boolean

    • Returns true if the cell has a road on any edge.

      Parameters

      • col: number
      • row: number

      Returns boolean

    • Set or clear a road through the given edge. Does NOT update the neighbour cell.

      Parameters

      • col: number
      • row: number
      • edgeIndex: number
      • state: boolean

      Returns void

    • The cell on the other side of the given edge, plus that cell's edge index for the shared edge. Returns null when the neighbour is off-map. Needs the layout orientation because edge indices are orientation-specific.

      Parameters

      Returns { col: number; row: number; edge: number } | null

    • Set or clear a road through an edge on BOTH cells that share it — road rendering requires the half-edges to agree, and keeping that invariant by hand is error-prone. Returns the affected cells (one if the neighbour is off-map) so callers can mark them dirty.

      Parameters

      • col: number
      • row: number
      • edgeIndex: number
      • state: boolean
      • orientation: HexOrientation

      Returns { col: number; row: number }[]

    • Start a transaction for a multi-event interaction (e.g. a paint stroke): mutate through the returned MapTransaction as events arrive, then call commit() once to get a replayable MapEdit for undo/redo. Mutations apply to the map immediately; the transaction only records before/after snapshots of the touched cells.

      Returns MapTransaction

    • Run a batch of edits as a single undoable unit. Returns a MapEdit; pass its cells to ChunkManager.markDirtyCells() and keep it for undo/redo.

      Parameters

      Returns MapEdit

      const edit = map.edit(tx => {
      tx.setTerrain(4, 4, TerrainType.Water);
      tx.setElevation(4, 4, -1);
      });
      chunks.markDirtyCells(edit.cells);
      // later: edit.undo(); chunks.markDirtyCells(edit.cells);
    • Iterates over every cell in row-major order, calling cb(col, row) for each.

      Parameters

      • cb: (col: number, row: number) => void

      Returns void

    • Zero out all cell data so the map can be regenerated in place.

      Returns void

    • Returns the pre-computed water surface elevation for a cell (elevation index units). Multiply by your elevScale to get world-space Y. Returns 0 for non-water cells and before computeWaterSurfaces has been called.

      Parameters

      • col: number
      • row: number

      Returns number

    • Hex distance to the nearest land-adjacent cell of the same water body (0 = shore cell, larger = deeper open water, capped at 255). Populated by computeWaterSurfaces. Returns 0 for non-water cells.

      Parameters

      • col: number
      • row: number

      Returns number

    • BFS flood-fill that finds every connected water body and records its surface elevation in waterSurfaces plus each cell's distance-to-shore in shoreDistances. The surface is max(0, maxFloorElevation + 1): one step above the highest floor cell, clamped so ocean bodies (floor ≤ −1) always surface at 0. Elevated lakes (floor ≥ 0) surface one step above their floor.

      Called automatically by ChunkManager.update() before any dirty chunk rebuilds, and by generators / deserializers after map data is written. Call it yourself after bulk edits if you need getWaterSurface to be accurate before the next ChunkManager.update().

      Parameters

      • isWater: (terrain: number) => boolean = ...

        Predicate that returns true for liquid terrain indices. Defaults to the built-in water terrain (index 5). Pass a custom predicate when using additional liquid terrain types.

      • OptionaldirtyRegions: readonly { colStart: number; colEnd: number; rowStart: number; rowEnd: number }[]

        When provided, only water bodies intersecting these cell-coordinate regions are re-flooded; everything else keeps its current values. Regions MUST extend at least one cell beyond the edited cells so bodies merely adjacent to an edit are re-seeded (ChunkManager passes its dirty chunk bounds expanded by one). Requires surfaces to have been fully computed once before.

      Returns void

    • BFS from (col, row) that returns all cells in the same connected water body. Returns an empty array if the starting cell is not a water cell. Useful for editor tools that need to paint a whole lake consistently.

      Parameters

      • col: number
      • row: number
      • isWater: (terrain: number) => boolean

      Returns { col: number; row: number }[]