DatumHuePlatform v0.0.24datumhue.com
Contents

handle13 methods, 2 fields

Grid

A 2D integer grid with pathfinding, FOV, flood-fill, cellular automata, and procedural fills. Cells are 0-based, addressed as (x, y) = (column, row) with a top-left origin and Y increasing downward — the vertical mirror of TileMap's bottom-left Y-up frame, so copying cells into a tilemap flips the row: ty = rows - 1 - gy.

Obtained from
datumhue.grid.new
Accepted by
PathAgent:set_target, PathAgent:advance, PathAgent:drive, Voxel:heightmap, Voxel:stamp_grid

The examples on this page start from:

lua
-- An 8 x 6 room. A wall (1) runs down column 3 from the top row,
-- leaving the bottom row open.
local grid = datumhue.grid.new(8, 6)
grid:fill_rect(3, 0, 1, 5, 1)

Fields 2

FieldTypeAccessDescription
widthintegerread-onlyGrid width in cells.
heightintegerread-onlyGrid height in cells.

Methods 13

Grid:get

method
Grid:get(x: integer, y: integer) -> integer?

Cell value at (x, y), or nil when out of bounds.

Grid:set

method
Grid:set(x: integer, y: integer, value: integer)

Set cell (x, y) to value; no-op when out of bounds.

Grid:fill

method
Grid:fill(value: integer)

Set every cell to value.

Grid:fill_rect

method
Grid:fill_rect(x: integer, y: integer, w: integer, h: integer, value: integer)

Fill a rectangle with value; no-op when w or h is non-positive.

Example
-- (x, y) is the rectangle's top-left cell; y grows downward.
grid:fill_rect(5, 3, 2, 2, 7)
print(grid:get(5, 3), grid:get(6, 4)) --> 7 7
print(grid:get(5, 2), grid:get(7, 5)) --> 0 0

Grid:find_path

method
Grid:find_path(x1: integer, y1: integer, x2: integer, y2: integer, opts: grid.FindPathOptions) -> grid.Cell[]?

A* path from (x1,y1) to (x2,y2), or nil if unreachable.

