lotus is an experimental, vectorized evolutionary ecology simulator.
The goal is to explore population dynamics on large grids where every organism has compact DNA that compiles into behavior-relevant traits: resource use, movement preferences, environmental tolerance, reproduction strategy, mutation rate, and mating compatibility. The design keeps organism behavior as shared array math parameterized by genomes, so the simulator can scale before it grows more biologically expressive.
- Vectorized grid simulation with NumPy-first data structures.
- Compact genomes that compile into phenotype arrays.
- Resources and terrain as named grid channels, not hardcoded assumptions.
- Reproduction through replication first, with sexual recombination support.
- Emergent species as an analysis layer based on genome, phenotype, lineage, and reproductive compatibility.
- Experiment metadata that keeps titles, hypotheses, owners, and tags attached to generated artifacts.
- Run artifacts and state snapshots that power API/web configuration, visualization, and analysis workflows.
src/lotus/ Python simulation package
tests/ Deterministic tests for core behavior
examples/ Small runnable experiments and visualization scripts
configs/ TOML world/run configurations
docs/ Architecture notes and roadmap
apps/api/ FastAPI run launch, catalog, and artifact API
apps/web/ React workbench for monitoring, analysis, and config editing
Use the existing conda environment:
conda run -n blossom python -m pip install -e .Optional extras are declared for later work:
conda run -n blossom python -m pip install -e ".[viz,data,web,dev]"The API uses the web extra. Add viz when API-launched runs should generate
static reports and images:
conda run -n blossom python -m pip install -e ".[web,viz]"
conda run -n blossom uvicorn apps.api.main:app --reloadRun the browser workbench:
cd apps/web
npm install
npm run devRun the tests:
conda run -n blossom pytestGenerate a starter config and machine-readable schema:
conda run -n blossom lotus config --template --output configs/local.toml
conda run -n blossom lotus config --schema --output docs/config.schema.json
conda run -n blossom lotus config --validate configs/local.tomlThe API and browser config editor use the same schema. The web app can load
TOML presets from configs/, validate the resulting JSON payload, and launch
single runs or deterministic seed-replicate ensembles through the API.
Estimate scale before launching larger studies:
conda run -n blossom lotus plan run \
--config configs/speciation_lab.toml \
--steps 500 \
--snapshot-interval 25
conda run -n blossom lotus plan sweep \
--config configs/speciation_lab.toml \
--param simulation.reproduction_cost=4.0,6.0,8.0 \
--replicates 3 \
--jsonRun a research-style experiment:
conda run -n blossom lotus run \
--config configs/tidepool.toml \
--run-name tidepool-demoRun a denser sexual-reproduction experiment:
conda run -n blossom lotus run \
--config configs/speciation_lab.toml \
--run-name speciation-demoInspect the resulting run directory:
conda run -n blossom lotus inspect runs/tidepool-demoValidate artifacts before analysis:
conda run -n blossom lotus validate runs/tidepool-demo
conda run -n blossom lotus validate runs/reproduction-water-sweepRegenerate the notebook handoff index for a run:
conda run -n blossom lotus index runs/tidepool-demo
conda run -n blossom lotus index runs/reproduction-water-sweepRegenerate the static HTML report for a run:
conda run -n blossom lotus report runs/tidepool-demoExport a portable artifact bundle:
conda run -n blossom lotus bundle runs/tidepool-demo
conda run -n blossom lotus bundle runs/reproduction-water-sweep \
--output runs/reproduction-water-sweep.zipRender saved snapshots and write replay media:
conda run -n blossom lotus render \
runs/tidepool-demo \
--mode ecotypes \
--animate \
--cell-size 4
conda run -n blossom lotus render \
runs/tidepool-demo \
--mode water_depth \
--video \
--no-frames \
--contour-layer density \
--contour-levels 7 \
--fps 24 \
--cell-size 4For full step-by-step browser playback, set [run].snapshot_interval = 1
before launching the run. Coarser intervals keep artifacts smaller but replay
only the saved frames. MP4/WebM export requires ffmpeg on PATH; in the
project environment use conda install -n blossom -c conda-forge ffmpeg.
Compare multiple completed runs:
conda run -n blossom lotus compare \
runs/tidepool-demo \
runs/speciation-demo \
--output-dir runs/comparisons/tidepool-vs-speciationSummarize the strongest selection proxy signals for a completed run:
conda run -n blossom python examples/analyze_selection.py \
runs/speciation-demo \
--top 8Run deterministic seed replicates as an ensemble:
conda run -n blossom lotus ensemble \
--config configs/speciation_lab.toml \
--replicates 4 \
--ensemble-name speciation-replicatesSummarize ensemble-level metric variation and selection signals:
conda run -n blossom python examples/analyze_ensemble.py \
runs/speciation-replicates \
--top 8Run a hypothesis-driven parameter sweep with matched seed replicates:
conda run -n blossom lotus sweep \
--config configs/speciation_lab.toml \
--param simulation.reproduction_cost=4.0,6.0,8.0 \
--param world.water_level=0.35,0.50 \
--replicates 3 \
--sweep-name reproduction-water-sweepCatalog accumulated runs, ensembles, and sweeps:
conda run -n blossom lotus catalog runs \
--validate \
--output runs/catalog.json \
--csv runs/catalog.csvMeasure throughput for a config:
conda run -n blossom lotus benchmark \
--config configs/tidepool.toml \
--steps 40 \
--repeats 3 \
--output runs/tidepool-benchmark.jsonSee docs/performance.md for current local benchmark results, normal-run timing fields, and scale limits.
Run an emergent predator-prey lab from the grid simulator:
conda run -n blossom lotus run \
--config configs/predator_prey_lab.toml \
--overwriteThis uses DNA-expressed predation drive, efficiency, and defense with local
same-cell encounters. Inspect prey_count, predator_count,
predation_events, trophic trait timelines, and the scaled Lotka-Volterra
reference in metrics.csv, trait_timeline.csv, the static report, or the web
Monitor and Analysis views. The preset is tuned for a visible delayed trophic
wave: a deterministic seed-41 calibration run produced prey counts from 418 to
2,691, predator counts from 18 to 689, and an observed predator lag of roughly
24 steps.
Generate a direct deterministic Lotka-Volterra reference curve:
conda run -n blossom lotus lotka-volterra \
--steps 160 \
--output runs/lotka_volterra.csv \
--plot runs/lotka_volterra.pngThis writes the classic ODE trajectory (alpha, beta, gamma, delta) to
CSV and optionally plots prey/predator cycles. Use it as the canonical baseline
when comparing emergent grid runs, or when you want the famous differential
equation behavior directly rather than an organism-level approximation.
Run a small compatibility demo and save only a final frame:
conda run -n blossom lotus-demo --steps 80 --output runs/demo.pngOr run the example directly:
conda run -n blossom python examples/quickstart.pyThis is an initial scaffold with a working vectorized simulation loop:
- Terrain/resource grid generation.
- Struct-of-arrays organism state.
- Genome-to-phenotype compilation.
- Resource uptake with per-cell contention.
- DNA-informed local movement.
- DNA-informed temperature/water tolerance and environmental stress costs.
- DNA-informed mate selectivity and genetic-distance sexual compatibility.
- DNA-informed local predation with predator/prey metrics and predation energy accounting.
- Asexual replication and local sexual recombination.
- Mutation, death, resource regeneration, diffusion, and basic analysis helpers.
- Per-step research metrics including genetic diversity, ecotypes, lineages, and resource means.
- Per-step phenotype distribution, energy-selection proxy, and aggregate trait-selection summary artifacts for tracking how DNA-expressed traits move through a run.
- Predator/prey lab preset at
configs/predator_prey_lab.toml. - Per-run, per-step, and compact performance summary artifacts for elapsed seconds, step time, steps/sec, and organism updates/sec.
- Durable run directories with manifests, JSONL/CSV metrics, performance
summary CSVs,
.npzsnapshots, lineage event CSVs, ecotype timelines, trait-selection summaries, final ecotype profiles, analysis indexes, and rendered PNGs. - Run manifests include runtime, package, path, and git provenance.
- Configured experiment metadata is stored in manifests, catalog exports, API responses, and the web run list.
- Run validation checks required artifacts and internal summary/count consistency before downstream analysis.
- Ensemble and sweep validation checks grouped manifests, child runs, comparison outputs, ensemble/sweep reports, ensemble metric summaries, sweep effects tables, group evolution summaries, group performance summaries, and group selection summaries.
- Static HTML run reports with summary cards and metric plots.
- Matplotlib-based state rendering for density, resources, ecotypes, and composite state.
- Snapshot replay rendering and animated GIF/MP4/WebM export.
- API/browser snapshot projections for density, energy, lineage richness, terrain, water, temperature, and named resources.
- Browser replay controls for saved snapshots with selectable scalar layers, contour overlays, active-layer value scales, and summary stats.
- Multi-run comparison reports with final metric tables and timeline plots.
- API/web interactive multi-run comparisons with final metric tables and overlaid timelines.
- Deterministic replicate ensembles with per-run validation,
ensemble_metrics.csv,ensemble_report.html, group evolution summaries, group performance summaries, group selection summaries, and comparison outputs. - Cartesian parameter sweeps with matched seed replicates, per-run validation,
sweep_manifest.json,sweep_effects.csv,sweep_report.html, group evolution summaries, group performance summaries, and all-run comparison outputs. - API/web launch controls and analysis dashboards for deterministic seed-replicate ensembles and parameter sweeps.
- API-launched jobs expose step/replicate progress counters and latest run population/energy metrics for monitor dashboards.
- API job history is persisted under the configured runs root and recovered across API restarts.
- Deterministic ZIP artifact bundles for run, ensemble, and sweep handoff through CLI, API, and web artifact links.
- Artifact cataloging for run discovery, validation summaries, and JSON/CSV export.
- Repeatable benchmark command for steps/sec and organism-updates/sec measurements.
- Emergent predator-prey preset with DNA-expressed predation traits, local same-cell attacks, trophic metrics, predator/prey report plots, and a scaled Lotka-Volterra reference overlay plus phase-space plot in the web monitor.
- Config template, strict validation, TOML preset, and JSON schema helpers for CLI, API, and web configuration flows.
- Versioned model controls for genome expression ranges, sexual compatibility metrics/kernels, recombination, mutation distribution, and ecotype binning.
- FastAPI boundary for API-launched runs and ensembles, config schema, job status, run catalogs, validation, metrics, analysis CSVs, and artifact files.
- React workbench for live run monitoring, dedicated analysis views, and schema-driven config editing with preset loading, live validation, and API run submission.
- Web Docs view with a curated scientific guide and rendered project documentation exposed through whitelisted API endpoints.
- Notebook-friendly
analysis_index.jsonfiles and API payloads that summarize artifact paths, table columns, row counts, snapshots or child runs, metadata, validation, storage footprint, provenance, and grouped execution settings. - Web Analysis view renders that analysis index as a notebook handoff panel alongside diversity, ecotype timeline, reproduction event, genome embedding, and ecotype profile views.
Configuration files can include [metadata], [world], [genetics],
[simulation], [reproduction], [analysis], and [run] sections. CLI flags
override [run] values, which keeps local
experiments and future web/API-driven runs on the same schema.
Unknown sections or fields are rejected during parsing so typos fail before a
simulation starts.
World configs can also tune the initial energy range, which is useful for
experiments that should enter reproduction quickly.
Lineage tracking distinguishes organism_id from lineage_id: every birth gets
a unique organism ID, while asexual replication preserves lineage ID and sexual
recombination creates a new lineage. Run artifacts include lineage_events.csv
so ancestry can be analyzed after the simulation, plus ecotype_timeline.csv
for stable provisional species/ecotype tracking across steps.
Final runs also include ecotype_profiles.csv, which summarizes each final
ecotype's phenotype, lineage diversity, location, and local resource context.
ecotype_resource_niches.csv expands those profiles into one row per
ecotype/resource pair with DNA-expressed affinity, toxicity, local availability,
and net resource opportunity.
ecotype_compatibility.csv compares final ecotype genome centroids with the
configured mate distance metric and compatibility kernel, providing a lightweight
reproductive isolation matrix for provisional species analysis.
species_candidates.csv clusters final ecotypes into candidate species complexes
when their centroid compatibility exceeds
analysis.species_compatibility_threshold.
species_timeline.csv retrospectively maps per-step ecotype abundance records
into those final candidate species, making candidate species growth and
persistence inspectable over time.
genome_embedding.csv adds one final row per organism with PCA coordinates,
ecotype ID, lineage ID, position, energy, and compact phenotype fields for
scatter plots and downstream clustering.
Sexual births also record mate_compatibility, and per-step metrics include
reproductive_isolation_index so divergence can be measured over time.
Sweeps use dotted config paths such as simulation.reproduction_cost and
world.water_level. Each parameter combination becomes a validated config
variant, and replicate seeds are reused across variants so metric differences
are easier to attribute to the swept parameters. Sweep effect rows include both
group mean deltas and paired current-minus-baseline deltas matched by seed and
the other swept parameter values, with deterministic normal-approximation 95%
confidence intervals for group means and paired deltas.
See docs/architecture.md and docs/roadmap.md for the intended direction.