Sunkenland
gamesGet ready for a Waterworld-themed survival game with modular base building, sunken city scavenging, crafting, base defense, and invasions of NPC clans for resources and territory. Ready for the water apocalypse?
README
Sunkenland
Author & Contributers
| Name | Github Profile |
|---|---|
| Brainshead | https://github.com/brainshead |
Documentation
[!NOTE] Latest document can also be found in root of your container when installing server.
Sunkenland is a Waterworld-themed survival game. Explore sunken cities, build your base, craft items, trade, and fight pirates as you struggle to survive in an aquatic post-apocalypse world plagued by hunger and violence.
Install notes
To launch properly, the Sunkenland dedicated server software requires a map. However, the software does not generate the map itself.
This egg includes a default map created through the game. If the user desires a different map, they must create it through Sunkenland and import it to the server manually.
To locate your save files on Windows, go to the following directory:
%USERPROFILE%\AppData\LocalLow\Vector3 Studio\Sunkenland\Worlds
On the server, you can find the map here:
/.wine/drive_c/users/container/AppData/LocalLow/Vector3 Studio/Sunkenland/Worlds
On this location you also find AdminSteamIDs.txt and BanSteamIDs.txt
Put in Steam ID line by line of users to be admins or to be banned.
[!CAUTION] Remember to change the
WORLD_GUIDvariable, if you upload a new world to your server! Otherwise the server will crash upon launching it.
Installation/System Requirements
| Bare Minimum | Recommended | |
|---|---|---|
| Game Ownership | Server can start without it | Game is needed for creating custom maps |
| RAM | 4 GB+ | 8 GB+ |
| Storage | 5 GB+ | 20 GB+ |
| CPU | 2 cores with high single-core performance (≥3.0 GHz, modern architecture) | 4 cores with high IPC and boost clocks (≥3.5–4.5 GHz; modern architecture preferred) |
[!Important] Sunkenland Dedicated Server is built on Unity and is primarily single-threaded and wine also have overhead.
CPU clock speed and IPC matter far more than total core count.
The server simulation (world, physics, AI) runs largely on one primary thread
Additional cores provide limited benefit
Server Ports
Ports required to run the server in a table format.
| Port | Default |
|---|---|
| Game Port | 25000 |
Notes
[!NOTE]
- There's no strict "server name" variable. It's tied to the World/Map Name. The install script is modified to rename the folder to whatever the users sets as
SERVER_NAME.- When you want change the server name, a reinstall is required to let the script run the renaming of the world name.
Docker Images (1)
| Name | Image |
|---|---|
ghcr.io/ptero-eggs/yolks:wine_latest | ghcr.io/ptero-eggs/yolks:wine_latest |
Startup Command
wine ./Sunkenland-DedicatedServer.exe -nographics -batchmode -worldGuid {{WORLD_GUID}} -region {{REGION}} -password {{PASSWORD}} -maxPlayerCapacity {{MAX_PLAYER}} -publicIP {{SERVER_IP}} -publicPort {{SERVER_PORT}} Variables (10)
App ID
The ID corresponding to the game to download.
- Environment:
SRCDS_APPID- Default:
2667530- User Viewable:
- ✅
- User Editable:
- ❌
- Rules:
required|numeric|digits_between:1,10
Auto Update Server
This is to auto-update the game server.
- Environment:
AUTO_UPDATE- Default:
1- User Viewable:
- ✅
- User Editable:
- ✅
- Rules:
required|boolean
Windows Install
This is required to install the correct version. Removing or touching this will overwrite the files with a non-existing Linux releases.
- Environment:
WINDOWS_INSTALL- Default:
1- User Viewable:
- ❌
- User Editable:
- ❌
- Rules:
required|string|in:1
[SYSTEM] WINEDEBUG
don't change this !!!
- Environment:
WINEDEBUG- Default:
-all- User Viewable:
- ❌
- User Editable:
- ❌
- Rules:
required|string|max:20
World GUID
The world GUID is the later part of the world save file, for example, in this save file 'YourWorldName~11223344-5566-7788-99aa-bbccffeeff00', the part after '~' symbol is the guid, i.e.'11223344-5566-7788-99aa-bbccffeeff00'. Specify Which World to start the game, if the world save file with entered GUID cannot be found, the server will fail to start and shut down itself
- Environment:
WORLD_GUID- Default:
11223344-5566-7788-99aa-bbccddeeff00- User Viewable:
- ✅
- User Editable:
- ✅
- Rules:
required|string
Region
Set the custom Region. Default is ASIA. Please check Region Code Table below. Asia=asia, Chinese Mainland=cn, Japan=jp, Europe=eu, South America=sa South Korea=kr, USA, East=us, USA, West=usw
- Environment:
REGION- Default:
asia- User Viewable:
- ✅
- User Editable:
- ✅
- Rules:
required|string
Max Player
Set the Max Player Count. The minimum value is 3 and the maximum value is 15. Default is 3
- Environment:
MAX_PLAYER- Default:
3- User Viewable:
- ✅
- User Editable:
- ✅
- Rules:
required|numeric|between:3,15
Server Password
Set the password. Default is empty; Note that using characters other than ASCII may result in password verification failure. The length limit is 8
- Environment:
PASSWORD- Default:
12345678- User Viewable:
- ✅
- User Editable:
- ✅
- Rules:
required|string|max:8
[SYSTEM] WINETRICKS_RUN
- Environment:
WINETRICKS_RUN- Default:
mono vcrun2022- User Viewable:
- ❌
- User Editable:
- ❌
- Rules:
required|string
Server Name
Name of the server
- Environment:
SERVER_NAME- Default:
Pterodactyl World- User Viewable:
- ✅
- User Editable:
- ✅
- Rules:
nullable|string
Installation Script
ghcr.io/ptero-eggs/installers:debianbash#!/bin/bash
# Sunkenland SteamCMD Base Installation Script
# Image: ghcr.io/ptero-eggs/installers:debian
# Server Files: /mnt/server
# --- Install dependencies ---
apt update -y
apt install -y rsync curl tar git
# --- Steam Variables ---
# STEAM_USER, STEAM_PASS, STEAM_AUTH - Steam login info (optional)
# SRCDS_APPID - Steam App ID (Sunkenland = 2512750)
# SRCDS_BETAID, SRCDS_BETAPASS - Optional beta branch/password
# WINDOWS_INSTALL - Set to 1 for Windows game
# INSTALL_FLAGS - Extra steamcmd flags
# AUTO_UPDATE - Set to 1 or 0
# --- Validate Steam credentials ---
if [[ -z "${STEAM_USER}" || -z "${STEAM_PASS}" ]]; then
echo "No Steam credentials provided. Using anonymous login."
STEAM_USER="anonymous"
STEAM_PASS=""
STEAM_AUTH=""
else
echo "Steam user set to: ${STEAM_USER}"
fi
# --- Install SteamCMD ---
cd /tmp
mkdir -p /mnt/server/steamcmd
curl -sSL -o steamcmd.tar.gz https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz
tar -xzvf steamcmd.tar.gz -C /mnt/server/steamcmd
mkdir -p /mnt/server/steamapps
cd /mnt/server/steamcmd
chown -R root:root /mnt
export HOME=/mnt/server
# --- Run SteamCMD to install the game ---
./steamcmd.sh +force_install_dir /mnt/server +login ${STEAM_USER} ${STEAM_PASS} ${STEAM_AUTH} $( [[ "${WINDOWS_INSTALL}" == "1" ]] && echo '+@sSteamCmdForcePlatformType windows' ) +app_update ${SRCDS_APPID} $( [[ -n "${SRCDS_BETAID}" ]] && echo "-beta ${SRCDS_BETAID}" ) $( [[ -n "${SRCDS_BETAPASS}" ]] && echo "-betapassword ${SRCDS_BETAPASS}" ) ${INSTALL_FLAGS} validate +quit
# --- Setup Steam client libraries ---
mkdir -p /mnt/server/.steam/sdk32
cp -v linux32/steamclient.so ../.steam/sdk32/steamclient.so
mkdir -p /mnt/server/.steam/sdk64
cp -v linux64/steamclient.so ../.steam/sdk64/steamclient.so
# --- Validate SERVER_NAME ---
if [[ -z "${SERVER_NAME}" ]]; then
echo "SERVER_NAME is empty. Using fallback: 'Pterodactyl Sunkenland'"
SERVER_NAME="Pterodactyl Sunkenland"
else
echo "SERVER_NAME is: ${SERVER_NAME}"
fi
# --- Define world file directory ---
WORLD_BASE="/mnt/server/.wine/drive_c/users/container/AppData/LocalLow/Vector3 Studio/Sunkenland"
WORLD_DIR="$WORLD_BASE/Worlds"
# --- Optional world file setup ---
TARGET_GUID="11223344-5566-7788-99aa-bbccddeeff00"
if [[ "${WORLD_GUID}" == "$TARGET_GUID" ]]; then
echo "Detected matching GUID '$TARGET_GUID' — Downloading standard world files..."
# Clone specific folder from GitHub (sparse checkout)
mkdir -p /tmp/world_files
git clone --depth 1 --filter=blob:none --sparse --branch main https://github.com/Ptero-Eggs/game-eggs/sunkenland /tmp/world_files/worlds
cd /tmp/world_files/worlds
git sparse-checkout init --cone
git sparse-checkout set sunkenland/world_files
git pull origin main
# Copy world files into place
mkdir -p "$WORLD_BASE"
rsync -a /tmp/world_files/worlds/sunkenland/world_files/Worlds/ "$WORLD_DIR/"
# Rename downloaded world folder
ORIGINAL_FOLDER="$WORLD_DIR/World~${WORLD_GUID}"
NEW_FOLDER="$WORLD_DIR/${SERVER_NAME}~${WORLD_GUID}"
if [[ -d "$ORIGINAL_FOLDER" ]]; then
if [[ "$ORIGINAL_FOLDER" != "$NEW_FOLDER" ]]; then
if [[ -d "$NEW_FOLDER" ]]; then
echo "Removing existing folder at $NEW_FOLDER to avoid nesting."
rm -rf "$NEW_FOLDER"
fi
mv "$ORIGINAL_FOLDER" "$NEW_FOLDER"
echo "World folder renamed from 'World' to '${SERVER_NAME}', with GUID: ${WORLD_GUID}"
else
echo "World folder already named correctly: $ORIGINAL_FOLDER"
fi
else
echo "Expected world folder not found at: $ORIGINAL_FOLDER"
fi
rm -rf /tmp/world_files
else
echo "WORLD_GUID is '${WORLD_GUID}' — skipping auto world setup."
fi
# --- Handle manually uploaded world folder ---
FOUND_FOLDERS=$(find "$WORLD_DIR" -maxdepth 1 -type d -name "*~${WORLD_GUID}" -printf "%f\n")
if [[ -n "$FOUND_FOLDERS" ]]; then
while IFS= read -r folder; do
ORIGINAL_FOLDER="$WORLD_DIR/$folder"
NEW_FOLDER="$WORLD_DIR/${SERVER_NAME}~${WORLD_GUID}"
if [[ "$ORIGINAL_FOLDER" != "$NEW_FOLDER" ]]; then
if [[ -d "$NEW_FOLDER" ]]; then
echo "Removing existing folder at $NEW_FOLDER to avoid nesting."
rm -rf "$NEW_FOLDER"
fi
mv "$ORIGINAL_FOLDER" "$NEW_FOLDER"
echo "Manually uploaded world folder renamed to: $NEW_FOLDER"
else
echo "World folder already correctly named: $ORIGINAL_FOLDER"
fi
done <<< "$FOUND_FOLDERS"
else
echo "No folder found with GUID: $WORLD_GUID"
fi
# --- Ensure AdminSteamIDs.txt and BanSteamIDs.txt exist ---
FINAL_WORLD_DIR="$WORLD_DIR/${SERVER_NAME}~${WORLD_GUID}"
if [[ -d "$FINAL_WORLD_DIR" ]]; then
ADMIN_FILE="$FINAL_WORLD_DIR/AdminSteamIDs.txt"
BAN_FILE="$FINAL_WORLD_DIR/BanSteamIDs.txt"
if [[ ! -f "$ADMIN_FILE" ]]; then
touch "$ADMIN_FILE"
echo "Created missing AdminSteamIDs.txt"
else
echo "AdminSteamIDs.txt already exists"
fi
if [[ ! -f "$BAN_FILE" ]]; then
touch "$BAN_FILE"
echo "Created missing BanSteamIDs.txt"
else
echo "BanSteamIDs.txt already exists"
fi
else
echo "World folder not found at: $FINAL_WORLD_DIR — skipping admin/ban file creation"
fi
echo "-----------------------------------------"
echo "Sunkenland installation completed."
echo "-----------------------------------------"