A large share of the dedicated servers people rent - Valheim, Rust, 7 Days to Die, Unturned, SCP: Secret Laboratory, The Forest, Sons of the Forest, V Rising, Core Keeper - are Unity programs started without a window. They all share the same skeleton: a binary next to a <Name>_Data folder, two switches (-batchmode -nographics) that turn the game into a headless process, a log file that Unity writes in a predictable place unless told otherwise, and a scripting backend (Mono or IL2CPP) that decides how modding works. Learn that skeleton once and every Unity server becomes easier to read, start and debug, whichever studio made it.
Which servers are Unity, and why it matters#
Unity is an engine, not a server framework. Every studio writes its own networking, its own config format and its own admin system on top of it, so knowing that a game is Unity does not tell you where its settings live. What it does tell you is how the process behaves at the operating-system level: how it starts, how it logs, how it uses memory and threads, and how mods get into it.
| Game | Server binary on Linux | Configured mainly by |
|---|---|---|
| Valheim | valheim_server.x86_64 | Launch arguments |
| Rust | RustDedicated | +convar arguments and server.cfg |
| 7 Days to Die | 7DaysToDieServer.x86_64 | serverconfig.xml |
| Unturned | Unturned_Headless.x86_64 | Commands.dat and Config.json |
| SCP: Secret Laboratory | Launched via LocalAdmin | config_gameplay.txt |
| Sons of the Forest | Windows only: SonsOfTheForestDS.exe | dedicatedserver.cfg |
You can usually tell a Unity server by its files. Look for a folder called <something>_Data, a UnityPlayer.so (Linux) or UnityPlayer.dll (Windows) beside the binary, and inside the data folder files called globalgamemanagers and resources.assets. If those are there, everything in this post applies.
Some games people assume are Unity are not. Palworld, ARK, Satisfactory, Abiotic Factor and Squad are Unreal Engine (covered in Unreal Engine dedicated server basics); Terraria is XNA/FNA; Don't Starve Together and Factorio run on their studios' own engines; Space Engineers is VRage. The distinction is practical - the log location, the threading model and the mod loaders are different.
Batchmode, nographics and the launch line#
Unity started life as an engine for programs with a window. A dedicated server is the same player binary told not to open one. Two standard Unity command-line arguments do that:
-batchmode- run without the interactive player loop expecting a user: no window, no input, no dialogs. Error pop-ups that would block a desktop build are suppressed.-nographics- do not initialise a graphics device at all. Without it, batchmode on a machine with no GPU may still try to create one and fail, or allocate memory for rendering that will never happen.
Almost every Unity server's start script passes both. On top of them each game adds its own arguments, which Unity ignores and the game's code reads. The shapes differ:
# Valheim: plain dash arguments read by the game$ ./valheim_server.x86_64 -nographics -batchmode -name "Crew" -port 2456 \ -world "Midgard" -password "longship-42"# Rust: Unity flags, then +convar pairs$ ./RustDedicated -batchmode -nographics +server.port 28015 \ +server.identity "main" +server.hostname "My Rust server"# 7 Days to Die: a config file does most of the work$ ./7DaysToDieServer.x86_64 -batchmode -nographics -dedicated \ -configfile=serverconfig.xml -logfile output_log.txtSince Unity 2021.2 there is also a dedicated "Dedicated Server" build target. A game built that way strips rendering code out of the binary and runs headless by default, so the switches become belt and braces rather than required. Older games and many current ones still ship an ordinary player build and rely on the switches, which is why you should never remove them from a start line even if the server seems to run without them.
On a panel such as Pterodactyl the launch line lives in the egg's startup command, and the game-specific parts are exposed as variables on the Startup tab. You edit the variables; the Unity switches stay fixed underneath. Game server startup parameters explained covers how those variables map onto the command line across engines.
The frame rate is the tick rate
A Unity server is a game loop. Every frame it runs physics, AI and networking, then starts again. In batchmode there is no vsync to hold it back, so a server whose developer forgot to cap the frame rate will run as many frames per second as one core can manage and sit at 100% CPU with nobody connected. Most games cap it through Application.targetFrameRate and expose the cap as a setting - Rust has fps.limit, for example. If an empty Unity server pins a core, look for that setting before assuming something is wrong. What tick rate actually means explains the trade between frames and responsiveness.
Where Unity servers write their logs#
Unity writes its own log - engine messages plus everything the game prints through Debug.Log - to a file called Player.log. Where that file goes depends on the platform and on one argument:
| Situation | Log location |
|---|---|
Linux, no -logFile | ~/.config/unity3d/<Company>/<Product>/Player.log |
Windows, no -logFile | %USERPROFILE%\AppData\LocalLow\<Company>\<Product>\Player.log |
-logFile path/to/file.txt | That file, relative to the working directory |
-logFile - (where supported) | Standard output, so it appears in the console |
<Company> and <Product> are the strings the studio set in the project, for example IronGate/Valheim. The previous run's log is usually kept as Player-prev.log in the same folder.
This is the single most common reason people say a Unity server "has no logs". The game is logging perfectly well, just into a hidden folder in the home directory of whatever user runs it. Panel eggs almost always pass -logFile with either a file inside the server directory or a dash so that output reaches the console, because the console is the only window you have.
Some games keep their own logs on top of Unity's. 7 Days to Die writes output_log files with timestamps when told to; Rust writes per-identity logs if you pass -logfile; SCP: SL's LocalAdmin keeps its own logs folder. When something fails, check both: the game's log for game errors, Unity's for engine and native-library errors. Game server logs explained has a per-game map.
Lines that look alarming and are not
Unity server logs open with a block of engine chatter that frightens people every time. Most of it is harmless on a headless machine:
Initialize engine version: 2022.3.xForcing GfxDevice: NullNullGfxDevice: Version: NULL 1.0 [1.0]Desktop is 0 x 0 @ 0 HzFallback handler could not load library .../Mono/libcWhat each of those means:
Initialize engine versiontells you which Unity release the game uses. Worth noting when a mod loader asks.Forcing GfxDevice: Nulland theNullGfxDeviceblock are-nographicsworking as intended.Desktop is 0 x 0 @ 0 Hzis the absence of a display, which is correct.Fallback handler could not load librarylines are Mono probing for native libraries under alternative names. They appear on almost every Linux Unity server and almost never matter.The referenced script on this Behaviour is missingis a content warning the studio shipped with. Annoying, not fatal.
The lines that do matter come later: a NullReferenceException repeated every frame, DllNotFoundException, anything mentioning SteamAPI_Init failing, and the last lines before the process exits. How to read a server console goes through reading upward from the failure.
The files: what the _Data folder holds#
A Unity server install looks roughly like this, with names varying by game:
server/ valheim_server.x86_64 the player binary UnityPlayer.so the engine valheim_server_Data/ Managed/ C# assemblies (Mono builds only) Assembly-CSharp.dll the game's own code MonoBleedingEdge/ the Mono runtime Plugins/ native libraries (Steamworks and others) globalgamemanagers engine settings baked at build time *.assets, *.resS game content linux64/steamclient.so Steam client library for the server steam_appid.txt which Steam app this isNothing inside _Data is configuration you should edit. It is the game, and SteamCMD will overwrite it on the next update (run with validate and it will also "repair" anything you changed). Settings, saves, ban lists and mod configs live elsewhere - in launch arguments, in a config file the game reads from the server root, or in a save directory. The save location is game-specific and often defaults to the same hidden .config/unity3d or AppData\LocalLow path as the log, which is why many games offer an argument to move it (-savedir in Valheim, +server.identity in Rust, UserDataFolder in 7 Days to Die's config). Game server save files explained lists them.
steam_appid.txt deserves a mention. Steamworks reads it to know which app it is running as. If it is missing or holds the wrong id, SteamAPI_Init() fails and the server either refuses to start or starts without Steam features, so players cannot find or join it. Start scripts often write it or export SteamAppId before launching; Valheim's start_server.sh does exactly that, along with setting LD_LIBRARY_PATH=./linux64 so the bundled steamclient.so is found.
Mono vs IL2CPP: why it decides how mods work#
Unity compiles a game's C# code in one of two ways, and for a server owner this is the most consequential detail of all.
- Mono: the game's code ships as .NET assemblies in
_Data/Managed, and Mono runs them at load time. Those DLLs can be loaded, inspected and patched. Every mature Unity modding ecosystem - BepInEx 5 for Valheim and many others, Oxide/uMod and Carbon for Rust, RocketMod and OpenMod for Unturned, EXILED for SCP: SL - depends on that. - IL2CPP: the C# is converted to C++ and compiled to native code at build time. There is no
Managedfolder, just a largeGameAssembly.soorGameAssembly.dlland anil2cpp_datafolder. Mods need a heavier toolchain (BepInEx 6, MelonLoader) that generates proxy assemblies, and they break more often on updates.
You can tell which you have by looking: a Managed folder full of DLLs means Mono, GameAssembly means IL2CPP. Check before you plan a modded server. A game that is Mono on the server but IL2CPP on the client (it happens) can still take server-side plugins, but client mods follow different rules.
The usual Mono mod loaders inject themselves with Doorstop, a small native library that runs before the game's code. That is why BepInEx for Valheim ships a different start script and a doorstop_libs folder: the script sets environment variables (LD_PRELOAD on Linux) so the loader runs first. If a modded server starts but loads no mods, the start command is almost always still the vanilla one. The details for Valheim are in Valheim mods with BepInEx on a server, and mod load order explained covers dependencies once the loader is working.
Memory, CPU and threads#
Unity servers have a recognisable resource profile, and knowing it stops you buying the wrong upgrade.
One busy thread. Unity runs game logic on the main thread. Physics, jobs and some networking can use worker threads, and a few studios have moved heavy work off the main thread, but in practice the frame time of a Unity server is set by one core. Clock speed matters more than core count. If the panel graph shows a 2-core plan at 50% with players complaining about lag, that is one core at 100% and one idle. Reading game server CPU usage explains the arithmetic.
Memory that grows. Mono uses a garbage collector that rarely gives memory back to the operating system, and games load content as players explore. A Unity server that started at 2 GB and sits at 4 GB after three days is usually behaving normally - though leaks in game code are common too. A scheduled restart, at a quiet hour, is the standard answer to both. Game server memory leaks covers telling the two apart.
Garbage collection pauses. When the collector runs it can stop the main thread for tens of milliseconds on a large heap, which players feel as a hitch at regular intervals. Unity's incremental collector (available since 2019) spreads the work, but whether a game enables it is the studio's choice, not yours.
Saves on the main thread. Many Unity games serialise the world on the main thread, so the server freezes for the duration of the save. Faster storage shortens it; a longer autosave interval makes it rarer but loses more on a crash. Game server autosave intervals weighs that trade.
| Symptom | Likely cause | First check |
|---|---|---|
| Empty server at 100% of one core | Uncapped frame rate | The game's FPS or tick cap setting |
| Hitch every few minutes | Autosave or GC | Does it line up with "saving" in the log |
| Memory climbs all week | Normal growth or a leak | Does a restart bring it back to baseline |
| Lag that scales with builds | Entity count | Game-specific entity tools |
Linux, Steam libraries and the errors you will hit#
Most Unity servers ship a native Linux build, which is good news - no Wine needed. The Forest and Sons of the Forest are the well-known exceptions: their servers are Windows-only and run on Linux under Wine. The native builds do depend on a handful of native libraries, and missing ones produce the errors that dominate support threads.
dlopen failed trying to load: steamclient.so[S_API FAIL] SteamAPI_Init() failed; SteamAPI_IsSteamRunning() failed.The server cannot find Steam's client library. Steamworks looks for it in ~/.steam/sdk64/steamclient.so (and sdk32 for 32-bit builds). The usual fix is to copy the one SteamCMD installed:
$ mkdir -p ~/.steam/sdk64$ cp ~/steamcmd/linux64/steamclient.so ~/.steam/sdk64/Some start scripts instead put ./linux64 on LD_LIBRARY_PATH, which works as long as the script is used. Starting the binary directly, bypassing the script, is a classic way to reintroduce this error.
Other errors that point at the platform rather than the game:
- `DllNotFoundException` for a named library: a native dependency is missing. On a minimal distro this is often a 32-bit library, or
libatomic,libpulseor similar that the game links against even with no audio. The name in the message is what to install. - `Segmentation fault` on start: frequently a mod loader built for the wrong Unity version, or a damaged install. Run SteamCMD with
validateand try again without mods. - The process exits instantly with no log: the log went somewhere you are not looking. Add
-logFilewith an explicit path, start again, then read that file.
On a hosted panel these libraries are part of the image, so the first two are rare; the third is the one you are likely to meet. If you run your own machine, Linux vs Windows game servers covers when a Linux build is missing and you need Wine instead.
Updates and versions#
Unity servers are delivered through SteamCMD like any other Steam server, so updating is app_update <appid> validate. Two Unity-specific points sit on top of that.
First, the engine version can change with a game update. When a studio moves from one Unity release to another, every native mod loader and every IL2CPP proxy needs updating, and the breakage is total rather than one plugin at a time. Patch notes rarely mention it; the Initialize engine version line in the log does. Note it before an update and compare afterwards.
Second, client and server must match exactly in nearly every Unity game, because the network protocol is generated from the game's own code. A one-build difference is enough to refuse a connection. When a patch lands, the server must be updated before anyone on the new client can join - and a modded server should wait for its loader. The order of operations is in the update day checklist, and SteamCMD app ids and beta branches covers holding a server on an older build when a game offers one.
FAQ#
Do I need a GPU to run a Unity game server?
No. With -batchmode -nographics Unity creates a null graphics device and does no rendering. Servers run on ordinary CPU-only machines, and that is how every host runs them. If a server complains about graphics, one of the two switches is missing.
Why is my Unity server using a whole core with nobody online?
Either the frame rate is uncapped, so the loop spins as fast as it can, or the game simulates the world even when empty. Look for a frame or tick limit in the game's settings first. A capped server idling at a few percent is the normal picture.
Can I use BepInEx on any Unity server?
BepInEx 5 works on Mono builds. IL2CPP builds need BepInEx 6 or another loader, and support is shakier. Check for a Managed folder full of DLLs before you plan around it. Some games have their own preferred framework (Oxide or Carbon for Rust, RocketMod or OpenMod for Unturned), which beats a generic loader.
Where do I find the log if the console shows nothing?
Look for Player.log under ~/.config/unity3d/<Company>/<Product>/ on Linux or AppData\LocalLow\<Company>\<Product>\ on Windows, or add -logFile with a path you choose. On a panel the egg usually sends output to the console already.
Is a Unity server slower than an Unreal one?
Neither engine is inherently faster as a server. What matters is how the studio built its simulation: how much runs on the main thread, how entities are stored, how saving works. Compare games, not engines.




Comments
Completely anonymous: no account, no email, no cookie. We store the name you type, the text and the time - nothing else. Links are limited and markup is not rendered.