← Back to DoppelGamer

Server setup

DoppelGamer is a website plus a separate Windows PC that runs Counter-Strike 2 with bots. The website only sends commands to that PC's match service. Nothing on this page runs in your browser.

Private matches only. The bot base starts CS2 with -insecure, which turns Valve's anti-cheat off. Never join an official or public match from that install, and never point this project at a public server.

1. Every player: Steam and CS2

  1. Install Steam.
  2. Download Counter-Strike 2 (free).
  3. Each player needs CS2 on their own PC. The site cannot stream the game.

2. Game host: bot base, plugins, CloneDirector, clone profiles

One Windows PC hosts the match. A normal Steam install does not include any of the parts below; a person installs them by hand. Source: project repository.

  1. Bot base. Install the CS2 bot base (Metamod, CounterStrikeSharp and its bot controller) by hand, following the bot base's own instructions. Its launcher may not be modified or redistributed, so it is not part of this project. Check that game/csgo/gameinfo.gi contains the addons/metamod line; a CS2 update or crash can remove it.
  2. CloneDirector. Build it against the same installed BotControllerApi.dll:
    $api = '<CS2>\game\csgo\addons\counterstrikesharp\shared\BotControllerApi\BotControllerApi.dll'
    dotnet build clone-director/CloneDirector.csproj -c Release "-p:BotControllerApiPath=$api"
    Copy CloneDirector.dll, CloneDirector.Core.dll, CloneDirector.deps.json and CloneDirector.runtimeconfig.json from clone-director/bin/Release/net10.0/ into game/csgo/addons/counterstrikesharp/plugins/CloneDirector/. Do not copy the bot controller's or CounterStrikeSharp's DLLs there.
  3. Clone profiles. Copy the repository's clones/ folder (each profile JSON with its route folder) into that plugin folder. Each clone needs its own bot name in the bot base's botprofile.vpk: with CS2 closed, keep a copy of the original and run clone-director/tools/add_clone_bot_entries.py.
  4. MatchBridge. The match service builds and installs this small plugin itself when started with -Bots clone (next step). It needs the .NET SDK.
  5. Start CS2 on the host with its plugins loaded:
    cs2.exe -steam -insecure -netconport 2121 -usercon
    Then load Mirage (map de_mirage). Clone mode supports Mirage only.

3. Match service on the game host

Install uv, then in PowerShell from match-service:

$env:CS2_CLONE_ROUTES = 'recorded'
$env:PUBLIC_URL = 'https://dopplegamer.gay/api'   # links in API answers use the public site
$env:SERVER_IP = '<address players use to reach the CS2 server>'
.\start-cs2.ps1 -Bots clone -Record off -Port 8000 -Listen <private address of this PC>

The service uses port 8000 everywhere in this deployment. -Listen defaults to 127.0.0.1 (this PC only); give it the PC's private-network address only when the web host must reach it. Check it on the game host:

Invoke-RestMethod http://127.0.0.1:8000/health

The answer must name the cs2 backend and show the console as reachable. An answer from the mock backend means no real game is connected.

4. Networking

  • Visitors reach only https://dopplegamer.gay. The site forwards /api/… to the match service over a private network between the web host and the game host (for example Tailscale).
  • Never open these ports to the internet: the match service (8000), CS2's network console (2121) and the game-state feed. The service has no login of its own.
  • Joining a match is a separate game connection to the CS2 server (UDP 27015 by default). The website address does not provide it. Players on other networks need a reachable address in SERVER_IP and SERVER_PORT; keep the match private.

5. Play

  1. Enter the site, open Play, choose an available bot and your side.
  2. Start the match (operator access needed, see below), wait until it is ready, then use Join in CS2.
  3. Stop the match from the same page when you are done.

6. Limits

  • One match at a time, and at most one human: the person at the game host's CS2.
  • Matches are kept in memory and disappear when the service restarts.
  • Live bot positions appear only for bot-vs-bot matches (CS2 sends them to a spectator).
  • The demo login before the site is a browser-only screen, not an account. Upload previews, sample leaderboard data, voices and studio pages are demonstrations, not finished features.
  • When the game host is off, Play shows the service as offline.

7. Operator access

Anyone can view matches. Starting, stopping or changing anything needs the operator access code, which the site owner sets on the web host.