Commit Graph
10 Commits
Author SHA1 Message Date
jensandClaude Sonnet 5 3332553cb5 Give each running game its own screen, capped at 10 concurrent
Previously every game shared one always-on Xvnc/fluxbox/websockify
desktop, so starting two games at once meant they fought over focus on
the same screen and the same ALSA device. Now:

- server.sh no longer starts a shared desktop at all - it just runs
  setup_server.py. There's no default display anymore.
- start_game() allocates a free display from GAME_DISPLAY_NUMS
  (:90-:99, one per MAX_CONCURRENT_GAMES=10 slot), spins up a fresh
  Xvnc+fluxbox+websockify for it, and launches the game with DISPLAY set
  to that display. All four processes are tracked together per game.
- stop_game() tears down all four; is_running() does the same lazily if
  the game exited on its own (crash/quit), so a slot doesn't stay stuck
  just because nobody clicked Stop.
- Starting past the 10-slot cap is refused with an error shown on that
  game's row instead of silently failing.
- Each running game's row gets its own "Open Screen" link (client-side
  JS, since the port is only known once the game is actually started)
  instead of one global noVNC link.
- run.sh publishes the whole 8090-8099 noVNC port range up front, since
  Docker can't add port mappings to an already-running container.

Verified end-to-end: two different games running concurrently get fully
independent Xvnc/fluxbox/websockify/game process sets and noVNC
endpoints; stopping one leaves the other untouched; the capacity guard
correctly refuses a start at the limit.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NiNnj78HGx1KWyCCo39HSz
2026-07-28 15:25:00 +02:00
jensandClaude Sonnet 5 afb18f1b38 Add ScummVM support and generalize manifest zip lookup
Add scummvm to the Dockerfile. Its binary lives at /usr/games/scummvm
(Debian's convention for game packages), not reliably on $PATH under a
non-login shell, so manifests reference it by absolute path.

Generalize the manifest schema from a bare "zip" filename (implicitly
under Games\dosbox\ on the SMB share) to "zip_path" (a full path
relative to the share root), since the SCUMM games' zips live in their
own folders (Games\Monkey Island\, Games\Indiana Jones\, etc.) rather
than being colocated with their manifest like stuntcar/t7g were.
Manifests themselves still all live in the Games\dosbox\ catalog
directory regardless of where the actual zip sits.

Added and verified (install/start/stop/uninstall via monkey2) manifests
for: monkey, monkey2, atlantis, indy3, tentacle. Skipped the German CD
release of Day of the Tentacle (loose files at the zip root, no single
top-level folder - incompatible with the current extraction convention)
and Curse of Monkey Island (untested, much larger).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NiNnj78HGx1KWyCCo39HSz
2026-07-28 14:29:11 +02:00
jensandClaude Sonnet 5 dcdf4fa9b3 Update TODO reference from common/ to the new docker-common repo
common/scripts/ was replaced by the docker-common repo.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NiNnj78HGx1KWyCCo39HSz
2026-07-28 11:00:51 +02:00
jensandClaude Sonnet 5 2c70def189 Note audio streaming should be shared across noVNC-family projects
Follow the common/scripts/signals.sh precedent: build the browser
audio + noVNC piece project-agnostically in common/, then copy it into
each project's own scripts/ rather than making it dosbox-specific.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NiNnj78HGx1KWyCCo39HSz
2026-07-28 10:49:02 +02:00
jensandClaude Sonnet 5 568c284a8a Add TODO items for SCUMM game manifests and low-latency game audio
Audio note: rules out the obvious compressed-stream + <audio> tag
approach up front, since codec/element buffering can't realistically hit
the tens-of-ms target - raw PCM over WebSocket into an AudioWorkletNode
is the concrete plan instead.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NiNnj78HGx1KWyCCo39HSz
2026-07-28 10:43:38 +02:00
jensandClaude Sonnet 5 827f03f087 Drive games from per-game JSON manifests instead of raw zip scanning
Games are no longer discovered from *.zip files on the SMB share; each
game now has its own <name>.json manifest (name/title/zip/start_cmd)
living next to its zip, discovered dynamically via smbclient. Nothing
about a game's identity or how to install/start it is hardcoded in the
image anymore. The setup page also grew Start/Stop/Uninstall buttons,
backed by real process tracking (Popen + terminate/kill).

Piloted on stuntcar only (manifest already uploaded to the share); t7g
has no manifest yet so it won't appear until one's added. The old
game.sh/start_game.sh docker-exec launch path is left as-is for now and
overlaps with the new Start button - noted in TODO.md for later cleanup.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NiNnj78HGx1KWyCCo39HSz
2026-07-28 10:27:33 +02:00
jensandClaude Sonnet 5 c6ae36ba67 Replace auto-download with an interactive HTML game setup UI
No games are fetched at container start anymore. scripts/setup_server.py
is a small stdlib-only Python HTTP server, started alongside Xvnc/fluxbox/
websockify, serving an HTML page on ${SETUP_PORT} (70${DISPLAY_NUM},
published as 7099 by run.sh) that lists every *.zip found live on the SMB
share with an Installed/Install status per game. Clicking Install
downloads and extracts just that game into ${GAMES_HOME} on demand.
Replaces the old fetch_games.sh, which unconditionally pulled every game
on first start.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NiNnj78HGx1KWyCCo39HSz
2026-07-28 08:37:12 +02:00
jensandClaude Sonnet 5 44bbd00336 Fetch games into a volume at runtime instead of baking them into the image
927MB of the image was just t7g's two CD ISOs, which can't be meaningfully
compressed (already-compressed FMV/audio). Move the smbget/unzip step out
of the Dockerfile and into scripts/fetch_games.sh, run from server.sh on
container start: it populates GAMES_HOME on first run and skips the fetch
if games are already present. run.sh mounts a named volume so the games
survive --rm restarts instead of being re-downloaded every time. Image
drops from 1.6GB to ~690MB; first container start now needs network access
to the vlda-01 SMB share to seed the volume.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NiNnj78HGx1KWyCCo39HSz
2026-07-28 08:25:26 +02:00
jensandClaude Sonnet 5 79cc239dca Shrink image by merging game fetch/extract into one layer
The downloaded zips and their extracted contents lived in separate RUN
layers, so the zips never actually left the image despite a later
rm -rf /tmp/apps layer. unzip/smbclient were also left installed after
only being needed at build time. Merging fetch, extract, cleanup, and
package purge into a single RUN drops the image from 2.31GB to 1.6GB.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NiNnj78HGx1KWyCCo39HSz
2026-07-28 08:18:18 +02:00
jensandClaude Sonnet 5 c4049a7d79 Add TODO.md
Tracks reducing the image size of jayfield/dosbox-novnc.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018QuKZRefXR3hVaUiXgeu6i
2026-07-27 23:37:26 +02:00