(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 algebra) #:use-module (gnu packages audio) #:use-module (gnu packages base) #:use-module (gnu packages bash) #:use-module (gnu packages build-tools) #:use-module (gnu packages compression) #:use-module (gnu packages curl) #: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 lua) #:use-module (gnu packages pkg-config) #:use-module (gnu packages pulseaudio) #:use-module (gnu packages sdl) #:use-module (gnu packages serialization) #:use-module (gnu packages speech) #:use-module (gnu packages textutils) #:use-module (gnu packages tls) #:use-module (gnu packages version-control) #: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 meson) #:use-module (guix build-system trivial) #:use-module (guix download) #:use-module (guix git-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:)) ;; Simutrans (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" "PROG=simutrans") #: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'. (install-file "build/default/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.")))) (define-public simutrans-makeobj (package (inherit simutrans) (name "simutrans-makeobj") (arguments `(#:make-flags '("VERBOSE=1" "OPTIMISE=1" "OSTYPE=linux" "BACKEND=posix" "makeobj") #:tests? #f ; there are no tests for makeobj #: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) (install-file "build/default/makeobj/makeobj" (string-append (assoc-ref outputs "out") "/bin"))))))) (inputs (list libpng)) (native-inputs (list pkg-config)) (synopsis "Addon compiler for Simutrans") (description "@code{makeobj} compiles images and configuration files into addons for the Simutrans game, as @code{.pak} files."))) (define-public simutrans-pak128 (let ((version "2.8.2") ; last tagged version (revision "39") ; number of commits since last tagged version (commit "02ff45afdd3003c258c45aeb3d28b3b25f10172e")) ; latest as of 2023-04-30 (package (name "simutrans-pak128") ; note: needs simutrans >= 123 (version (git-version version revision commit)) (source (origin (method git-fetch) (uri (git-reference (url "https://github.com/simutrans/pak128") (commit commit))) (file-name (git-file-name name version)) (sha256 (base32 "0jg5yc769xrn22wn29ch0nz414xv518cdwkpk6makb14kh6zpdz4")))) (native-inputs (list simutrans-makeobj zip git)) (build-system gnu-build-system) (arguments `(#:make-flags '("all") ; the "all" target builds the pak and installs it #:parallel-build? #f ; don't run "rm" in parallel with builds #:phases ,#~(modify-phases %standard-phases (delete 'bootstrap) (delete 'configure) (replace 'build (lambda* (#:key inputs outputs (make-flags '()) (parallel-build? #t) #:allow-other-keys) (let ((makeobj (search-input-file inputs "bin/makeobj")) (out (assoc-ref outputs "out"))) ((assoc-ref %standard-phases 'build) #:make-flags (cons* (string-append "MAKEOBJ=" makeobj) ;; Makefile adds /pak128 to DESTDIR. (string-append "DESTDIR=" out "/share/games/simutrans") (string-append "PAKID=pak128 " #$version " for " #$(package-version simutrans)) make-flags) #:parallel-build? parallel-build?)))) (delete 'check) (delete 'install)))) (home-page "https://forum.simutrans.com/index.php?board=26.0") (synopsis "Graphical pak set for Simutrans, 128x128 tile size") (description "This is a self-contained set of assets for the Simutrans game. When Simutrans could only support 64px size graphics, work on pak128 already started. This is the first pak set 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)))) ;; 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)) ;; Symlink the data files into place. Must be done first. (union-build #$output (list #$base-game #$@paksets)) ;; Install wrapper script to pass the right workdir to simutrans. ;; We can't use a `program-file' here since that would introduce ;; a circular dependency between that file and this package. (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))) ;; Kerbal Space Program ;; $ 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."))))) ;; Powder Toy (define-public powder-toy (package (name "powder-toy") (version "97.0.352") (source (origin (method git-fetch) (uri (git-reference (url "https://github.com/The-Powder-Toy/The-Powder-Toy") (commit (string-append "v" version)))) (file-name (git-file-name name version)) (sha256 (base32 "1kzf8m47f3rqp770rkjbmrcarm6rb46d0n4y456wlw0qiwfmsqiw")))) (build-system meson-build-system) (arguments `(#:configure-flags ,#~(list "-Dstatic=none" (string-append "-Dworkaround_elusive_bzip2_include_dir=" #$(file-append bzip2 "/include"))) #:phases (modify-phases %standard-phases ;; Ninja doesn't install the manpage. (add-after 'unpack 'install-manpage (lambda* (#:key inputs outputs #:allow-other-keys) (let* ((out (assoc-ref outputs "out")) (destination (string-append out "/share/man/man6/powder.6"))) (rename-file "resources/powder.man" "resources/powder.6") (install-file "resources/powder.6" (dirname destination)) ;; Compress manpage to match others on the system. (invoke (search-input-file inputs "bin/gzip") destination)))) ;; For some reason, ninja doesn't install the final binary properly. (replace 'install (lambda* (#:key outputs #:allow-other-keys) (let ((out (assoc-ref outputs "out"))) (install-file "powder" (string-append out "/bin")) (rename-file "resources/appdata.xml" "resources/powder.appdata.xml") (install-file "resources/powder.appdata.xml" (string-append out "/share/metainfo")) (install-file "resources/powder.desktop" (string-append out "/share/applications")))))))) ;; Guix' luajit works with lua-5.1. (inputs (list bzip2 fftwf jsoncpp curl libpng lua-5.1 luajit sdl2 zlib)) (native-inputs (list pkg-config gzip)) (home-page "https://powdertoy.co.uk/") (synopsis "Desktop version of the classic 'falling sand' physics sandbox") (description "Have you ever wanted to blow something up? Or maybe you always dreamt of operating an atomic power plant? Do you have a will to develop your own CPU? The Powder Toy lets you to do all of these, and even more! The Powder Toy is a free physics sandbox game, which simulates air pressure and velocity, heat, gravity and a countless number of interactions between different substances! The game provides you with various building materials, liquids, gases and electronic components which can be used to construct complex machines, guns, bombs, realistic terrains and almost anything else. You can then mine them and watch cool explosions, add intricate wirings, play with little stickmen or operate your machine. You can browse and play thousands of different saves made by the community or upload your own – we welcome your creations! There is a Lua API – you can automate your work or even make plugins for the game. The Powder Toy is free and the source code is distributed under the GNU General Public License, so you can modify the game yourself or help with development.") (license license:gpl3))) ;;; Oolite (define-public oolite (package (name "oolite") (version "1.90") (source (origin (method git-fetch) (uri (git-reference (url "https://github.com/OoliteProject/oolite") (commit version) (recursive? #t))) (file-name (git-file-name name version)) (sha256 (base32 "1fkirmgv303gq8mvg71zi66xfx11qm3ppqxyzirxwp983xjih9kw")))) (build-system gnu-build-system) (arguments `(#:phases (modify-phases %standard-phases (delete 'configure) ; no ./configure (replace 'build (lambda _ (invoke "make" "-f" "Makefile" "-j" "release-deployment")))))) (inputs (list espeak)) (native-inputs (list)) (home-page "https://oolite.space/") (synopsis "Open-world space opera game") (description "Oolite is inspired by the 8-bit classic Elite, and many aspects of gameplay will be familiar to players of that game. In the tradition of open-world games, there's no overall story: you can be a millionaire trader, a veteran combateer, a feared pirate, a lonely miner, a notorious smuggler, or all of them, or something else entirely, based on your own actions. For those new to the game, the @url{https://oolite.space/starting, getting started} page has some hints for beginners to see you safely through your first flight, and suggests ways to continue in future.") (license #f)))