Inspiration
r/place proved something about Reddit: the platform is at its best when an entire community touches one shared canvas at the same moment. But r/place is chaos by design, and — crucially — it ends. We wanted the opposite: a shared creation that is ordered, that persists, and that a community can still be proud of months later.
So we asked: what if a whole subreddit built one city together — not by shouting over each other, but by following the same simple rule everyone else follows? Every tile you place must fit. A road has to connect to a road. A shop needs customers nearby. A port has to touch water. And nothing you build ever resets.
That single constraint turns a blank grid into a genuine collaboration: your tile only works because of the tiles your neighbors placed before you. That's the hook — a city that is literally load-bearing on its community.
What it does
Subcity is a persistent, collaborative city-builder that lives inside a Reddit post. There is exactly one city per subreddit, and it never resets.
- Place tiles under real constraints. Every placement is validated server-side against a data-driven rule engine — roads must connect, shops need nearby houses, ports must be on the waterfront. Invalid moves cost you nothing; valid ones become permanent city.
- A living economy. Basic buildings cost energy (a pool that refills over time) and earn coins; 26 building types span housing, commerce, and civic buildings that confer strategic effects — income, extra energy, "respect" value multipliers, repair coverage, even disaster shielding.
- Co-op disasters. Tornadoes, floods, and cyclones periodically damage a district; damaged buildings stop earning until anyone repairs them. Build a fire station to shield your neighborhood, or a repair shop to fix things in seconds instead of minutes.
- It's alive in real time. Other players' placements, disasters, and repairs animate on your map as they happen — including a visible community "repair swarm" after a disaster.
- Reasons to come back. Daily reward chests, a rotating daily task, weekly community mega-projects, a builder-level progression that unlocks bigger buildings, streaks, milestone badges, flair tiers, and a daily auto-posted "city recap" that pulls the subreddit back in.
How we built it
Subcity is a Devvit Web app — a webview game backed by a serverless Reddit backend.
- Client: React 19 + Vite + Tailwind CSS v4 for the HUD, and a Phaser 4 scene for the world. All world art is procedurally generated pixel art — there are zero external image assets — in a deliberate GBA / Pokémon-Ruby palette with a single self-hosted pixel font.
- Server: a Hono API on Devvit's serverless runtime. It is fully server-authoritative: the client's rule mirror is advisory only, and every placement, purchase, and repair is validated and committed on the server.
- Data: Reddit's per-subreddit Redis. The world is stored as a chunked grid (16×16 tiles per key) and loaded viewport-only, so payload scales with what you can see, not with the size of the city.
- Realtime: Devvit's realtime plugin broadcasts placements, disasters, and repairs on separate channels for live presence and co-op.
- Scheduling: cron tasks drive the daily rollover, disaster ticks, streak-reminder DMs, and the daily recap post.
A couple of systems are pure math. The collective city level rises on a widening curve, so each level costs more community value than the last:
$$\text{level}(v) = \left\lfloor \sqrt{\frac{v}{40}} \right\rfloor + 1, \qquad v_{L} = 40\,(L-1)^2$$
And a builder's civic buildings compound: a placed tile's stored value is ( \text{round}!\big(\text{base} \times (1 + \sum_i r_i)\big) ), where each "respect" building (hospital, clinic, temple, museum) contributes its own fraction ( r_i ).
Challenges we ran into
Building a real-time, persistent multiplayer game on a serverless platform forced some interesting design:
- No timers. You can't run a loop that ticks income or refills energy. We accrue both lazily on read — coins grow by
rate × elapsedHoursand energy byfloor((now − lastTick) / interval)the moment you next look. No background jobs, exact results. - No canvas on the server. We wanted a rendered "postcard" of the city posted daily, but the server can't run Phaser. So the daily recap became a stats-driven post that diffs the city against yesterday ("+213 tiles, the city reached Level 7") — which turned out to be more Reddit-native anyway.
- Per-subreddit Redis as the entire persistence model. Designing keys and a chunked world so one shared, ever-growing city stays fast (and can't be abused into billions of sparse chunks) was the core data challenge.
- Extensibility without engine rewrites. Adding buildings kept meaning edits in a dozen files, so we refactored civic effects into a data-driven system: each building declares an
effectKindand magnitude, and the economy, energy, and disaster engines apply them generically. Going from 4 to 15+ civic buildings became mostly data. - Zero-asset art. Every building is drawn in code. To scale to 26 tile types without 26 bespoke sprites, we built a parametrized "civic shell" plus a distinct emblem per building, so the whole set still reads as one cohesive family.
Accomplishments that we're proud of
- A single hook that is genuinely Reddit-native and on-theme: one permanent, community-built, rule-constrained city.
- Real depth — constraint engine, economy, co-op disasters, and a full daily/weekly/seasonal retention stack — that still runs cleanly on serverless.
- Everything drawn in code, in a consistent retro art style with no licensed assets.
What we learned
- How to build a server-authoritative, real-time game on Devvit Web, and how to model a persistent shared world in per-subreddit Redis.
- That serverless constraints are a design tool: "no timers" pushed us to lazy accrual, and "no canvas" pushed us to a more shareable recap.
- That data-driven systems pay for themselves the moment you want to add content under a deadline.
What's next for Subcity
- District naming and player-authored labels for neighborhoods.
- Bigger weekly mega-projects and cross-subreddit events.
- Transaction-hardening the coin/energy writes for perfectly concurrent play.
- More civic mechanics (police coverage, power grid) on the same data-driven effect system.
Built With
- css3
- devvit
- devvit-web
- eslint
- hono
- html5
- javascript
- node.js
- phaser.js
- pixel-art
- procedural-generation
- react
- realtime
- redis
- tailwindcss
- typescript
- vite
- web-audio-api
Log in or sign up for Devpost to join the conversation.