Sunkenland

Games
Report Issue

Get 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?

Contributors:
README

Sunkenland

Author & Contributers

Name Github Profile Buy me a Coffee
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_GUID variable, 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+

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
Container: ghcr.io/ptero-eggs/installers:debian
Entrypoint: bash
#!/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 "-----------------------------------------"