Example
local path = grid:find_path(0, 0, 7, 0, { blocked = { 1 } })
-- Both ends are included; it goes round the wall's open end.
print(#path, path[1].x, path[#path].x) --> 11 0 7
print(path[6].x, path[6].y) --> 3 5
-- Close the gap and nothing gets through.
grid:set(3, 5, 1)
print(grid:find_path(0, 0, 7, 0, { blocked = { 1 } })) --> nil

opts grid.FindPathOptions options 1 key

KeyTypeDefaultDescription
blocked requiredinteger[]no defaultCell values treated as impassable walls.

returns grid.Cell record 2 keys

KeyTypeDescription
xintegerCell column.
yintegerCell row.

Grid:agent

method
Grid:agent(opts: grid.AgentOptions) -> PathAgent

Create a PathAgent starting at the given position: a mover that owns the walk-the-waypoints bookkeeping against this grid (or any grid passed to its methods later).

Example
-- Positions are in cells: 0.5 is the middle of cell 0.
local agent = grid:agent({
    x = 0.5,
    y = 0.5,
    speed = 4,
    blocked = { 1 },
    repath = 0.5,
})
agent:set_target(grid, 7, 0)
print(agent.x, agent.y) --> 0.5 0.5

opts grid.AgentOptions options 7 keys

KeyTypeDefaultDescription
x requirednumberno defaultStarting position, in cells.
y requirednumberno defaultStarting position, in cells.
speed requirednumberno defaultMovement speed, in cells per second.
blockedinteger[]no cell value blocks the agentCell values the agent will not path through.
repathnumberthe agent paths once per set_target, and whenever it has no pathRepath cadence in seconds while a target is set.
arrive_radiusnumber0Stop this many cells short of the target center instead of standing on it -- for follow-at-distance movers; 0 arrives on the cell.
stop_beforeinteger[]the agent walks into every cell it paths throughCell values the agent paths through but will not walk into: the walk halts flush before such a cell and the advance result carries it as stopped. Handle the cell (open the door, clear the line) and the walk resumes on its own once the cell's value changes.

Grid:slide

method
Grid:slide(x: number, y: number, dx: number, dy: number, w: number, h: number, opts: grid.SlideOptions) -> number, number

Move a w x h axis-aligned box centered at (x, y) by (dx, dy), sliding against cells whose value is in solid: the x move applies and clamps first, then the y move — the classic tile character controller. Units are cells (1.0 = one cell); a clamped box stops flush on the cell face. Cells outside the grid are open, and a box already overlapping a solid cell collides only with cells it newly enters. Returns the final center.

Example
-- A 1 x 1 box centered in cell (1, 0) moves 3 cells right.
local x, y = grid:slide(1.5, 0.5, 3, 0, 1, 1, { solid = { 1 } })
-- It stops flush against the wall in column 3.
print(x, y) --> 2.5 0.5

opts grid.SlideOptions options 1 key

KeyTypeDefaultDescription
solid requiredinteger[]no defaultCell values the box collides with.

Grid:dijkstra

method
Grid:dijkstra(opts: grid.DijkstraOptions) -> Grid

A new Grid of distance scores from weighted sources (-1 unreachable).

Example
local steps = grid:dijkstra({
    sources = { { x = 7, y = 0 } },
    blocked = { 1 },
})
-- Steps from the source; -1 where it cannot reach.
print(steps:get(7, 0), steps:get(4, 0), steps:get(3, 0)) --> 0 3 -1

opts grid.DijkstraOptions options 2 keys

KeyTypeDefaultDescription
sources requiredgrid.DijkstraSource[]no defaultWeighted source cells the distance field flows out from.
blocked requiredinteger[]no defaultCell values treated as impassable walls.

Grid:field_of_view

method
Grid:field_of_view(x: integer, y: integer, opts: grid.FieldOfViewOptions) -> grid.Cell[]

Visible cells from (x,y).

Example
local seen = grid:field_of_view(1, 2, { range = 4, opaque = { 1 } })
local visible = {}
for _, cell in ipairs(seen) do
    visible[cell.x .. "," .. cell.y] = true
end
-- The wall is seen; what is behind it is not.
print(visible["3,2"], visible["4,2"]) --> true nil

opts grid.FieldOfViewOptions options 2 keys

KeyTypeDefaultDescription
range requiredintegerno defaultMaximum sight radius in cells.
opaque requiredinteger[]no defaultCell values that block line of sight.

returns grid.Cell record 2 keys

KeyTypeDescription
xintegerCell column.
yintegerCell row.

Grid:flood_fill

method
Grid:flood_fill(x: integer, y: integer, opts: grid.FloodFillOptions) -> grid.Cell[]

8-connected flood fill from (x,y).

Example
-- Spreads through matching cells, diagonals included.
local room = grid:flood_fill(0, 0, { match = { 0 } })
-- Every open cell: 48 cells less the 5 of the wall.
print(#room) --> 43

opts grid.FloodFillOptions options 1 key

KeyTypeDefaultDescription
match requiredinteger[]no defaultCell values the fill is allowed to spread into.

returns grid.Cell record 2 keys

KeyTypeDescription
xintegerCell column.
yintegerCell row.

Grid:count_neighbors

method
Grid:count_neighbors(x: integer, y: integer, opts: grid.CountNeighborsOptions) -> integer

Count of the 8 neighbors whose value is in match.

Example
-- Of the 8 cells around (2, 2), 3 are wall.
print(grid:count_neighbors(2, 2, { match = { 1 } })) --> 3

opts grid.CountNeighborsOptions options 1 key

KeyTypeDefaultDescription
match requiredinteger[]no defaultCell values counted as matching neighbors.

Grid:automata_step

method
Grid:automata_step(opts: grid.AutomataStepOptions)

Advance one cellular-automata generation in place.

Example
local life = datumhue.grid.new(5, 5)
life:fill_rect(1, 2, 3, 1, 1)
-- Conway's rules: the row of three turns into a column.
life:automata_step({
    alive = { 1 },
    birth = { 3 },
    survival = { 2, 3 },
})
print(life:get(2, 1), life:get(2, 3), life:get(1, 2)) --> 1 1 0

opts grid.AutomataStepOptions options 5 keys

KeyTypeDefaultDescription
alive requiredinteger[]no defaultCell values considered alive this generation.
birth requiredinteger[]no defaultLive-neighbor counts that turn a dead cell alive.
survival requiredinteger[]no defaultLive-neighbor counts that keep a live cell alive.
alive_valueinteger1Value written to cells alive next generation.
dead_valueinteger0Value written to cells dead next generation.

Grid:fill_noise

method
Grid:fill_noise(sampler: NoiseSampler, opts?: grid.FillNoiseOptions)

Bucket a noise sampler into integer cell values.

Example
local hills = datumhue.noise.perlin({ seed = 1, frequency = 0.2 })
-- Below -0.2 is water (0), up to 0.3 grass (1), above that rock (2).
grid:fill_noise(hills, {
    thresholds = { -0.2, 0.3 },
    values = { 0, 1, 2 },
})
print(grid:get(0, 0)) --> 1

opts grid.FillNoiseOptions options 4 keys

KeyTypeDefaultDescription
thresholdsnumber[]no cutoffs; with values also omitted, one cutoff at 0Ascending noise cutoffs partitioning samples into buckets.
valuesinteger[]no values; with thresholds also omitted, 0 for samples below 0 and 1 for the restCell value per bucket; length must equal len(thresholds)+1.
offset_xnumber0Horizontal offset added to each cell's sample coordinate.
offset_ynumber0Vertical offset added to each cell's sample coordinate.

datumhue.com

(c) 2026 Shuusei AB. Quote excerpts of this manual, with attribution to DatumHue, in your own documentation, tutorials, course materials, reviews, and other writing or video. Republishing it in whole or in substantial part needs written permission: support@datumhue.com.

Victor Mono is licensed under the SIL Open Font License 1.1
Copyright (c) 2024, Rune Bjørnerås (https://github.com/rubjo)

This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL


-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------

PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.

The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.

DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.

"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).

"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).

"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.

"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.

PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:

1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.

2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.

3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.

4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.

5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.

TERMINATION
This license becomes null and void if any of the above conditions are
not met.

DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.

Try

    ↑↓ selectEnter openTab filter

    Settings

    Theme
    Text
    Print

    Keyboard shortcuts

    / or Ctrl KSearch
    ↑ ↓ EnterPick a result
    TabNext result filter
    j kNext or previous entry
    [ ]Previous or next page
    yCopy a link to the current entry
    ?These shortcuts
    EscClose

    On this page