Flow Module
Build-time level authoring: stamps, box styles, containers, and landmark recording all run when the level builds (`Flow.run`/`Flow.build`), never per frame. Build once, then keep per-frame queries on `Flow.isTag`, or hoist the lookup with `Flow.tryTagGrid`. Hex grids author identically: build the grid with `CellGrid2D.createHex` and run the same document. Authoring is cell-space, so geometry affects world positions and spatial queries only; reported rectangles are offset-space bounding boxes.
Functions and values
| Function or value |
Description
|
|
Places `stamp` at an exact offset of its container: the top-left sits `x` cells from the left edge and `y` cells from the top edge. Exact placement occupies no flow space (zero footprint), so it mounts inside `overlay` children and grid areas like `docked` does; a zero dimension of the wrapped stamp stretches on its axis from that origin to the container's far edge. Negative offsets clamp at 0. Name the stamped element to report its rectangle.
|
Full Usage:
Flow.border content section
Parameters:
'T
section : GridSection2D<'T>
Modifiers: inline Type parameters: 'T |
Outlines the box with one content.
|
Full Usage:
Flow.build extract stamp grid
Parameters:
int -> int -> 'T -> string seq
stamp : Stamp<'T>
grid : CellGrid2D<'T>
Returns: CellGrid2D<'T> * Landmarks
Type parameters: 'T |
`run` and `Landmarks.scanTiles` in one call: lays `stamp` out over the grid, then derives the per-cell tag bit grids from the painted tiles through `extract` (x, y, content -> tags). Use it when tiles carry meaning the simulation should query: `let struct (level, marks) = grid |> Flow.build tileTags levelBody`
|
Full Usage:
Flow.buildLayers extract stamps grids
Parameters:
int -> int -> 'T -> string seq
stamps : Stamp<'T>[]
grids : CellGrid2D<'T>[]
Returns: (CellGrid2D<'T> * Landmarks)[]
Type parameters: 'T |
`runLayers` and `Landmarks.scanTiles` per layer — the plural of `build`: every layer derives its per-cell tag bit grids from its own painted tiles through `extract` (x, y, content -> tags).
|
|
|
Full Usage:
Flow.cell at content section
Parameters:
CellPoint
content : 'T
section : GridSection2D<'T>
Modifiers: inline Type parameters: 'T |
Paints one cell at a local coordinate — the content atom.
|
Full Usage:
Flow.checker odd even section
Parameters:
'T
even : 'T
section : GridSection2D<'T>
Modifiers: inline Type parameters: 'T |
Checkerboards the box between two contents.
|
Full Usage:
Flow.checkerBorder odd even section
Parameters:
'T
even : 'T
section : GridSection2D<'T>
Modifiers: inline Type parameters: 'T |
Paints alternating cells along the box border.
|
Full Usage:
Flow.circle spec content section
Parameters:
CircleSpec
content : 'T
section : GridSection2D<'T>
Modifiers: inline Type parameters: 'T |
Paints a midpoint circle from the spec; `Filled` spans the interior. Circle semantics are pixel-space; hex-true rings come from `Hex2DSpatial.ring`.
|
Full Usage:
Flow.clear () section
Parameters:
unit
section : GridSection2D<'T>
Modifiers: inline Type parameters: 'T |
Erases the whole box.
|
Full Usage:
Flow.clumps spec paint section
Parameters:
ScatterSpec
paint : GridSection2D<'T> -> GridSection2D<'T>
section : GridSection2D<'T>
Modifiers: inline Type parameters: 'T |
Stamps a small paint pipeline the spec's `Count` times at random spots in the box (seeded) — rock clusters, puddles, rubble. The pipeline receives a section whose offset is the chosen cell and whose extent runs to the box's bottom-right corner, so paint relative to the section origin.
|
|
|
Full Usage:
Flow.corners content section
Parameters:
'T
section : GridSection2D<'T>
Modifiers: inline Type parameters: 'T |
Puts one content on the four corners of the box.
|
Full Usage:
Flow.dock spec section
Parameters:
DockSpec<'T>
section : GridSection2D<'T>
Returns: GridSection2D<'T>
Type parameters: 'T |
Paints the spec's `Stamp` into a docked rectangle of `section`. The spec's `Anchor` says where (`Dock.Top ||| Dock.CenterX` and so on); `Inset` distances the element from the container's edges, per side. `StretchX`/`StretchY` span the section minus the insets of their two edges, and a zero footprint dimension stretches on its axis without them. Returns `section` for pipeline chaining. Records no positions; `Flow.docked` is the level-document form that reports its rectangle.
|
|
A docked element for composition: paints the spec's `Stamp` into a docked rectangle of whatever container it mounts into and occupies no flow space (zero footprint). The spec's `Anchor` says where (`Dock.Top ||| Dock.CenterX` and so on); `Inset` distances the element from the container's edges, per side. `StretchX`/`StretchY` span the container minus the insets of their two edges, and a zero footprint dimension of the wrapped stamp stretches on its axis without them. Pair with `overlay` to place docks over a base layout. Name the stamped element to report its docked rectangle.
|
|
|
Full Usage:
Flow.fill content section
Parameters:
'T
section : GridSection2D<'T>
Modifiers: inline Type parameters: 'T |
Fills the whole box with one content.
|
Full Usage:
Flow.fillRect area content section
Parameters:
CellRect
content : 'T
section : GridSection2D<'T>
Modifiers: inline Type parameters: 'T |
Fills a sub-rectangle of the box with one content, in box-local coordinates — the local-area counterpart of `fill` for rooms, roads, and platforms inside a bigger element.
|
|
A CSS-grid-like container. Tracks size the columns and rows: `Fixed` tracks take literal cells, `Auto` tracks size to the largest footprint of their span-1 places (a spanning place shares its footprint over the `Auto` tracks in its span), `Weight` tracks share the leftover length of the assigned area, `Percent` tracks take a fraction of it. `Areas` uses CSS grid-area strings (`"main main side"` spans columns, `.` is an empty cell). Places mount by named template area or by explicit slot; slots may overlap, and paint order is `Places` order, later places on top: `grid { Cols = [| Fixed 20; Weight 1f |]; Rows = [| Fixed 6 |]; Gap = 1; Areas = [| "map side" |]; Places = [| struct (Area "map", dungeon) |] }`
|
|
A fixed-size group that lays its children out over its own area with overlay rules: each child paints into the group's box and later children paint on top. Children are full-bleed — `canvas`, `docked`, `at`, `strip`, `stretch` — so a sized child throws at construction: it would silently paint the whole box. The size is stated once, here; `canvas` children fill the box, `docked`/`at` children anchor within it, and `stretch` stretches a sized layout over it.
|
|
Per-cell walking query: is the cell covered by an element tagged `tag` (or marked with it in the tiles via `Flow.scanTiles`)? Out of range cells are never tagged. One dictionary lookup and one array read, no allocation — `CellPoint` is a struct; hoist the lookup with `Flow.tryTagGrid` in tight loops.
|
Full Usage:
Flow.line start finish content section
Parameters:
CellPoint
finish : CellPoint
content : 'T
section : GridSection2D<'T>
Modifiers: inline Type parameters: 'T |
Paints a Bresenham line between two local points — roads, pipes, fences.
|
Full Usage:
Flow.map mapping section
Parameters:
'T -> 'T
section : GridSection2D<'T>
Modifiers: inline Type parameters: 'T |
Rewrites the existing cells of the box through `mapping` — a derive pass after other styles.
|
Full Usage:
Flow.noise spec content section
Parameters:
ScatterSpec
content : 'T
section : GridSection2D<'T>
Modifiers: inline Type parameters: 'T |
Scatters the spec's `Count` cells of one content over the box (seeded).
|
Full Usage:
Flow.noiseBy spec generator section
Parameters:
ScatterSpec
generator : int -> int -> 'T
section : GridSection2D<'T>
Modifiers: inline Type parameters: 'T |
Scatters the spec's `Count` cells of generated content over the box (seeded); the callback receives the cell coordinates (x across the box, y down the box) and returns the content. The sparse counterpart of `texture` — prop variety picked per scattered cell.
|
|
Stacks children over the full area of the container, later children paint over earlier ones. Children are full-bleed — `canvas`, `docked`, `at`, `strip`, `stretch` — so a sized child throws at construction: it would silently paint the whole assigned area. Place fixed-footprint children with `at`/`docked`, stretch a sized layout with `stretch`, or use a footprint-honoring container (`grid`/`row`/`column`). Every legal child is zero-footprint, so the composite is context-sized (zero footprint).
|
Full Usage:
Flow.paint stamp section
Parameters:
Stamp<'T>
section : GridSection2D<'T>
Returns: GridSection2D<'T>
Type parameters: 'T |
Paints a stamp with its top-left at the section origin and returns the section, for use in existing `Layout.*` pipelines. Records no positions.
|
Full Usage:
Flow.polygon points filled content section
Parameters:
(int * int)[]
filled : bool
content : 'T
section : GridSection2D<'T>
Modifiers: inline Type parameters: 'T |
Paints a polygon from local vertices — `clip-path: polygon()`. `filled` spans the interior.
|
|
A single-cell prop: one content, one cell. The workhorse of clutter.
|
Full Usage:
Flow.rect borderContent fillContent section
Parameters:
'T
fillContent : 'T
section : GridSection2D<'T>
Modifiers: inline Type parameters: 'T |
Fills the box, then outlines it.
|
Full Usage:
Flow.region tags w h
Parameters:
string list
w : int
h : int
Returns: Stamp<'T>
Type parameters: 'T |
A non-painting landmark: records `tags` over the element's whole rectangle. Equivalent to a tagless `Stamp.box`, so it lays out like any other child (fixed footprint in a grid area, `expand` in a row, ...). Place it through containers that honor footprints (grid areas, row/column); inside `overlay`/`group` children, dock it.
|
Full Usage:
Flow.repeatX count content section
Parameters:
int
content : 'T
section : GridSection2D<'T>
Modifiers: inline Type parameters: 'T |
Paints a horizontal run of `count` cells from the box origin — `background-repeat: repeat-x`.
|
Full Usage:
Flow.repeatY count content section
Parameters:
int
content : 'T
section : GridSection2D<'T>
Modifiers: inline Type parameters: 'T |
Paints a vertical run of `count` cells from the box origin — `background-repeat: repeat-y`.
|
Full Usage:
Flow.replace oldContent newContent section
Parameters:
'T
newContent : 'T
section : GridSection2D<'T>
Modifiers: inline Type parameters: 'T (requires equality) |
Replaces every occurrence of one content with another, box-wide.
|
|
|
Full Usage:
Flow.run stamp grid
Parameters:
Stamp<'T>
grid : CellGrid2D<'T>
Returns: CellGrid2D<'T> * Landmarks
Type parameters: 'T |
Lays a stamp out over the whole grid and returns the grid together with its landmarks: the resolved rectangles of named elements, tag groups, and per-cell tag bit grids: `let struct (level, placed) = grid |> Flow.run levelBody`
|
Full Usage:
Flow.runLayers stamps grids
Parameters:
Stamp<'T>[]
grids : CellGrid2D<'T>[]
Returns: (CellGrid2D<'T> * Landmarks)[]
Type parameters: 'T |
Paints each stamp into its own grid, in order — the plural of `run`. The caller creates and owns the grids; a layer is an array position, stamp i paints grid i, bottom first. Each layer gets its own landmarks registry, so element names are unique per layer and may repeat across layers. Hex grids work unchanged: painting is cell-space. Throws ArgumentException when the arrays differ in length, when a stamp carries `Expand` (as `run` does), or when the grids differ in width or height. Every stamp and every grid is checked before any grid is painted. `let layers = grids |> Flow.runLayers stamps`
|
|
Scatters sized children over the assigned area at seeded, non-overlapping origins — prop clusters, debris fields, spawn rings. Candidate origins are the container's cells in the order of a seeded permutation (a fixed xorshift shuffle — the placement cannot drift across .NET versions, unlike the BCL random generator behind the paint-side scatter styles); children place in the given order and each takes the first origin where its footprint fits without overlapping an earlier one. The same seed and the same container build the same level every run. A child that fits nowhere fails the build naming the child when it is named. The footprint is the largest child's, so give it a sized region — a grid area, `Flow.stretch` over a `group`, or a stretched dock; a child with a zero axis (a context-sized child, or any element sized `0` on one side) places as one cell on that axis, and `expand` children throw.
|
Full Usage:
Flow.scatterBorder spec content section
Parameters:
ScatterSpec
content : 'T
section : GridSection2D<'T>
Modifiers: inline Type parameters: 'T |
Scatters the spec's `Count` cells along the box border (seeded) — a weathered edge, crumbling ramparts, asteroid fringes.
|
Full Usage:
Flow.scatterLine spec content section
Parameters:
ScatterLineSpec
content : 'T
section : GridSection2D<'T>
Modifiers: inline Type parameters: 'T |
Scatters the spec's `Count` cells along the line between its `From` and `To` points (seeded) — a broken road, a dotted route.
|
Full Usage:
Flow.setIfEmpty at content section
Parameters:
CellPoint
content : 'T
section : GridSection2D<'T>
Modifiers: inline Type parameters: 'T |
Sets one cell only when it is still empty — the `:empty` selector. Later styles still paint over it.
|
|
A full-bleed child that stretches its stamp over the whole assigned area of the container — the sanctioned way to mount a sized layout as an `overlay`/`group` child. Zero footprint, so it joins any full-bleed container; a zero dimension of the wrapped stamp means the same thing it always does. Name the wrapped element to report the stretched rectangle.
|
|
A full-length strip docked to one edge (`Dock.Top`, `Dock.Bottom`, `Dock.Left` or `Dock.Right`) with the given thickness in cells: `strip Dock.Bottom 1 [ fill Sand ]` is a full-width, one-cell-tall bar on the bottom edge. Occupies no flow space; pair with `overlay`.
|
|
|
Full Usage:
Flow.texture generator section
Parameters:
int -> int -> 'T
section : GridSection2D<'T>
Modifiers: inline Type parameters: 'T |
Generates the box cell by cell; the callback receives local coordinates (x across the box, y down the box).
|
|
|
Full Usage:
Flow.tryTagGrid tag landmarks
Parameters:
string
landmarks : Landmarks
Returns: bool[] voption
Modifiers: inline |
The raw per-cell bit grid of `tag` (`x + y * landmarks.Width`), for hot loops: hoist the lookup out of the loop and read the array per cell. `ValueNone` when no cell carries the tag. Out of range indices are never tagged, so bounds checks stay with the caller.
|
Full Usage:
Flow.weather spec oldContent newContent section
Parameters:
WeatherSpec
oldContent : 'T
newContent : 'T
section : GridSection2D<'T>
Modifiers: inline Type parameters: 'T (requires equality) |
Replaces content box-wide with the spec's `Probability` (seeded) — weathering.
|
Mibo