Logo Mibo

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

Flow.at x y stamp

Full Usage: Flow.at x y stamp

Parameters:
    x : int
    y : int
    stamp : Stamp<'T>

Returns: Stamp<'T>
Type parameters: 'T

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.

x : int
y : int
stamp : Stamp<'T>
Returns: Stamp<'T>

Flow.border content section

Full Usage: Flow.border content section

Parameters:
Modifiers: inline
Type parameters: 'T

Outlines the box with one content.

content : 'T
section : GridSection2D<'T>

Flow.build extract stamp grid

Full Usage: Flow.build extract stamp grid

Parameters:
    extract : 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`

extract : int -> int -> 'T -> string seq
stamp : Stamp<'T>
grid : CellGrid2D<'T>
Returns: CellGrid2D<'T> * Landmarks

Flow.buildLayers extract stamps grids

Full Usage: Flow.buildLayers extract stamps grids

Parameters:
    extract : 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).

extract : int -> int -> 'T -> string seq
stamps : Stamp<'T>[]
grids : CellGrid2D<'T>[]
Returns: (CellGrid2D<'T> * Landmarks)[]

Flow.canvas styles

Full Usage: Flow.canvas styles

Parameters:
Returns: Stamp<'T>
Type parameters: 'T

A context-sized box of styles: paints whatever area its container assigns to it — a grid area, an overlay child, a docked rectangle, an expanded slot. It has no intrinsic footprint; a zero dimension always means "stretch on that axis".

styles : BoxStyle<'T> list
Returns: Stamp<'T>

Flow.cell at content section

Full Usage: Flow.cell at content section

Parameters:
Modifiers: inline
Type parameters: 'T

Paints one cell at a local coordinate — the content atom.

at : CellPoint
content : 'T
section : GridSection2D<'T>

Flow.checker odd even section

Full Usage: Flow.checker odd even section

Parameters:
Modifiers: inline
Type parameters: 'T

Checkerboards the box between two contents.

odd : 'T
even : 'T
section : GridSection2D<'T>

Flow.checkerBorder odd even section

Full Usage: Flow.checkerBorder odd even section

Parameters:
Modifiers: inline
Type parameters: 'T

Paints alternating cells along the box border.

odd : 'T
even : 'T
section : GridSection2D<'T>

Flow.circle spec content section

Full Usage: Flow.circle spec content section

Parameters:
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`.

spec : CircleSpec
content : 'T
section : GridSection2D<'T>

Flow.clear () section

Full Usage: Flow.clear () section

Parameters:
Modifiers: inline
Type parameters: 'T

Erases the whole box.

() : unit
section : GridSection2D<'T>

Flow.clumps spec paint section

Full Usage: Flow.clumps spec paint section

Parameters:
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.

spec : ScatterSpec
paint : GridSection2D<'T> -> GridSection2D<'T>
section : GridSection2D<'T>

Flow.column opts children

Full Usage: Flow.column opts children

Parameters:
Returns: Stamp<'T>
Type parameters: 'T

Lays children out top to bottom. Same rules as `row` with the axes swapped.

opts : FlowOpts
children : Stamp<'T> seq
Returns: Stamp<'T>

Flow.corners content section

Full Usage: Flow.corners content section

Parameters:
Modifiers: inline
Type parameters: 'T

Puts one content on the four corners of the box.

content : 'T
section : GridSection2D<'T>

Flow.dock spec section

Full Usage: Flow.dock spec section

Parameters:
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.

spec : DockSpec<'T>
section : GridSection2D<'T>
Returns: GridSection2D<'T>

Flow.docked spec

Full Usage: Flow.docked spec

Parameters:
Returns: Stamp<'T>
Type parameters: 'T

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.

spec : DockSpec<'T>
Returns: Stamp<'T>

Flow.expand stamp

Full Usage: Flow.expand stamp

Parameters:
Returns: Stamp<'T>
Type parameters: 'T

Marks an element to share the leftover main-axis space of its container (flex-grow). Alias for `Stamp.expand`, so level documents can stay on `Flow.*`. Only `row`/`column` honor it; containers and combinators reject it.

stamp : Stamp<'T>
Returns: Stamp<'T>

