Evolutionary Laboratories

Welcome — start here.

Welcome to the Evolutionary Laboratories. On these pages you can use interactive simulations to explore evolutionary mechanisms and processes in an intuitive, hands-on way.

How to use the rooms

Every room follows the same pattern: set the parameters with the sliders and buttons at the top, press Run (or Start), and read the panels that fill in below. Nothing is precomputed — each run is a fresh simulation, so running the same settings twice will not give the same result: these are random processes, and the parameters set tendencies, never outcomes.

Two features are worth knowing about before you start:

  • The History Scrubber at the bottom of each room lets you drag back through a finished run and replay any generation. Nothing is lost when a run ends.
  • The small red ? buttons beside a control or a panel explain what it does, what the numbers mean, and what to look for. If something on screen is unclear, there is usually a ? next to it.

The five rooms build on each other. The first two use shapes to make the idea of accumulated change visible; the middle two introduce the actual population-genetics machinery with alleles; the last one puts both together. Working through them in order is recommended, but each room stands on its own.

01The Copying Room

Mutation & accumulated change

What it shows. A single starting figure is copied over and over. Every copy introduces a small random error — no error is large, and none of them is aimed at anything. You can run up to 100 lineages side by side, all starting from the identical same figure.

Try this. Set 2 lineages and press Start copying. Watch the two shapes, which began identical, slowly stop resembling each other. Then set the mutation size to its smallest value and run it again for many generations. Finally, switch to 100 lineages to see the whole cloud of possibilities at once.

What to notice. There is no selection here and no goal — yet the shapes still change, and they change in different directions. The divergence readout (Δ) climbs steadily. This is the base fact all the other rooms build on: copying is imperfect, it introduces mutations, which are not bad or good per se.

→ Open the Copying Room

02The Branching Room

Divergence & speciation

What it shows. The same copying process, but now lineages split. One ancestor becomes two independent lineages, each of which keeps drifting on its own and may split again. You choose when the splits happen by dragging the marks on the little tree diagram.

Try this. Run it once with the default splits. When it finishes, scroll to the Tanglegram at the bottom: on the left is the true history you just watched, on the right is the family tree an algorithm reconstructs using only the final shapes. Compare them. Then drag the splits so they all happen close together and run it again.

What to notice. The reconstructed tree often disagrees with the real one. Lineages that happened to drift very little can look like close relatives even when they separated long ago, and a fast-changing lineage can look like an outsider. This is the central problem of real phylogenetics: similarity is not the same thing as ancestry.

→ Open the Branching Room

03The Drift Room

The Wright–Fisher model

What it shows. This is where the real population genetics starts. A population of N individuals carries two alleles, A and B. Each generation is built by randomly sampling the previous one — the spinning wheel makes a single draw, and a full generation means one draw per gene copy. Nobody has any advantage; the only force at work is chance.

Try this. Run the default settings and watch the first three generations sample one individual at a time. Then set N = 10 and run, and afterwards set N = 200 and run again with everything else unchanged. Finally press Run 10 Simulations to see ten independent populations at once.

What to notice. Small populations lurch around and quickly end up with only one allele left; large populations barely move, but will eventually also fix an allele, although after more generations. In fact, one important point to note is that in evolution time is measured in generations, not years. Once an allele reaches 0 or 1 it can never come back — drift permanently destroys variation. And across ten identical runs the outcomes differ wildly, which is why a single run can never tell you what a random process "does".

→ Open the Drift Room

04The Selection Room

Wright–Fisher + selection

What it shows. Exactly the same sampling machinery as the Drift Room, with one addition: allele A now carries a fitness advantage s. Before each generation is drawn, the frequency is reweighted by fitness — so selection tilts the odds, and then ordinary random sampling does the drawing. Under diploid settings you can also set dominance h.

Try this. Run with s = 0.1 at N = 200, and notice how closely the real trajectory tracks the dashed line (which is what selection would do with no randomness at all). Then run the same s = 0.1 at N = 10. Finally switch to Diploid, set s = 0.2, and compare h = 1 against h = 0.

What to notice. What matters is not s by itself but N·s — the product of population size and advantage. In a small population, drift regularly overwhelms a genuine fitness advantage and loses it. And a recessive advantageous allele (h = 0) is nearly invisible to selection while it is rare, because it is hiding inside heterozygotes, so it too can be lost like a neutral allele.

→ Open the Selection Room

05The Adaptation Room

Multi-trait selection vs. drift

