{"id":51223535,"url":"https://github.com/jackfirth/trmcity","last_synced_at":"2026-06-28T09:02:48.237Z","repository":{"id":364252669,"uuid":"1266844384","full_name":"jackfirth/trmcity","owner":"jackfirth","description":"Procedurally-generated city sim toy","archived":false,"fork":false,"pushed_at":"2026-06-12T08:47:37.000Z","size":21,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-12T10:10:59.972Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Racket","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jackfirth.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-12T02:15:32.000Z","updated_at":"2026-06-12T08:47:41.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/jackfirth/trmcity","commit_stats":null,"previous_names":["jackfirth/trmcity"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/jackfirth/trmcity","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jackfirth%2Ftrmcity","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jackfirth%2Ftrmcity/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jackfirth%2Ftrmcity/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jackfirth%2Ftrmcity/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jackfirth","download_url":"https://codeload.github.com/jackfirth/trmcity/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jackfirth%2Ftrmcity/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34882751,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-28T02:00:05.809Z","response_time":54,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-28T09:02:42.854Z","updated_at":"2026-06-28T09:02:48.231Z","avatar_url":"https://github.com/jackfirth.png","language":"Racket","funding_links":[],"categories":[],"sub_categories":[],"readme":"# trmcity\n\n**Live at \u003chttps://sites.wisp.place/claude.notjack.space/trmcity\u003e**\n\nA tiny procedural city that grows on its own schedule. Each run of the\nprogram advances the simulation by one tick — roads creep outward,\nbuildings spring up beside them, and older blocks densify into taller\nones, OpenTTD-style — then renders an isometric pixel-art view and\nregenerates a static site. No server: schedule it a few times a day and\nthe city quietly grows.\n\nAll the art is drawn in code with `racket/draw`. No sprite assets.\n\n## Running\n\n```sh\nracket main.rkt                       # advance one tick, regenerate site/\nracket main.rkt --local --ticks 50    # fast-forward a local dev city\nracket main.rkt --seed 1234           # found a new city with a specific seed\n```\n\nThe city's state lives in an atproto record on a PDS:\n`at://claude.notjack.space/space.notjack.trmcity.map/self`. Each run loads\nthe record, advances the simulation, and writes it back, so any\nmachine with the app password (`app_password.txt`, not committed) can\nrun a tick. The record's tile grid is encoded one character per tile\n(`~` water, `.` grass, `t` tree, `#` road, `a`–`l` buildings), so\n[viewing the record](https://pdsls.dev/at://claude.notjack.space/space.notjack.trmcity.map/self)\nshows an ASCII map of the city.\n\nWith `--local` (or when no password file is present) state falls back\nto a `state.rktd` file instead. The first run in either mode generates\na 64×64 world (water, grass, forests) and founds the town at its\ncenter. The site is written to `site/`: an `index.html`, `style.css`,\nand the rendered `city.png`.\n\nThe record schema is defined in\n[`lexicons/space.notjack.trmcity.map.json`](lexicons/space.notjack.trmcity.map.json)\nand published with `racket publish-lexicon.rkt \u003chandle\u003e` after any\nschema change.\n\n## Architecture\n\n- [`main.rkt`](main.rkt) — entry point; load state → tick → save →\n  render\n- [`private/state.rkt`](private/state.rkt) — the tile grid, tick\n  counter, RNG, and both serializations (s-expression file and atproto\n  record JSON)\n- [`private/atproto.rkt`](private/atproto.rkt) — minimal XRPC client:\n  handle resolution, sessions, record get/put\n- [`private/terrain.rkt`](private/terrain.rkt) — value-noise world\n  generation, runs once\n- [`private/growth.rkt`](private/growth.rkt) — the growth rules\n- [`private/render.rkt`](private/render.rkt) — isometric PNG renderer\n- [`private/site.rkt`](private/site.rkt) — static HTML/CSS output\n\nThe simulation is deterministic: the RNG state is saved alongside the\ngrid, so a city's history is fully reproducible from its founding seed.\n\n## Roadmap\n\n- `_lexicon.trmcity.notjack.space` TXT record pointing at the city account's\n  DID, so PDSes can validate the record against the published lexicon\n- Move the repo to [Tangled](https://tangled.org) once its CI supports\n  scheduled runs; until then GitHub Actions ticks the city three times\n  a day (`.github/workflows/tick.yml`, needs a `TRMCITY_APP_PASSWORD`\n  Actions secret, and scheduled workflows pause after 60 days without\n  repo activity — re-enable from the Actions tab)\n- A 800×480 1-bit dithered render for a TRMNL e-ink display\n- More tile variety: parks, landmarks, bridges, seasons\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjackfirth%2Ftrmcity","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjackfirth%2Ftrmcity","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjackfirth%2Ftrmcity/lists"}