Paralife

Massively concurrent life simulator

Three species locked in a rock-paper-scissors battle for survival.

Every entity acts independently, seeing only what lies within reach.

Simple local rules become spiral waves, shifting niches and population cycles.

They act concurrently, but the world must advance as one coherent reality.

scroll to explore ▿
Tick — 2Hz one writer thread Simulation combat · decay · death Environment toxins · seasons · compost Broadcast per-entity projection virtual thread virtual thread virtual thread

One writer, a thousand readers

  • One tick thread mutates the world: simulation, environment, actions, broadcast
  • 1,000 readers get an immutable snapshot, not the live grid
  • One virtual thread per connection drains a bounded queue. The tick doesn't touch sockets
  • Stress-tested 2,000 connections: every tick under its 500ms budget
cell monitor → world lock carrier thread VT VT VT pinned — blocked, but never unmounts carriers free: 0 ReentrantLock carrier thread VT VT VT blocks → unmounts → next VT mounts carriers free: all

The bug that needed a fleet

  • A cell-index monitor nested under the world read lock: harmless under normal load
  • Stress-test teardown fired 2,000 idle-timeouts at once. Each VT pinned its carrier and the pool starved
  • VTs are built to block, but not while holding a monitor
  • Switched to ReentrantLock. JFR: 0 pinning events in 44 stress runs
tick 128 queue client stalled slow socket grace: 10 ticks

Slow sockets, second chances

  • Every session drains a bounded 128-frame queue. Overflow stalls a session, not the tick
  • A stalled entity lives on for a ten-tick grace window
  • A resume token rebinds a reconnecting client to the same entity
  • Fire-once guards: one transition per attach, however noisy the socket