about summary refs log tree commit diff
path: root/pkgs/games/gog/factorio/default.nix
diff options
context:
space:
mode:
authoraszlig <aszlig@nix.build>2020-12-28 09:30:45 +0100
committeraszlig <aszlig@nix.build>2020-12-30 16:37:54 +0100
commit2c24ba1d864d98d4c2c3a50501a41b61b43f854a (patch)
tree3b7346ea52c84a34cc66fb94ed97c25c6a0e4ba5 /pkgs/games/gog/factorio/default.nix
parent4f91df5db28a67fda6eca81ae9be7e580e637f98 (diff)
games: Add Factorio
This has been laying around since a few weeks but instead of just using
a simple shell script wrapper (which I had in the first place), I
decided to directly patch the binary during rC3.

The main reason why I went this route was because in the long run we
want to have a generic implementation we can use to patch all sorts of
games, similar to what we have with monogame-patcher.

So the way the *current* patcher roughly works is by allocating an area
called "compost", which is then used as some kind of abstraction for
allocating code and data to be used for the references/logic that we
need to patch.

The latter involves patching XDG_DATA_HOME into the game and changing
the "/usr/share/factorio" path to use the ones within the store path
($out/share/factorio). Fortunately, Factorio already assumes that
everything within /usr/share/factorio (or our path for that matter) is
read-only, so we don't need to add extra code/conditions specifically to
handle that.

Patching both cases is made possible by patching a third location
(get_executable_name), which tries to get the current executable path
via several methods (using /proc/self/exe, running "ps", ...) at
runtime, which in our case is really unnecessary and a perfect
opportunity to replace the function logic by the hardcoded path and
using the rest of the function for our compost area.

While patching might sound straigtforward, I actually introduced two
little (but hard to debug) bugs, where I'm very grateful to all those
folks (you know who you are) at rC3 who were actually following along
and provided helpful input.

In the long term, the goal is to rewrite the patcher with more elaborate
type information (eg. right now function/opcode information is raw JSON)
and generalise it enough that we can use it to get rid of a few other
wrappers.

Signed-off-by: aszlig <aszlig@nix.build>
Diffstat (limited to 'pkgs/games/gog/factorio/default.nix')
-rw-r--r--pkgs/games/gog/factorio/default.nix44
1 files changed, 44 insertions, 0 deletions
diff --git a/pkgs/games/gog/factorio/default.nix b/pkgs/games/gog/factorio/default.nix
new file mode 100644
index 00000000..109e03a2
--- /dev/null
+++ b/pkgs/games/gog/factorio/default.nix
@@ -0,0 +1,44 @@
+{ lib, buildGame, fetchGog, alsaLib, libGL, libpulseaudio, xorg
+, python3, python3Packages, runCommand
+}:
+
+buildGame rec {
+  name = "factorio-${version}";
+  version = "1.0.0";
+
+  src = fetchGog {
+    productId = 1238653230;
+    sha256 = "1n6a4qbp9i161jdn0f28ih7zc1blraqk0ypi3pizkc7ddc7bb7ja";
+  };
+
+  nativeBuildInputs = [ python3 python3Packages.r2pipe ];
+
+  buildInputs = [
+    alsaLib libGL libpulseaudio xorg.libICE xorg.libSM xorg.libX11
+    xorg.libXcursor xorg.libXext xorg.libXinerama xorg.libXrandr
+  ];
+
+  postPatch = "python3 ${lib.escapeShellArg (runCommand "patcher" {
+    src = lib.sourceFilesBySuffices ./. [ ".py" ];
+    nativeBuildInputs = [
+      python3Packages.mypy
+      python3Packages.flake8
+      python3Packages.pytest
+      python3Packages.hypothesis
+      python3Packages.r2pipe
+    ];
+  } ''
+    pytest "$src" -o "cache_dir=$PWD"
+    mypy "$src"
+    flake8 "$src"
+    install -vD -m 0644 "$src/patch.py" "$out"
+  '')} bin/x64/factorio";
+
+  installPhase = ''
+    install -vD bin/x64/factorio "$out/bin/factorio"
+    mkdir -p "$out/share"
+    cp -rT data "$out/share/factorio"
+  '';
+
+  sandbox.paths.required = [ "$XDG_DATA_HOME/factorio" ];
+}