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
- Zones loaded from
- 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.shfor 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:XXXXXXformat (recommended) - Or
[U:1:XXXXXX]format (modern SteamID3) - Find your Steam ID in-game with
statuscommand - 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-cssdsflag 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):
- Edit
addons/sourcemod/configs/databases.cfg - Change driver from
sqlitetomysql - Configure host, database, user, password
- 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 zonescfg/sourcemod/plugin.shavit-zones-json.cfg- Sets JSON URLaddons/stripper/- Map entity fixesaddons/sourcemod/configs/shavit-mapfixes.cfg- Map settingsaddons/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:
- update_cssds() - Download/update CSS DS via SteamCMD (skipped by default)
- steamclient_binary() - Locate and symlink steamclient.so (32-bit)
- 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
- configure_shavit_zones() - Download JSON zones, stripper configs, mapfixes
- configure_shavit_database() - Create SQLite database config
- configure_admins() - Create admins from SRCDS_ADMINS env var
- cfg() - Copy server.cfg
- 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
- Check MetaMod:
meta list - Check SourceMod:
sm version - Check errors:
sm plugins list - 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:
-
Check if map exists in surf-zones:
- Visit: https://github.com/wrldspawn/surf-zones/tree/main/z
- Search for
surf_<mapname>.json
-
Verify JSON zones enabled:
sm_cvar shavit_zones_usesql // Should be "0" -
Check sm-json loaded:
sm exts list // Look for sm-json or json.inc in includes -
Check logs:
addons/sourcemod/logs/shavit/- Look for HTTP/JSON errors
-
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
- Check logs:
docker-compose logs cssds - Verify port 27015 available
- Check disk space
- Verify SteamCMD succeeded
Credits
- Shavit Surf Timer - bhopppp
- sm-json - clugg
- sm_closestpos - rtldg
- sm-ripext - ErikMinekus
- MomSurfFix - GAMMACASE
- EventQueue Fix - hermansimensen
- RNGFix - jason-e
- Surf Zones - wrldspawn
- MetaMod:Source - AlliedModders
- SourceMod - AlliedModders
License
This setup configuration is provided as-is. Individual components retain their original licenses.