Constellate

Fling a comet. Light the stars. Map the night sky, together.

Constellate is a daily physics puzzle thatit post. Drag back, release, and send a comet arcing across a night-sky arena — ricochet off neon bumpers, bend around black holes,ar. Light them all and they connect into a named constellation. Clear the day's sky in as few shots as you can.


Inspiration

The best daily games — Wordle, chess puzzlare a shape: 30 seconds to two minutes, one fresh challenge a day, and a reason to come back tomorrow. We wanted that rhythm, but ething where the satisfaction comes from a shot landing just right, and where every solved puzzle adds to something bigger tha

The night sky was the natural metaphor. Yol; you're lighting stars until they form a constellation, and the best of those get mapped into a permanent, communal Sky Atlas. perfect shot" feeling; the sky gives you the "we built this together" feeling.


What it does

  • A new puzzle every single day. Each day's sky is procedurally generated from the date, so everyone plays the sam it's guaranteed solvable by construction.
  • A satisfying core shot. Slingshot ai preview** that simulates the exact path the comet will take before you release.
  • Streaks & leaderboards. Solve the da; the board ranks by fewest shots, then fastest time.
  • Race the ghost. A translucent replayun races alongside yours.
  • Create your own. An in-app editor leut you can't submit it until you've solved it yourself, which proves it's clearable and sets its par.
  • The Sky Atlas. The community's best constellations get featured and mapped into a shared, ever-growing hall of fame

How we built it

Constellate is a Devvit Web app — Reddonly persistence layer is Redis. No external database, no external hosting.

  • Client: Phaser 4 + TypeScript + Vite, running in the post webview.
  • Server: Hono on Devvit's serverl /api/* surface. The server derives the player's identity from Reddit — the client is never trusted for scoring.
  • Storage: Redis sorted sets and hashes for personal bests, daily leaderboards, streaks, votes, the commun
  • Scheduler: a midnight-UTC cron posts a fresh daily puzzle to the feed and promotes the top community puzzle into t

*The physics is a custom deterministic inbrary. One step() function advances the simulation a single fixed timestep (gravity wells, friction, speed cap, movement, then wall/b Because it's deterministic, the *exact same step() powers four things at once:

  • the live game,
  • the aim preview (predict() runs tht),
  • the ghost replay of the leader's run, and
  • the server-side verifier.

That last one is the anti-cheat: when you quence of shots*, and the server re-simulates them. A run only counts if it truly lights every star, and the server's shot counis what goes on the leaderboard. Preview, ghost, live play, and verification are all the same math, so they can never disagree.

The art has a hard constraint: no imagtures — everything is drawn from live Phaser shapes (circles, rectangles, graphics), with a single bundled pixel font (Press Start 2, the twinkling starfield, and the settings gear icon are shapes. Audio is the same story: every sound effect and the ambient e with the WebAudio API — zero audio files.


Challenges we ran into

"Only the arrow renders." Early on, the whole game was blank except a hand-drawn aim arrow. After a headless Phaalls were valid, the tell was that only directly-drawn Graphics showed up — offscreen generateTexture() simply doesn't render down the path of rebuilding the entire art layer from live shapes, which turned into a feature: it's lightweight, crisp, and perf

*Making cheating impossible without a ser't want a leaderboard anyone could POST a fake score to. Moving the physics into shared code so the *server could replay every rua subtle bug: the live game checked whether stars were lit per frame, while the verifier checked per step. Legit fast shots were to check ignition per physics step made them byte-for-byte consistent.

Guaranteeing every generated puzzle is solvable. A daily that can't be solved is a disaster when everyone gets the same n space and never let an obstacle cover one, then brute-force-verified across dozens of generated days: zero solvability violation

Empty screens kill a "shared sky." A cg when the gallery is empty. We built a one-time idempotent seeder of hand-authored, verified constellations, plus a "living sky" on the (or a judge) never lands on a blank grid.


What we learned

  • Determinism is a feature, not a detail. One shared step() function collapsed four hard problems — preview, tency — into one.
  • Constraints sharpen identity. Being files pushed us toward a shapes-and-synth aesthetic that ended up being the look.
  • Trust nothing from the client. Ident server; the client is just a renderer with good manners.

Built with

Devvit (Reddit Developer Platform) · Devvit Web · Phaser 4 · TypeScript · Vite · Hono · Redis · WebAudio API · custom deter

Built With

Share this project:

Updates