Commit Graph

8 Commits

Author SHA1 Message Date
Steve Biedermann 2bb369fc88 feat(ui): zoom with the wheel, pan with the middle button
The map canvas now fills its panel and draws through a view transform,
so it stays sharp at every zoom level. The wheel zooms around the
pointer, dragging with the middle button pans, and right click clears
the selection. The wheel listener is attached natively and non-passive
because Leptos delegates `wheel` to the document, where browsers ignore
`preventDefault`.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-10-12 21:02:35 +02:00
Steve Biedermann ec861de3ba docs: document the shard cluster, economy and per-shard databases
Describe the gateway and shard processes, transparent transfers, the
economy and console peers in the README. Compose creates one Postgres
database per shard and passes `SHARD_DATABASE_URL` and `SIM_SHARDS`;
the Justfile and Dockerfile use per-shard SQLite files.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-10-12 20:43:11 +02:00
Steve Biedermann 00ea5899c1 feat(ui): show markets, workplaces, carts, crops and shard borders
The map draws markets, workplaces coloured by trade, carts, merchants,
crop fields that turn gold when ripe, every home and dashed shard
borders. The side panel lists each person's job and coins and shows
economy and employment statistics. The server includes `crop_ripe` in
the state.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-10-12 20:42:11 +02:00
Steve Biedermann eac68db433 feat: run shards as separate processes behind a gateway
The server is now a gateway that starts SIM_SHARDS shard processes
(`sim shard --index I --count N ...`), each with its own database from
the SHARD_DATABASE_URL template. The gateway steps all shards in
lockstep over a /control WebSocket, publishes the entity directory and
market board between steps, merges the shards' views into one world
for the UI and routes edits to the shards they concern.

Shards send entity messages and transfers to each other directly over
/remote WebSockets; every step waits until its outgoing messages are
accepted, so nothing is in flight when the next step starts or a
snapshot is taken. Shard processes exit when the gateway goes away.

Update Picard to f88b9cb and register every other shard as a console
peer `shard-N`, so one console session can list, inspect, manage and
message the actors of all shards.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-10-12 20:29:11 +02:00
Steve Biedermann bdf819f721 feat: jobs, markets, haggling, carts and merchants
Each shard founds markets and workplaces (farms, woodcutters, quarries,
hunters, toolmakers, cartwrights). Adults are hired, commute to work,
sell their goods at the market, get paid and go home. Markets, workplaces
and carts are actors; prices follow local supply and demand and trades
are haggled. Merchants trade with markets on other shards through the
router, so they do not know whether a market is remote.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-10-12 20:10:22 +02:00
Steve Biedermann bc58855ff5 feat: shard-aware world with transparent actor transfers
Add a router that delivers actor messages locally or to the shard that
currently hosts the entity. People and animals that leave their shard's
columns depart with their full state, forward messages while in flight
and are re-admitted on the destination shard. Enlarge the default world.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-10-12 19:20:30 +02:00
Steve Biedermann 0009206a3c refactor(world)!: make Picard actors own entity state
People, rabbits, wolves and partnerships are now Picard actors that own
their state and apply their own rules (ageing, hunger and meals,
starvation, energy, breeding costs, death, birth intervals). The world
no longer keeps mirrored Vecs that were read from and written back to
generic entity actors every step; it only reaches entities through
typed messages and replies, correlated by request id through a single
inbox actor.

World-level state (terrain, resources, stockpile, houses, calendar, the
world random stream) stays in the world, and behaviour decisions stay
on the simulation thread because the Rune VM is not Send. Replies are
processed in entity order and each person has its own persisted random
stream, so runs and snapshot restores stay deterministic.

Rabbits killed by hunters no longer move or breed later in the same
tick.

BREAKING CHANGE: Picard actors are named person-<id>, rabbit-<id>,
wolf-<id> and partnership-<id> instead of entity-<id>, which changes
the paths used with the actor console.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-10-12 16:47:44 +02:00
Steve Biedermann 549cd2c283 dev: update AGENTS.md 2026-10-12 13:47:04 +02:00