How abdalla-eldoumani/dust works
1. Product shape
- DUST is a monorepo for a single game experience: a Next.js frontend, a Convex realtime backend, and a Python ingestion pipeline that feeds content into the game.
2. Frontend application shell
- apps/web is the main user-facing app, built with the Next.js App Router.
- Key routes are split by concern: landing (/), tutorial/about, solo play (/play), multiplayer (/multiplayer and /multiplayer/[code]), leaderboard, and Clerk sign-in/up pages.
- src/app/layout.tsx, middleware.ts, providers.tsx, and the auth pages define the app shell, route protection, and client providers.
3. Game loop boundary
- The core game loop lives in src/components/game and src/lib.
- Visual degradation is handled by the decay subsystem (decay-engine, text/layout/color/image decay modules), while gameplay UI is split into fake page renderers, tools, scoring screens, archive controls, and timers.
- src/store/game-store.ts and src/store/multiplayer-store.ts hold session state on the client.
4. Content pipeline for rounds
- Gameplay content is not just static pages; it is selected/generated from a content layer in src/lib/content.
- This layer includes caching, difficulty selection, a Convex adapter, and demo content, which suggests the app can switch between local/demo content and backend-provided content.
- The /api/generate-content route is the server-side entry point for AI-assisted content generation using Anthropic Claude.
5. Real-time backend and data ownership
- packages/backend/convex is the persistent system of record.
- The Convex modules model the domain around users, pages, pageVariants, cachedContent, archives, gameSessions, levels, leaderboard, and multiplayer.
- This is where score, session state, archived selections, and multiplayer room state are stored and synchronized.
6. Solo mode architecture
- Solo play is primarily frontend-driven but backed by Convex for persistence and ranking.
- The client evaluates page content locally, applies decay locally, and records outcomes/archives to backend tables so progress and leaderboard data can survive across sessions.
7. Multiplayer architecture
- Multiplayer is a separate gameplay path with room creation, waiting/lobby, in-match status, round results, and match results components.
- Convex provides the shared realtime state and synchronization channel for multiplayer rooms, while the client handles the live UX around joining, waiting, playing, and scoring.
- The docs/specs/multiplayer-pre-game-leave-spec.md indicates explicit room lifecycle rules around pre-game leaving.
8. Leaderboard and progression
- The leaderboard is a backend-backed aggregate exposed to the frontend via realtime queries.
- leaderboard components render the ranked view, while Convex is responsible for authoritative score storage and any scoping rules documented in docs/specs/leaderboard-scope-spec.md.
9. Authentication and identity
- Clerk handles sign-in/sign-up and user identity on the frontend.
- Convex is configured for Clerk JWT auth, so authenticated user identity flows from Clerk into backend queries/mutations and then into gameplay persistence and ranking.
10. Offline ingestion and curation pipeline
- dust_ingest/ is a separate Python toolchain for sourcing and preparing web content.
- It includes scraping, HTML sanitization, normalization, variant validation, leveling/difficulty assignment, LLM-based alteration, and upload to Convex.
- This pipeline feeds the game’s page corpus rather than serving end-user traffic directly.
11. Shared workspace boundaries
- packages/config provides shared TypeScript config, and packages/env centralizes environment validation.
- apps/web depends on these shared packages, keeping runtime configuration and type settings consistent across the frontend and backend packages.
12. External services that materially shape the architecture
- Next.js is the runtime for the UI and API route.
- Convex is the realtime database and serverless backend.
- Clerk is the auth boundary.
- Anthropic Claude is used for content generation.
- Vercel deployment config and Turborepo orchestration indicate the repo is structured for multi-package builds and deployment.
Main entry points: layout.tsx App shell · schema.ts Convex backend · decaying-page.tsx Game UI · route.ts Generate API
Components 27
Frontend app
Next.js user-facing experience and client-side game loop
- App shell · Top-level Next.js layout, middleware, and providers for the UI shell
apps/web/src/app/layout.tsx - Landing · Public entry page for the game
apps/web/src/app/page.tsx - How to play · Tutorial and onboarding content
apps/web/src/app/how-to-play/page.tsx - Solo play · Single-player game entry and play surface
apps/web/src/app/play/page.tsx - Multiplayer · Multiplayer lobby and room entry routes
apps/web/src/app/multiplayer/page.tsx - Auth pages · Clerk sign-in and sign-up routes
apps/web/src/app/sign-in/[[...sign-in]]/page.tsx - Leaderboard · Ranked results view for players and sessions
apps/web/src/app/leaderboard/page.tsx - Generate API · Server route for AI-assisted content generation
apps/web/src/app/api/generate-content/route.ts - Game UI · Core game loop UI, decay presentation, scoring, and tools
apps/web/src/components/game/decaying-page.tsx - Decay engine · Orchestrates text, layout, color, and image degradation
apps/web/src/lib/decay/decay-engine.ts - Game store · Client session state for solo gameplay
apps/web/src/store/game-store.ts - Multiplayer store · Client room and match state for multiplayer UX
apps/web/src/store/multiplayer-store.ts - Content layer · Caching, difficulty, demo content, and Convex-backed content selection
apps/web/src/lib/content/content-cache.ts - Leaderboard UI · Ranked table and user rank presentation
apps/web/src/components/leaderboard/leaderboard-table.tsx - Match UI · Lobby, waiting, round results, and match results screens
apps/web/src/components/game/multiplayer/room-lobby.tsx
Backend system
Convex persistent data model, realtime state, and auth-bound operations
- Convex backend · Persistent system of record for users, content, sessions, and multiplayer
packages/backend/convex/schema.ts - Auth config · Convex authentication boundary configured for Clerk JWTs
packages/backend/convex/auth.config.ts - Game data · Pages, variants, cached content, levels, archives, sessions, and leaderboard tables
packages/backend/convex/pages.ts - Multiplayer state · Realtime room lifecycle and match synchronization
packages/backend/convex/multiplayer.ts - Leaderboard data · Authoritative score storage and leaderboard queries
packages/backend/convex/leaderboard.ts
Ingestion pipeline
Python content sourcing and preparation flow
- Ingest pipeline · Scrape, sanitize, normalize, level, alter, and upload content
dust_ingest/cli.py
Shared packages
Workspace-wide config and environment validation
- TS config · Shared TypeScript configuration for packages and apps
packages/config/tsconfig.base.json - Env config · Centralized runtime environment validation
packages/env/src/web.ts
Other components
- Next.js · Frontend runtime and API execution environment
- Anthropic Claude · Model provider used for content generation and alteration
- Clerk · Identity provider for sign-in, sign-up, and user sessions
- Convex · Realtime database and serverless backend platform
Connections 29
- Next.js → App shell: hosts · Next.js serves the app shell and routes
- Next.js → Generate API: executes · API route runs in the Next.js runtime
- App shell → Landing: renders · Shell composes public landing experience
- App shell → How to play: renders · Shell composes tutorial route
- App shell → Solo play: renders · Shell composes solo play route
- App shell → Multiplayer: renders · Shell composes multiplayer routes
- App shell → Leaderboard: renders · Shell composes leaderboard route
- App shell → Auth pages: protects · Middleware and providers support auth pages
- Solo play → Game UI: uses · Solo play mounts the core game UI
- Multiplayer → Match UI: uses · Multiplayer routes mount match and lobby UI
- Game UI → Decay engine: applies · Core gameplay uses degradation engine
- Game UI → Game store: reads/writes · Solo game state lives in client store
- Match UI → Multiplayer store: reads/writes · Multiplayer UX is driven by client room state
- Game UI → Content layer: loads · Game loop selects round content from content layer
- Content layer → Convex backend: queries · Content can come from Convex-backed sources
- Content layer → Convex: syncs · Backend adapter connects content selection to Convex
- Generate API → Anthropic Claude: calls · Server route invokes Claude for generation
- Generate API → Convex backend: writes · Generated content is persisted through backend
- Convex backend → Auth config: authenticates · Convex uses Clerk identity for access control
- Convex backend → Game data: stores · Domain modules persist pages, variants, archives, and sessions
- Convex backend → Multiplayer state: syncs · Realtime room state is owned by Convex
- Convex backend → Leaderboard data: aggregates · Ranking data is computed from backend scores
- Leaderboard → Leaderboard UI: renders · Leaderboard page uses ranked table components
- Leaderboard UI → Convex backend: queries · Leaderboard view reads realtime backend data
- Match UI → Convex backend: syncs · Lobby and match flow use Convex realtime state
- Ingest pipeline → Anthropic Claude: uses · Pipeline can alter or generate content with LLMs
- Ingest pipeline → Convex backend: uploads · Prepared content is uploaded into Convex
- TS config → App shell: supports · Shared TS settings keep frontend packages aligned
- Env config → App shell: validates · Frontend runtime env is centrally validated