Skip to content

WIP: Launcher library + example (Quake 3)

Ambrevar requested to merge launcher into master

From issue #8 the need for runtime installers / configurators becomes quite clear. So we need game wrappers that:

  • find the game data;
  • install the game and possibly patch it;
  • start the game.

This means that the launcher must be able to read ~/.config/guix-gaming/games.scm, which is non-trivial in Bash. Anyways, writing wrappers in Bash is a pain, it's weak, not-flexible and error-prone.

So I thought "why not writing them in Guile"? Guile is a necessary dependency of Guix, so it comes for free.

I've worked on it, and here is an excerpt of the quake-3-arena argument (using the trivial build system):

(for-each
 pretty-print
 `((load-compiled
    ;; TODO: Calling load-compiled has the benefit of not
    ;; requiring the guile-guix-launcher-lib input to be
    ;; propagated, but use-module is more idiomatic.  More pros and cons?
    ,(string-append (assoc-ref %build-inputs "guile-guix-launcher-lib")
                    "/lib/guile/"
                    "2.2"
                    "/site-ccache/guix/build/utils.go"))

   (load-compiled
    ,(string-append (assoc-ref %build-inputs "guile-guix-launcher-lib")
                    "/lib/guile/"
                    "2.2"
                    "/site-ccache/guix-gaming/launcher/utils.go"))

   (use-modules (ice-9 match)
                (guix build utils)
                (guix-gaming launcher utils))

   (define help "Could not find the game key.") ; TODO: Improve message.

   (let ((path (string-append (getenv "HOME") "/.q3a/baseq3/q3key")))
     (unless (file-exists? path)
       (mkdir-p (dirname path))
       ;; TODO: Don't fail when key is missing.
       (let* ((config (read-config help 'quake-3-arena))
              (key (assoc-ref config 'key))))
       (with-output-to-file path
         (lambda _
           (format #t "~a~%" key))))
     ;; ARCH must be double-unquoted here.
     (system* ,(string-append "./ioquake3." ,arch)))))

With a dedicated build system, we could even remove the shabang line and the load-compileds.

Pretty cool, nah?

Notice that I've created a dedicated Guile library which includes (guix build utils) and (guix-gaming launcher utils), so that the launcher can use them without depending on either Guix nor this channel. Question: can we actually depend on channels and use their libraries? Don't know if it's a good idea, maybe my library approach is better.

Thoughts? @roptat @wordempire @ajgrf ?

Edited by Ambrevar

Merge request reports