Introduction

This flake provides a number of modules for creating and managing steam game severs by leveraging [nix-steam-fetcher] to download the game server files into the /nix/store.

It loosely grouped into two components:

  1. A generic services.steam-servers.servers module that provides a convenient set of options for setting up most steam servers
  2. Opinionated modules (such as services.steam-servers.stationeers) which provide a more tailored experience for specific games. These modules use services.steam-servers.servers under-the-hood.

Installation

With flakes

Add nix-steam-servers to your inputs:

{ # flake.nix
  inputs = {
    steam-servers.url = "github:scottbot95/nix-steam-servers";
    steam-servers.inputs.nixpkgs.follows = "nixpkgs"; # Optional
  };
}

Include the exported nixos module in your configuration:

{ # configuration.nix
  imports = [
    inputs.steam-servers.nixosModules.default
  ];
}

Without flakes

This repo is currently only avaiable with flakes.

Basic Usage

The simplest use-case is one of the pre-defined opinionated modules for a specific game. For example, creating a basic Stationeers server could look something like this:

{ # configuration.nix
  services.steam-servers.servers = {
    services.steam-servers.stationeers.my-server = {
      enable = true;
      openFirewall = true;
      # Any customizations...
    };
  };
}

Advanced Usage

For games that don't (yet) have an opinionated module written for them, it is possible to use the generic services.steam-servers.servers module that all the opinionated modules are built on top of.

The key part of generic servers is the executable option. This is the path to the executable that will be started. It may be an absolute path, or a path relative to the datadir.

The other primary feature that services.steam-server.servers provides is the ability to construct files in the datadir by either symlinking them in, or by creating a writeable file with pre-defined contents. There are three options to this effect: symlinks, files, and dirs. Both symlinks and files accept a struct where the keys are the file/symlink that will be created in datadir and the values are either an absolute path to copy/symlink or a struct defining how to create the file.

_module.args

Additional arguments passed to each module in addition to ones like lib, config, and pkgs, modulesPath.

This option is also available to all submodules. Submodules do not inherit args from their parent module, nor do they provide args to their parent module or sibling submodules. The sole exception to this is the argument name which is provided by parent modules to a submodule and contains the attribute name the submodule is bound to, or a unique generated name if it is not bound to an attribute.

Some arguments are already passed by default, of which the following cannot be changed with this option:

  • lib: The nixpkgs library.

  • config: The results of all options after merging the values from all modules together.

  • options: The options declared in all modules.

  • specialArgs: The specialArgs argument passed to evalModules.

  • All attributes of specialArgs

    Whereas option values can generally depend on other option values thanks to laziness, this does not apply to imports, which must be computed statically before anything else.

    For this reason, callers of the module system can provide specialArgs which are available during import resolution.

    For NixOS, specialArgs includes modulesPath, which allows you to import extra modules from the nixpkgs package tree without having to somehow make the module aware of the location of the nixpkgs or NixOS directories.

    { modulesPath, ... }: {
      imports = [
        (modulesPath + "/profiles/minimal.nix")
      ];
    }
    

For NixOS, the default value for this option includes at least this argument:

  • pkgs: The nixpkgs package set according to the nixpkgs.pkgs option.

Type: lazy attribute set of raw value

Declared by:

services.steam-servers.datadir

Base directory for all steam servers created with this module.

Type: path

Default: "/var/lib/steam-servers"

Example: "/mnt/nfs/steam"

Declared by:

services.steam-servers.group

Group to use when running steam servers

Type: string

Default: ${cfg.user}

Declared by:

services.steam-servers.user

User to use when running steam servers and creating top-level resources

Type: string

Default: "steam-server"

Declared by:

_module.args

Additional arguments passed to each module in addition to ones like lib, config, and pkgs, modulesPath.

This option is also available to all submodules. Submodules do not inherit args from their parent module, nor do they provide args to their parent module or sibling submodules. The sole exception to this is the argument name which is provided by parent modules to a submodule and contains the attribute name the submodule is bound to, or a unique generated name if it is not bound to an attribute.

Some arguments are already passed by default, of which the following cannot be changed with this option:

  • lib: The nixpkgs library.

  • config: The results of all options after merging the values from all modules together.

  • options: The options declared in all modules.

  • specialArgs: The specialArgs argument passed to evalModules.

  • All attributes of specialArgs

    Whereas option values can generally depend on other option values thanks to laziness, this does not apply to imports, which must be computed statically before anything else.

    For this reason, callers of the module system can provide specialArgs which are available during import resolution.

    For NixOS, specialArgs includes modulesPath, which allows you to import extra modules from the nixpkgs package tree without having to somehow make the module aware of the location of the nixpkgs or NixOS directories.

    { modulesPath, ... }: {
      imports = [
        (modulesPath + "/profiles/minimal.nix")
      ];
    }
    

For NixOS, the default value for this option includes at least this argument:

  • pkgs: The nixpkgs package set according to the nixpkgs.pkgs option.

Type: lazy attribute set of raw value

Declared by:

services.steam-servers."7-days-to-die"

Options to configure one or more 7 Days to Die servers.

Type: attribute set of (submodule)

Default: { }

Declared by:

services.steam-servers."7-days-to-die".<name>.enable

Whether to enable 7 Day to Die Dedicated Server.

Type: boolean

Default: false

Example: true

Declared by:

services.steam-servers."7-days-to-die".<name>.package

Package to use for 7 Days to Die binary

Type: package

Default: pkgs."7-days-to-die"

Declared by:

services.steam-servers."7-days-to-die".<name>.config.AdminFileName

admin file name. Path relative to the SaveGameFolder

Type: string

Default: "serveradmin.xml"

Declared by:

services.steam-servers."7-days-to-die".<name>.config.AirDropFrequency

How often airdrop occur in game-hours, 0 == never

Type: signed integer

Default: 72

Declared by:

services.steam-servers."7-days-to-die".<name>.config.AirDropMarker

