Each grid cell holds either grass, a vulnerable woody seedling, or a fire/grazing-tolerant mature tree. Every simulated year: trees seed new saplings near existing trees and at a low background rate; disturbance (fire frequency + grazing pressure, weighted by how much grass fuel is present) has a chance to kill seedlings before they mature; a seedling that survives several undisturbed years graduates into a tree; and grass cover under a cell falls as nearby tree canopy shades it out.
disturbance = fireFreq·fuelFactor(grass) + grazePressure·0.7
seedlingSurvival = 1 − disturbance (mature trees mostly immune)
grass(cell) -= shade(nearby tree canopy)·dt
- Fire frequency — how often burns sweep the landscape; effective only where grass fuel is still dense enough to carry it.
- Grazing pressure — large herbivores browsing shoots and trampling seedlings; still suppresses saplings even when grass is thin, unlike fire.
- The feedback loop — trees that escape disturbance shade out grass beneath them; less grass means less fuel; weaker fires let the next cohort of seedlings escape too. Once tree cover crosses roughly 40%, the loop increasingly runs itself even if you raise the sliders back up.
- Trajectory — watch whether cover settles into a stable open savanna or keeps climbing toward closed woodland; the tipping point is not symmetric, so recovery from encroachment needs stronger disturbance than the level that would have prevented it.
Real-world relevance: this is why fire-suppression policy and the loss of large grazers (through fencing, poaching, or land-use fragmentation) are linked to a documented global expansion of woody cover into former grasslands, even without any change in rainfall.