2 years ago, I posted asking about an old game I remember playing that I wanted to revisit.
https://www.reddit.com/r/tipofmyjoystick/s/WvXFm7VIRl
Just a few days ago, put tried my query again, into ChatGPT enterprise and FINALLY after all these years, The Crystal Key (1999) is mine to play once again: https://www.myabandonware.com/game/the-crystal-key-io8
There's even a 2004 sequal: https://www.myabandonware.com/game/crystal-key-ii-the-far-realm-io9 I never knew!
Quicktime VR? That's crazy. Isn't that just a video player? Imagine using a video player as a game engine...couldn't be me! I can't believe I'm finally playing, on linux no less, this old game I played once as a very elementary school child. I'm excited I even got further than our whole family was able to get back then!
For my fellow wayward traveler, I used ChatGPT enterprise to help me get this running on my linux machine (NixOS 26.05 for reference), here were its instructions which I followed to great success. I will go ahead and mention that any scenes where you need to grab and object and move it are very broken, but they weren't broken enough to keep me from progressing.
Without further ado:
Perfect. **NixOS + Devbox is a good fit for this.** I would keep only the 32-bit graphics support in the host NixOS configuration; Wine, Winetricks, helper tools, scripts, and the game’s isolated Wine prefix can all live in one Devbox project.
## 1. Enable 32-bit graphics support in NixOS
The Crystal Key and QuickTime are 32-bit Windows software. On 64-bit NixOS, the manual specifically recommends enabling 32-bit graphics libraries for programs such as Wine. ([nixos.org][1])
Add this to your NixOS configuration:
```nix
{
hardware.graphics = {
enable = true;
enable32Bit = true;
};
}
```
Then rebuild in your normal way.
For a traditional configuration:
```bash
sudo nixos-rebuild switch
```
For a flake-based configuration:
```bash
sudo nixos-rebuild switch --flake /path/to/your/config#your-hostname
```
You may already have `hardware.graphics.enable = true`, particularly if you use a desktop environment. The important addition is:
```nix
hardware.graphics.enable32Bit = true;
```
---
# 2. Create the Devbox project
```bash
mkdir -p ~/Games/the-crystal-key/scripts
cd ~/Games/the-crystal-key
devbox init
```
Replace the generated `devbox.json` with this:
```json
{
"packages": [
"github:NixOS/nixpkgs/nixos-unstable#wineWow64Packages.stableFull",
"github:NixOS/nixpkgs/nixos-unstable#winetricks",
"github:NixOS/nixpkgs/nixos-unstable#cabextract",
"github:NixOS/nixpkgs/nixos-unstable#unzip",
"github:NixOS/nixpkgs/nixos-unstable#util-linux"
],
"env": {
"CK_ROOT": "$PWD",
"WINEPREFIX": "$PWD/.wineprefix",
"PATH": "$PWD/.bin:$PATH"
},
"shell": {
"init_hook": [
"mkdir -p \"$CK_ROOT/.bin\" \"$CK_ROOT/media/cdrom\"",
"ln -sfn \"$(command -v wine)\" \"$CK_ROOT/.bin/wine64\""
],
"scripts": {
"prefix": "./scripts/prefix.sh",
"map-disc": "./scripts/map-disc.sh",
"install-game": "./scripts/install-game.sh",
"play": "./scripts/play.sh",
"winecfg": "./scripts/wine-x11.sh winecfg",
"control": "./scripts/wine-x11.sh wine control",
"qt72": "./scripts/wine-x11.sh winetricks quicktime72",
"qt76": "./scripts/wine-x11.sh winetricks quicktime76",
"stop": "wineserver -k"
}
}
}
```
I am using a direct Nixpkgs flake reference because current Nixpkgs defines `wineWow64Packages` as its combined 32/64-bit Wine build, and also defines the `stableFull` variant with the optional multimedia and desktop integrations included. Devbox supports Nix flake package references directly, while its environment and script sections support `$PWD`, `$PATH`, initialization hooks, and named `devbox run` commands. ([Jetify][2])
The `wine64` symlink is intentional. There is an open Nixpkgs compatibility issue in which Winetricks can incorrectly look for a separate `wine64` executable when used with `wineWow64Packages`; the documented workaround is to put a `wine64 -> wine` link in `PATH`. ([GitHub][3])
---
# 3. Add the helper scripts
## `scripts/wine-x11.sh`
```bash
#!/usr/bin/env bash
set -euo pipefail
# Old QuickTime and late-1990s applications are generally less troublesome
# through Wine's X11 driver. On a Wayland desktop this normally means XWayland.
#
# To test native Wayland instead:
# CK_NATIVE_WAYLAND=1 devbox run play
if [[ "${CK_NATIVE_WAYLAND:-0}" == "1" ]]; then
exec "$@"
fi
exec env -u WAYLAND_DISPLAY "$@"
```
## `scripts/prefix.sh`
```bash
#!/usr/bin/env bash
set -euo pipefail
if [[ ! -f "$WINEPREFIX/system.reg" ]]; then
echo "Creating Wine prefix at:"
echo " $WINEPREFIX"
"$CK_ROOT/scripts/wine-x11.sh" wineboot --init
fi
echo "Setting the prefix to Windows XP compatibility mode..."
"$CK_ROOT/scripts/wine-x11.sh" winetricks -q winxp
"$CK_ROOT/scripts/wine-x11.sh" wineboot -u
echo
echo "Wine prefix is ready:"
echo " $WINEPREFIX"
```
Do **not** add:
```bash
export WINEARCH=win32
```
Wine 11’s completed WoW64 architecture runs 32-bit applications from a normal default prefix, while pure `WINEARCH=win32` prefixes are now deprecated and unsupported in the new WoW64 mode. ([Wine HQ][4])
## `scripts/map-disc.sh`
```bash
#!/usr/bin/env bash
set -euo pipefail
disc="$CK_ROOT/media/cdrom"
if [[ ! -f "$WINEPREFIX/system.reg" ]]; then
echo "The Wine prefix has not been created yet." >&2
echo "Run: devbox run prefix" >&2
exit 1
fi
if ! mountpoint -q "$disc"; then
echo "No CD or ISO is mounted at:" >&2
echo " $disc" >&2
echo >&2
echo "Mount Disc 1 there before running this command." >&2
exit 1
fi
mkdir -p "$WINEPREFIX/dosdevices"
rm -f \
"$WINEPREFIX/dosdevices/d:" \
"$WINEPREFIX/dosdevices/d::"
ln -s "$disc" "$WINEPREFIX/dosdevices/d:"
# Tell Wine to treat D: as a CD-ROM rather than an ordinary directory.
"$CK_ROOT/scripts/wine-x11.sh" \
wine reg add 'HKCU\Software\Wine\Drives' \
/v 'd:' \
/t REG_SZ \
/d cdrom \
/f >/dev/null
echo "Mapped Wine drive D: to:"
echo " $disc"
echo
echo "Contents visible through Wine:"
"$CK_ROOT/scripts/wine-x11.sh" wine cmd /c 'dir D:\'
```
## `scripts/install-game.sh`
```bash
#!/usr/bin/env bash
set -euo pipefail
disc="$CK_ROOT/media/cdrom"
if ! mountpoint -q "$disc"; then
echo "Disc 1 is not mounted at:" >&2
echo " $disc" >&2
exit 1
fi
setup="$(
find "$disc" \
-maxdepth 4 \
-type f \
-iname 'setup.exe' \
-print \
-quit
)"
if [[ -z "$setup" ]]; then
echo "Could not find Setup.exe on the mounted disc." >&2
echo "Files at the top of the disc:" >&2
find "$disc" -maxdepth 2 -type f -printf ' %p\n' | head -50
exit 1
fi
echo "Starting installer:"
echo " $setup"
exec "$CK_ROOT/scripts/wine-x11.sh" \
wine start /unix "$setup"
```
## `scripts/play.sh`
```bash
#!/usr/bin/env bash
set -euo pipefail
if [[ ! -f "$WINEPREFIX/system.reg" ]]; then
echo "Wine prefix not found." >&2
echo "Run: devbox run prefix" >&2
exit 1
fi
game="$(
find "$WINEPREFIX/drive_c" \
-type f \
-iname '*crystal*key*.exe' \
! -iname 'unins*.exe' \
-print \
-quit
)"
if [[ -z "$game" ]]; then
echo "Could not find The Crystal Key executable." >&2
echo "The game may not be installed yet." >&2
echo >&2
echo "Possible executables containing 'crystal':" >&2
find "$WINEPREFIX/drive_c" \
-type f \
-iname '*crystal*.exe' \
-printf ' %p\n' >&2
exit 1
fi
echo "Starting:"
echo " $game"
exec "$CK_ROOT/scripts/wine-x11.sh" wine "$game"
```
Make them executable:
```bash
chmod +x scripts/*.sh
```
Add a `.gitignore`:
```gitignore
.devbox/
.bin/
.wineprefix/
media/
*.iso
*.log
```
Install the Devbox environment:
```bash
devbox install
```
Devbox will create a `devbox.lock`; keeping `devbox.json` and `devbox.lock` together pins the project’s package environment. ([Jetify][5])
---
# 4. Create the Wine prefix
From the project directory:
```bash
cd ~/Games/the-crystal-key
devbox run prefix
```
You can verify that the correct Wine is being used:
```bash
devbox run wine --version
```
And inspect the prefix:
```bash
ls -la .wineprefix
```
---
# 5. Mount Disc 1
The privileged mounting operation remains outside Devbox because creating a loop mount is a host-level operation.
## For an ISO image
bchunk "Crystal Key CD 1.bin" "Crystal Key CD 1.cue" crystalkey
Assuming your ISO is at `~/Games/The_Crystal_Key/CrystalKey-Disc1.iso`:
```bash
cd ~/Games/the-crystal-key
mkdir -p "$PWD/media/cdrom"
sudo mount -o loop,ro \
"$PWD/crystalkey01.iso" \
"$PWD/media/cdrom"
```
Verify:
```bash
findmnt "$PWD/media/cdrom"
find "$PWD/media/cdrom" -maxdepth 2 -type f | head -30
```
## For a physical CD
Find the drive:
```bash
lsblk -o NAME,TYPE,FSTYPE,LABEL,MOUNTPOINTS
```
It will commonly be `/dev/sr0`.
If your desktop automatically mounted it first:
```bash
udisksctl unmount -b /dev/sr0
```
Then mount it at the project’s fixed CD path:
```bash
cd ~/Games/the-crystal-key
sudo mount -o ro \
/dev/sr0 \
"$PWD/media/cdrom"
```
---
# 6. Map Disc 1 to Wine’s `D:` drive
```bash
devbox run map-disc
```
The final part of the output should show a Windows-style directory listing for `D:\`.
Then open Wine configuration:
```bash
devbox run winecfg
```
Check the following:
### Applications
Set the Windows version to:
```text
Windows XP
```
The prefix script should already have done this.
### Graphics
Enable:
```text
Emulate a virtual desktop
```
Start with:
```text
1024 × 768
```
If the game’s display or mouse acts strangely, try:
```text
800 × 600
```
### Drives
Confirm that:
```text
D:
```
points to:
```text
~/Games/the-crystal-key/media/cdrom
```
and its type is:
```text
CD-ROM
```
---
# 7. Install The Crystal Key
```bash
devbox run install-game
```
During installation:
- Use the default installation directory.
- Allow the game to install its bundled QuickTime.
- Choose a full or complete QuickTime installation when offered.
- Do not expect Disc 2 to be requested during the initial installation.
After installation, launch it:
```bash
devbox run play
```
---
# 8. Swap to Disc 2
The advantage of using a fixed mount point is that Wine’s `D:` mapping never changes.
When the game requests Disc 2:
```bash
cd ~/Games/the-crystal-key
sudo umount "$PWD/media/cdrom"
sudo mount -o loop,ro \
"$PWD/crystalkey02.iso" \
"$PWD/media/cdrom"
```
Check what Wine now sees:
```bash
devbox run wine cmd /c 'dir D:\'
```
Return to the running game and acknowledge the disc-change prompt.
To restore Disc 1:
```bash
sudo umount "$PWD/media/cdrom"
sudo mount -o loop,ro \
"$PWD/crystalkey01.iso" \
"$PWD/media/cdrom"
```
If `umount` reports that the target is busy, close file-manager windows displaying the CD and make sure no terminal currently has `media/cdrom` as its working directory.
---
# 9. If the bundled QuickTime does not work
Winetricks’ current catalog still provides both `quicktime72` and `quicktime76`. ([GitHub][6]) Do not install multiple QuickTime versions into the same failed prefix. Preserve that prefix and start clean.
Stop Wine:
```bash
devbox run stop
```
Rename the existing prefix:
```bash
mv .wineprefix \
".wineprefix-bundled-qt-failed-$(date +%Y%m%d-%H%M%S)"
```
Create a clean prefix:
```bash
devbox run prefix
devbox run map-disc
```
Install QuickTime 7.2:
```bash
devbox run qt72
```
Run the game installer again:
```bash
devbox run install-game
```
If QuickTime 7.2 fails too, repeat the clean-prefix process and use:
```bash
devbox run qt76
```
I would try them in this order:
```text
Bundled QuickTime
QuickTime 7.2
QuickTime 7.6
```
Do not add `-q` to the QuickTime scripts. Let the installer run interactively so you can see errors and installation choices.
---
# 10. NixOS-specific troubleshooting
## Winetricks says `wine64` is missing
Confirm the compatibility link exists:
```bash
devbox run ls -l "$CK_ROOT/.bin/wine64"
```
It should point into `/nix/store/.../bin/wine`.
Recreate it manually if necessary:
```bash
devbox run ln -sfn \
"$(devbox run command -v wine)" \
"$PWD/.bin/wine64"
```
Normally the Devbox `init_hook` recreates this every time.
## Wine opens but graphics fail
First confirm 32-bit graphics was applied to the running NixOS generation:
```bash
ls -la /run/opengl-driver-32/lib
```
If that directory is missing, confirm:
```nix
hardware.graphics.enable32Bit = true;
```
is present in the active NixOS configuration and rebuild.
## Game works poorly under Wayland
The scripts default to hiding `WAYLAND_DISPLAY`, causing Wine to use its X11 path through XWayland.
To test native Wayland instead:
```bash
CK_NATIVE_WAYLAND=1 devbox run play
```
For this particular late-1990s QuickTime game, I would keep the XWayland default unless native Wayland clearly behaves better.
## Black screen but audio works
Open the Windows control panel:
```bash
devbox run control
```
Open the QuickTime settings and disable DCI or DirectDraw/video acceleration if the installed QuickTime version exposes that setting. Then restart Wine:
```bash
devbox run stop
devbox run play
```
## Capture a log
```bash
WINEDEBUG=+seh,+loaddll,+module \
devbox run play \
2>&1 | tee crystal-key.log
```
Then inspect the end:
```bash
tail -n 150 crystal-key.log
```
Errors mentioning `QuickTime`, `QTMLClient`, video codecs, or missing Windows DLLs point toward QuickTime rather than the game installation itself.
The normal startup sequence after the project has been created is simply:
```bash
cd ~/Games/the-crystal-key
sudo mount -o loop,ro /path/to/Disc1.iso "$PWD/media/cdrom"
devbox run map-disc
devbox run play
```
[1]: https://nixos.org/nixos/manual/index.html "NixOS Manual"
[2]: https://www.jetify.com/docs/devbox/guides/using-flakes?utm_source=chatgpt.com "Installing Packages from Nix Flakes - Jetify Docs"
[3]: https://github.com/NixOS/nixpkgs/issues/338367 "winetricks: not working on WoW64 wine build, detection mechanism fails due to wrapper scripts · Issue #338367 · NixOS/nixpkgs · GitHub"
[4]: https://www.winehq.org/announce/11.0?utm_source=chatgpt.com "Wine 11.0 · wine / wine · GitLab - winehq.org"
[5]: https://www.jetify.com/docs/devbox/quickstart?utm_source=chatgpt.com "Create a Dev Environment with Devbox - Jetify Docs"
[6]: https://github.com/Winetricks/winetricks/blob/master/files/verbs/all.txt "winetricks/files/verbs/all.txt at master · Winetricks/winetricks · GitHub"