Flow.fill content section

Full Usage: Flow.fill content section

Parameters:
Modifiers: inline
Type parameters: 'T

Fills the whole box with one content.

content : 'T
section : GridSection2D<'T>

Flow.fillRect area content section

Full Usage: Flow.fillRect area content section

Parameters:
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.

area : CellRect
content : 'T
section : GridSection2D<'T>

Flow.grid opts

Full Usage: Flow.grid opts

Parameters:
Returns: Stamp<'T>
Type parameters: 'T

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) |] }`

opts : GridOpts<'T>
Returns: Stamp<'T>

Flow.group w h children

Full Usage: Flow.group w h children

Parameters:
    w : int
    h : int
    children : Stamp<'T> list

Returns: Stamp<'T>
Type parameters: 'T

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.

w : int
h : int
children : Stamp<'T> list
Returns: Stamp<'T>

Flow.isTag tag at landmarks

Full Usage: Flow.isTag tag at landmarks

Parameters:
Returns: bool

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.

tag : string
at : CellPoint
landmarks : Landmarks
Returns: bool

Flow.line start finish content section

Full Usage: Flow.line start finish content section

Parameters:
Modifiers: inline
Type parameters: 'T

Paints a Bresenham line between two local points — roads, pipes, fences.

start : CellPoint
finish : CellPoint
content : 'T
section : GridSection2D<'T>

Flow.map mapping section

Full Usage: Flow.map mapping section

Parameters:
Modifiers: inline
Type parameters: 'T

Rewrites the existing cells of the box through `mapping` — a derive pass after other styles.

mapping : 'T -> 'T
section : GridSection2D<'T>

Flow.noise spec content section

Full Usage: Flow.noise spec content section

Parameters:
Modifiers: inline
Type parameters: 'T

Scatters the spec's `Count` cells of one content over the box (seeded).

spec : ScatterSpec
content : 'T
section : GridSection2D<'T>

Flow.noiseBy spec generator section

Full Usage: Flow.noiseBy spec generator section

Parameters:
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.

spec : ScatterSpec
generator : int -> int -> 'T
section : GridSection2D<'T>

Flow.overlay children

Full Usage: Flow.overlay children

Parameters:
    children : Stamp<'T> seq

Returns: Stamp<'T>
Type parameters: 'T

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).

children : Stamp<'T> seq
Returns: Stamp<'T>

Flow.paint stamp section

Full Usage: Flow.paint stamp section

Parameters:
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.

stamp : Stamp<'T>
section : GridSection2D<'T>
Returns: GridSection2D<'T>

Flow.polygon points filled content section

Full Usage: Flow.polygon points filled content section

Parameters:
    points : (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.

points : (int * int)[]
filled : bool
content : 'T
section : GridSection2D<'T>

Flow.prop content

Full Usage: Flow.prop content

Parameters:
    content : 'T

Returns: Stamp<'T>
Type parameters: 'T

A single-cell prop: one content, one cell. The workhorse of clutter.

content : 'T
Returns: Stamp<'T>

Flow.rect borderContent fillContent section

Full Usage: Flow.rect borderContent fillContent section

Parameters:
    borderContent : 'T
    fillContent : 'T
    section : GridSection2D<'T>

Modifiers: inline
Type parameters: 'T

Fills the box, then outlines it.

borderContent : 'T
fillContent : 'T
section : GridSection2D<'T>

Flow.region tags w h

Full Usage: Flow.region tags w h

Parameters:
    tags : 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.

tags : string list
w : int
h : int
Returns: Stamp<'T>

Flow.repeatX count content section

Full Usage: Flow.repeatX count content section

Parameters:
Modifiers: inline
Type parameters: 'T

Paints a horizontal run of `count` cells from the box origin — `background-repeat: repeat-x`.

count : int
content : 'T
section : GridSection2D<'T>

Flow.repeatY count content section

Full Usage: Flow.repeatY count content section

Parameters:
Modifiers: inline
Type parameters: 'T

Paints a vertical run of `count` cells from the box origin — `background-repeat: repeat-y`.

count : int
content : 'T
section : GridSection2D<'T>

Flow.replace oldContent newContent section

Full Usage: Flow.replace oldContent newContent section

Parameters:
Modifiers: inline
Type parameters: 'T (requires equality)

Replaces every occurrence of one content with another, box-wide.

oldContent : 'T
newContent : 'T
section : GridSection2D<'T>

Flow.row opts children

Full Usage: Flow.row opts children

Parameters:
Returns: Stamp<'T>
Type parameters: 'T

Lays children out left to right and computes the container footprint. Fixed children keep their width; expanded children keep their width and split the leftover width of the assigned area by weight.

opts : FlowOpts
children : Stamp<'T> seq
Returns: Stamp<'T>

Flow.run stamp grid

Full Usage: Flow.run stamp grid

Parameters:
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`

