Egg Repository

Pterodactyl Community Egg Repository

Sunkenland

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?

Read Me

Sunkenland

Author & Contributers

NameGithub ProfileBuy me a Coffee
Brainsheadhttps://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 MinimumRecommended
Game OwnershipServer can start without itGame is needed for creating custom maps
RAM4 GB+8 GB+
Storage5 GB+20 GB+

Server Ports

Ports required to run the server in a table format.

PortDefault
Game Port25000

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.
Yolks
NameTag
ghcr.io/ptero-eggs/yolks:wine_latestghcr.io/ptero-eggs/yolks:wine_latest
Variables
NameDescriptionEnvironment VariableDefault ValueUser ViewableUser Editable
App IDThe ID corresponding to the game to download.SRCDS_APPID2667530YesNo
Auto Update ServerThis is to auto-update the game server.AUTO_UPDATE1YesYes
Windows InstallThis is required to install the correct version. Removing or touching this will overwrite the files with a non-existing Linux releases.WINDOWS_INSTALL1NoNo
[SYSTEM] WINEDEBUGdon't change this !!!WINEDEBUG-allNoNo
World GUIDThe 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 itselfWORLD_GUID11223344-5566-7788-99aa-bbccddeeff00YesYes
RegionSet 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=uswREGIONasiaYesYes
Max PlayerSet the Max Player Count. The minimum value is 3 and the maximum value is 15. Default is 3MAX_PLAYER3YesYes
Server PasswordSet the password. Default is empty; Note that using characters other than ASCII may result in password verification failure. The length limit is 8PASSWORD12345678YesYes
[SYSTEM] WINETRICKS_RUNWINETRICKS_RUNmono vcrun2022NoNo
Server NameName of the serverSERVER_NAMEPterodactyl WorldYesYes
Install Script
#!/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 "-----------------------------------------"