- Nix, Manager of Packages 🐲
- Flakes, The Mysterious One ❄️
- Home Manager, Manager of Home Directories 🏰
First, bust out your favorite text editor and add the repository to your flake:
[^]
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
home-manager = {
url = "github:nix-community/home-manager/master";
inputs.nixpkgs.follows = "nixpkgs";
};
nix-mod-manager.url = "github:nowaaru/nix-mod-manager/master";
};
outputs = {
home-manager,
nix-mod-manager, # 🌟
[v]
Afterwards, add it to your Home Manager configuration either as an import in a module file or directly through the module list:
[^]
specialArgs = {inherit inputs;};
modules = [];
};
homeConfigurations."rainbow-road" = home-manager.lib.homeManagerConfiguration {
inherit pkgs;
extraSpecialArgs = {inherit inputs;};
modules = [
nix-mod-manager.homeManagerModules.default # 🌟
./home.nix
];
};
[v]
And, voilà! nix-mod-manager is finally ready to roll! To start configuring, make a new module for your Home Manager configuration:
[^]
};
homeConfigurations."rainbow-road" = home-manager.lib.homeManagerConfiguration {
inherit pkgs;
extraSpecialArgs = {inherit inputs;};
modules = [
nix-mod-manager.homeManagerModules.default
./nix-mod-manager.nix # 🌟
./home.nix
];
};
};
nix-mod-manager's default module exports the programs.nix-mod-manager
module for you to change to your liking. To see what fields you can customize, check out the customization index.
The nix-mod-manager's lib
output contains the nnmm
(noire's-nix-mod-manager) library. In this library contains a handful of useful functions for things like creating mod derivations through referencing store files and fetching from remote CDNs.
nix-mod-manager exports the programs.nix-mod-manager
module. For the module to work, the enable
property must be set to true:
{
programs.nix-mod-manager = {
enable = true;
};
}
A game that is managed is called a client. The property is also aptly named clients
and requires an attribute set of attribute sets. Like the module, clients must also be enabled for their mods to be deployed:
{
programs.nix-mod-manager = {
enable = true;
clients = {
monster-hunter-world = {
enable = true;
};
};
};
}
A client requires a modsPath
and a rootPath
to be functional. The rootPath
field should be relative to the $HOME
(~
) directory, and the modsPath
field should be relative to the rootPath
field. If necessary, you can specify a binaryPath
for paired usage with binary mods.
{
programs.nix-mod-manager = {
enable = true;
clients = {
monster-hunter-world = {
enable = true;
modsPath = "nativePC";
rootPath = ".local/share/Steam/steamapps/common/Monster Hunter World";
binaryPath = "bin/";
};
};
};
}
A mod manager isn't a mod manager without mods. To get started, we'll be using Dynamic Acrylic Graphics (DAGs) from Home Manager. Mods can either be fetched via turning a store path into a derivation or fetching it through a fetcher. If a mod needs to be placed alongside the binary, the binaryMods
DAG should suffice.
with lib.nnmm; with fetchers;
{
programs.nix-mod-manager = {
enable = true;
clients = {
monster-hunter-world = {
enable = true;
modsPath = "nativePC";
rootPath = ".local/share/Steam/steamapps/common/Monster Hunter World";
binaryMods = {
example-binary-mod-0 = entryAnywhere (fetchGameBanana {
name = "my-super-cool-gamebanana-mod";
hash = lib.fakeHash;
});
};
mods = {
example-mod-0 = entryAfter ["example-binary-mod-0"] (mkLocalMod {
name = "example-mod-0";
store-path = /nix/store/...;
});
example-mod-1 = entryAfter ["example-binary-mod-1"] (mkLocalMod {
name = "example-mod-1";
store-path = /nix/store/...;
});
};
};
};
};
}
There is also a deploymentType
option that allows you to determine how mods are placed in the modsPath. It requires one of "organized"
or "loose"
, but set to "organized"
by default. The loose
type will drop the artifacts directly into the staging "modsPath"
, meanwhile the "organized"
type will make a numerically sorted list of folders depending on the load order:
with lib.nnmm; with fetchers;
{
programs.nix-mod-manager = {
enable = true;
clients = {
monster-hunter-world = {
enable = true;
modsPath = "nativePC";
deploymentType = "loose"; # 🌟
rootPath = ".local/share/Steam/steamapps/common/Monster Hunter World";
binaryMods = {
example-binary-mod-0 = entryAnywhere (fetchGameBanana {
name = "my-super-cool-gamebanana-mod";
hash = lib.fakeHash;
});
};
mods = {
example-mod-0 = entryAfter ["example-binary-mod-0"] (mkLocalMod {
name = "example-mod-0";
store-path = /nix/store/...;
});
example-mod-1 = entryAfter ["example-binary-mod-1"] (mkLocalMod {
name = "example-mod-1";
store-path = /nix/store/...;
});
};
};
};
};
}
If you don't know what to make a pull request about, then please don't bother to search for a reason, instead use the project a little bit and figure out something you don't like or something that you think most of the userbase would collectively enjoy. Misspellings and accidental character placements will be addressed at some point, but it is of nothing of urgency to make a pull request for. This isn't a repository you can farm points on!
If you notice something wrong with the project or the way it functions, let me know by making an issue! I'll get on it as quickly as my fingers 💅 and brain 🧠 allows me to - the latter of which likely being the bottleneck.
When making an issue, do be sure to remember the human and remember the newbie. Despite the facade of an anime icon or a mysterious set of blue-tinted buildings with a red room, there's still a human behind that icon, and that human could very well be new to what they're coming across. Newcomers will soon be our replacements, so no reason to bite the hand that will feed us the following day!
While creating nix-mod-manager, I had a very strong intention to use as much Nix as possible and rely as little on shell scripts to get a better grasp of the language, but now I feel it's to upkeep the "nix" aspect of the name. When making contributions, I would prefer and deeply appreciate if contributors used the intended language whenever they can (within reason).