{ lib , alsa-lib , factorio-utils , fetchurl , libGL , libICE , libSM , libX11 , libXcursor , libXext , libXi , libXinerama , libXrandr , libpulseaudio , libxkbcommon , makeDesktopItem , makeWrapper , releaseType , stdenv , wayland , mods ? [ ] , mods-dat ? null , versionsJson ? ./versions.json , username ? "" , token ? "" # get/reset token at https://factorio.com/profile , experimental ? false # true means to always use the latest branch }: assert releaseType == "alpha" || releaseType == "headless" || releaseType == "demo"; let inherit (lib) importJSON; helpMsg = '' ===FETCH FAILED=== Please ensure you have set the username and token with config.nix, or /etc/nix/nixpkgs-config.nix if on NixOS. Your token can be seen at https://factorio.com/profile (after logging in). It is not as sensitive as your password, but should still be safeguarded. There is a link on that page to revoke/invalidate the token, if you believe it has been leaked or wish to take precautions. Example: { packageOverrides = pkgs: { factorio = pkgs.factorio.override { username = "FactorioPlayer1654"; token = "d5ad5a8971267c895c0da598688761"; }; }; } Alternatively, instead of providing the username+token, you may manually download the release through https://factorio.com/download , then add it to the store using e.g.: releaseType=alpha version=0.17.74 nix-prefetch-url file://\''$HOME/Downloads/factorio_\''${releaseType}_x64_\''${version}.tar.xz --name factorio_\''${releaseType}_x64-\''${version}.tar.xz Note the ultimate "_" is replaced with "-" in the --name arg! ''; desktopItem = makeDesktopItem { name = "factorio"; desktopName = "Factorio"; comment = "A game in which you build and maintain factories."; exec = "factorio"; icon = "factorio"; categories = [ "Game" ]; }; branch = if experimental then "experimental" else "stable"; # NB `experimental` directs us to take the latest build, regardless of its branch; # hence the (stable, experimental) pairs may sometimes refer to the same distributable. versions = importJSON versionsJson; binDists = makeBinDists versions; actual = binDists.${stdenv.hostPlatform.system}.${releaseType}.${branch} or (throw "Factorio ${releaseType}-${branch} binaries for ${stdenv.hostPlatform.system} are not available for download."); makeBinDists = versions: let f = path: name: value: if builtins.isAttrs value then if value ? "name" then makeBinDist value else builtins.mapAttrs (f (path ++ [ name ])) value else throw "expected attrset at ${toString path} - got ${toString value}"; in builtins.mapAttrs (f [ ]) versions; makeBinDist = { name, version, tarDirectory, url, sha256, needsAuth }: { inherit version tarDirectory; src = if !needsAuth then fetchurl { inherit name url sha256; } else (lib.overrideDerivation (fetchurl { inherit name url sha256; curlOptsList = [ "--get" "--data-urlencode" "username@username" "--data-urlencode" "token@token" ]; }) (_: { # This preHook hides the credentials from /proc preHook = if username != "" && token != "" then '' echo -n "${username}" >username echo -n "${token}" >token '' else '' # Deliberately failing since username/token was not provided, so we can't fetch. # We can't use builtins.throw since we want the result to be used if the tar is in the store already. exit 1 ''; failureHook = '' cat <