every cell holding at least minimum - the cells a game applies its effect on
zeroes whatever sits on (x, y), leaving its neighbours alone; off-map is a no-op
adds amount to whatever is already on (x, y); off-map is a no-op
One diffusion step: every cell shares spread of its volume equally among its open
4-neighbours (a cell with no open neighbour keeps it all), then every cell keeps only
decay of what it ends up with. decay: 1 conserves volume and only moves it around;
anything lower thins the effect out over time. open(x, y) decides whether the effect
may cross into a cell, so the caller chooses what blocks it.
Returns the cells this step emptied, in reading order: those holding a volume before the
step and none after it. That is the moment a game turns the grass under a fire to embers,
and reporting it here saves the game diffing cellsAbove between two steps to notice.
the total volume across the whole map - useful for "has it burned out yet"
how much effect sits on (x, y) right now; 0 off-map
Staticfrom
A spreading volume field over a grid: a number per cell that creeps into its open neighbours and thins out over time. Fire, gas, caustic ooze, flood water - anything with a volume per cell.
Deliberately dumber than a simulation:
mwgholds the volumes and diffuses them, and the game decides what a volume means (readingcellsAboveeach turn to burn, poison or corrode whoever stands there, or to drown whoever wades in). Per-creature timers (applyStatusEffect) already cover "this victim burns for 3 turns"; this covers the other half, "this place burns until it burns out".Renderer-free and module-free, so a game can lay volumes over any grid without pulling in a terrain or combat module.
Example