stamp : Stamp<'T>
grid : CellGrid2D<'T>
Returns: CellGrid2D<'T> * Landmarks

Flow.runLayers stamps grids

Full Usage: Flow.runLayers stamps grids

Parameters:
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`

stamps : Stamp<'T>[]
grids : CellGrid2D<'T>[]
Returns: (CellGrid2D<'T> * Landmarks)[]

Flow.scatter seed children

Full Usage: Flow.scatter seed children

Parameters:
    seed : int
    children : Stamp<'T> seq

Returns: Stamp<'T>
Type parameters: 'T

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.

seed : int
children : Stamp<'T> seq
Returns: Stamp<'T>

Flow.scatterBorder spec content section

Full Usage: Flow.scatterBorder spec content section

Parameters:
Modifiers: inline
Type parameters: 'T

Scatters the spec's `Count` cells along the box border (seeded) — a weathered edge, crumbling ramparts, asteroid fringes.

spec : ScatterSpec
content : 'T
section : GridSection2D<'T>

Flow.scatterLine spec content section

Full Usage: Flow.scatterLine spec content section

Parameters:
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.

spec : ScatterLineSpec
content : 'T
section : GridSection2D<'T>

Flow.setIfEmpty at content section

Full Usage: Flow.setIfEmpty at content section

Parameters:
Modifiers: inline
Type parameters: 'T

Sets one cell only when it is still empty — the `:empty` selector. Later styles still paint over it.

at : CellPoint
content : 'T
section : GridSection2D<'T>

Flow.stretch stamp

Full Usage: Flow.stretch stamp

Parameters:
Returns: Stamp<'T>
Type parameters: 'T

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.

stamp : Stamp<'T>
Returns: Stamp<'T>

Flow.strip side thickness styles

Full Usage: Flow.strip side thickness styles

Parameters:
Returns: Stamp<'T>
Type parameters: 'T

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`.

side : Dock
thickness : int
styles : BoxStyle<'T> list
Returns: Stamp<'T>

Flow.taggedRects tag landmarks

Full Usage: Flow.taggedRects tag landmarks

Parameters:
Returns: CellRect list
Modifiers: inline

Returns every rectangle recorded under a tag, most recent first. Build-time/occasional queries; the per-cell hot path is `Flow.isTag`.

tag : string
landmarks : Landmarks
Returns: CellRect list

Flow.texture generator section

Full Usage: Flow.texture generator section

Parameters:
Modifiers: inline
Type parameters: 'T

Generates the box cell by cell; the callback receives local coordinates (x across the box, y down the box).

generator : int -> int -> 'T
section : GridSection2D<'T>

Flow.tryPosition name landmarks

Full Usage: Flow.tryPosition name landmarks

Parameters:
Returns: CellRect voption
Modifiers: inline

Looks up the resolved rectangle of a named element.

name : string
landmarks : Landmarks
Returns: CellRect voption

Flow.tryTagGrid tag landmarks

Full Usage: Flow.tryTagGrid tag landmarks

Parameters:
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.

tag : string
landmarks : Landmarks
Returns: bool[] voption

Flow.weather spec oldContent newContent section

Full Usage: Flow.weather spec oldContent newContent section

Parameters:
Modifiers: inline
Type parameters: 'T (requires equality)

Replaces content box-wide with the spec's `Probability` (seeded) — weathering.

spec : WeatherSpec
oldContent : 'T
newContent : 'T
section : GridSection2D<'T>

Type something to start searching.