A card-based survival strategy game where you swipe to shape the fate of entire realities. Powered by AI-generated narratives — navigate cyberpunk dystopias, mystical kingdoms, and galactic empires, or create your own.
A RetroVerse Studios game.
- Swipe-Based Gameplay: Swipe left or right to make choices that affect your reality's stats
- Four Core Stats: Manage Power, Wealth, People, and Knowledge — don't let any reach 0 or 100!
- Multiple Realities: Play through different themed scenarios, each with unique narratives
- Multi-Provider AI: Generate decks with Google Gemini, OpenAI, Anthropic Claude, or Ollama (local)
- Reality Editor: Create and customize your own realities with a visual graph editor
- Store System: Browse and play community-created realities (currently a demo with built-in sample content — see Roadmap)
- Progressive Web App: Install and play offline
- Sound Effects: Immersive audio feedback for game actions
- Node.js (v16 or higher)
- An API key from at least one AI provider (or Ollama running locally)
-
Clone the repository:
git clone <repository-url> cd swipeverse
-
Install dependencies:
npm install
-
(Optional) Create a
.env.localfile with your API keys:GEMINI_API_KEY=your_key_here OPENAI_API_KEY=your_key_here ANTHROPIC_API_KEY=your_key_hereYou can also configure API keys in-app via AI Settings on the main menu.
-
Start the development server:
npm run dev
- Choose a Reality: Select from pre-made realities or create your own
- Configure AI (first time): Click "AI Settings" to choose your AI provider
- Make Decisions: Swipe cards left or right to make choices
- Manage Stats: Keep all four stats balanced — if any reach 0 or 100, you lose!
- Survive: Navigate through 20 AI-generated scenarios to reach the end
Launch straight into a scenario — no menu, nothing installed on the player's device (the scenario is played ephemerally):
https://swipeverse.app/app/?play=<scenario-url>[&difficulty=easy|standard|hard][&shell=tarot|crt|handheld]
<scenario-url> must return JSON from a CORS-friendly host (GitHub raw/Pages
work; most LMS file storage doesn't — link out). Accepted shapes: a Reality
with an embedded deck (the editor's export — preferred, it carries the renamed
stats and theming), a full editor export array, or a bare Deck.
Educator workflow: build in the editor → ⚖ Analyze → Export → host the JSON in a repo → paste one link into the LMS.
| Provider | Key Required | Structured Output | Cost |
|---|---|---|---|
| Google Gemini (default) | Yes | Native JSON schema | Free tier available |
| OpenAI | Yes | JSON mode | Paid |
| Anthropic Claude | Yes | Text → JSON parse | Paid |
| Ollama | No (local) | JSON mode | Free |
The OpenAI provider supports any OpenAI-compatible API (Azure, Groq, Together, etc.) via the Base URL setting.
Use the built-in Reality Editor to:
- Define your reality's theme and setting
- Create custom AI instructions for card generation
- Design the visual style (fonts, colors, images)
- Add sound effects and background music
- Generate story decks with the AI Story Director
- Build branching narratives with the visual graph editor
npm run buildEach built-in reality bundles a generated starter deck (decks/*.json), so
the game is playable offline with no AI provider. Regenerate with
ANTHROPIC_API_KEY=... npm run generate:decks (optionally pass reality ids),
or author replacements in the editor — see decks/README.md. The current
decks are machine-generated and balance-checked but not yet playtested.
The store UI is finished but runs against mock data (services/apiService.ts fabricates
entries with fake network delays). To make it live:
- Host a catalog — the cheapest path is a public GitHub repo containing a
realities.json/decks.jsonthatfetchStoreRealities/fetchStoreDecksfetch via raw.githubusercontent.com. No backend needed. - Accept submissions — start with GitHub PRs/issues against that catalog repo
(replace
submitReality's mock with a link or agh-backed flow); graduate to a small API (e.g. Cloudflare Workers + KV) if volume justifies it. - Remove the demo label — delete the Demo badge and notice in
components/StoreScreen.tsxonce real data is wired up.
Decisions made while designing the store — recorded so future work doesn't relitigate them:
- Local collection is the source of truth; the store is discovery. "Add" copies content into the player's browser (realities list / deck library), and everything plays from local storage afterwards — instant and offline. Players never load content live from the store to play it.
- Bundled starter decks stay. They are the offline/zero-setup floor (the PWA's "install and play offline" promise) and cost ~50 KB. Deck size makes browser memory a non-issue (~15 KB per deck, localStorage holds ~5 MB).
- Deck precedence: player-imported deck → AI generation (if a provider is
configured) → bundled deck. Bundled decks are tagged
source: "bundled"and are replaceable defaults; anything the player imported is never overwritten by updates. - Deck library (shipped). "My Library" tab in the store: store adds accumulate
there and never overwrite; "Load into Reality" fills a reality's single active
deck slot while the library keeps the copy. Export/import to disk is the backup
story — localStorage dies to "Clear site data".
navigator.storage.persist()is requested at startup to prevent automatic eviction, but only a disk export survives a manual clear. - No accounts for now. Accounts/portfolios/private uploads/cloud-synced libraries all require a real backend (auth, per-user storage, moderation at scale). The PR-curated catalog gives publishing without any of that. Revisit only if a creator community materializes; the catalog format migrates cleanly.
- Threat model: decks are inert JSON — no code execution path, and React
escapes rendered text, so there is no "jailbreak from a deck". The real vectors:
- External URLs (
imageUrl,soundUrl,imageSet,deckUrl) — arbitrary hosts mean tracking/IP leaks and unmoderatable imagery. Policy: reject or strip external URLs on submission unless from an allowlisted host; prefer text-only store decks. systemInstructionon realities is prompt injection by design — it runs against the player's AI key. It can't steal the key, but it can steer generation somewhere nasty. Moderate this field like any other text; review realities more strictly than decks.- Skewed mechanics (e.g. ±50 effects everywhere) are a griefing vector —
already bounded by
validateAndRepairDeck's clamping.
- External URLs (
- Moderation flow: deck content is small, pure text — cheap to screen. On
submission, run all text (cards, name, description,
systemInstruction) through an automated moderation pass (moderation API or a cheap LLM classification); auto-approve high-confidence-clean, queue the rest for manual review. At early volumes, reviewing everything by hand is fine — the PR-based catalog makes every submission a human-approved diff anyway ("if I'm not comfortable, it doesn't go in").
- React 19 + TypeScript — UI framework
- Vite — Build tool
- Google Gemini / OpenAI / Claude / Ollama — AI content generation
- React Flow — Visual editor
- PWA — Offline support
MIT — RetroVerse Studios