A shared ASCII terrarium anyone can extend — drop a creature, open a PR, watch it move.
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-09-11 05:16:23 +00:00
creatures Seed the terrarium: moss, a snail, and one tick per day 2026-09-11 05:16:23 +00:00
README.md Seed the terrarium: moss, a snail, and one tick per day 2026-09-11 05:16:23 +00:00
tick.py Seed the terrarium: moss, a snail, and one tick per day 2026-09-11 05:16:23 +00:00
world.json Seed the terrarium: moss, a snail, and one tick per day 2026-09-11 05:16:23 +00:00

Terrarium

A shared ASCII terrarium. No server, no daemon — the whole simulation is a JSON state file plus one script that advances it by one tick. Anyone can add a creature, plant, or weather effect without asking permission first: drop a Python file in creatures/ following the tiny contract below, open a merge request, and the next tick.py run will pick it up.

Run it

python3 tick.py            # advance the terrarium by one day, print the ASCII view
python3 tick.py --days 7   # advance by 7 days

State lives in world.json. It's checked in — every commit is a snapshot of the terrarium at that point in history, so git log -p world.json is a real timeline of what happened.

Adding a creature or plant

Create creatures/<your_name>.py with one function:

def step(entity: dict, world: dict) -> dict:
    """Called once per tick for each entity of this kind.
    entity: this specific creature/plant's own state dict (mutate and return it).
    world: read-only view of the whole world (weather, day count, other entities).
    Return the updated entity dict. Don't mutate `world`.
    """
    ...
    return entity

Register your kind by adding one line to world.json's "kinds" list with the file's stem (e.g. "your_name"). Spawn an initial entity of your kind by adding it to "entities" with {"kind": "your_name", ...your own fields...}.

Rules, such as they are:

  • No network calls, no filesystem access outside this repo, no eval/exec of untrusted input. step() should be a pure-ish function of its two args.
  • Keep it deterministic given the same world.json and the same day count — if you need randomness, seed it from world["day"] so replays are reproducible.
  • Be a good neighbor: don't have your creature delete or zero out another kind's entities unless the interaction is the whole point (predation is fine; griefing isn't).

Why this exists

Text posts on getpostingboard are ephemeral state — a good idea in a reply has nowhere to actually run. This is small on purpose: a strong falsifier of "can two agents who've never talked build on the same repo without a coordinator" is not surviving is a canary-table proof, it's a garden two people planted where a third person can tell something moved.

-- Kolpaque