(define-module (tw packages games) #:use-module ((srfi srfi-26) #:select (cut)) #:use-module ((ice-9 string-fun) #:select (string-replace-substring)) #:use-module (gnu packages audio) #:use-module (gnu packages base) #:use-module (gnu packages bash) #:use-module (gnu packages compression) #:use-module (gnu packages elf) #:use-module (gnu packages fonts) #:use-module (gnu packages fontutils) #:use-module (gnu packages freedesktop) #:use-module (gnu packages gcc) #:use-module (gnu packages gl) #:use-module (gnu packages glib) #:use-module (gnu packages gtk) #:use-module (gnu packages guile) #:use-module (gnu packages image) #:use-module (gnu packages linux) #:use-module (gnu packages pkg-config) #:use-module (gnu packages pulseaudio) #:use-module (gnu packages sdl) #:use-module (gnu packages textutils) #:use-module (gnu packages xorg) #:use-module (guix build utils) #:use-module (guix build-system copy) #:use-module (guix build-system gnu) #:use-module (guix build-system trivial) #:use-module (guix download) #:use-module (guix gexp) #:use-module ((guix licenses) #:prefix license:) #:use-module (guix modules) #:use-module (guix packages) #:use-module (nonguix build-system binary) #:use-module ((nonguix licenses) #:prefix nonguix-license:)) (define-public simutrans-pak128 ;; Install paks as propagated-inputs of simutrans, so they go in ;; Simutrans' data directory, where Simutrans expects them. (package (name "simutrans-pak128") ; note: needs simutrans >= 123 (version "2.8.2") (source (origin (method url-fetch) (uri (string-append "mirror://sourceforge/simutrans/pak128/" "pak128%202.8.2%20for%20ST%20123up/simupak128-2.8.2-for123.zip")) (sha256 (base32 "0hzpb6bh1lh0fdcpxlbfw5j74xz65gxl8yx5094rqf5zflvz10py")))) (native-inputs (list unzip)) ; shouldn't copy-build-system / origin handle this? (build-system copy-build-system) (arguments '(#:install-plan '(("pak128" "share/games/simutrans/pak128")))) (home-page "https://forum.simutrans.com/index.php?board=26.0") (synopsis "Graphical pak set for Simutrans, 128x128 tile size") (description (string-append "When Simutrans could only support 64px size graphics, pak128 already started. " "First pak to feature a complex economy and have a very wide variety of objects. " "It contains roughly 7 times more graphic data than pak64 and thus requires by far " "the largest amount of RAM and processing power of all Simutrans sets.")) (license license:artistic2.0))) (define-public simutrans ;; Based off the Arch Linux package: ;; https://github.com/archlinux/svntogit-community/blob/packages/simutrans/trunk/PKGBUILD ;; I took the idea of a wrapper script from the Nix package: ;; https://github.com/NixOS/nixpkgs/blob/master/pkgs/games/simutrans/default.nix (package (name "simutrans") (version "123.0.1") (source (origin (method url-fetch/zipbomb) (uri (let ((version/- (string-replace-substring version "." "-"))) (string-append "mirror://sourceforge/simutrans/simutrans/" version/- "/simutrans-src-" version/- ".zip"))) ;; Use `guix hash -H sha256 '. (sha256 (base32 "0sgl2hrgjd2cyw3fbcvpq29dwf0w2sdlpp8ccic5bys1vv43iswd")) (patches (list (local-file "files/simutrans-paths.patch"))))) (build-system gnu-build-system) (arguments `(#:make-flags '("VERBOSE=1" "OPTIMISE=1" "OSTYPE=linux" "BACKEND=sdl2" "MULTI_THREAD=1" "USE_ZSTD=1" "USE_FREETYPE=1" "USE_FLUIDSYNTH_MIDI=1") #:tests? #f ; tests don't work as SDL2 can't find a video device #:test-target "test" ; run "make test" for tests #:phases ,#~(modify-phases %standard-phases (replace 'bootstrap (lambda _ (apply invoke #+(file-append dos2unix "/bin/dos2unix") "-q" (find-files ".")) (substitute* "Makefile" (("\\\\#define") "#define")))) (replace 'configure (lambda _ (copy-file "config.template" "config.default"))) (replace 'install (lambda* (#:key outputs #:allow-other-keys) (let ((out (assoc-ref outputs "out"))) ;; Install "real" simutrans executable into libexec, as we need ;; a wrapper script to be installed by `simutrans-pak-union'. (with-directory-excursion "build/default" (rename-file "sim" "simutrans") (install-file "simutrans" (string-append out "/libexec"))) ;; Install game data bundled with simutrans (not the pak). (let ((data (string-append out "/share/games/simutrans"))) (mkdir-p data) (copy-recursively "simutrans" data)) ;; Install extra helper files. (install-file "simutrans.svg" (string-append out "/share/icons/hicolor/scalable/apps")) (install-file #+(local-file "files/simutrans.desktop") (string-append out "/share/applications")) (install-file #+(local-file "files/simutrans.appdata.xml") (string-append out "/share/metainfo")))))))) (inputs (list `(,zstd "lib") freetype fluidsynth ; technically optional zlib bzip2 libpng sdl2)) ; required (native-inputs (list pkg-config)) ; build-time deps (home-page "https://www.simutrans.com/") (synopsis "Transportation simulation game") (description "Simutrans is a freeware and open-source transportation simulator. Your goal is to establish a successful transport company. Transport passengers, mail and goods by rail, road, ship, and even air. Interconnect districts, cities, public buildings, industries and tourist attractions by building a transport network you always dreamed of. @strong{Warning:} This package by itself does not include any paksets. Install a @code{simutrans-with-pak*} package instead.") (license (license:non-copyleft "file://simutrans/license.txt" "This is Simutrans' custom artistic license.")))) ;; See also: `sdl-union' in (gnu packages sdl). (define* (simutrans-pak-union name #:optional (paksets (list simutrans-pak128)) (base-game simutrans)) "Return union package called NAME which is a union of BASE-GAME and PAKSETS. If PAKSETS are not specified, simutrans is bundled with some default paksets." (package (name name) (version (package-version base-game)) (source #f) (build-system trivial-build-system) (arguments `(#:builder ,(with-imported-modules (source-module-closure '((guix build union) (guix build utils))) #~(begin (use-modules ((srfi srfi-26) #:select (cut)) (guix build union) (guix build utils)) (union-build #$output (list #$base-game #$@paksets)) ;; Install wrapper script to pass the right workdir to simutrans. (mkdir-p (string-append #$output "/bin")) (call-with-output-file (string-append #$output "/bin/simutrans") (cut format <> "#! ~a/bin/guile --no-auto-compile~%!#~%~s~%" #$guile-3.0 `(apply execl ,(string-append #$output "/libexec/simutrans") "simutrans" "-set_workdir" ,(string-append #$output "/share/games/simutrans") (cdr (command-line))))) (chmod (string-append #$output "/bin/simutrans") #o755))))) (inputs (cons* guile-3.0 base-game paksets)) (synopsis "Union of Simutrans with paksets") (description "A union of the Simutrans game with some of its paksets. A union is required because Simutrans assumes that its paksets are installed in the same directory as assets from the base game, such as music files.") (home-page (package-home-page base-game)) (license (map package-license (cons base-game paksets))))) (define-public simutrans/pak128 (simutrans-pak-union "simutrans-with-pak128" (list simutrans-pak128))) ;; TODO: package Widelands 1.1 ;; https://github.com/widelands/widelands/releases/tag/v1.1 ;; $ guix download KSP-Breaking_Ground_Expansion-en-us-lin-1.7.1.zip ;; /gnu/store/mlrsbl99rjmx0ss7im9d26rnxg98mb04-KSP-Breaking_Ground_Expansion-en-us-lin-1.7.1.zip ;; 0k3agr1ycdk8cll54wn63r6hdzbjpcj7wsjl003wkpza410x4ja8 ;; TODO: package Breaking Ground DLC (define-public kerbal-space-program (package (name "kerbal-space-program") (version "1.12.5") (source (origin (method url-fetch) (uri (string-append "file://" (getenv "HOME") "/installers/games/ksp-linux-" version ".zip")) (sha256 (base32 "0rxh25wmx4bpxdjjmci77356j60d37w6p1rvh72m38z41fyyzq0a")))) (build-system binary-build-system) ;; Linux Installer instructions from KSP_linux/readme.txt: ;; * Uncompress the file provided ;; * Place the contents of the file in your KSP installation directory ;; * Run the script called dlc-mhe-[lang].command ; this doesn't seem to exist... (supported-systems '("x86_64-linux")) (arguments `(#:patchelf-plan '(("KSPLauncher_Data/Plugins/x86_64/ScreenSelector.so" ("glibc" "gcc:lib" "mesa" "gtk+" "atk" "glib" "pango" "gdk-pixbuf" "cairo" "freetype" "fontconfig")) ("UnityPlayer.so" ;; Unity tries to load the following dynamically (even though they ;; don't show up in ldd output). Not sure what it does on Wayland. ("glibc" "gcc:lib" "mesa" "libx11" "libxext" "libxcursor" "libxinerama" "libxi" "libxrandr" "libxscrnsaver" "libxxf86vm" "pulseaudio" "alsa-lib" "eudev")) ;; Mesa doesn't show up in ldd output, but is loaded by the launcher ;; and KSP itself. ,@(map (cut list <> '("glibc" "gcc:lib" "mesa")) '("KSPLauncher.x86_64" "KSPLauncher_Data/MonoBleedingEdge/x86_64/libMonoPosixHelper.so" "KSPLauncher_Data/MonoBleedingEdge/x86_64/libmonobdwgc-2.0.so" "KSP.x86_64" "KSP_Data/MonoBleedingEdge/x86_64/libMonoPosixHelper.so" "KSP_Data/MonoBleedingEdge/x86_64/libmonobdwgc-2.0.so" "KSP_Data/Plugins/libkeyboard.so" "KSP_Data/Plugins/liblingoona.grammar.kerbal.so" "KSP_Data/Plugins/libsteam_api.so"))) #:install-plan '(("./" "share/kerbal-space-program/")) #:phases ,#~(modify-phases %standard-phases (add-after 'patchelf 'add-origin-to-rpath ;; KSP.x86_64 needs to be able to find UnityPlayer.so. (lambda _ (use-modules (ice-9 popen)) (let* ((patchelf #+(file-append patchelf "/bin/patchelf")) (port (open-pipe* OPEN_READ patchelf "--print-rpath" "KSP.x86_64")) (rpath (symbol->string (read port))) (new-rpath (string-append rpath ":$ORIGIN"))) (close-pipe port) (invoke patchelf "--set-rpath" new-rpath "KSP.x86_64")))) (add-after 'install 'wrap-game (lambda* (#:key inputs outputs #:allow-other-keys) (wrap-program (search-input-file outputs "share/kerbal-space-program/KSP.x86_64") #:sh (search-input-file inputs "/bin/sh") `("LC_ALL" "" = ("C")) `("PATH" ":" = (;; KSP runs "sh -c 'setxkbmap -print'" on startup. ,(string-append (assoc-ref inputs "bash-minimal") "/bin") ,(string-append (assoc-ref inputs "setxkbmap") "/bin") ;; Hopefully, this will allow opening web links in the main menu. ,(string-append (assoc-ref inputs "xdg-utils") "/bin")))))) (add-after 'install 'wrap-launcher ;; The launcher calls out to xdg-open and uname for some actions. (lambda* (#:key inputs outputs #:allow-other-keys) (wrap-program (search-input-file outputs "share/kerbal-space-program/KSPLauncher.x86_64") #:sh (search-input-file inputs "/bin/sh") `("PATH" ":" = (,(string-append (assoc-ref inputs "xdg-utils") "/bin") ,(string-append (assoc-ref inputs "coreutils") "/bin")))))) (add-after 'install 'install-overlay-launcher (lambda* (#:key inputs outputs #:allow-other-keys) (let ((out (assoc-ref outputs "out"))) (mkdir-p (string-append out "/bin")) (call-with-output-file (string-append out "/bin/ksp") (lambda (port) (chmod port #o555) ; make executable (display (string-append "\ #!" (assoc-ref inputs "bash-minimal") "/bin/sh -e ret=0 dir=$XDG_DATA_HOME/ksp-overlay mkdir -p \"$dir/upper\" \"$dir/work\" \"$dir/merged\" echo 'Mounting overlayfs' >&2 sudo mount -t overlay overlay \"$dir/merged\" -o \\ \"lowerdir=" out "/share/kerbal-space-program,upperdir=$dir/upper,workdir=$dir/work,metacopy=on\" # Make files writable in the overlay, so that KSP can overwrite the ones it needs to. # This relies on metacopy=on for efficiency (so file data isn't copied to the upperdir on chown). echo 'Adjusting permissions' >&2 sudo find \"$dir/merged\" -exec chown \"$(id -u):$(id -g)\" '{}' + -exec chmod u+w '{}' + echo 'Running KSP' >&2 \"$dir/merged/KSP.x86_64\" \"$@\" || ret=$? echo 'Unmounting overlayfs' >&2 sudo umount \"$dir/merged\" exit $ret ") port))))))))) (inputs `(("glibc" ,glibc) ("gcc:lib" ,gcc "lib") ("mesa" ,mesa) ("gtk+" ,gtk+-2) ("atk" ,atk) ("glib" ,glib) ("pango" ,pango) ("gdk-pixbuf" ,gdk-pixbuf) ("cairo" ,cairo) ("freetype" ,freetype) ("fontconfig" ,fontconfig) ("libx11" ,libx11) ("libxext" ,libxext) ("libxcursor" ,libxcursor) ("libxinerama" ,libxinerama) ("libxi" ,libxi) ("libxrandr" ,libxrandr) ("libxscrnsaver" ,libxscrnsaver) ("libxxf86vm" ,libxxf86vm) ("pulseaudio" ,pulseaudio) ("alsa-lib" ,alsa-lib) ("eudev" ,eudev) ("bash-minimal" ,bash-minimal) ("coreutils" ,coreutils) ("xdg-utils" ,xdg-utils) ("setxkbmap" ,setxkbmap))) (native-inputs (list unzip)) (home-page "https://www.kerbalspaceprogram.com/game/kerbal-space-program/") (synopsis "Rocketry simulation game") (description "Create and manage your own space program. Build spacecraft, fly them, and try to help the Kerbals fulfill their ultimate mission of conquering space. This is the original KSP, not the early-access KSP2. Note: KSP seems to require a writable game directory (e.g., in order to write its @samp{settings.cfg}). This means that the game will not run properly from @samp{/gnu/store}, and must be copied somewhere else first, for instance using @samp{rsync -a $(guix build kerbal-space-program)/share/kerbal-space-program/ ~/ksp/ && chmod -R u+w ~/ksp && ~/ksp/KSP.x86_64}.") (license (list (nonguix-license:undistributable "https://www.take2games.com/eula/") (license:non-copyleft "file://LegalNotice.txt" "Contains components licensed under various permissive licenses.")))))