Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Use grids and continuous space

Requires the environment feature (implied by model).

The space layer indexes agents by position so systems can find neighbours. There are two spaces, both built from a GridGeometry (the cell dimensions and whether boundaries wrap) and a channel id:

A SpaceHandle owns the channel that orders the systems that build and read the space.

Discrete grid

Populate the grid by staging each agent's cell, then query neighbours:

grid.stage(entity, col, row);
// ...after the staging stage...
let here = grid.occupants(col, row);              // entities in a cell
let neighbours = grid.moore_neighborhood(col, row, radius);
let adjacent = grid.von_neumann_neighborhood(col, row, radius);

For movement where several agents compete for the same destination cell, use the claims mechanism (GridClaims): agents bid for a cell and the winner resolves deterministically, so contested moves do not depend on visitation order. This is how the Sugarscape example moves agents.

Continuous space

Continuous space answers radius queries with exact distances, honouring toroidal wrapping where the geometry requests it:

for (entity, x, y) in space.neighbors_within(qx, qy, radius) {
    // agents within `radius` of (qx, qy)
}

Geometry and wrapping

GridGeometry uses saturating conversions from floating-point positions, returns empty ranges for queries that do not intersect the space, and wraps explicitly on a torus. The same geometry backs the spatial message specialisation, so spatial messaging and spatial queries agree on cells.

See the Sugarscape example (examples/sugarscape/) for a grid-based model.