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
Adopts bash-arithmetic exit-code computation ($((128 + SIGNUM))) instead
of piping to bc, dropping that dependency. Consolidates this project
onto docker-common's shared scripts (see that repo's CLAUDE.md).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NiNnj78HGx1KWyCCo39HSz
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
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
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
jayfield/novnc-baseimage (built by docker-novnc-baseimage) has been
retired, so this now builds on the public ich777/novnc-baseimage
instead. That image puts Xvnc/websockify on $PATH and noVNC's web
client at /usr/share/novnc/ rather than /opt/TurboVNC and /tmp, so
server.sh is updated to match. Verified with a full rebuild and
container start: Xvnc, fluxbox, and websockify all come up and the
noVNC web UI responds.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018QuKZRefXR3hVaUiXgeu6i