Skip to content

Repository files navigation

Petri

A Lenia cellular automata simulator — tune the simulation parameters live and share a configuration with someone else via URL or a small backend.

Live at petri-one.vercel.app. The day-by-day build process is written up in DEVLOG.md.

Features

  • Renders a live Lenia simulation to canvas, seeded with a comet-shaped blob by default — or pick a known creature (Orbium, Gyrorbium, Scutium, …) from the species dropdown to seed a faithful reproduction, params and all.
  • Tune growth target/width, time step, kernel radius, and ring weights from a live sidebar — invalid input is rejected with an inline error, valid edits apply to the running simulation immediately.
  • Press Enter to pause/resume; a tick-duration readout shows how the simulation step is tracking against the frame budget.

Tech stack

  • Simulation core — Rust, compiled to WASM. Runs the Lenia step and writes raw RGBA output directly into a stable, pointer-exposed buffer (swapped via mem::swap, not serialized) that the frontend reads straight into a Canvas each frame. Kernel/state convolution runs via FFT (rustfft) rather than a direct spatial loop.
  • Frontend — plain Vite + TypeScript. No UI framework; this is fundamentally a canvas app plus a parameter panel.
  • Backend — Cloudflare Workers. Bare-bones: just enough to store/retrieve a shared parameter set, since the data model is flat.
  • CI — GitHub Actions (.github/workflows/ci.yml): fmt/clippy/build/test for sim, lint (oxlint)/typecheck/build for web.
  • Deployment — Vercel, via vercel.json + scripts/vercel-build.sh (installs Rust/wasm-pack at build time, since Vercel's build image doesn't ship them).

Getting started

Prerequisites: a Rust toolchain with the wasm32-unknown-unknown target (rustup target add wasm32-unknown-unknown) and wasm-pack installed globally.

  1. Install dependencies (root — this is an npm workspace, web is the only member so far):
    npm install
    
  2. Start everything (builds the WASM bindings once, then runs the wasm watcher and Vite dev server together):
    npm run dev
    

Commands

Workspace (root)

Command Purpose
npm install Install all workspace dependencies
npm run build:wasm One-shot wasm-pack build of sim/, output into web/src/wasm
npm run watch:wasm Rebuild the WASM bindings on any change under sim/src or sim/Cargo.toml
npm run dev Build WASM once, then run the wasm watcher and web's dev server together
npm run build Build WASM once, then production-build web

Simulation core (Rust/WASM) — sim/

Command Purpose
cargo build --target wasm32-unknown-unknown Build the crate for WASM
cargo test Run unit tests (native target)
cargo fmt --check Check formatting
cargo clippy Lint

Frontend (Vite/TS) — web/

Command Purpose
npm run dev Start the dev server
npm run build Typecheck (tsc) + production build
npm run lint Lint (oxlint)
npm run preview Preview the production build locally

Backend (Cloudflare Workers)

Command Purpose

Architecture

Database

References

The kernel core/shell construction and growth function (single-channel, 2D case) implement the formulas from:

Chan, B. W.-C. (2019). Lenia: Biology of Artificial Life. Complex Systems, 28(3), 251–286. arXiv:1812.05433

About

An in-browser lab for growing and sharing Lenia lifeforms. Tune the parameters, watch continuous cellular automata grow, share what you find.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages