# DOSTalgia đŸ•šī¸ A nostalgic DOS game hub. Upload your old DOS games, auto-scrape artwork and metadata from IGDB, and play them directly in your browser via js-dos (DOSBox compiled to WebAssembly). ## Features ### 🎮 Play in the browser Every uploaded game is packaged into a `.jsdos` bundle — a standard ZIP with embedded DOSBox configuration. When you hit **Play**, js-dos v8 is loaded from CDN and starts the emulator instantly in your browser. No plugins, no native installs. **Save states are automatic** — js-dos persists your game progress to the browser's storage. Come back anytime and pick up where you left off. ### 📡 IGDB metadata & media Dostalgia integrates with [IGDB](https://www.igdb.com/) (via Twitch OAuth2) to auto-populate game info: - **Auto Scrape** — On upload, Dostalgia searches IGDB by title and fills in year, genre, developer, publisher, description, and cover art. If IGDB finds a DOS result, it prioritises it. - **Manual Search** — From the game detail page you can search IGDB by any query, browse results with cover thumbnails and DOS badges, and apply the one you want. - **Media** — Videos (YouTube embeds) and screenshots (1080p) are fetched and displayed in a scrollable media gallery with a preview player. Everything degrades gracefully — if Twitch credentials aren't configured, uploads and editing work fine, just without auto-scrape. ### đŸ“Ļ Handles any file structure DOS games come in all shapes. Dostalgia handles them transparently: - **Flattening** — If your ZIP has a single root directory (e.g. `doom/` with all files inside), the extractor flattens it so the game files sit at the bundle root. No extra nesting. - **Subdirectory games** — If files are deeper, the autoexec automatically `cd`s to the right directory before launching the executable. - **CD images** — Games shipped on CD-ROM often need the disc mounted. Dostalgia detects `.iso`, `.cue`, `.img`, `.ccd`, and `.bin` files, fixes broken CloneCD `.cue` references (where the referenced `.bin` is actually `.img`), and mounts them in both `dosbox.conf` and `jsdos.json`. - **CD-only games** — If the archive contains only CD images with no executable, a CD-only bundle is created that mounts the disc and drops you at the DOS prompt. - **Hardcoded paths** — `ConfigPatcher` scans game config files for hardcoded absolute paths (e.g. `C:\FALLOUT1\MASTER.DAT`) that broke after flattening, and rewrites them to relative paths. ### 🔍 Smart executable detection On upload, Dostalgia scans every `.exe`, `.com`, and `.bat` file and picks the best candidate as the main executable using a scoring system: 1. **Not an installer** — INSTALL/SETUP/CONFIG executables are deprioritised 2. **DOS executables** — Pure DOS apps are preferred over Windows ones 3. **Larger files** — Bigger executables are more likely to be the game 4. **Shallow depth** — Files closer to the root are preferred 5. **Self-extractor filtering** — PKZIP/PKSFX stubs are filtered out All discovered executables are stored and available in the **Edit** page, where you can pick a different one via radio buttons. > **âš ī¸ Cache note:** If you change the executable, the `.jsdos` bundle is patched in-place. Your browser may serve a cached version of the old bundle — if the game doesn't launch with the new executable, **hard-refresh** the play page (Ctrl+Shift+R / Cmd+Shift+R). ### 🛠 One-click Setup launcher Many DOS games include a `SETUP.EXE`, `INSTALL.EXE`, or `CONFIG.EXE` used to configure sound, controls, and graphics. When Dostalgia detects one: - A **🛠 Setup** button appears on the game detail page - Clicking it launches the setup executable *without modifying the main game bundle* - The setup bundle is generated **on-the-fly** by the server — a modified `.jsdos` is streamed with the setup executable in the autoexec, then discarded. Nothing is written to disk. ### đŸĒŸ Windows game detection DOSBox can't run Windows executables. Dostalgia's `PlatformDetector` reads MZ/PE/NE headers to detect Windows executables: - The game detail page shows a **đŸĒŸ Requires Windows 3.1** badge - The **Play** button is disabled with "Unplayable" text - If you click Play anyway, a warning overlay explains the limitation with a **Try anyway** fallback - Setup executables that are Windows-native are also filtered out from the Setup button ## How it works ``` ┌──────────────────────────────────────────┐ │ Upload ZIP (multipart) │ └────────────â”Ŧ─────────────────────────────┘ â–ŧ ┌──────────────────────────┐ │ Unzip & flatten dirs │ │ Fix .cue references │ │ Fix absolute paths │ └────────────â”Ŧ─────────────┘ â–ŧ ┌──────────────────────────┐ │ Detect executables │ │ Detect CD images │ │ Detect platform (DOS/W) │ └────────────â”Ŧ─────────────┘ â–ŧ ┌──────────────────────────┐ │ Build .jsdos bundle │ │ (ZIP + dosbox.conf + │ │ jsdos.json) │ └────────────â”Ŧ─────────────┘ â–ŧ ┌──────────────────────────┐ │ Auto-scrape IGDB │ │ (year, genre, cover, │ │ videos, screenshots) │ └────────────â”Ŧ─────────────┘ â–ŧ ┌──────────────────────────┐ │ Save game.json │ └──────────────────────────┘ ``` ## Quick Start ### With Docker Compose (easiest) ```bash # 1. (Optional) Enable IGDB metadata auto-scrape cp .env.example .env # Edit .env with your Twitch credentials (see IGDB section below) # 2. Build & run docker compose up -d ``` Open http://localhost:8765 ### With Docker ```bash docker build -t dostalgia . docker run -p 8765:8765 -v $(pwd)/data:/data \ -e TWITCH_CLIENT_ID=your_id \ -e TWITCH_CLIENT_SECRET=your_secret \ dostalgia ``` ## Development (without Docker) Terminal 1 — Frontend dev server: ```bash cd frontend && npm install && npm run dev ``` Terminal 2 — Quarkus dev server: ```bash mvn quarkus:dev ``` Open http://localhost:5173 (Vite proxies API calls to Quarkus on port 8765) ### Production build (local) ```bash cd frontend && npm install && npm run build mvn package -DskipTests java -jar target/quarkus-app/quarkus-run.jar ``` ## Architecture - **Backend**: Quarkus (Java 21, JAX-RS) — REST endpoints, zero external database - **Frontend**: Svelte 5 SPA with hash-based routing - **Emulation**: js-dos v8 loaded from CDN, runs DOSBox in WebAssembly - **Storage**: JSON-per-game under `/data/games/{id}/game.json` - **Saves**: Browser localStorage / indexedDB (managed by js-dos) ## API Method | Path | Description --- | --- | --- GET | `/api/games` | List all games GET | `/api/games/:id` | Get game details PATCH | `/api/games/:id` | Update game metadata DELETE | `/api/games/:id` | Delete a game POST | `/api/upload` | Upload a game ZIP (multipart) POST | `/api/games/:id/cover` | Upload cover art GET | `/api/games/:id/setup-bundle` | Stream a setup .jsdos bundle (on-the-fly) GET | `/api/games/:id/download` | Download the game's .jsdos bundle GET | `/api/igdb/status` | Check if IGDB is configured GET | `/api/igdb/search?q=` | Search IGDB for a game POST | `/api/igdb/scrape/:id` | Auto-scrape or apply specific IGDB result ## Game JSON Schema ```json { "id": "doom", "title": "Doom", "year": 1993, "genre": "FPS", "developer": "id Software", "publisher": "id Software", "description": "You've signed up for...", "bundle_file": "doom/doom.jsdos", "executable": "DOOM.EXE", "executables": ["DOOM.EXE", "SETUP.EXE"], "setup_exe": "SETUP.EXE", "has_setup": true, "platform": "dos", "bundle_size": 4194304, "has_cover": true, "screenshots": ["https://..."], "videos": ["dQw4w9WgXcQ"], "igdb_id": 3498, "ready": true, "created_at": "2026-05-27T10:00:00Z", "updated_at": "2026-05-27T10:00:00Z" } ``` ## IGDB Metadata (Optional) Dostalgia can auto-populate game metadata (year, genre, developer, publisher, cover art, screenshots, videos) from the [IGDB](https://www.igdb.com/) database. This requires a Twitch API application. **Setup:** 1. Go to https://dev.twitch.tv/console/apps → **Register Your Application** 2. Name: `Dostalgia` (or anything), OAuth Redirect URL: `http://localhost`, Category: **Other** 3. Copy the **Client ID** and generate a **Client Secret** 4. Provide them via environment variables: Method | How --- | --- Docker run | `-e TWITCH_CLIENT_ID=xxx -e TWITCH_CLIENT_SECRET=yyy` Docker Compose | Copy `.env.example` to `.env` and fill in the values Local dev | `export TWITCH_CLIENT_ID=xxx TWITCH_CLIENT_SECRET=yyy` IGDB features degrade gracefully — if credentials aren't set, uploads and metadata editing still work, just without auto-scrape. ## Comparison with RomM [RomM](https://www.romm.app/) is a popular ROM manager with web-based emulation. Here's how Dostalgia compares specifically for MS-DOS games: | Feature | Dostalgia | RomM | |---|---|---| | **Emulator** | js-dos v8 (dedicated DOSBox WebAssembly) | EmulatorJS with dosbox-pure core | | **Bundle format** | Auto-generated .jsdos with embedded config | Raw ZIP + manual .conf file | | **Executable detection** | Automatic (smart scoring: depth, size, platform, installer filtering) | Manual — user must type `mount`, `cd`, and `exe` commands or write a .conf | | **CD mounting** | Automatic — detects .iso/.cue/.img/.ccd/.bin, fixes broken cues, mounts in config | Manual — user must write `imgmount` commands in .conf | | **Setup executable** | Auto-detected, one-click launch via on-the-fly streaming bundle | Not supported — user must run setup manually from DOS prompt | | **Windows detection** | PE/NE header analysis, UI badge, disabled play button with fallback | Not supported | | **IGDB integration** | Yes — auto-scrape, manual search, cover, genre, dev, publisher, videos, screenshots | Not for DOS specifically | | **Config patching** | Automatic — `ConfigPatcher` rewrites hardcoded `C:\` paths in game configs | Not available | | **GOG DOS games** | Supported (after flattening + path patching) | Explicitly NOT supported | | **Database** | None — JSON files per game | PostgreSQL | | **Upload size** | 2 GB limit | Depends on configuration | | **Save states** | Yes (browser storage via js-dos) | Yes (via EmulatorJS) | | **Target audience** | DOS-only, streamlined | Multi-platform, general-purpose | **When to use RomM:** If you're managing ROMs across many platforms (NES, SNES, Genesis, PS1, etc.) alongside DOS games. **When to use Dostalgia:** If you have a focused DOS collection and want a zero-fuss experience where you upload a ZIP and everything just works — executable detection, CD mounting, metadata, screenshots. ## Publishing the Docker image The Docker image is fully self-contained (Java JAR + static frontend, no database). To publish: ```bash docker build -t dostalgia . docker tag dostalgia ghcr.io/yourname/dostalgia:latest docker push ghcr.io/yourname/dostalgia:latest ``` Secrets are never baked into the image — users provide `TWITCH_CLIENT_ID` / `TWITCH_CLIENT_SECRET` at runtime via environment variables (or skip IGDB entirely).