Skip to content

About

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

Shards of Dreams

"Shards of Dreams" is a TypeScript monorepo hosting a surreal 2D RPG MVP. The client is a Vite + React front end styled with TailwindCSS; the server is an Express API prepared for SQLite persistence via Drizzle ORM. Shared TypeScript contracts and JSON content power exploration, dialogue, combat, and progression systems across both layers.

Project Layout

client/              React front end (Vite, Tailwind, Zustand-free state)
  src/app/          App shell and layout
  src/features/     Feature slices (combat, dialogue, exploration, save)
  src/state/        Central game state, content dictionaries
server/             Express server + Vite dev bridge
  src/routes/       API endpoints (`/api/save`, `/api/content/:key`)
  src/services/     Cross-route services (content cache, etc.)
  src/db/           Drizzle schema + better-sqlite3 driver
shared/             Cross-cutting types and JSON content

Key gameplay content lives under shared/content/:

  • palaceFear.json – room graph for the Palace of Fear.
  • dialogueBeach.json – branching Lister dialogue.
  • enemies.json, skills.json – combat actors and abilities.

Prerequisites

  • Node.js 20 LTS (includes npm 10+).
  • SQLite is bundled via better-sqlite3; no external service is required.

Installation

npm install

This installs both runtime and development dependencies (including @types/better-sqlite3 for the server) and automatically bootstraps the Electron workspace under desktop/—even when installing with production flags—so commands such as npm run desktop:dev and npm run desktop:build have access to tools like concurrently and rimraf.

Available Scripts

Type Check

npm run check

Runs the TypeScript compiler (tsc) for the root project and then type-checks the Electron workspace under desktop/.

Development (client + server)

npm run dev

Starts the Express server (server/src/index.ts) via tsx. In development the server attaches Vite middleware, so the React client and API are served together on port 5000.

The Express layer now includes structured request logging for all /api/* calls, trimming payload previews to 160 characters so terminal output remains readable during longer sessions.

Production Build

npm run build
  1. Builds the Vite client bundle into dist/public.
  2. Bundles the Express server with esbuild into dist/server/index.js.

Production Start

npm run start

Runs the bundled Express server (node dist/server/index.js) which serves static assets from dist/public.

Desktop Application

The Electron wrapper lives in the desktop/ workspace. It reuses the existing Vite renderer build and bundles dedicated main/preload processes.

Desktop Development

npm run desktop:dev

Runs the Vite dev server alongside the Electron main process via concurrently. The command waits for the renderer (port 5173 by default) before launching Electron with TypeScript entry points.

Desktop Build & Packaging

npm run desktop:build

Executes the full desktop pipeline: cleans previous artifacts, builds the renderer, compiles the main and preload scripts with tsc, and invokes electron-builder to produce distributables in dist/.

Verified with Node.js 20.18.0 / npm 10.8.2 on Linux x64 (electron-builder 24.13.3) via npm run desktop:build to confirm the release pipeline succeeds end-to-end after the dependency cleanup refactor.

Standalone Build

npm run build:standalone:win

Generates a self-contained distribution for the current platform (defaults to Windows x64 when run via the npm script):

  1. Runs the standard production build if dist/ is missing.
  2. Copies the client bundle, bundled server, SQLite database, and native better_sqlite3.node binary into the standalone folder.
  3. Uses pkg to compile dist/server/index.js into a platform-specific executable targeting Node.js 18.

To build for a different target explicitly, run the script directly and supply --target <platform>-<arch>, for example node scripts/build-standalone.mjs --target win-x64 or --target linux-arm64. You can also pass --platform and --arch separately. Windows aliases such as win, win32, win64, and windows64 are all accepted and normalized to the supported win32 target.

The resulting folder contains the executable (DreamShards.exe on Windows, DreamShards elsewhere), the public/ assets directory, a server/dreamshards.db starter database, and the better_sqlite3.node native module required by SQLite. Ship or zip the entire folder to run the game without a separate Node.js installation.

Gameplay Flow

  1. Main Menu – start a new dream or load the latest autosave.
  2. Dialogue – converse with Lister on the Dream Beach; choices toggle flags and unlock skills.
  3. Exploration – move through the Palace of Fear rooms, collect shards, trigger encounters, and initiate the boss gate.
  4. Combat – turn-based system with weakness bonuses, status effects (Vulnerable, Weakened, Guarded), skills, and items.
  5. Ending – post-boss epilogue reflects shard count and key decisions.

Auto-save runs whenever the game state changes outside the menu. Manual save/load buttons in the top bar call localStorage, and Push to Shore sends a snapshot to /api/save for future persistence work. Auto-save runs whenever the game state changes outside the menu. Manual save/load buttons in the top bar call localStorage. The "Push to Shore" button currently restores the latest snapshot (with a confirmation when leaving an active run); wiring it to the remote save endpoint is still TODO.

Drizzle ORM & Database

  • Schema: server/src/db/schema.ts (saves table).
  • Config: server/drizzle.config.ts (SQLite file stored at server/dreamshards.db by default).
  • Save endpoints are thin wrappers over Drizzle queries and accept an optional limit query string when listing saves (GET /api/save?limit=10). The limit is clamped between 1 and 25 and defaults to 5 to keep responses compact while still surfacing recent data quickly.
  • Shared content is streamed through server/src/services/contentService.ts, which caches parsed JSON in memory and automatically invalidates cached entries when the underlying files change on disk. This keeps frequently requested resources (enemy stats, palace layouts, etc.) fast without sacrificing live-reload friendliness during development.

API Reference

Saves

  • POST /api/save
    • Body: { state: AppState }.
    • Validation: The payload is checked against a zod schema (server/src/schemas/appState.ts) so malformed snapshots are rejected with a 400 before they reach storage.
    • Response: { ok: true, id: number }.
  • GET /api/save?limit=<1-25>
    • Optional limit query string controls how many records are returned (defaults to 5).
    • Response: { ok: true, saves: SaveRecord[] }.
  • GET /api/save/:id
    • Response: { ok: true, save: SaveRecord } when found, otherwise { ok: false, message: "not found" } with a 404.

Content

  • GET /api/content/:key
    • Serves JSON from shared/content/<key>.json for the allowed keys skills, enemies, palaceFear, and dialogueBeach.
    • Responses are cached in memory per file mtime so repeated requests avoid disk reads while editing content locally automatically busts the cache.
  • Drizzle commands (examples):
    npx drizzle-kit generate
    npx drizzle-kit push

Coding Standards

  • TypeScript everywhere with strict mode enabled.
  • TailwindCSS for styling; avoid bringing back the shadcn UI bundle removed during the rewrite.
  • Shared types in shared/types.ts drive both runtime data and compile-time safety.

Known Issues / TODOs

  • npm audit may report moderate/high vulnerabilities from upstream packages (see install output); treat as a dependency hygiene backlog item.
  • UI still uses placeholder art hooks (client/src/assets/README.md).
  • Remote persistence is not wired into the UI yet:
    • Client has pushSnapshotToServer() (client/src/features/save/saveSystem.ts).
    • Server accepts POST /api/save and supports listing/lookup (GET /api/save, GET /api/save/:id).
    • The top bar "Push to Shore" action currently restores the latest local snapshot instead of calling the API.

Feel free to expand content JSON or add additional palaces by extending the shared schema and client state dictionaries.

About

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages