2026-02-11 18:26:00 +11:00
2026-02-11 18:26:00 +11:00
2026-02-11 18:26:00 +11:00
2026-02-11 18:26:00 +11:00
2025-12-20 16:45:46 +11:00
2026-02-10 11:36:02 +11:00
2026-02-10 13:11:31 +11:00
YUH
2026-02-09 18:15:01 +11:00
2026-02-11 18:26:00 +11:00

megastructure.surf

A Docker-based Counter-Strike: Source surf server with Shavit Surf Timer and community physics fix plugins.

Overview

This repository contains a complete CSS surf server setup using Docker containers. The setup includes:

  • CSS Dedicated Server (CSSDS) - Running in 32-bit mode for compatibility
  • Shavit Surf Timer - Surf-specific fork (v1.0.6) with JSON zone support and SQLite
  • MetaMod:Source - Plugin loader framework
  • SourceMod - Server administration and plugin platform
  • Community Physics Plugins - Essential surf fixes and enhancements
  • JSON Zone Loading - Automatic zone loading from surf-zones repository

Architecture

Docker Service

cssds (CSS Dedicated Server)

  • Based on Debian Bookworm
  • Runs SteamCMD to download/update CSS DS
  • Installs MetaMod:Source and SourceMod
  • Installs surf-specific plugins and timer system
  • Runs in 32-bit mode for plugin compatibility
  • Port: 27015 (configurable via SRCDS_PORT)

Key Files

.
├── docker-compose.yaml          # Service orchestration
├── etc/
│   ├── cssds.dockerfile        # CSS DS container definition
│   ├── run.sh                  # Main setup and launch script
│   ├── update_cssds.txt        # SteamCMD script for CSS DS
│   └── cfg/
│       └── server.cfg          # Server configuration
└── data/                       # Persistent data (volume mount)
    └── cssds/                  # CSS server files and database

Installed Plugins & Extensions

Timer System

Shavit Surf Timer v1.0.6 (GitHub)

  • Surf-specific fork with enhanced features
  • Full surf timer with SQLite backend (no separate database needed)
  • Replays, rankings, zone system, statistics
  • JSON zone support from surf-zones repository
    • Zones loaded from https://wrldspawn.github.io/surf-zones/z/{map}.json
    • Includes stripper configurations and mapfixes
    • Matches KSF (Kreedz Surf Federation) server behavior
  • Config location: addons/sourcemod/configs/shavit/

Required Extensions

sm-json v5.0.1 (GitHub)

  • Pure SourcePawn JSON library for zone loading
  • Provides JSONArray.FromFile() for loading JSON zones

sm_closestpos v1.1.1 (GitHub)

  • Required for ghost/replay functionality
  • Enables replay bot positioning

sm-ripext v1.3.2 (GitHub)

  • HTTP/REST extension for Shavit
  • Required for shavit-wrsh plugin
  • Alternative JSON/HTTP support

DHooks v2.2.0 (GitHub)

  • Included with SourceMod
  • Required by most modern plugins

Physics Fix Plugins

MomSurfFix v1.1.5 (GitHub)

  • Fixes Source engine surf physics to match Momentum Mod behavior
  • Essential for proper surf mechanics

EventQueue Fix v1.3.2 (GitHub)

  • Fixes map entity timing issues
  • Ensures triggers and outputs work correctly

RNGFix v1.1.3 (GitHub)

  • Fixes Source engine RNG determinism issues
  • Ensures consistent physics behavior

Note: PushFix Definitive Edition is NOT installed as it's CS:GO only and not compatible with CSS.

Base Plugins

SourceMod includes built-in plugins for server administration:

  • Admin Menu, Basic Commands, Player Commands
  • Rock The Vote, Map Nominations, MapChooser
  • Reserved Slots, Basic Bans
  • And more (see etc/run.sh for full list)

Setup & Usage

Prerequisites

  • Docker
  • Docker Compose
  • ~10GB disk space for server files

Environment Variables

Configure in docker-compose.yaml or .env file:

# Server Settings
METAMOD_VERSION: "1.12"      # MetaMod:Source version
SOURCEMOD_VERSION: "1.12"    # SourceMod version
SRCDS_PORT: 27015           # Server port
SRCDS_MAXPLAYERS: 32        # Max player slots
SRCDS_STARTMAP: "surf_ski_2" # Starting map
SRCDS_IP: "0.0.0.0"         # Bind IP address

# Admin Configuration (comma-separated Steam IDs)
SRCDS_ADMINS: "STEAM_1:0:12345678,STEAM_1:1:87654321"

Admin Steam ID Format:

  • Use STEAM_1:Y:XXXXXX format (recommended)
  • Or [U:1:XXXXXX] format (modern SteamID3)
  • Find your Steam ID in-game with status command
  • Or use https://steamid.io/

Building & Running

# Build the container
docker-compose build

# Start the server
docker-compose up -d

# View logs
docker-compose logs -f cssds

# Restart the server
docker-compose restart cssds

# Stop the server
docker-compose down

Update Server Files

The server installation is persistent - game files are only downloaded on first run. To force an update:

# Update CSS game files
docker-compose run cssds bash ./etc/run.sh --update-cssds

Or modify the environment to skip updates by default (already configured):

  • Default: Updates are skipped for faster restarts
  • Use --update-cssds flag to force updates

Database Configuration

The server uses SQLite by default (no separate database needed):

  • Database file: addons/sourcemod/data/sqlite/shavit-local.sq3
  • Automatically created on first run
  • Stores player times, rankings, and replay data

To switch to MariaDB later (optional):

  1. Edit addons/sourcemod/configs/databases.cfg
  2. Change driver from sqlite to mysql
  3. Configure host, database, user, password
  4. Restart server

JSON Zones Configuration

The server is automatically configured to use JSON zones instead of SQL-based zones:

Automatic Setup:

  • Zones loaded from surf-zones repository
  • Includes 400+ maps with pre-configured zones
  • No manual zone creation needed for supported maps
  • URL: https://wrldspawn.github.io/surf-zones/z/{map}.json

Configuration Files Created:

  • cfg/sourcemod/plugin.shavit-zones.cfg - Disables SQL zones
  • cfg/sourcemod/plugin.shavit-zones-json.cfg - Sets JSON URL
  • addons/stripper/ - Map entity fixes
  • addons/sourcemod/configs/shavit-mapfixes.cfg - Map settings
  • addons/sourcemod/configs/shavit-styles.cfg - KSF-style configurations

Benefits:

  • No manual zone editing for popular maps
  • Community-maintained and updated
  • Includes map fixes
  • Matches KSF server standards
  • Faster deployment

Server Configuration

Edit etc/cfg/server.cfg for server settings:

  • Hostname, RCON password (change default!)
  • Surf physics (gravity, air accelerate, max velocity)
  • HUD settings (minimal by default)
  • Network rates
  • Player settings

Important: Change the default RCON password:

rcon_password "changeme"  // CHANGE THIS!

In-Game Commands

Admin Commands

rcon_password <password>    // Authenticate RCON
rcon sm_admin               // Open admin menu
sm_map <mapname>            // Change map
sm_kick <player>            // Kick player
sm_ban <player> <time>      // Ban player

Player Commands

!wr                         // World records
!top                        // Top players
!profile                    // Your profile
!rank                       // Your rank
!recent                     // Recent records
!nominate                   // Nominate map
!rtv                        // Rock the vote
!stage <number>             // Teleport to stage
!r / !restart               // Restart timer
!pause                      // Pause timer
!cp / !checkpoint           // Save checkpoint
!tp / !teleport             // Teleport to checkpoint
!hide                       // Hide players
!hideweapon                 // Hide weapon
!hud                        // HUD settings
!zones                      // Show/edit zones

Console Commands

sm plugins list             // List loaded plugins
sm exts list                // List loaded extensions
sm cmds                     // List all commands
status                      // Show players and Steam IDs

Development Notes

32-bit Mode

The server runs in 32-bit mode for maximum plugin compatibility:

  • Most SourceMod plugins and extensions are 32-bit only
  • DHooks and other critical extensions lack 64-bit versions
  • 32-bit provides better compatibility with the plugin ecosystem

Plugin Installation Pattern

All plugins follow an idempotent installation pattern in etc/run.sh:

if [ ! -f "$CSTRIKE/addons/sourcemod/plugins/plugin.smx" ]; then
    cd /tmp
    wget "https://github.com/author/repo/releases/download/version/plugin.zip"
    unzip -o "plugin.zip"
    cp -r addons/* "$CSTRIKE/addons/" 2>/dev/null || true
    rm -rf "plugin.zip" addons/
    echo "Installed Plugin vX.Y.Z"
fi

This allows safe re-runs without reinstalling existing plugins.

Run Script Flow

The etc/run.sh script executes in this order:

  1. update_cssds() - Download/update CSS DS via SteamCMD (skipped by default)
  2. steamclient_binary() - Locate and symlink steamclient.so (32-bit)
  3. install_surf() - Install timer, extensions, and physics plugins
    • Install MetaMod:Source if missing
    • Install SourceMod if missing
    • Install sm-json (JSON library)
    • Install sm_closestpos (replay positioning)
    • Install sm-ripext (HTTP/REST)
    • Install Shavit Surf Timer with sounds/materials
    • Install shavit-zones-json from original bhoptimer
    • Install MomSurfFix, EventQueue Fix, RNGFix
  4. configure_shavit_zones() - Download JSON zones, stripper configs, mapfixes
  5. configure_shavit_database() - Create SQLite database config
  6. configure_admins() - Create admins from SRCDS_ADMINS env var
  7. cfg() - Copy server.cfg
  8. run_cssds() - Launch the dedicated server

Version Strategy

Fixed versions are used for:

  • Stability - Known working versions
  • Reproducibility - Deterministic builds
  • No API dependencies - Avoids rate limits
  • Easy rollback - Specific version control

Verification

Check Installed Plugins

docker exec -it $(docker ps -qf "name=cssds") \
  ls -la /home/steam/cssds/cstrike/addons/sourcemod/plugins/*.smx

Check Extensions

docker exec -it $(docker ps -qf "name=cssds") \
  ls -la /home/steam/cssds/cstrike/addons/sourcemod/extensions/*.so

In-Game Verification

Connect to the server and run:

sm plugins list
sm exts list

You should see:

  • Plugins: Shavit (multiple modules), momsurffix2, eventqueuefix, rngfix
  • Extensions: sm-json, closestpos, ripext, dhooks, sdkhooks

Troubleshooting

Plugins Not Loading

  1. Check MetaMod: meta list
  2. Check SourceMod: sm version
  3. Check errors: sm plugins list
  4. Check logs: addons/sourcemod/logs/

Common Issues:

  • Missing extension dependencies (install sm-json, closestpos, ripext)
  • Wrong architecture (use 32-bit plugins/extensions)
  • File permissions (ensure steam user owns files)

Zones Not Loading

Symptoms: Map loads but no start/end zones

Solutions:

  1. Check if map exists in surf-zones:

  2. Verify JSON zones enabled:

    sm_cvar shavit_zones_usesql
    // Should be "0"
    
  3. Check sm-json loaded:

    sm exts list
    // Look for sm-json or json.inc in includes
    
  4. Check logs:

    • addons/sourcemod/logs/shavit/
    • Look for HTTP/JSON errors
  5. Create zones manually:

    !zones     // Zone editor
    !edit      // Admin zone editor
    

Missing Sounds/Materials

Symptoms: Missing finish sounds, zone decals

Solution: Reinstall Shavit to get sound/material files:

rm /path/to/data/cssds/cstrike/addons/sourcemod/plugins/shavit-core.smx
docker-compose restart cssds

Server Won't Start

  1. Check logs: docker-compose logs cssds
  2. Verify port 27015 available
  3. Check disk space
  4. Verify SteamCMD succeeded

Credits

License

This setup configuration is provided as-is. Individual components retain their original licenses.

Description
No description provided
Readme 196 KiB
Languages
ReScript 73.5%
Shell 13%
TypeScript 11.6%
Dockerfile 1.1%
Just 0.8%