Skip to content

Godot

Godot supports headless server execution and can produce lightweight server builds. The approach differs between Godot 3.x and 4.x, but the principles are the same: strip out rendering, audio, and input systems that a server does not need.

Godot 4.x supports a --headless flag that disables the display server, rendering, and audio:

./your_project --headless --main-pack server.pck

In Godot 3.x, the --no-window flag hides the window but does not fully disable rendering or audio internals. For true headless operation in 3.x, use the --server flag (available in 3.5+) or compile a custom server template with rendering disabled:

./your_project --server --main-pack server.pck

For production server builds, use a server export template if available, or configure a custom export preset:

  1. Create a new export preset for your target platform (Linux is recommended)
  2. In the export preset, exclude client-only resources (textures, audio, shaders)
  3. Use feature tags to conditionally include/exclude content
  4. Export as a PCK file paired with a headless Godot binary

You can build custom export templates with server-optimized modules disabled (rendering, audio, etc.) by compiling Godot from source with specific build flags:

scons platform=linuxbsd target=template_release module_text_server_adv_enabled=no vulkan=no opengl3=no disable_3d=yes module_openxr_enabled=no

This is a starting point. See Godot’s build documentation for the full list of modules you can disable to minimize your server binary.

GDScript works fine for server logic. It’s lightweight and has no additional runtime dependencies.

C# (Godot 4.x with .NET) adds the .NET runtime as a dependency on the server. This means:

  • The server machine needs the .NET runtime installed or bundled
  • Build size increases
  • Startup time may be slightly longer

Neither choice is wrong, but if your server logic is simple, GDScript avoids the extra dependency overhead.

Godot does not automatically strip unused resources from exports the way some engines do. To keep your server build lean:

  • Use a separate Godot project or export preset for the server
  • Use .gdignore files in directories that contain client-only assets
  • Create a resource filter in your export preset to exclude file types (.png, .ogg, .wav, .tres for visual resources)
  • Keep server scenes and client scenes in separate directories

Godot’s built-in MultiplayerAPI and ENetMultiplayerPeer work in headless mode. If you’re using a custom networking solution, verify it does not depend on the SceneTree’s rendering or input processing.

Key configuration to expose as startup arguments:

  • Port number
  • Max clients
  • Tick rate (if you’re using a fixed-step server loop)
  • Map or scene to load

_process vs. _physics_process: Server logic should run in _physics_process for consistent tick rates. _process is framerate-dependent, which behaves unpredictably without a display.

VisualServer / RenderingServer calls: Any code that touches the rendering server will fail or behave unexpectedly in headless mode. Guard these with feature checks or keep them strictly in client-side scripts.

Signals tied to UI: If you connect signals to UI nodes that don’t exist on the server, you’ll get runtime errors. Use is_instance_valid() or conditional checks before connecting to UI elements.

Export size: Without careful resource filtering, Godot can export the full project including all textures and audio. Always verify your server build size is dramatically smaller than your client build.