{ lib, alsa-lib, factorio-utils, fetchurl, libGL, libICE, libSM, libX11, libXcursor, libXext, libXi, libXinerama, libXrandr, libpulseaudio, libxkbcommon, makeDesktopItem, makeWrapper, releaseType, stdenv, wayland, 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 ... }@args: assert releaseType == "alpha" || releaseType == "headless" || releaseType == "demo" || releaseType == "expansion"; let inherit (lib) importJSON; mods = args.mods or [ ]; 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! If you go this route you might want to tell Nix to explicitly hold on to the source tarball. Otherwise it could get GC'd from the Nix store and you'd have to redownload it next time the package wants to rebuild to use a newer dependency. E.g. if you're using NixOS: system.extraDependencies = [ factorio.src ]; ''; 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, candidateHashFilenames ? [ ], }: { 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 <