Sets if a marker is added to map/compass for air drops.

Type: boolean

Default: true

Declared by:

services.steam-servers."7-days-to-die".<name>.config.BedrollDeadZoneSize

Size (box “radius”, so a box with 2 times the given value for each side’s length) of bedroll deadzone, no zombies will spawn inside this area, and any cleared sleeper volumes that touch a bedroll deadzone will not spawn after they’ve been cleared.

Type: signed integer

Default: 15

Declared by:

services.steam-servers."7-days-to-die".<name>.config.BedrollExpiryTime

Number of real world days a bedroll stays active after owner was last online

Type: signed integer

Default: 45

Declared by:

services.steam-servers."7-days-to-die".<name>.config.BlockDamageAI

How much damage do AIs to blocks (percentage in whole numbers)

Type: signed integer

Default: 100

Declared by:

services.steam-servers."7-days-to-die".<name>.config.BlockDamageAIBM

How much damage do AIs during blood moons to blocks (percentage in whole numbers)

Type: signed integer

Default: 100

Declared by:

services.steam-servers."7-days-to-die".<name>.config.BlockDamagePlayer

How much damage do players to blocks (percentage in whole numbers)

Type: signed integer

Default: 100

Declared by:

services.steam-servers."7-days-to-die".<name>.config.BloodMoonEnemyCount

This is the number of zombies that can be alive (spawned at the same time) at any time PER PLAYER during a blood moon horde, however, MaxSpawnedZombies overrides this number in multiplayer games. Also note that your game stage sets the max number of zombies PER PARTY. Low game stage values can result in lower number of zombies than the BloodMoonEnemyCount setting. Changing this setting has a huge impact on performance.

Type: signed integer

Default: 8

Declared by:

services.steam-servers."7-days-to-die".<name>.config.BloodMoonFrequency

What frequency (in days) should a blood moon take place. Set to ‘0’ for no blood moons

Type: signed integer

Default: 7

Declared by:

services.steam-servers."7-days-to-die".<name>.config.BloodMoonRange

How many days can the actual blood moon day randomly deviate from the above setting. Setting this to 0 makes blood moons happen exactly each Nth day as specified in BloodMoonFrequency

Type: signed integer

Default: 0

Declared by:

services.steam-servers."7-days-to-die".<name>.config.BloodMoonWarning

The Hour number that the red day number begins on a blood moon day. Setting this to -1 makes the red never show.

Type: signed integer

Default: 8

Declared by:

services.steam-servers."7-days-to-die".<name>.config.BuildCreate

cheat mode on/off

Type: boolean

Default: false

Declared by:

services.steam-servers."7-days-to-die".<name>.config.DayLightLength

in game hours the sun shines per day

Type: signed integer

Default: 18

Declared by:

services.steam-servers."7-days-to-die".<name>.config.DayNightLength

real time minutes per in game day

Type: signed integer

Default: 60

Declared by:

services.steam-servers."7-days-to-die".<name>.config.DropOnDeath

0 = nothing, 1 = everything, 2 = toolbelt only, 3 = backpack only, 4 = delete all

Type: integer between 0 and 4 (both inclusive)

Default: 1

Declared by:

services.steam-servers."7-days-to-die".<name>.config.DropOnQuit

0 = nothing, 1 = everything, 2 = toolbelt only, 3 = backpack only

Type: integer between 0 and 3 (both inclusive)

Default: 0

Declared by:

services.steam-servers."7-days-to-die".<name>.config.DynamicMeshEnabled

Is Dynamic Mesh system enabled

Type: boolean

Default: true

Declared by:

services.steam-servers."7-days-to-die".<name>.config.DynamicMeshLandClaimBuffer

Dynamic Mesh LCB chunk radius

Type: signed integer

Default: 3

Declared by:

services.steam-servers."7-days-to-die".<name>.config.DynamicMeshLandClaimOnly

Is Dynamic Mesh system only active in player LCB areas

Type: boolean

Default: true

Declared by:

services.steam-servers."7-days-to-die".<name>.config.DynamicMeshMaxItemCache

How many items can be processed concurrently, higher values use more RAM

Type: signed integer

Default: 3

Declared by:

services.steam-servers."7-days-to-die".<name>.config.EACEnabled

Enables/Disables EasyAntiCheat

Type: boolean

Default: true

Declared by:

services.steam-servers."7-days-to-die".<name>.config.EnableMapRendering

Enable/disable rendering of the map to tile images while exploring it. This is used e.g. by the web dashboard to display a view of the map.

Type: boolean

Default: false

Declared by:

services.steam-servers."7-days-to-die".<name>.config.EnemyDifficulty

0 = Normal, 1 = Feral

Type: one of 0, 1

Default: 0

Declared by:

services.steam-servers."7-days-to-die".<name>.config.EnemySpawnMode

Enable/Disable enemy spawning

Type: boolean

Default: true

Declared by:

services.steam-servers."7-days-to-die".<name>.config.GameDifficulty

0=easiest, 5=hardest

Type: integer between 0 and 5 (both inclusive)

Default: 1

Declared by:

services.steam-servers."7-days-to-die".<name>.config.GameMode

Game mode

Type: string

Default: "GameModeSurvival"

Declared by:

services.steam-servers."7-days-to-die".<name>.config.GameName

Whatever you want the game name to be. This affects the save game name as well as the seed used when placing decoration (trees etc) in the world. It does not control the generic layout of the world if creating an RWG world

Type: string

Default: "My Game"

Declared by:

services.steam-servers."7-days-to-die".<name>.config.GameWorld

“RWG” (see WorldGenSeed and WorldGenSize options below) or any already existing world name in the Worlds folder (currently shipping with e.g. “Navezgane”, “PREGEN6k”, “PREGEN8k”, “PREGEN10k”, …)

Type: string

Default: "Navezgane"

Declared by:

services.steam-servers."7-days-to-die".<name>.config.HideCommandExecutionLog

Hide logging of command execution. 0 = show everything, 1 = hide only from Telnet/ControlPanel, 2 = also hide from remote game clients, 3 = hide everything

Type: integer between 0 and 3 (both inclusive)

Default: 0

Declared by:

services.steam-servers."7-days-to-die".<name>.config.LandClaimCount

Maximum allowed land claims per player.

Type: signed integer

Default: 3

Declared by:

services.steam-servers."7-days-to-die".<name>.config.LandClaimDeadZone

Keystones must be this many blocks apart (unless you are friends with the other player)

Type: signed integer

Default: 30

Declared by:

services.steam-servers."7-days-to-die".<name>.config.LandClaimDecayMode

Controls how offline players land claims decay. 0=Slow (Linear) , 1=Fast (Exponential), 2=None (Full protection until claim is expired).

Type: integer between 0 and 2 (both inclusive)

Default: 0

Declared by:

services.steam-servers."7-days-to-die".<name>.config.LandClaimExpiryTime

The number of real world days a player can be offline before their claims expire and are no longer protected

Type: signed integer

Default: 7

Declared by:

services.steam-servers."7-days-to-die".<name>.config.LandClaimOfflineDelay

The number of minutes after a player logs out that the land claim area hardness transitions from online to offline. Default is 0

Type: signed integer

Default: 0

Declared by:

services.steam-servers."7-days-to-die".<name>.config.LandClaimOfflineDurabilityModifier

How much protected claim area block hardness is increased when a player is offline. 0 means infinite (no damage will ever be taken). Default is 4x

Type: signed integer

Default: 4

Declared by:

services.steam-servers."7-days-to-die".<name>.config.LandClaimOnlineDurabilityModifier

How much protected claim area block hardness is increased when a player is online. 0 means infinite (no damage will ever be taken). Default is 4x

Type: signed integer

Default: 4

Declared by:

services.steam-servers."7-days-to-die".<name>.config.LandClaimSize

Size in blocks that is protected by a keystone

Type: signed integer

Default: 41

Declared by:

services.steam-servers."7-days-to-die".<name>.config.Language

Primary language for players on this server. Values: Use any language name that you would users expect to search for. Should be the English name of the language, e.g. not ‘Deutsch’ but ‘German’

Type: string

Default: "English"

Declared by:

services.steam-servers."7-days-to-die".<name>.config.LootAbundance

percentage in whole numbers

Type: signed integer

Default: 100

Declared by:

services.steam-servers."7-days-to-die".<name>.config.LootRespawnDays

days in whole numbers

Type: signed integer

Default: 7

Declared by:

services.steam-servers."7-days-to-die".<name>.config.MaxChunkAge

The number of in-game days which must pass since visiting a chunk before it will reset to its original state if not revisited or protected (e.g. by a land claim or bedroll being in close proximity).

Type: signed integer

Default: -1

Declared by:

services.steam-servers."7-days-to-die".<name>.config.MaxQueuedMeshLayers

Maximum amount of Chunk mesh layers that can be enqueued during mesh generation. Reducing this will improve memory usage but may increase Chunk generation time

Type: signed integer

Default: 1000

Declared by:

services.steam-servers."7-days-to-die".<name>.config.MaxSpawnedAnimals

If your server has a large number of players you can increase this limit to add more wildlife. Animals don’t consume as much CPU as zombies. NOTE: That this doesn’t cause more animals to spawn arbitrarily: The biome spawning system only spawns a certain number of animals in a given area, but if you have lots of players that are all spread out then you may be hitting the limit and can increase it.

Type: signed integer

Default: 50

Declared by:

services.steam-servers."7-days-to-die".<name>.config.MaxSpawnedZombies

This setting covers the entire map. There can only be this many zombies on the entire map at one time. Changing this setting has a huge impact on performance.

Type: signed integer

Default: 64

Declared by:

services.steam-servers."7-days-to-die".<name>.config.MaxUncoveredMapChunksPerPlayer

Override how many chunks can be uncovered on the ingame map by each player. Resulting max map file size limit per player is (x * 512 Bytes), uncovered area is (x * 256 m²). Default 131072 means max 32 km² can be uncovered at any time

Type: signed integer

Default: 131072

Declared by:

services.steam-servers."7-days-to-die".<name>.config.PartySharedKillRange

The distance you must be within to receive party shared kill xp and quest party kill objective credit.

Type: signed integer

Default: 100

Declared by:

services.steam-servers."7-days-to-die".<name>.config.PersistentPlayerProfiles

If disabled a player can join with any selected profile. If true they will join with the last profile they joined with

Type: boolean

Default: false

Declared by:

services.steam-servers."7-days-to-die".<name>.config.PlayerKillingMode

Player Killing Settings (0 = No Killing, 1 = Kill Allies Only, 2 = Kill Strangers Only, 3 = Kill Everyone)

Type: signed integer

Default: 3

Declared by:

services.steam-servers."7-days-to-die".<name>.config.PlayerSafeZoneHours

Hours in world time this safe zone exists

Type: signed integer

Default: 5

Declared by:

services.steam-servers."7-days-to-die".<name>.config.PlayerSafeZoneLevel

If a player is less or equal this level he will create a safe zone (no enemies) when spawned

Type: signed integer

Default: 5

Declared by:

services.steam-servers."7-days-to-die".<name>.config.Region

region this server is in. Values: NorthAmericaEast, NorthAmericaWest, CentralAmerica, SouthAmerica, Europe, Russia, Asia, MiddleEast, Africa, Oceania

Type: string

Default: "NorthAmericaEast"

Declared by:

services.steam-servers."7-days-to-die".<name>.config.SaveDataLimit

The maximum disk space allowance for each saved game in megabytes (MB). Saved chunks may be forceably reset to their original states to free up space when this limit is reached. Negative values disable the limit.

Type: signed integer

Default: -1

Declared by:

services.steam-servers."7-days-to-die".<name>.config.SaveGameFolder

Use this to only override the save game path.

Type: string

Default: "/var/lib/steam-servers/7-days-to-die/‹name›/UserData/Saves"

Declared by:

services.steam-servers."7-days-to-die".<name>.config.ServerAdminSlots

This many admins can still join even if the server has reached MaxPlayerCount

Type: signed integer

Default: 0

Declared by:

services.steam-servers."7-days-to-die".<name>.config.ServerAdminSlotsPermission

Required permission level to use the admin slots above

Type: signed integer

Default: 0

Declared by:

services.steam-servers."7-days-to-die".<name>.config.ServerDescription

you want the server description to be, will be shown in the server browser.

Type: string

Default: "A 7 Days to Die server"

Declared by:

services.steam-servers."7-days-to-die".<name>.config.ServerDisabledNetworkProtocols

protocols that should not be used. Separated by comma. Possible values: LiteNetLib, SteamNetworking. Dedicated servers should disable SteamNetworking if there is no NAT router in between your users and the server or when port-forwarding is set up correctly

Type: string

Default: "SteamNetworking"

Declared by:

services.steam-servers."7-days-to-die".<name>.config.ServerLoginConfirmationText

If set the user will see the message during joining the server and has to confirm it before continuing. For more complex changes to this window you can change the ‘serverjoinrulesdialog’ window in XUi

Type: string

Default: ""

Declared by:

services.steam-servers."7-days-to-die".<name>.config.ServerMaxAllowedViewDistance

Max viewdistance a client may request (6 - 12). High impact on memory usage and performance.

Type: signed integer

Default: 12

Declared by:

services.steam-servers."7-days-to-die".<name>.config.ServerMaxPlayerCount

Maximum Concurrent Players

Type: signed integer

Default: 8

Declared by:

services.steam-servers."7-days-to-die".<name>.config.ServerMaxWorldTransferSpeedKiBs

Maximum (!) speed in kiB/s the world is transferred at to a client on first connect if it does not have the world yet. Maximum is about 1300 kiB/s, even if you set a higher value.

Type: signed integer

Default: 512

Declared by:

services.steam-servers."7-days-to-die".<name>.config.ServerName

Whatever you want the name of the server to be.

Type: string

Default: "My Game Host"

Declared by:

services.steam-servers."7-days-to-die".<name>.config.ServerPassword

Password to gain entry to the server

Type: string

Default: ""

Declared by:

services.steam-servers."7-days-to-die".<name>.config.ServerPort

Port you want the server to listen on. Keep it in the ranges 26900 to 26905 or 27015 to 27020 if you want PCs on the same LAN to find it as a LAN server.

Type: 16 bit unsigned integer; between 0 and 65535 (both inclusive)

Default: 26900

Declared by:

services.steam-servers."7-days-to-die".<name>.config.ServerReservedSlots

Out of the MaxPlayerCount this many slots can only be used by players with a specific permission level

Type: signed integer

Default: 0

Declared by:

services.steam-servers."7-days-to-die".<name>.config.ServerReservedSlotsPermission

Required permission level to use reserved slots above

Type: signed integer

Default: 100

Declared by:

services.steam-servers."7-days-to-die".<name>.config.ServerVisibility

Visibility of this server: 2 = public, 1 = only shown to friends, 0 = not listed. As you are never friend of a dedicated server setting this to “1” will only work when the first player connects manually by IP.

Type: integer between 0 and 2 (both inclusive)

Default: 0

Declared by:

services.steam-servers."7-days-to-die".<name>.config.ServerWebsiteURL

Website URL for the server, will be shown in the serverbrowser as a clickable link

Type: string

Default: ""

Declared by:

services.steam-servers."7-days-to-die".<name>.config.TelnetEnabled

Enable/Disable the telnet

Type: boolean

Default: true

Declared by:

services.steam-servers."7-days-to-die".<name>.config.TelnetFailedLoginLimit

After this many wrong passwords from a single remote client the client will be blocked from connecting to the Telnet interface

Type: signed integer

Default: 10

Declared by:

services.steam-servers."7-days-to-die".<name>.config.TelnetFailedLoginsBlocktime

How long will the block persist (in seconds)

Type: signed integer

Default: 10

Declared by:

services.steam-servers."7-days-to-die".<name>.config.TelnetPassword

Password to gain entry to telnet interface. If no password is set the server will only listen on the local loopback interface

Type: string

Default: ""

Declared by:

services.steam-servers."7-days-to-die".<name>.config.TelnetPort

Port of the telnet server

Type: 16 bit unsigned integer; between 0 and 65535 (both inclusive)

Default: 8081

Declared by:

services.steam-servers."7-days-to-die".<name>.config.TerminalWindowEnabled

Show a terminal window for log output / command input (Windows only)

Type: boolean

Default: true

Declared by:

services.steam-servers."7-days-to-die".<name>.config.TwitchBloodMoonAllowed

If the server allows twitch actions during a blood moon. This could cause server lag with extra zombies being spawned during blood moon.

Type: boolean

Default: false

Declared by:

services.steam-servers."7-days-to-die".<name>.config.TwitchServerPermission

Required permission level to use twitch integration on the server

Type: signed integer

Default: 90

Declared by:

services.steam-servers."7-days-to-die".<name>.config.UserDataFolder

Use this to override where the server stores all generated data, including RWG generated worlds.

Type: string

Default: "/var/lib/steam-servers/7-days-to-die/‹name›/UserData"

Declared by:

services.steam-servers."7-days-to-die".<name>.config.WebDashboardEnabled

Enable/disable the web dashboard

Type: boolean

Default: false

Declared by:

services.steam-servers."7-days-to-die".<name>.config.WebDashboardPort

Port of the web dashboard

Type: 16 bit unsigned integer; between 0 and 65535 (both inclusive)

Default: 8080

Declared by:

services.steam-servers."7-days-to-die".<name>.config.WebDashboardUrl

External URL to the web dashboard if not just using the public IP of the server, e.g. if the web dashboard is behind a reverse proxy. Needs to be the full URL, like ‘https://domainOfReverseProxy.tld:1234/’. Can be left empty if directly using the public IP and dashboard port

Type: string

Default: ""

Declared by:

services.steam-servers."7-days-to-die".<name>.config.WorldGenSeed

If RWG this is the seed for the generation of the new world. If a world with the resulting name already exists it will simply load it

Type: string

Default: "asdf"

Declared by:

services.steam-servers."7-days-to-die".<name>.config.WorldGenSize

If RWG, this controls the width and height of the created world. Officially supported sizes are between 6144 and 10240 and must be a multiple of 2048, e.g. 6144, 8192, 10240.

Type: signed integer

Default: 6144

Declared by:

services.steam-servers."7-days-to-die".<name>.config.XPMultiplier

XP gain multiplier (percentage in whole numbers)

Type: signed integer

Default: 100

Declared by:

services.steam-servers."7-days-to-die".<name>.config.ZombieBMMove

0-4 (walk, jog, run, sprint, nightmare)

Type: integer between 0 and 3 (both inclusive)

Default: 3

Declared by:

services.steam-servers."7-days-to-die".<name>.config.ZombieFeralMove

0-4 (walk, jog, run, sprint, nightmare)

Type: integer between 0 and 3 (both inclusive)

Default: 3

Declared by:

services.steam-servers."7-days-to-die".<name>.config.ZombieFeralSense

0-3 (Off, Day, Night, All)

Type: integer between 0 and 3 (both inclusive)

Default: 0

Declared by:

services.steam-servers."7-days-to-die".<name>.config.ZombieMove

0-4 (walk, jog, run, sprint, nightmare)

Type: integer between 0 and 3 (both inclusive)

Default: 0

Declared by:

services.steam-servers."7-days-to-die".<name>.config.ZombieMoveNight

0-4 (walk, jog, run, sprint, nightmare)

Type: integer between 0 and 3 (both inclusive)

Default: 3

Declared by:

services.steam-servers."7-days-to-die".<name>.datadir

Directory to store save state of the game server. (eg world, saves, etc)

Type: path

Default: ${services.steam-servers.datadir}/7-days-to-die/${name}

Declared by:

services.steam-servers."7-days-to-die".<name>.extraArgs

Extra command line arguments to pass to the server

Type: list of string

Default: [ ]

Declared by:

services.steam-servers."7-days-to-die".<name>.logFile

Logfile to output logs to

Type: string

Default: "/var/lib/steam-servers/7-days-to-die/‹name›/output_log__`date +%Y-%m-%d__%H-%M-%S`.txt"

Declared by:

services.steam-servers."7-days-to-die".<name>.openFirewall

Whether to open ports in the firewall. Does not open telnet/admin ports

Type: boolean

Default: false

Declared by:

_module.args

Additional arguments passed to each module in addition to ones like lib, config, and pkgs, modulesPath.

This option is also available to all submodules. Submodules do not inherit args from their parent module, nor do they provide args to their parent module or sibling submodules. The sole exception to this is the argument name which is provided by parent modules to a submodule and contains the attribute name the submodule is bound to, or a unique generated name if it is not bound to an attribute.

Some arguments are already passed by default, of which the following cannot be changed with this option:

  • lib: The nixpkgs library.

  • config: The results of all options after merging the values from all modules together.

  • options: The options declared in all modules.

  • specialArgs: The specialArgs argument passed to evalModules.

  • All attributes of specialArgs

    Whereas option values can generally depend on other option values thanks to laziness, this does not apply to imports, which must be computed statically before anything else.

    For this reason, callers of the module system can provide specialArgs which are available during import resolution.

    For NixOS, specialArgs includes modulesPath, which allows you to import extra modules from the nixpkgs package tree without having to somehow make the module aware of the location of the nixpkgs or NixOS directories.

    { modulesPath, ... }: {
      imports = [
        (modulesPath + "/profiles/minimal.nix")
      ];
    }
    

For NixOS, the default value for this option includes at least this argument:

  • pkgs: The nixpkgs package set according to the nixpkgs.pkgs option.

Type: lazy attribute set of raw value

Declared by:

services.steam-servers.palworld

Options to configure one or more Stationers servers.

Type: attribute set of (submodule)

Default: { }

Declared by:

services.steam-servers.palworld.<name>.enable

Whether to enable Palworld Dedicated Server.

Type: boolean

Default: false

Example: true

Declared by:

services.steam-servers.palworld.<name>.package

Package to use for Palworld binary

Type: package

Default: pkgs.palworld

Declared by:

services.steam-servers.palworld.<name>.datadir

Directory to store save state of the game server. (eg world, saves, etc)

Type: path

Default: ${services.steam-servers.datadir}/palworld/${name}

Declared by:

services.steam-servers.palworld.<name>.extraArgs

Extra command line arguments to pass to the server

Type: list of string

Default: [ ]

Declared by:

services.steam-servers.palworld.<name>.openFirewall

Whether to open ports in the firewall.

Type: boolean

Default: false

Declared by:

services.steam-servers.palworld.<name>.port

UDP port to listen on

Type: 16 bit unsigned integer; between 0 and 65535 (both inclusive)

Default: 8211

Declared by:

services.steam-servers.palworld.<name>.worldSettings

World settings used to generate PalWorldSettings.ini

Type: attribute set

Default: { }

Declared by:

_module.args

Additional arguments passed to each module in addition to ones like lib, config, and pkgs, modulesPath.

This option is also available to all submodules. Submodules do not inherit args from their parent module, nor do they provide args to their parent module or sibling submodules. The sole exception to this is the argument name which is provided by parent modules to a submodule and contains the attribute name the submodule is bound to, or a unique generated name if it is not bound to an attribute.

Some arguments are already passed by default, of which the following cannot be changed with this option:

  • lib: The nixpkgs library.

  • config: The results of all options after merging the values from all modules together.

  • options: The options declared in all modules.

  • specialArgs: The specialArgs argument passed to evalModules.

  • All attributes of specialArgs

    Whereas option values can generally depend on other option values thanks to laziness, this does not apply to imports, which must be computed statically before anything else.

    For this reason, callers of the module system can provide specialArgs which are available during import resolution.

    For NixOS, specialArgs includes modulesPath, which allows you to import extra modules from the nixpkgs package tree without having to somehow make the module aware of the location of the nixpkgs or NixOS directories.

    { modulesPath, ... }: {
      imports = [
        (modulesPath + "/profiles/minimal.nix")
      ];
    }
    

For NixOS, the default value for this option includes at least this argument:

  • pkgs: The nixpkgs package set according to the nixpkgs.pkgs option.

Type: lazy attribute set of raw value

Declared by:

services.steam-servers.servers

Options for configuring a generic game server.

Type: attribute set of (submodule)

Default: { }

Declared by:

services.steam-servers.servers.<name>.enable

Whether to enable this game server.

Type: boolean

Default: false

Example: true

Declared by:

services.steam-servers.servers.<name>.args

Arguments passed to executable

Type: list of string

Default: [ ]

Declared by:

services.steam-servers.servers.<name>.autostart

Whether to start this server automatically.

When false, services can be started manually via systemctl start.

Type: boolean

Default: true

Declared by:

services.steam-servers.servers.<name>.datadir

Directory to store save state of the game server. (eg world, saves, etc)

Type: path

Default: ${services.steam-servers.datadir}/${name}

Declared by:

services.steam-servers.servers.<name>.description

Description of this steam server. Will be used for the systemd unit.

Type: string

Default: ""

Declared by:

services.steam-servers.servers.<name>.dirs

Set of directories to copy into datadir. The name is the path relative to datadir and the value is the path to the directory to be copied into the approriate location.

If files in the source are newer than their copy in datadir, they will be overwritten.

Type: attribute set of path

Default: { }

Declared by:

services.steam-servers.servers.<name>.executable

Executable for the starting the server.

May be an absolute path or one relative to datadir

Type: string

Example: "./7DaysToDieServer.x86_64"

Declared by:

services.steam-servers.servers.<name>.files

Set of files to copy into datadir. The name is the path relative to datadir and the value is the path to the file to be copied into the approriate location.

This can be useful for files that the game server expects to be able to open in write mode.

Files copied this way will be removed after service shutdown.

Type: attribute set of (path or (submodule))

Default: { }

Declared by:

Set of files to symlink into datadir. The name is the path relative to datadir.

All symlinks will be cleaned-up when the service stops

Type: attribute set of (path or (submodule))

Default: { }

Declared by:

services.steam-servers.servers.<name>.tmuxStopKeys

When using tmux, what keys to send via tmux send-keys to shutdown the server.

Type: string

Default: "^C"

Example: "/stop Enter"

Declared by:

services.steam-servers.servers.<name>.useTmux

Whether or not to run server inside a tmux session. This can be useful for servers that have a console you can run commands in.

If enabled, a tmux socket will be created at $RUNTIME_DIRECTORY/steam-servers/${name} and the server executable will be ran inside the tmux session.

WARNING: At this time terminal output from tmux is not sent to journald. This means that you will NOT have persistant logs without some other mechanism. This can make debuging server crashes VERY difficult, but is necessary for some servers

Type: boolean

Default: false

Declared by:

_module.args

Additional arguments passed to each module in addition to ones like lib, config, and pkgs, modulesPath.

This option is also available to all submodules. Submodules do not inherit args from their parent module, nor do they provide args to their parent module or sibling submodules. The sole exception to this is the argument name which is provided by parent modules to a submodule and contains the attribute name the submodule is bound to, or a unique generated name if it is not bound to an attribute.

Some arguments are already passed by default, of which the following cannot be changed with this option:

  • lib: The nixpkgs library.

  • config: The results of all options after merging the values from all modules together.

  • options: The options declared in all modules.

  • specialArgs: The specialArgs argument passed to evalModules.

  • All attributes of specialArgs

    Whereas option values can generally depend on other option values thanks to laziness, this does not apply to imports, which must be computed statically before anything else.

    For this reason, callers of the module system can provide specialArgs which are available during import resolution.

    For NixOS, specialArgs includes modulesPath, which allows you to import extra modules from the nixpkgs package tree without having to somehow make the module aware of the location of the nixpkgs or NixOS directories.

    { modulesPath, ... }: {
      imports = [
        (modulesPath + "/profiles/minimal.nix")
      ];
    }
    

For NixOS, the default value for this option includes at least this argument:

  • pkgs: The nixpkgs package set according to the nixpkgs.pkgs option.

Type: lazy attribute set of raw value

Declared by:

services.steam-servers.stationeers

Options to configure one or more Stationers servers.

Type: attribute set of (submodule)

Default: { }

Declared by:

services.steam-servers.stationeers.<name>.enable

Whether to enable Stationeers Dedicated Server.

Type: boolean

Default: false

Example: true

Declared by:

services.steam-servers.stationeers.<name>.package

Package to use for Stationeers binary

Type: package

Default: pkgs.stationeers

Declared by:

services.steam-servers.stationeers.<name>.adminPasswordPath

Path to a secret file containing a password required to connect to RCON.

Can be null for no RCON support.

Type: null or string

Default: null

Declared by:

services.steam-servers.stationeers.<name>.config.AutoSave

Whether to enable autosaving of the server

Type: boolean

Default: true

Declared by:

services.steam-servers.stationeers.<name>.config.DisconnectTimeout

Type: signed integer

Default: 10000

Declared by:

services.steam-servers.stationeers.<name>.config.GamePort

Game port

Type: 16 bit unsigned integer; between 0 and 65535 (both inclusive)

Default: 27016

Declared by:

services.steam-servers.stationeers.<name>.config.HungerRate

Rate at which hungre drains

Type: signed integer or floating point number

Default: 0.5

Declared by:

services.steam-servers.stationeers.<name>.config.LocalIpAddress

Local address to bind game server to

Type: string

Default: "0.0.0.0"

Declared by:

services.steam-servers.stationeers.<name>.config.NetworkDebugFrequency

Type: signed integer

Default: 500

Declared by:

services.steam-servers.stationeers.<name>.config.ResearchPoolKey

ResearchOff, ResearchOn, or a custom key from a mod

Type: string

Default: "ResearchOn"

Declared by:

services.steam-servers.stationeers.<name>.config.RespawnCondition

Easy, Normal, Stationeers, or mod provided

Type: string

Default: "Easy"

Declared by:

services.steam-servers.stationeers.<name>.config.RoomControlTickSpeed

Type: signed integer or floating point number

Default: 1

Declared by:

services.steam-servers.stationeers.<name>.config.SaveInterval

Auto-save interval (in seconds)

Type: signed integer

Default: 300

Declared by:

services.steam-servers.stationeers.<name>.config.SavePath

Path to world saves directory

Type: path

Default: "/var/lib/steam-servers/stationeers/‹name›"

Declared by:

services.steam-servers.stationeers.<name>.config.ServerMaxPlayers

Max number of simultaneous players on the server

Type: signed integer

Default: 10

Declared by:

services.steam-servers.stationeers.<name>.config.ServerName

Name of the server shown to clients

Type: string

Default: "Stationeers"

Declared by:

services.steam-servers.stationeers.<name>.config.ServerVisible

Whether or not server is publicly discoverable

Type: boolean

Default: false

Declared by:

services.steam-servers.stationeers.<name>.config.StartLocalHost

Type: boolean

Default: true

Declared by:

services.steam-servers.stationeers.<name>.config.StartingConditions

Default, Minimal, Vulcan, Venus, BareBones, or mod provided. (possible ignored by server)

Type: string

Default: "Default"

Declared by:

services.steam-servers.stationeers.<name>.config.SunOrbitPeriod

Multiplier on the time it takes for the sun to orbit, default is 20 minutes, 10 minute day 10 night.

Type: signed integer or floating point number

Default: 1

Declared by:

services.steam-servers.stationeers.<name>.config.UPNPEnabled

Whether to enable UPnP. Not recommended as enabling UPnP is inherently a security risk

Type: boolean

Default: false

Declared by:

services.steam-servers.stationeers.<name>.config.UpdatePort

Steam update port

Type: 16 bit unsigned integer; between 0 and 65535 (both inclusive)

Default: 27015

Declared by:

services.steam-servers.stationeers.<name>.config.WorldOrigin

Type: boolean

Default: false

Declared by:

services.steam-servers.stationeers.<name>.datadir

Directory to store save state of the game server. (eg world, saves, etc)

Type: path

Default: ${services.steam-servers.datadir}/stationeers/${name}

Declared by:

services.steam-servers.stationeers.<name>.difficulty

Difficulty setting to use when creating worlds

Type: string

Default: "normal"

Declared by:

services.steam-servers.stationeers.<name>.extraArgs

Extra command line arguments to pass to the server

Type: list of string

Default: [ ]

Declared by:

services.steam-servers.stationeers.<name>.extraConfig

Extra config to add to the settings.xml

Type: attribute set

Default: { }

Declared by:

services.steam-servers.stationeers.<name>.openFirewall

Whether to open ports in the firewall. Does not open telnet/admin ports

Type: boolean

Default: false

Declared by:

services.steam-servers.stationeers.<name>.serverPasswordPath

Path to a secret file containing a password required to connect to the server.

Can be null for no password.

Type: null or string

Default: null

Declared by:

services.steam-servers.stationeers.<name>.worldName

Name of the save game to use. A new world of type worldType will be created of save does not exist.

Type: string

Default: ${name}

Declared by:

services.steam-servers.stationeers.<name>.worldType

World type to use when creating a new world.

Must be one of moon, mars, europa, europa2, mimas, vulcan, vulcan2, space, loulan, venus or a mod-provided value

Type: string

Default: "mars"

Declared by:

Contribution Guidelines

This file contains instructions that will help you make a contribution.

Licensing

The Nix Steam Servers packages, modules and this user guide are licensed under the MIT license.

Before you contribute

Here you can take a look at the existing issues. Feel free to contribute, but make sure you have a GitHub account first :) .

If you're new to open source, please read GitHub's guide on How to Contribute to Open Source. It's a quick read, and it's a great way to introduce yourself to how things work behind the scenes in open-source projects.

Before sending a pull request, make sure that you've read all the guidelines. If you don't understand something, please state your question clearly in an issue.

Creating an issue

If you need to create an issue, make sure to clearly describe it, including:

  • The steps to reproduce it if it's a bug
  • The version of nix-steam-servers used

Making changes

If you want to introduce changes to the project, please follow these steps:

  • Fork the repository on GitHub
  • Create a branch on your fork. Don't commit directly to master
  • Add the necessary tests for your changes
  • Push your changes to the branch in your repository fork
  • Submit a pull request to the original repository

Make sure you based your commits on logical and atomic units!

Examples of git history

Git history that we want to have

*   e3ed88b (HEAD -> contribution-guide, upstream/main, origin/main, origin/HEAD, main) Merge pull request #470 from zimbatm/fix_lru_cache

|\

| * 1ab7d9f Use rayon for multithreading command

|/

*   e9c5bb4 Merge pull request #468 from zimbatm/multithread

|\

| * de2d6cf Add lint property for Formatter struct

| * cd2ed17 Fix impl on Formatter get_command() function

|/

*   028c344 Merge pull request #465 from rayon/0.15.0-release

|\

| * 7b619d6 0.15.0 release

|/

*   acdf7df Merge pull request #463 from zimbatm/support-multi-part-namespaces

Git history that we are trying to avoid:

*   4c8aca8 Merge pull request #120 from zimbatm/add-rayon

|\

| * fc2b449 use rayon for engine now

| * 2304683 add rayon config

| * 5285bd3 bump base image to F30

* |   4d0fbe2 Merge pull request #114 from rizary/create_method_create_release

|\ \

| * | 36a9396 test changed

| * | 22f681d method create release for github created

* | |   2ef4ea1 Merge pull request #119 from rizary/config.rs

|\ \ \

| |/ /

|/| |

| * | 5f1b8f0 unused functions removed

* | |   a93c361 Merge pull request #117 from zimbatm/add-getreleases-to-abstract

|\ \ \

| |/ /

|/| |

| * | 0a97236 add get_releses for Cargo

| * | 55e4c57 add get_releases/get_release into engine.rs

|/ /

* |   badeddd Merge pull request #101 from zimbatm/extreme-cachin

Additionally, it's always good to work on improving documentation and adding examples.

Thank you for considering contributing to nix-steam-servers.

Writing Server Modules

Tenets

The primary goal of the opinionated server modules is to provide a more ergonomic way to create and manage servers of a specifc game. To that end, you should adhere to the following tenets:

  • Modules shoud be easy to use
  • Modules should be secure by default
  • Whenever possible, modules should allow running multiple servers on the same host

Guidelines

From these tenets, we can conclude several guidelines:

  • Modules should generally be an attribute set of server options to allow running multiple instances
  • Default config values should provide a working server
    • Ideally, a user consuming a server would simply need to write services.steam-servers.some-game.my-server.enable = true;
  • Default config values should provide a secure starting point
    • Don't automatically open firewall ports
    • Don't automatically list server on public listings (when support by the game)
  • It should be easy to extend the CLI args/server config file generated

Templates

The following templates are some useful starting points for creating new modules. Make sure to replace <game> with the actual name of the game

modules/<game>/options.nix

{ # modules/<game>/options.nix
  config,
  lib,
  pkgs,
  ...
}:
with lib; let
  baseCfg = config.services.steam-servers;
  moduleLib = import ../lib.nix lib;
  inherit (moduleLib) mkOpt;

  serverModule = {
    config,
    name,
    ...
  }: {
    options = {
      enable = mkEnableOption (mdDoc "<game> Dedicated Server");

      package = mkOption {
        type = types.package;
        default = pkgs.<game>;
        defaultText = literalExpression "pkgs.<game>";
        description = mdDoc "Package to use for <game> binary";
      };

      datadir = mkOption {
        type = types.path;
        default = "${baseCfg.datadir}/<game>/${name}";
        defaultText = literalExpression "\${services.steam-servers.datadir}/<game>/\${name}";
        description = mdDoc ''
          Directory to store save state of the game server. (eg world, saves, etc)
        '';
      };

      openFirewall = mkOption {
        type = types.bool;
        default = false;
        description = mdDoc "Whether to open ports in the firewall";
      };

      config = {
        # Config options
      };

      extraConfig = mkOpt types.attrs {} "Extra config to add to the server config";

      extraArgs = mkOpt (with types; listOf str) [] "Extra command line arguments to pass to the server";
    };
  };
in {
  options.services.steam-servers.<game> = mkOption {
    type = types.attrsOf (types.submodule serverModule);
    default = {};
    description = mdDoc ''
      Options to configure one or more <game> servers.
    '';
  };
}

modules/<game>/default.nix

{ # modules/<game>/default.nix
  config,
  lib,
  ...
}:
with lib; let
  baseCfg = config.services.steam-servers;
  cfg = baseCfg.stationeers;
  enabledServers = filterAttrs (_: conf: conf.enable) cfg;
in {
  imports = [./options.nix];

  config = mkIf (enabledServers != {}) {
    networking.firewall =
      mkMerge
      (map
        (conf:
          mkIf conf.openFirewall {
            allowedUDPPorts = [conf.config.UpdatePort conf.config.GamePort];
          })
        (builtins.attrValues enabledServers));

    services.steam-servers.servers =
      mapAttrs'
      (name: conf: let
        args =
          [
            # Disable UI in unity
            "-batchmode"
            "-nographics"
          ]
          ++ (map escapeShellArg conf.extraArgs);
      in
        nameValuePair "<game>-${name}" {
          inherit args;
          inherit (conf) enable datadir;

          symlinks = {
            "settings.ini".value = conf.config;
          };

          executable = "${conf.package}/server_executable";
        })
      cfg;
  };
}

modules/<game>/default.test.nix

# modules/<game>/default.test.nix
{lib, ...}:
with lib; {
  name = "<game>";

  nodes = {
    server = {
      virtualisation = {
        cores = 2;
        memorySize = 4096;
      };

      services.steam-servers."<game>".test = {
        enable = true;
        # Any other config needed for a meaningful test
      };
    };
  };

  testScript = ''
    server.wait_for_unit("<game>-test.service")
    server.wait_for_open_port(26900) # Can only check TCP ports

    # Wait for some text in the syslog that indicates server started
    server.wait_for_console_text("started <game> Server")

    # Check save file has been created
    server.succeed("test -d ${cfg.datadir}/saves/${cfg.worldName}")
  '';
}

Contributor Covenant Code of Conduct

Our Pledge

In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.

Our Standards

Examples of behavior that contributes to creating a positive environment include:

  • Using welcoming and inclusive language
  • Being respectful of differing viewpoints and experiences
  • Gracefully accepting constructive criticism
  • Focusing on what is best for the community
  • Showing empathy towards other community members

Examples of unacceptable behavior by participants include:

  • The use of sexualized language or imagery and unwelcome sexual attention or advances
  • Trolling, insulting/derogatory comments, and personal or political attacks
  • Public or private harassment
  • Publishing others' private information, such as a physical or electronic address, without explicit permission
  • Other conduct which could reasonably be considered inappropriate in a professional setting

Our Responsibilities

Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.

Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.

Scope

This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.

Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting this repository owners on Github. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.

Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.

Attribution

This Code of Conduct is adapted from the Contributor Covenant, version 1.4, available at http://contributor-covenant.org/version/1/4