What it shows. Everything so far, combined. Three founder fish — Gigi, Mario and Nani — each split into two lineages: a Neutral one where nothing is selected, and a Habitat one assigned to a Stream, Pond or River. Five traits (shape, colour, eye size, fin size, tail size) each behave as an independent gene, mutating and then running a full Wright–Fisher trajectory exactly as in the Selection Room. Each habitat favours a different combination of traits.

Try this. Press Run and watch the two lineages of each founder evolve side by side from the same ancestor. When it finishes, compare the Average divergence from own founder for Neutral versus Habitat. Then assign the same habitat to two different founders and run again. As a control, open More parameters and set every selection coefficient to 0.

What to notice. The Habitat lineages travel much further from their ancestor than the Neutral ones — that gap is what selection contributes on top of drift. Two unrelated founders placed in the same habitat tend to converge on a similar look, which is convergent evolution. And in the trait tables, both lineages accumulate a similar number of mutations; selection's real effect is on how many of them become substitutions.

→ Open the Adaptation Room

A note on this beta

This is a beta version and may still contain bugs — we're continually working to improve each room. If you run into problems, have questions, or have suggestions, please get in touch with Lino Ometto at lino.ometto@unipv.it.

Acknowledgements

These laboratories were conceived and directed by Lino Ometto, who set the scientific content, the pedagogical design, and the choices behind every model. The simulation code, interface, and explanatory texts were written collaboratively with Claude, Anthropic's AI assistant, working through Claude Code.

The Copying Room

Descent with modification – One shape is copied by hand, again and again. Each copy is drawn from the last one, with a small, honest mistake. Nothing is steered toward a goal — the changes simply pile up.

gen 0 / 100 — idle

Press Start copying to watch generation 0 begin its journey. Each lineage starts from the exact same figure — any difference you see later came from nowhere but accumulated copying error.

Pairwise divergence

The Branching Room

Divergence & speciation – One ancestor, copied and mutated generation after generation, occasionally splits into two independent lineages. Neither split is steered toward any goal — each new branch just keeps drifting on its own.

gen 0 / 500 — idle
Lineage colours  ·  Cards & split snapshots

The Drift Room

Wright–Fisher model – Simulating allele frequencies in a finite population over generations. Each generation is a random sample drawn from the previous one. Over time, random variance causes alleles to drift toward fixation or loss.

Configure parameters and press Run.
Sampling Wheel
Generation0
Ind. drawn
Freq f(A)
Current Population Allele A    Allele B
Allele Frequency (f) over Generations
Binomial Distribution P(k | N, f)E[k] = N·f = · O[k] =
Binomial Variance V = f·(1−f) / N
Fixation & loss

The Selection Room

Wright–Fisher model + selection – The same finite-population sampling as the Drift Room, but allele A now carries a fitness advantage: individuals carrying it are more likely to be copied into the next generation. Watch how selection strength (s) and population size (N) compete with random drift.

Configure parameters and press Run.
Sampling Wheel
Generation0
Ind. drawn
Freq f(A)
Δf (selection shift)
Current Population Allele A    Allele B
Allele Frequency (f) over Generations
Binomial Distribution P(k | N, f′)E[k] = N·f′ = · O[k] =
Binomial Variance V = f·(1−f) / N
Fixation & loss

The Adaptation Room

Multi-trait selection vs. drift – Three founder fish — Gigi, Mario, and Nani — each split into a neutral lineage and a habitat-assigned lineage. Five traits (shape, colour, eye size, fin size, tail size) each mutate and fix independently under selection + drift, exactly as in the Selection Room, one trait "locus" at a time. Watch whether habitat-driven selection reaches a characteristic look faster, and more reliably, than drift alone.

More parameters (mutation size, selection & mutation rate per trait, population size)
N
Configure parameters and press Run.
Each row compares one founder's Neutral and Habitat lineage, both starting from the same ancestor. The fish shown is that lineage's consensus — its typical individual
Gigi
Ancestor - G0
Mario
Ancestor - G0
Nani
Ancestor - G0

Final divergence matrix (Δ, 0.00 = identical): generation-0 founder (rows) vs. each lineage's final consensus fish (columns).

Average divergence from own founder:

Tanglegram Comparison:
Left: the actual lineage history — Gigi, Mario, and Nani arise independently (a root polytomy, not a nested split), each then dividing into a Neutral and a Habitat lineage. Right: the phylogenetic tree inferred by UPGMA clustering using only the six lineages' final observable shapes. Notice any discrepancies?