Why this game ??

Retention is usually bolted onto a session game. VISITORS inverts that: away-time is the game engine. Devvit has no per-user cron, so visits are a pure deterministic function of (userId, lastVisitTs, baitId) on next init: idempotent, fair, no farm-refresh (min away gate). Migratory creatures give the sub something to gossip about across days.

What is Visitors (player loop in 10 seconds)

  1. Open post: if enough time has passed, /api/init rolls new visits.
  2. Reveal cards flip (rarity sparkle for rare / migratory).
  3. Expand Play: place bait piles, photo critters, pet for poses.
  4. Field guide + migration map with real u/ holders.
  5. Share streak or rare flex to comments; come back after hours for more rolls.

How it works (architecture)

Layer Role
Devvit Ibview Inline splash (garden status); expanded game shell
Client DOM tabs + Phaser garden (Boot / Garden); SVG creature art; Ib Audio
Hono API /api/init visit rolls, bait set, collection, migratory journey, share
Redis User garden hash, collection hash, migratory JSON + journey feed sorted set, collectors board
Scheduler Nightly expire-migratory-holds so one-of-ones do not stick forever on inactive gardens
Shared visit-algo.ts (Iights, streak bonus, bait affinity), roster constants

Mod menu: create post; "Simulate overnight (12h)" backdates last visit so demos can show rolls without waiting real hours (moderator only, not the production player path).

Virality / hook (User Engagement on Reddit)

Return: Min away window + roll intervals mean fresh visitors only after real time. Streak multiplies rare Iight. Migratory holders change: "does u/X still have Bramble?"

Share: POST /api/share prefers feed comments (streak flex, rare flex, migratory gossip). Clipboard is fallback only. Polaroid strip of tonight's visitors is built for bragging.

Reddit-native features

  • Real usernames on migratory holders ("u/name has them right now").
  • Async multiplayer migration: one global instance of each one-of-one moves betIen gardens.
  • Comment-native share for garden flex and chase bait.
  • Crest-style identity where wired; social envy without turning karma into a score theme.
  • Collection and collectors leaderboard as soft social comparison.

Not karma-as-theme: bait, creatures, nights of care. Reddit is the garden neighborhood and comment thread.

Demo post / subreddit

Field Value
Subreddit r/visitors_game_dev
App owner u/KafkaOnWifi
Devvit package visitors-game
Example playtest post https://www.reddit.com/r/visitors_game_dev/comments/1ux1ppx/visitors_set_out_bait_see_who_wanders_in_tonight/

Note: private sub requires approved members for multi-account demos.

Tech stack

  • Client: Phaser 4.2 garden play, DOM/CSS shell, SVG creatures, Vite 8, TypeScript
  • Server: Hono, Devvit 0.13.6, Redis (permissions: redis; share uses Reddit APIs where available)
  • Shared: visit algorithm, roster, bait types
  • Tests: npx tsx tools/test-visits.ts (deterministic rolls / affinity)
  • Platform: Node >= 22.2; mobile-first; no outer scroll

How to test (60s path)

  1. Open the demo post; wait for splash garden status.
  2. Expand → Play tab (default): place bait, photo a visitor, pet once.
  3. If collection non-empty, open Field guide; open Migration and read holder u/.
  4. Share a streak or rare line once (should prefer comment).
  5. Mods: "Simulate overnight" then re-open to show a fresh roll batch.
  6. Leave, wait, return later for the real retention beat.

Proof on Reddit

  • Visits computed by visit-algo from real Redis user state, not random UI fluff.
  • Migratory keys track a single global holder with journey log and expire job.
  • Share path posts comments when post context exists.
  • Dual-account server multiplayer was exercised on live Redis (bait/init/migratory across accounts).
  • README matches architecture: Phaser garden + DOM shell (no fake "full Phaser app" claim).
  • Skip-to-morning / demo shortcuts stay gated (?demo=1 or mod menu), not the default player loop.

Built With

Share this project:

Updates

Submission history