%%{init: {"flowchart": {"nodeSpacing": 45, "rankSpacing": 55}}}%%
flowchart TD
M["🌍 Metacommunity<br/>patches of every age,<br/>linked by dispersing seeds"]
P["🌳 Patch<br/>competing individuals<br/>sharing one light environment"]
I["🌱 Individual<br/>grows, dies, sets seed"]
M -->|"a mosaic of many"| P
P -->|"a stand of many"| I
The big picture
theory · start here
If you are meeting plant for the first time, start here. This page gives you the whole mental model — what the model tracks, how the pieces fit together, what questions it can answer, and where each idea shows up in the code — without any equations. When you want the maths, the gentle maths primer builds up the equations one step at a time, and the size-structured PDE page has the full treatment.
What plant models
plant is a simulator for forests of competing plants. Given one or more plant strategies — ways of being a plant, such as cheap fast-growing leaves versus dense slow wood — it works out how a patch of ground fills with vegetation over time, how those plants shade and out-compete one another, how the stand thins and matures, and which strategies can persist over the long run.
The defining feature is that plant builds everything from the bottom up. Nothing about the forest is imposed in advance: stand structure, size distributions, self-thinning, succession, and coexistence all emerge from the growth, death, and seeding of individual plants, each responding to the light it experiences. If you change how a single plant works, the whole forest that grows out of it changes too.
That makes plant useful for questions like:
- How does a patch of forest develop from bare ground to mature stand?
- How do plants with different traits compete, and who wins where?
- What mix of strategies can coexist in a disturbed landscape?
- Which trait values are evolutionarily stable — the “best” way to be a plant in a given environment?
The core idea: traits, not species
plant does not think in terms of named species. It thinks in terms of functional traits — measurable properties that shape how a plant grows and survives. A “strategy” is just a choice of trait values.
The default FF16 model is built around four key traits:
| Trait | Symbol | What it captures |
|---|---|---|
| Leaf mass per area (LMA) | \(\phi\) | cheap, thin, short-lived leaves ↔︎ tough, dense, long-lived leaves |
| Wood density | \(\rho\) | light fast-growing wood ↔︎ dense durable wood |
| Seed mass | \(\omega\) | many small seeds ↔︎ few large, well-provisioned seeds |
| Maximum height | \(H_{\rm mat}\) | short understorey plant ↔︎ tall canopy tree |
The power of this approach is trade-offs. A single trait pulls on many parts of the plant’s biology at once. Cheap leaves (low LMA), for instance, are productive per gram but wear out fast — so choosing a low LMA raises both photosynthesis and leaf turnover together. plant encodes these linkages through hyper-parameterisation: you set a trait, and the model derives the whole bundle of physiological parameters that trait implies. This is why a handful of trait numbers can stand in for an entire way of life.
Three nested scales
The model is organised as three scales nested inside one another. Each scale is built out of the one below it.
- Individual — a single plant with a set of traits and a size (its height). It intercepts light, builds tissue, risks dying, and produces seeds.
- Patch — a small area of ground where many individuals grow together. They compete by shading one another, so every plant in the patch shares one common light environment. A disturbance (fire, storm, landslide…) can wipe a patch clean and reset it to bare ground.
- Metacommunity — the whole landscape: a large collection of patches, each at a different age since its last disturbance, all connected because seeds disperse freely between them.
A key simplification makes this tractable: because seeds mix across the whole landscape, one patch followed through its entire life stands in for the whole metacommunity. Simulating a single patch from bare ground to old age, and knowing how common patches of each age are, is enough to describe everything.
Two halves: biology and bookkeeping
Internally, plant separates cleanly into two parts, and it helps to keep them apart in your head.
%%{init: {"flowchart": {"subGraphTitleMargin": {"top": 8, "bottom": 14}, "padding": 12, "nodeSpacing": 45, "rankSpacing": 45}}}%%
flowchart LR
subgraph S["Strategy — the biology"]
direction TB
s1["a plant's size<br/>+ its light environment"] --> s2["growth, death,<br/>seed rates"]
end
subgraph D["Demographic core — the bookkeeping"]
direction TB
d1["rates, tracked<br/>over time"] --> d2["how the whole<br/>population changes"]
end
S -->|"rates plug in"| D
models["FF16 · K93 · TF24 · TF24f"] -.->|"pick one"| S
- The strategy is the biology. Given a plant’s size and the light it experiences, it returns three instantaneous rates: how fast the plant grows, how likely it is to die, and how many seeds it makes. This is where photosynthesis, carbon budgets, and hydraulics live.
- The demographic core is the bookkeeping. It knows nothing about photosynthesis; it just takes those rates and integrates them over time to work out how a population of plants grows, thins, and reproduces. Swap the strategy and you swap the biology; the bookkeeping stays the same.
This split is why the theory is organised into Core (the bookkeeping, shared by everything) and Models (the strategies).
Inside a strategy: a plant’s carbon economy
It is worth peeking inside the “biology” box, because it explains where growth, death, and seeds actually come from. In the FF16 model, all three rates trace back to a single quantity: the net biomass a plant produces each year.
flowchart LR
L["Light captured<br/>by leaves"] --> P["Photosynthesis<br/>(income)"]
P --> B["Net biomass<br/>= income − respiration<br/>− tissue turnover"]
B --> SPLIT{"How to<br/>spend it?"}
SPLIT -->|"mostly when young"| G["Build tissue →<br/>grow taller (g)"]
SPLIT -->|"more when mature"| F["Make seeds (f)"]
B -.->|"low production<br/>raises risk"| D["Mortality (d)"]
A plant earns carbon by photosynthesising, pays it back through respiration and the constant turnover of leaves and roots, and invests whatever is left. Young plants spend that surplus on growing taller (chasing light); as they approach their maximum height they divert more of it into seeds. And a plant whose production runs low — because it is shaded, say — faces a higher chance of death. That single carbon budget, sketched above, is the engine behind every individual in the model. The FF16 page and the assimilation & hydraulics page give the full detail.
Meet the strategies
plant ships with a small family of interchangeable strategies:
- FF16 — the default. A detailed, trait-based carbon economy (the one sketched above). Start here unless you have a reason not to.
- K93 — Kohyama’s 1993 model. Growth, death, and fecundity are written as direct functions of stem diameter and stand basal area, with no explicit carbon budget. A compact, fast, “phenomenological” strategy.
- TF24 — extends the leaf model with explicit plant hydraulics and stomatal behaviour: the plant chooses how much to open its stomata to balance carbon gain against the risk of drying out. Use it when water and drought matter.
- TF24f — a faster variant of TF24. Instead of re-solving the leaf’s optimal state from scratch at every step, it lets that state acclimate over time, tracking a changing environment with a short lag. Same hydraulics, cheaper to run.
You can also write your own — the demographic core will run it unchanged.
What the model tracks: cohorts and the size distribution
Inside a patch, plant does not follow every individual plant separately. Instead it tracks a size distribution: how many plants of each height are present in the patch at a given age. Early on the distribution is a dense crowd of tiny seedlings; as the patch ages it spreads out, thins, and a few tall winners pull ahead.
The clever part is how it follows that distribution. Rather than chopping height into fixed bins, plant tracks a handful of cohorts — groups of plants that germinated at the same moment — and lets each one ride its own growth trajectory upward.
flowchart LR s1["seed pulse<br/>at age 0"] --> c1["cohort 1<br/>rises in height"] s2["seed pulse<br/>at age 5"] --> c2["cohort 2<br/>rises behind it"] s3["seed pulse<br/>at age 20"] --> c3["cohort 3"] c1 --> canopy["tall, sparse<br/>survivors"] c2 --> mid["mid-canopy"] c3 --> under["shaded<br/>understorey"]
Each cohort is a moving point on the height axis, carrying a “how many plants are here” density with it. Following a few well-placed cohorts is far cheaper than resolving the whole distribution on a grid, yet it stays accurate — this is the characteristic method, and the number and timing of cohorts is chosen automatically. (The characteristic method and node-spacing pages cover the machinery.)
Competition is a feedback loop
Everything interesting in plant comes from one feedback loop. Plants deploy leaf area; leaf area casts shade; shade changes the light every plant experiences; and that light feeds straight back into how fast each plant grows and how likely it is to survive.
flowchart LR A["Plants deploy<br/>leaf area"] --> B["Canopy casts shade —<br/>the light environment"] B --> C["Less light below<br/>slows growth,<br/>raises mortality"] C --> D["Size distribution<br/>shifts: some win,<br/>some die"] D --> A
Because taller plants shade shorter ones but not vice versa, competition for light is asymmetric — a small head start compounds. This one loop is what produces self-thinning (crowded stands shed stems as they grow), succession (the mix of winners changes over time), and the layered vertical structure of a real forest — none of it built in by hand.
Disturbance and the patch mosaic
No patch lasts forever. Fires, storms, landslides, and other disturbances periodically reset a patch to bare ground. Because these strike at random across the landscape, at any moment the landscape is a mosaic of patches of every age — some freshly cleared, some mid-succession, a few very old.
plant summarises this mosaic with a single number: the mean interval between disturbances. From it, the model works out how common patches of each age are. Young patches are common (most patches have been disturbed fairly recently); very old patches are rare (they have usually been reset before reaching old age). This age distribution is what lets a single simulated patch represent the whole landscape: to average over the metacommunity, you average over patch age, weighting by how common each age is.
Paying for itself: the birth-rate loop
There is one more loop, at the landscape scale. Seeds produced in patches disperse across the whole metacommunity and rain back down to start new plants. For the metacommunity to be at equilibrium, a strategy must pay for itself: the seeds it exports over a patch’s lifetime must match the seeds arriving to sustain it.
plant finds that balance by solving a fixed point — guessing a seed-arrival rate, running a patch to see how many seeds come back out, and adjusting until the two agree.
flowchart LR
A["Guess a seed-<br/>arrival rate"] --> B["Run one patch<br/>through its whole life"]
B --> C["Count the seeds<br/>it exports"]
C --> Q{"exported =<br/>assumed?"}
Q -->|"no"| E["Adjust the rate"]
E --> B
Q -->|"yes"| F["Equilibrium —<br/>the strategy<br/>pays for itself"]
This is exactly what happens when you call run_scm(..., refine_schedule = TRUE) in the guides. A strategy that cannot export as many seeds as it consumes is, in the long run, a loser — it dwindles toward extinction. One that produces a surplus can spread. That observation is the doorway to the deepest question the model was built for.
The big payoff: which strategies win?
Once you can find the self-consistent birth rate for a resident community, you can ask whether a rare mutant with slightly different traits could invade it. You drop a handful of the mutant’s seeds into the landscape without letting them change the light environment (they are too rare to matter yet), and ask: over its lifetime, does one seed produce more than one seed in return?
- More than one → the mutant grows in number; it can invade.
- Fewer than one → the mutant fades out; the resident holds.
This per-seed return is the model’s measure of invasion fitness. By scanning across trait values, you can map which strategies beat which, and find the special trait values that no mutant can invade — the evolutionarily stable strategies (ESS), the model’s prediction for how plants “should” be built in a given environment. This is the subject of the adaptive dynamics page, and it is where trait-based thinking pays off: the winners are not named species but positions in trait space.
What you can measure: emergent properties
Because the forest is built from the bottom up, a huge range of stand- and landscape-level patterns fall out of a run as emergent results — you read them off, you don’t program them in:
- Self-thinning — the classic size–density line, stems lost as they grow (see the self-thinning guide).
- Stand structure — height and density profiles, canopy layering, leaf-area distribution through the canopy.
- Biomass and its allocation — total and per-tissue (leaf, sapwood, bark, heartwood) mass through time.
- Succession & coexistence — which strategies dominate when, and which combinations can persist together.
- Metacommunity averages — landscape-scale means obtained by integrating patch outputs over the age distribution (see emergent properties).
The life of a simulation
Putting it together, a typical plant run moves through these stages — and each maps onto a step in the guides:
flowchart TB A["1 · Choose a strategy<br/>and trait values"] --> B["2 · Set the environment<br/>(light, rainfall)"] B --> C["3 · Seed a patch and<br/>grow it from bare ground"] C --> D["4 · Plants grow, shade<br/>each other, thin and die"] D --> E["5 · Find the birth rate<br/>that balances (equilibrium)"] E --> F["6 · Read off outputs:<br/>structure, biomass, fitness"]
The worked example walks through exactly this arc end to end.
From idea to code
Each concept above has a direct counterpart in the package:
| Idea | In plant |
Guide |
|---|---|---|
| Pick a strategy & its traits | scm_base_parameters("FF16"), trait_matrix(), add_strategies() |
Strategies & traits |
| Set the light / rainfall environment | Environment() |
Extrinsic drivers |
| Grow a single plant | FF16_Individual() |
Your first individual |
| Run a patch through its life | run_scm() |
Patch dynamics |
| Find the birth rate that balances | run_scm(..., refine_schedule = TRUE) |
Self-thinning |
| Tidy & expand the outputs | collect = TRUE, expand_state() |
Example analysis |
A quick glossary
| Term | In plain words |
|---|---|
| Strategy | A way of being a plant — a set of trait values and the biology they imply. |
| Trait | A measurable plant property (LMA, wood density, seed mass, max height) that shapes growth and survival. |
| Individual / node / cohort | A group of same-aged plants, tracked together as a point moving up the height axis. |
| Patch | A stand of competing plants sharing one light environment; reset by disturbance. |
| Size distribution | How many plants of each height are present in a patch of a given age. |
| Light environment | How much light reaches each height in the canopy — the medium of competition. |
| Metacommunity | The whole landscape: a mosaic of patches of every age, linked by dispersing seeds. |
| Birth / seed rain | The rate at which a strategy’s seeds arrive in a patch. |
| Equilibrium | The state where seeds exported match seeds arriving — the strategy pays for itself. |
| Invasion fitness | The per-seed return of a rare mutant; > 1 means it can invade. |
| Emergent property | A stand- or landscape-level pattern that falls out of the simulation rather than being programmed in. |
Where to go next
Pick the path that matches what you want to do:
- I want to run it. Head to the guides — start with your first individual, then patch dynamics.
- I want to understand the equations. Read the gentle maths primer next, then the full size-structured PDE and adaptive dynamics pages.
- I want a strategy’s biology. See the models overview, the FF16 model, and the assimilation & hydraulics page.