···
1
-
{ lib, config, pkgs, ... } @ args:
5
-
isEnabled = config.modules.games.enable && config.modules.games.palworld.enable;
6
-
baseCfg = config.modules.games;
7
-
cfg = config.modules.games.palworld;
9
-
name = "palworld-server";
10
-
scripts = (import ./lib/scripts.nix) args;
12
-
generateSettings = name: value: let
15
-
(optName: optVal: let
16
-
optType = builtins.typeOf optVal;
18
-
if optType == "string"
19
-
then "\"${optVal}\""
20
-
else if optType == "bool"
25
-
else toString optVal;
26
-
in "${optName}=${encodedVal}")
29
-
builtins.toFile name ''
30
-
[/Script/Pal.PalGameWorldSettings]
31
-
OptionSettings=(${concatStringsSep "," optionSettings})
35
-
ServerName = "Unnamed Server";
36
-
AllowConnectPlatform = "Steam";
37
-
CoopPlayerMaxNum = cfg.maxPlayers;
38
-
bIsUseBackupSaveData = true;
39
-
RCONEnabled = false;
40
-
RESTAPIEnabled = false;
45
-
Paths=../../../Engine/Content
46
-
Paths=%GAMEDIR%Content
47
-
Paths=../../../Engine/Plugins/2D/Paper2D/Content
48
-
Paths=../../../Engine/Plugins/Animation/ControlRigSpline/Content
49
-
Paths=../../../Engine/Plugins/Animation/ControlRig/Content
50
-
Paths=../../../Engine/Plugins/Animation/IKRig/Content
51
-
Paths=../../../Engine/Plugins/Animation/MotionWarping/Content
52
-
Paths=../../../Engine/Plugins/Bridge/Content
53
-
Paths=../../../Engine/Plugins/Compositing/Composure/Content
54
-
Paths=../../../Engine/Plugins/Compositing/OpenColorIO/Content
55
-
Paths=../../../Engine/Plugins/Developer/AnimationSharing/Content
56
-
Paths=../../../Engine/Plugins/Developer/Concert/ConcertSync/ConcertSyncClient/Content
57
-
Paths=../../../Engine/Plugins/Editor/BlueprintHeaderView/Content
58
-
Paths=../../../Engine/Plugins/Editor/GeometryMode/Content
59
-
Paths=../../../Engine/Plugins/Editor/ModelingToolsEditorMode/Content
60
-
Paths=../../../Engine/Plugins/Editor/ObjectMixer/LightMixer/Content
61
-
Paths=../../../Engine/Plugins/Editor/ObjectMixer/ObjectMixer/Content
62
-
Paths=../../../Engine/Plugins/Editor/SpeedTreeImporter/Content
63
-
Paths=../../../Engine/Plugins/Enterprise/DatasmithContent/Content
64
-
Paths=../../../Engine/Plugins/Enterprise/GLTFExporter/Content
65
-
Paths=../../../Engine/Plugins/Experimental/ChaosCaching/Content
66
-
Paths=../../../Engine/Plugins/Experimental/ChaosClothEditor/Content
67
-
Paths=../../../Engine/Plugins/Experimental/ChaosNiagara/Content
68
-
Paths=../../../Engine/Plugins/Experimental/ChaosSolverPlugin/Content
69
-
Paths=../../../Engine/Plugins/Experimental/CommonUI/Content
70
-
Paths=../../../Engine/Plugins/Experimental/Dataflow/Content
71
-
Paths=../../../Engine/Plugins/Experimental/FullBodyIK/Content
72
-
Paths=../../../Engine/Plugins/Experimental/GeometryCollectionPlugin/Content
73
-
Paths=../../../Engine/Plugins/Experimental/GeometryFlow/Content
74
-
Paths=../../../Engine/Plugins/Experimental/ImpostorBaker/Content
75
-
Paths=../../../Engine/Plugins/Experimental/Landmass/Content
76
-
Paths=../../../Engine/Plugins/Experimental/MeshLODToolset/Content
77
-
Paths=../../../Engine/Plugins/Experimental/PythonScriptPlugin/Content
78
-
Paths=../../../Engine/Plugins/Experimental/StaticMeshEditorModeling/Content
79
-
Paths=../../../Engine/Plugins/Experimental/UVEditor/Content
80
-
Paths=../../../Engine/Plugins/Experimental/Volumetrics/Content
81
-
Paths=../../../Engine/Plugins/Experimental/Water/Content
82
-
Paths=../../../Engine/Plugins/FX/Niagara/Content
83
-
Paths=../../../Engine/Plugins/JsonBlueprintUtilities/Content
84
-
Paths=../../../Engine/Plugins/Media/MediaCompositing/Content
85
-
Paths=../../../Engine/Plugins/Media/MediaPlate/Content
86
-
Paths=../../../Engine/Plugins/MovieScene/SequencerScripting/Content
87
-
Paths=../../../Engine/Plugins/PivotTool/Content
88
-
Paths=../../../Engine/Plugins/PlacementTools/Content
89
-
Paths=../../../Engine/Plugins/Runtime/AudioSynesthesia/Content
90
-
Paths=../../../Engine/Plugins/Runtime/AudioWidgets/Content
91
-
Paths=../../../Engine/Plugins/Runtime/GeometryProcessing/Content
92
-
Paths=../../../Engine/Plugins/Runtime/Metasound/Content
93
-
Paths=../../../Engine/Plugins/Runtime/ResonanceAudio/Content
94
-
Paths=../../../Engine/Plugins/Runtime/SunPosition/Content
95
-
Paths=../../../Engine/Plugins/Runtime/Synthesis/Content
96
-
Paths=../../../Engine/Plugins/Runtime/WaveTable/Content
97
-
Paths=../../../Engine/Plugins/Runtime/WebBrowserWidget/Content
98
-
Paths=../../../Engine/Plugins/SkyCreatorPlugin/Content
99
-
Paths=../../../Engine/Plugins/VirtualProduction/CameraCalibrationCore/Content
100
-
Paths=../../../Engine/Plugins/VirtualProduction/LiveLinkCamera/Content
101
-
Paths=../../../Engine/Plugins/VirtualProduction/Takes/Content
102
-
Paths=../../../Engine/Plugins/Web/HttpBlueprint/Content
103
-
Paths=../../../Pal/Plugins/DLSS/Content
104
-
Paths=../../../Pal/Plugins/EffectsChecker/Content
105
-
Paths=../../../Pal/Plugins/HoudiniEngine/Content
106
-
Paths=../../../Pal/Plugins/PPSkyCreatorPlugin/Content
107
-
Paths=../../../Pal/Plugins/PocketpairUser/Content
108
-
Paths=../../../Pal/Plugins/SpreadSheetToCsv/Content
109
-
Paths=../../../Pal/Plugins/Wwise/Content
111
-
[/script/onlinesubsystemutils.ipnetdriver]
112
-
LanServerMaxTickRate=60
113
-
NetServerMaxTickRate=60
115
-
[/script/engine.player]
116
-
ConfiguredInternetSpeed=104857600
117
-
ConfiguredLanSpeed=104857600
119
-
[/script/socketsubsystemepic.epicnetdriver]
120
-
MaxClientRate=104857600
121
-
MaxInternetClientRate=104857600
123
-
[/script/engine.engine]
124
-
bSmoothFrameRate=true
125
-
SmoothedFrameRateRange=(LowerBound=(Type=Inclusive,Value=30.000000),UpperBound=(Type=Exclusive,Value=60.000000))
126
-
bUseFixedFrameRate=false
128
-
MinDesiredFrameRate=30
129
-
NetClientTicksPerSecond=60
133
-
options.modules.games.palworld = {
134
-
enable = mkOption {
136
-
description = "Whether to enable Palworld Dedicated Server.";
140
-
package = mkOption {
141
-
type = types.package;
142
-
default = pkgs.palworld-server;
145
-
public = mkOption {
148
-
description = "Whether to enable Community Server mode";
151
-
autostart = mkOption {
156
-
datadir = mkOption {
158
-
default = "${baseCfg.datadir}/palworld";
162
-
type = types.nullOr types.str;
163
-
default = "0.0.0.0";
171
-
threads = mkOption {
176
-
maxPlayers = mkOption {
181
-
settings = mkOption {
182
-
type = types.attrs;
187
-
config = mkIf isEnabled {
188
-
modules.router.nftables.capturePorts = [ cfg.port ];
189
-
networking.firewall.allowedUDPPorts = [ cfg.port ];
191
-
systemd.tmpfiles.rules = [
192
-
"d ${cfg.datadir} 0755 ${baseCfg.user} ${baseCfg.group} - -"
195
-
systemd.services."${name}" = let
197
-
Pal = "${cfg.package}/Pal";
198
-
Engine = "${cfg.package}/Engine";
202
-
settings = baseSettings // cfg.settings;
204
-
"Pal/Binaries/Linux/steamclient.so" = "${pkgs.steamworks-sdk-redist}/lib/steamclient.so";
205
-
"Pal/Saved/Config/LinuxServer/PalWorldSettings.ini" = generateSettings "PalWorldSettings.ini" settings;
206
-
"Pal/Saved/Config/LinuxServer/Engine.ini" = builtins.toFile "Engine.ini" engineSettings;
212
-
"-port=${toString cfg.port}"
214
-
"-NoAsyncLoadingThread"
215
-
"-UseMultithreadForDS"
216
-
"-players=${toString cfg.maxPlayers}"
217
-
"-NumberOfWorkerThreadsServer=${toString cfg.threads}"
219
-
++ optionals (cfg.ip != null) [ "-publicip=${cfg.ip}" ]
220
-
++ optionals cfg.public [ "-publiclobby" ];
221
-
bin = getExe (pkgs.mkSteamWrapper "${cfg.datadir}/Pal/Binaries/Linux/PalServer-Linux-Shipping");
222
-
in "${bin} ${concatStringsSep " " args}";
224
-
wantedBy = mkIf cfg.autostart [ "multi-user.target" ];
225
-
after = [ "network.target" ];
226
-
path = with pkgs; [ xdg-user-dirs util-linux ];
230
-
${scripts.mkDirs name dirs}
231
-
${scripts.mkFiles name files}
235
-
Restart = "on-failure";
236
-
User = "${baseCfg.user}";
237
-
Group = "${baseCfg.group}";
238
-
WorkingDirectory = "${cfg.datadir}";
241
-
CPUQuota = "${toString ((cfg.threads + 1) * 100)}%";
243
-
PrivateDevices = true;
245
-
PrivateUsers = true;
246
-
ProtectClock = true;
247
-
ProtectProc = "noaccess";
248
-
ProtectKernelLogs = true;
249
-
ProtectKernelModules = true;
250
-
ProtectKernelTunables = true;
251
-
RestrictRealtime = true;
252
-
LockPersonality = true;
254
-
# Palworld needs namespaces and system calls
255
-
RestrictNamespaces = false;
256
-
SystemCallFilter = [];