Skip to content

Enable Support for Discoverable CSM Servers#344

Open
vrnhgd wants to merge 23 commits into
CitiesSkylinesMultiplayer:masterfrom
vrnhgd:master
Open

Enable Support for Discoverable CSM Servers#344
vrnhgd wants to merge 23 commits into
CitiesSkylinesMultiplayer:masterfrom
vrnhgd:master

Conversation

@vrnhgd

@vrnhgd vrnhgd commented Jul 6, 2026

Copy link
Copy Markdown

I play CS1 every once in a blue moon. Have always wanted to be able to play a proper multiplayer game via CSM, but it's so challenging to find somebody else that's technical enough to get everything set up (and match extensions).

The set of changes described here implements the following:

  1. support MS Visual Studio 18 / 2026 (a194bed) and search for Cities Skylines in various install directories (i.e. I'm lazy and don't want to have to type in the install dir every time and it's in an expected place 99% of the time) (e8885f7)
  2. adds convenience scripts for running the game server via PowerShell and deploying DLLs to a secondary test host via SSH/SCP (e8885f7, 13f97d9, ad961de)
  3. Update data model for server naming and host discoverability (2e25e18)
  4. Update UI to expose discoverability settings (2181fec)
  5. add HTTP endpoints to the game server to allow users to query public APIs (7dd005a)
  6. use a custom Json parser... JsonUtility wasn't playing nicely and neither was Newtonsot.Json (67bc06c, 6f087bb)

@vrnhgd

vrnhgd commented Jul 6, 2026

Copy link
Copy Markdown
Author

How it works:

  1. A host creates a server the same way that you would using existing CSM mods:
image
  1. If host has set the game to discoverable, the core API server will actually advertise existence of the server in its server list
{
  "Servers": [
    {
      "Name": "roond's world",
      "CurrentPlayers": 0,
      "MaxPlayers": 0,
      "HasPassword": true,
      "Address": "100.66.251.86:4230"
    }
  ]
}
  1. Host gets notification that their process is available
image
  1. Non-Host Player can either directly type in the IP address etc. OR they can now browse available public matches
image
  1. If there's a public available match, you can click "join" and it will auto-populate the relevant IP address/port combo required. Note that passwords are still required
image

@vrnhgd vrnhgd mentioned this pull request Jul 6, 2026
3 tasks
@vrnhgd

vrnhgd commented Jul 6, 2026

Copy link
Copy Markdown
Author

improvements that I could use help with because I don't really have experience:

  • some kind of fail2ban/jail for users who spam public servers or the API server

some improvements that could be made as future pull requests:

  • IP address/port shouldn't be exposed to the user at all in the UI when connecting to a public game (a smart enough user could reasonably use WireShark or something, so the point of this is to remove irrelevant info for non-technical users)
  • users should be able to compute point-to-point host ping time and all-player max ping time to determine if they're comfortable with the RTT. we should probably set reasonable limits on maximum latency before CSM won't support multiplayer
  • current/maximum player count needs to be displayed

@kaenganxt kaenganxt left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your contribution, that is really appreciated!

I would have one request: Could you maybe use the existing LiteNetLib protocol to retrieve the server list from the GS instead of HTTP?

I think the HTTP implementation is quite some overhead (including JSON parsing) and needs some extra considerations on the hosting side as well (port forwarding).

About your questions:

some kind of fail2ban/jail for users who spam public servers or the API server

that's usually part of the hosting side and not of the application, so doesn't need to be done in the GS

IP address/port shouldn't be exposed to the user at all in the UI when connecting to a public game (a smart enough user could reasonably use WireShark or something, so the point of this is to remove irrelevant info for non-technical users)

Using the token instead of the IP address to connect should be fine. This is the same then as connecting through the Steam overlay.

I've added some comments already to the code, but didn't have time to test it yet.

Comment thread scripts/deploy.ps1 Outdated
Comment thread src/csm/Panels/BrowseServersPanel.cs Outdated
Comment thread src/csm/Panels/BrowseServersPanel.cs Outdated
Comment thread src/csm/Panels/BrowseServersPanel.cs Outdated
@vrnhgd

vrnhgd commented Jul 6, 2026

Copy link
Copy Markdown
Author

I have zero experience using LiteNetLib but I'll take a stab at it. Do you have ideas of a different way that I can do ser-des for the server information? if not, JSON deserialization still will be required though since the Server objects are JSON.

I've made the other changes that you suggested on the review!

Comment thread src/csm/Panels/BrowseServersPanel.cs Outdated
Comment thread src/csm/Panels/BrowseServersPanel.cs Outdated
vrnhgd added 2 commits July 7, 2026 18:19
extract SteamHelpers' connect-by-token logic into JoinGamePanel.JoinByToken,
reused by both the Steam friend-invite path and the public server browser -
BrowseServersPanel now joins via ServerToken instead of the raw address, and
PasswordPromptPanel delegates to the same shared method instead of duplicating
the connect logic

@kaenganxt kaenganxt left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While testing, I found some UI issues with this patch:

Image

Maybe you can make the panel a bit higher.

Image I think a line break should work.

Comment thread src/gs/CSM.GS.csproj Outdated
Comment thread src/gs/Program.cs
Comment thread src/gs/Dockerfile
@vrnhgd

vrnhgd commented Jul 22, 2026

Copy link
Copy Markdown
Author

I won't be able to modify the position of the UI panel as I don't have access to my machine that runs CSM... can't test it locally. I've completed your other items though. If you'd like to make the change to move the panel up a bit I'm happy to include it!

@vrnhgd
vrnhgd marked this pull request as ready for review July 22, 2026 02:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants