Skip to content

Light

A fixture is rated at the water surface, which is the figure a manufacturer publishes. What the tank runs on is what reaches the substrate, so the rating is gated by the photoperiod and then carried down the water column by Beer–Lambert, through the water and the green water suspended in it. Each plant reads that substrate PAR at its own height, through the water and the canopy above its leaves and the film coating them, and the last 24 hours of it are kept to read each plant’s day against.

MechanicStatusWhy
PAR at the substratesettledsurfacePar × exp(−k · depth). Beer–Lambert through a depth the capacity already implies, so a fixture is worth less in a deeper tank without anyone declaring it.
Saturation curvesettledtanh(PAR / Ik), the Jassby–Platt response. Near-linear below Ik, flat above it — a brighter fixture stops buying anything.
Light reaches income through the reservesettledEvery benefit a plant earns is earned on the reserve its photosynthesis fills, so light reaches income through the reserve, and a fed plant earns through the night.
Ik derived from the species bandsettledA fixed multiple of the band’s lower bound, so one number carries both the saturation curve and the daily light edge and they cannot drift apart.
The canopysettledLeaf attenuates like water — Beer–Lambert per unit of leaf area index — so a planting shades what grows beneath it and each plant reads its own height.
The bloomssettledBeer–Lambert on a bloom’s coverage, one coefficient per habitat. Green water joins the water’s extinction by its coverage, so it shades itself, the film below it and each plant by its depth; film coats every leaf at its coverage.
The day’s lightsettledA 24-slot history, one slot rewritten each tick. Each plant’s day is read against the day its species is rated to live on — the day, not the hour — and nothing starves on it.
The day at heightscaffoldingA plant’s day is the substrate’s day read through the canopy and the film as they stand now, so after a trim, a removal, a plantlet or a scrub the whole window is re-read at once rather than an hour at a time.
Light taken, by the hourscaffoldingLight settles before the biology, off the blooms the hour starts with, so the light a bloom takes lags its growth by an hour, and each past slot of the day keeps the green water of its own hour.
Photoperiod shapescaffoldingA rectangular window: rated PAR or zero, with no ramp at either edge.
Depth tracks standing waterscaffoldingAttenuation runs over the height the capacity implies. A half-drained tank lights its substrate as if it were full.
Crown placementmissingCrowns have no positions. Each falls at random over the floor and takes at most its floor share, so a tall crown shades what grows beneath it softer than in a real tank, and units a keeper spaces side by side, which would not overlap, shade each other.
SpectrummissingA fixture is one PAR number. No colour, no Kelvin, no spectral fit to a species.
depth = ∛(capacity / 2) × 10 cm
surfacePar = schedule active ? fixture.par : 0 µmol/m²/s
k = waterAttenuationPerCm + algaeAttenuationPerCm × green water's coverage / 100
light = surfacePar × exp(−k × depth)

Clear freshwater loses roughly 1 % of its PAR per centimetre in the 400–700 nm band, so the loss is modest per cm and considerable over a tank. Through clear water:

CapacityDepthPAR survivingWhat a 50 fixture lands
20 L21.5 cm81 %40
40 L27.1 cm76 %38
100 L36.8 cm69 %35
150 L42.2 cm66 %33
300 L53.1 cm59 %29

Fixtures come in four ratings — 25, 50, 90, 150 — the hobby’s low, medium, high and very high tiers. On a 150 L tank they land 16 / 33 / 59 / 98 PAR at the substrate, which is where those tiers actually sit once the water has taken its share.

A bloom takes light by Beer–Lambert on its coverage, as it fixes and burns by it. A kind’s habitat decides how the light crosses it.

KindCrossed asTakes
Green waterSpread through the columnalgaeAttenuationPerCm at full coverage, in proportion to it, added to k: from the substrate, and from every leaf by the depth above it
FilmA coat on every lit surface, leaves included, at its coveragecoverage × (1 − e^(−algaeCoatOpticalDepth)) of a leaf’s light

At the shipped coefficients a full bloom of green water adds 0.09 per cm to the water’s 0.01, and a full coat of film passes 41 % of a leaf’s light. Through the 42 cm of a 150 L tank green water takes from the substrate:

CoverageSubstrate light taken
517 %
1543 %
3068 %
6090 %
8095 %

The lamp hangs over the tank, so film on the glass never stands between it and a plant; only the film on its leaves does.

A species answers light along tanh(PAR / Ik), where Ik is its saturating irradiance — derived, not declared, at saturationIrradianceFactor times the lower bound of its tolerable band. At the shipped factor a plant at the bottom of its band runs at 46 % of its maximum, at Ik 76 %, and at twice Ik 96 %. Each species’ band and Ik are on the roster.

A plant’s three benefit channels are earned on the reserve its photosynthesis fills, so light reaches its income through the reserve — the budget is under Plants.

A unit spreads its leaves evenly from the floor to its height, over its own footprint. Light at a height inside the tank has come through the water above it and every crown that reaches higher, and each takes its Beer–Lambert share: the water per cm, the leaves per unit of leaf area index.

u_j = size_j / 100
// crown j's share of the floor
c_j = footprint_j / (2 × depth²)
// the share of the light crown j takes at height z
τ_j(z) = 1 − exp(−k_L × LAI_j × u_j × max(0, 1 − z / h_j))
// at the mean leaf, z_i = h_i / 2
s_i = f × exp(k × z_i + ½ × k_L × LAI_i × (1 − u_i) − Σ_j≠i c_j × τ_j(z_i))
// at the crown top
χ_i = f × exp(k × h_i − Σ_j≠i c_j × τ_j(h_i))

k is the water’s extinction as it stands, k_L is leafAttenuationPerLai, and f the share of a leaf’s light the film on it passes; a unit’s height h, leaf area index and footprint come off its growth form at its size.

TermReads as
k × zThe water and green water between the substrate and the leaf, given back: a tall plant’s leaves stand nearer the lamp, so a carpet loses the most to green water
fThe film on its leaves, the same on every plant
½ × k_L × LAI × (1 − u)Its own crown, counted against a full unit’s. A grown unit alone reads the substrate light plus that water gain; a sparser one is less self-shaded — up to ×2.0 for a sword and ×2.4 for a carpet patch or a clump
Σ c × τEvery other crown, placed at random over the floor: each takes at most its floor share, and one no taller than the leaf takes nothing

A plant reads light × s_i at its mean leaf, where it earns, and light × χ_i at its crown top, where it burns — the top leaf has none of its own crown above it. With leafAttenuationPerLai at 0 the leaves take nothing, and a plant reads the water alone. What reaches the floor is exp(−Σ c_j × τ_j(0)) of the substrate light; the rest is the planting’s floor shade, and the fixture’s rating carried to the floor through both is its floor light.

The lamp’s rating times the path to a leaf — the water, the canopy, the green water above it and the film on it, each a share passed — is what the leaf reads while the lamp is on.

The canopy is built once an hour, off the planting the hour starts with, and photosynthesis and vitality read the same one.

// each tick, as the hour settles
lightByHour[tick % 24] = light
dli = Σ lightByHour × 3600 / 10⁶ mol/m²/d
edge = tolerableLight[0] × 8 × 3600 / 10⁶ mol/m²/d, per species

The tank keeps the last 24 hours of substrate PAR, one slot per hour of the day, and the daily light integral is their sum in the hobby’s unit. Under a steady schedule it holds constant through day and night. When the fixture dies or the schedule shortens, it falls one lit hour at a time as those hours come round, and reaches zero a day after the last lit hour.

A species is rated to live on the low end of its PAR band held for the 8-hour day care sheets assume — 0.86 mol/m²/d for monte carlo, 0.23 for anubias. Each plant’s day is the integral at its own leaf, dli × s_i: today’s canopy over the whole window. Nothing starves on it — a plant starves on its reserve — but it is the yardstick its light is read against. A new tank opens with the history of the schedule it was built on, read through the optics it will run on, as though it had run it all along.

hourOfDay = tick % 24, and the schedule is a start hour plus a duration that wraps midnight cleanly. The default fixture runs 08:00 for ten hours. There is no dawn and no dusk: the tick before the window the substrate reads 0, the tick inside it reads the full attenuated rating.

ConsumerHow
PhotosynthesisPer plant, tanh(PAR / Ik) at its mean leaf scales the carbon it fixes into its reserve, and the O₂ that comes with it
A plant’s dayThe day’s light at its mean leaf, against its rated day
Plant light-high stressorPAR at its crown top over the species band, while the lamp is on
AlgaeThe mean PAR over its habitat, on the plants’ curve at its own Ik, and the day of it against its own rated day: green water the column’s mean — (e^{kD} − 1) / kD times the substrate figure, through its own shade — and film the walls at that mean and the floor and hardscape at what the canopy leaves, weighted by area

Light is not a stock. It is recomputed from scratch every tick before anything reads it, and has no source and no drain — only a value. Its history is a record of those values, rewritten one hour at a time. The canopy is no stock either: it is derived from the planting every hour.

The optics coefficients are listed in the reference under Optics, and the plant constants that read this light — saturationIrradianceFactor and lightExcessiveSeverity — under Plants.

ConstantMeaningValue
MAX_LIGHT_PARCeiling on a fixture rating — full noon sun at the surface2000 µmol/m²/s

A rating past MAX_LIGHT_PAR is a typo rather than a lighting choice, and tank construction refuses it.

NeighbourReadWritten
EquipmentThe fixture’s rating, its enabled flag and its photoperiod—
EnvironmentDepth, from the box capacity implies—
PlantsEvery unit’s size and growth form, which build the canopyLight at each plant’s own height: at the mean leaf, the photosynthesis rate and the day read against its rated day; at the crown top, the light-high stressor
AlgaeGreen water’s coverage, in the water’s extinction; film’s, the coat on every leafThe mean PAR over each kind’s habitat: the light curve on what it fixes, and the day of it
Water & gases—Indirectly: the photoperiod is what makes oxygen and CO₂ swing across a day

src/simulation/equipment/ for the fixture and the attenuation, src/simulation/plants/ for the canopy, src/simulation/core/ for the saturation curve, src/simulation/config/ for the optics coefficients and the severities.