Write a Guix Package Recipe for Elona

2024-08-18
Forward links: related:Roguelike related:Guix under:Blog Backward links:

Elona is a freeware open-world Roguelike. Sadly it is for Windows only, but we can run it under Wine. Given that we are using Guix now, why not run it with the help of Guix? The benefit is obvious: we can pin the dependencies so that system updates won't break our game environment; we can isolate the game in a container, just in case; and, most importantly, hacking is fun!

Since it makes few sense to pack a Windows game as a Guix package, and also I don't know how to do it at all, let's simply prepare a perfect environment for Elona.

Manifest

Manifest for the environment is simple:

(use-modules (guix)
             (gnu packages)
             (gnu packages base))


(define-public elona-locales
  (make-glibc-utf8-locales
   glibc
   #:locales (list "en_US" "ja_JP" "zh_CN")
   #:name "elona-locales"))

(concatenate-manifests
 (list
  (packages->manifest (list elona-locales))
  (specifications->manifest
   '("coreutils"
     "wine64-staging"
     "grep"))))

Note that

  1. We need Wine, and wine64-staging seems to perform best at my site
  2. grep is used later to search for locale path, see below.
  3. We declare a smaller version of locales, named elona-locales.

Environment Script

Next, let's write the script used to enter Guix shell container. Inspired by (George 2023).

#!/usr/bin/env bash
set -ex

exec guix time-machine --channels=channels.scm --  shell \
     --container \
     --network \
     --share=/dev/snd/seq \
     --preserve='^DISPLAY$' --preserve='^XAUTHORITY$' \
     --expose=$XAUTHORITY \
     --expose=/sys/class/input \
     --expose=/sys/devices \
     --expose=/sys/dev \
     --expose=/sys/bus/pci \
     --preserve='XDG_RUNTIME_DIR' \
     --expose="$XDG_RUNTIME_DIR/pulse" \
     --expose=/dev/dri \
     -m manifest.scm

Note that

  • --network seems to be required for X11/Wine.
  • Even if the host is using pipewire, we still need to --expose="$XDG_RUNTIME_DIR/pulse" for sound.

Run Script

export GUIX_LOCPATH=/gnu/store/$(ls -F /gnu/store | grep 'elona-locales.*/' | tail -n 1)lib/locale
export LOCPATH=$GUIX_LOCPATH

export LC_COLLATE=ja_JP.utf8
export LC_CTYPE=ja_JP.utf8

export WINEPREFIX=$(pwd)/prefix

wine elona/elona.exe

Run script is pretty straightforward too:

  1. Set up Locale path. The grep trick is from (Żelazny and Tournier 2020).
  2. Export locale settings. This is based on (Chicken 2019).
  3. Export Wine setting.
  4. Run the game, and enjoy!

Wrap-up

I put the scripts in a public repo, with short documentation on how to use them.

Reference

Chicken, Biting. 2019. “Running Elona via Wine.” August 2, 2019. https://elona.fandom.com/wiki/User_blog:Biting_Chicken/Running_Elona_via_Wine.
George, Steve. 2023. “Guix Shell for Virtual Environments and Containers.” April 29, 2023. https://www.futurile.net/2023/04/29/guix-shell-virtual-environments-containers/.
Żelazny, Wiktor, and Simon Tournier. 2020. “Locales in a Guix Container (Somewhat Related to R-Readr)?” February 20, 2020. https://lists.gnu.org/archive/html/help-guix/2020-02/msg00170.html.