| config | ||
| dist | ||
| scripts | ||
| steam | ||
| systemd | ||
| .dockerignore | ||
| .gitignore | ||
| compose.yaml | ||
| CONTRIBUTING.md | ||
| CONTRIBUTOR-TERMS.md | ||
| Dockerfile | ||
| LICENSE | ||
| README.md | ||
straywild Dedicated Server
This repository packages the headless straywild server produced by the main
game project. Gameplay and networking code remain in the straywild
repository so clients and servers use the same protocol implementation.
Production tags follow the coordinated straywild release train. Package a
game release with the same vX.Y.Z-alpha tag checked out in this repository.
The package manifest records both the exact game commit and the exact dedicated
packaging commit; packaging refuses to run when its matching release tag does
not point to the current commit.
Stage a build
Export the Linux Dedicated Server preset from the game project, then stage
its executable and PCK with the exact game version and source commit:
game_commit="$(git -C ../straywild rev-parse HEAD)"
./scripts/stage-build.sh \
../straywild/builds/vX.Y.Z-alpha/server-linux-x86_64 \
X.Y.Z-alpha \
"${game_commit}" \
../straywild
The staged binaries under dist/ are release inputs and are intentionally not
tracked by Git. dist/BUILD_INFO records the version, full game and packaging
commits, export preset, platform, and binary hashes. Manifest version 3 also
records the consolidated notice layout. Packaging refuses a
version mismatch, packaging-tag mismatch, or failed internal checksum.
Staging also requires the clean main game checkout at that exact commit and
copies its authoritative licenses, attribution/provenance record, and font
notices into the package. This repository does not maintain duplicate copies.
Create a deterministic native archive after staging:
./scripts/package-native.sh X.Y.Z-alpha
Install or update natively
The native archive contains its BUILD_INFO and internal checksums. Transfer
both the archive and its adjacent .sha256 file, then install it:
sudo ./scripts/install-native-release.sh \
packages/straywild-dedicated-server-X.Y.Z-alpha-linux-x86_64.tar.gz \
packages/straywild-dedicated-server-X.Y.Z-alpha-linux-x86_64.tar.gz.sha256
Releases are immutable directories under /opt/straywild-server/releases.
The installer verifies the outer archive hash, internal hashes, manifest, and
platform before atomically changing /opt/straywild-server/current. When the
sample systemd unit is already active, a failed start automatically restores
the prior release. Manually return to the recorded previous release with:
sudo ./scripts/rollback-native.sh
Copy config/server.cfg.example to /etc/straywild-server.cfg and adjust the
room name, UDP port, player limit, and public-listing preference. Set TZ in
/etc/straywild-server.env to an IANA timezone such as America/New_York when
the server's world should follow that region's wall clock and daylight-saving
rules; the packaged default is UTC. The timezone must be present before the
server process starts, so restart the service after changing it. Forward the
configured UDP port through the host firewall and router when accepting
Internet players.
The data directory contains the server identity and moderation state. Keep it persistent and back it up; replacing it changes the server fingerprint shown to returning players.
Configuration is applied in this order: config file, environment variables,
then command-line overrides. Supported command-line options are --name,
--bind, --port, --max-players, --data-dir, --discovery-url,
--operators, --chat-log-path, --chat-logging, --no-chat-logging,
--public, and --private. Value options use --option=value.
Keep the first standalone -- shown above; it separates Godot engine flags
from server flags.
Chat privacy
Chat logging is disabled by default. With the default configuration, chat is kept only in the connected player's current UI, is not replayed to players who join or reconnect, and is not written to disk. The live session's chat is destroyed when that session ends.
A dedicated-server operator can explicitly opt into logging by setting
chat_logging=true under [privacy], setting
straywild_CHAT_LOGGING=true, or passing --chat-logging. The optional
chat_log_path, straywild_CHAT_LOG_PATH, or --chat-log-path setting must
be an absolute path; it defaults to logs/chat.jsonl inside the configured
data directory. Players joining a server with logging enabled receive an
in-game privacy warning. The JSON Lines log contains UTC timestamps, player
display names, and message bodies. Treat it as sensitive data and configure
access, retention, and rotation deliberately.
Headless operators
Headless moderation is granted by authenticated player identity, never by a display name or shared password. A player can copy their complete 64-character fingerprint from Settings → Data & Identity → Copy Player Fingerprint.
Add trusted fingerprints to /etc/straywild-server.cfg:
[moderation]
operators=PackedStringArray("0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef")
Alternatively, provide a comma-separated list through
straywild_SERVER_OPERATORS or --operators=fingerprint1,fingerprint2.
Configuration file values are overridden by the environment, then by the
command line. Restart the server after changing the allowlist.
The server grants operator status only after the connecting player proves ownership of that exact identity key. Operators can kick, ban, unban, and clear shared session artwork through the in-game Players page. They cannot grant operator access, revoke another operator, or moderate another operator. Keep the server data directory persistent because it owns the server identity and stored bans.
Public listing requires the discovery URL and a publicly reachable ENet UDP port. Discovery makes a server findable but does not relay gameplay traffic.
For a systemd installation, create a dedicated straywild system user,
install the sample configuration and environment files under /etc, and copy
systemd/straywild-server.service to the system unit directory. The unit runs
the atomic current release link and expects /var/lib/straywild-server to be
writable by that user. When migrating an older direct-path installation, stop
the service, run the installer once, replace/reload the unit, and then start it.
After that one-time migration, future upgrades can be applied while the unit
is running.
For a direct foreground run from staged build inputs:
./dist/straywildServer.x86_64 \
-- \
--config=/etc/straywild-server.cfg \
--data-dir=/var/lib/straywild-server
Run with Docker Compose
./scripts/stage-build.sh \
../straywild/builds/vX.Y.Z-alpha/server-linux-x86_64 \
X.Y.Z-alpha \
"$(git -C ../straywild rev-parse HEAD)" \
../straywild
docker compose build
docker compose up -d
Set values such as straywild_SERVER_NAME, straywild_SERVER_PORT,
straywild_SERVER_MAX_PLAYERS, straywild_SERVER_PUBLIC, TZ, and the
optional comma-separated straywild_SERVER_OPERATORS in a local .env file.
Chat logging remains off unless straywild_CHAT_LOGGING=true is explicitly
set. The Compose service runs without Linux capabilities, uses a read-only root
filesystem, and stores persistent state in a named volume.
Steam distribution
Publish the server as a separate Steam Tool AppID/depot linked to the base
game. Replace the placeholders in copies of the files under steam/, then use
SteamCMD to upload the staged dist/ directory. Keep the example files free of
private Steam credentials.
Licensing
Project-owned source code in this packaging repository and the packaged game server code are licensed under GPL-3.0-or-later. Every binary package includes the license and a corresponding-source record for its exact game commit.
The server PCK contains straywild creative assets and third-party material.
Their governing terms, credits, and provenance are maintained once in the
main game's
docs/ATTRIBUTION.md,
with the asset license and trademark terms beside that record. Every staged
server package copies those files from its exact game source commit.
Unsolicited contributions are not accepted; see
CONTRIBUTING.md. Historical and expressly invited work is
governed by CONTRIBUTOR-TERMS.md.
Copyright © 2026 Woofmeow.