docs: comprehensive README covering all features
Build & Deploy / build-and-deploy (push) Successful in 14s
Build & Deploy / build-and-deploy (push) Successful in 14s
- Browser play with js-dos & auto save states - IGDB metadata/media integration (auto scrape, search, apply) - File structure handling (flattening, subdirectories, CD mounting, path patching) - Smart executable detection algorithm explained - One-click Setup launcher (on-the-fly streaming) - Windows game detection & UI marking - Comparison with RomM feature-by-feature - Cache-busting note for executable changes - Architecture pipeline diagram
This commit is contained in:
@@ -1,6 +1,95 @@
|
||||
# Dostalgia
|
||||
# DOSTalgia 🕹️
|
||||
|
||||
A nostalgic DOS game hub. Upload your old DOS games, scrape artwork, and play them directly in the browser via js-dos (WebAssembly DOSBox).
|
||||
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
|
||||
|
||||
@@ -50,22 +139,27 @@ java -jar target/quarkus-app/quarkus-run.jar
|
||||
|
||||
## Architecture
|
||||
|
||||
- **Backend**: Quarkus (Java 21, JAX-RS) — ~5 REST resource classes, zero database
|
||||
- **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/igdb/search?q=` | Search IGDB (placeholder) |
|
||||
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
|
||||
|
||||
@@ -76,15 +170,28 @@ java -jar target/quarkus-app/quarkus-run.jar
|
||||
"year": 1993,
|
||||
"genre": "FPS",
|
||||
"developer": "id Software",
|
||||
"bundle_file": "doom.jsdos",
|
||||
"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,
|
||||
"ready": 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, cover art, screenshots, videos) from the [IGDB](https://www.igdb.com/) database. This requires a Twitch API application.
|
||||
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:**
|
||||
|
||||
@@ -93,10 +200,46 @@ Dostalgia can auto-populate game metadata (year, genre, developer, cover art, sc
|
||||
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` |
|
||||
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).
|
||||
|
||||
Reference in New Issue
Block a user