trophy 1375
Apr 2021 380 posts
We started talking more about how serverside code is going to work. I am assuming the following:

1. People who want serverside code are going to be self hosting all of their servers
2. It will only be on dedicated servers

Correct me if I'm wrong.

So what does the workflow look like for this stuff? How do you want it to work? 

Do we have a separate "server" project that references the regular game project? A bit like editor projects, but gets loaded on dedicated servers? Is that useless, because I assume you want to keep its contents secret?

Do we let you load arbitrary dlls on the server? Like we could have a folder called server and if you put a dll in it, it'll try to load it. The classes inside will be added to typelibrary, so in your regular game code you'd check for an implementation of a class or something?

What is your use case? How do we best make this work?
trophy 150
Jun 2021 181 posts
I will be hosting servers on my own with dedicated.

I had an idea for it to use preprocessor directives / ifdef, not sure how realistic that is.
Preferably the server should be able to run without a whitelist.
I've gotten used to the workflow already of shared code, but I wouldn't mind hiding my backend calls.
trophy 1240
Jul 2021 15 posts
Boz one year ago edited one year ago
The idea of being able to load dlls feels like it would be fairly beneficial to some degree, for example would allow developers to just easily spin up a sql connection. Hell even would allow developers to experiment for SDK's that they currently cant use within s&box.

Small concern however, what would be stopping someone from just writing malicious server side code that can affect the user? 
trophy 930
Oct 2021 82 posts

idk about how it should work inside but it would be great if it were possible to use servers for your own games, for example, a pvp game in which you can direct players from the lobby to one server with the logic of the game and return back to the lobby  and we could use servers according to the old Gmod approach with a common list and categories
trophy 1978
Sep 2021 248 posts
💚 Thank you, Garry, for taking on this task, we've been waiting for this

Self-hosted? Yes. Using dedicated servers? Definitely yes. You got this part absolutely right. Before going any further, I think I should mention three fundamental principles:
  1. Server-side code must remain private. It should only exist on developers' pc and as compiled DLLs on a web server. There should be no way for it to reach the clients. 
  2. An Authority Server is the best approach here. I know P2P is working for now, but you guys are doing an amazing job, and soon a wave of game devs (especially from Unity/Godot) will come in wanting to create large-scale multiplayer projects, where P2P just won’t cut it. 
  3. There should be replication of data from server to client. I can't explain it technically, but if the server has a Set on some property, then after a change (if we specified it), it should be sent to the same property Set on the client.
 Keeping those in mind, let's move forward. I’m not an experienced Network Engineer, so I might talk nonsense from a technical perspective, but I have enough multiplayer experience from Garry's Mod, Rust, and Minecraft.

 Your idea about project.server.dll and integrating it into the TypeLibrary sounds like a good way. I remember we discussed these topics back in autumn 2024 in the Council's chat. Instead of just explaining, let me show how I visualize the workflow in my head: 
  •  You create a project and choose a network mode in the settings: Singleplayer (default), P2P, or Authoritative Server
  •  If you select Authority Server, you can mark necessary classes/methods/properties with the [Server]  or[Replication] attribute. These won’t be included in the client’s dll
  •  When building the game, you separation (client logic and server): 
    •  A project.dll, which goes to the Cloud so people can find and play your game on sbox.game. In example: UI, render things, get/local set and etc
    •  A project.server.dll, which stays on your PC and is manually uploaded (via FTP or any other method) to a dedicated server. The server picks it up from, say, a server/ folder. 
  •  Inside [Server] methods/classes/properties, you can work with whitelisted methods/classes. Because, realistically, any DLL can be injected into a server to bypass a whitelist, so restricting this too much makes no sense. 
  • Other big features might come in later, like 512-1024 player slots, multiple map instances loaded into a single scene, etc.
 That’s my vision. Of course, there are still questions about TypeLibrary, replication of data, and how server code will interact with the regular code—I haven’t fully thought that through yet. But I think this sets the right direction. 

Final thoughts, this is a huge step for s&box, and I really hope you guys nail it. Once we get private server code, we’ll attract: Investors, Game developers from Unity/Godot who have been waiting for this, People from Rust/GMod/GTA 5 multiplayer communities. Looking forward to any criticism
trophy 45
Jun 2023 23 posts
s&box already has everything you need to run such servers, the only thing missing is the "Assembly.Load(byte[] data)" method. If you're concerned about security, you can make this method available only on dedicated servers.

For example:
public static Assembly LoadAssembly(byte[] data)
{
   if (Networking.IsDedicatedServer)
   {
      return Assemly.Load(data);
   }

   return null;
}

I'm more concerned about the fact that anyone can look at the source code of any game. I understand that C# (.NET) does not provide 100% code protection, but I would like the code to at least be obfuscated. Overall, the decision to create your own library file format (.cll) is was a good idea, but there is an extractor on GitHub. If it were harder to get the source code, many would be more willing to post their games to the public.
trophy 155
Banned
Sep 2022 101 posts
Allowing any DLLs to be loaded on the dedicated server would be nice for talking to SQL. Or Mongo. But probably SQL (sorry, Zombie).
trophy 1835
Jul 2021 8 posts
Personally, I'd prioritize developer experience over "privacy" of server code. If people want to pirate your game, that's a very privileged problem to have. Full disclosure, I built a game on private, centralized server model, and it's not an experience I'm enthusiastic to repeat.

I understand it's an important feature for a lot of people, and I hope their needs get met. But I hope those of us who don't want it aren't railroaded into paying some penalty for it (IE more complex workflow, worse hotload performance).

To be honest, it's very likely the P2P model ends up being a better fit for my future projects, I'm just really partial to the authoritative server model with community-hosted servers.

Regarding obfuscation, I feel the same about it. From a technical perspective, it's basically impossible to obfuscate the high-level structure while supporting reflection, and difficult to obfuscate low-level code without compromising performance.
trophy 1375
Apr 2021 380 posts
Unrelated but with regards to P2P or Server Authoritive.. when you're running a dedicated server it's not P2P. It only really becomes P2P when you let clients be the owners of objects, but even then the messages are sent via the dedicated server - not between clients.

I wanted to avoid building the same code with basically #ifdef SERVER everywhere. This is what we do in Rust and it adds a lot of complication and gets us in trouble. That said, I don't really see a good alternative to that right now. It seems like the most pragmatic thing to do.
trophy 1978
Sep 2021 248 posts
I got it, that the Authority Server is already in place when a dedicated server is running. Some folks from the community confused me a bit, and I honestly thought there was some kind of weird P2P going on 😅

As for #ifdef SERVER if that’s what it takes to keep the server code private (like having a project.server.dll), then I and a lot of other serious developers who want to build indie/large multiplayer games are totally fine with that. We’re willing to accept the trade-offs: repeated code, clunky preprocessor directives, even messy code style. If it means we can keep server logic truly private, we’re in. 
trophy 5280
Mar 2023 13 posts
What if you make a way where you can create parent game(S) for existing one(C) to run on server, so that players from (c) can connect to (s) and play it. Then you just don't publish (s), so code isn't public. 
trophy 5
May 2021 9 posts
Personally my own workflow when making games using a client w/ server auth architecture is to have separate projects for client & server. I don't typically like to have all of that logic in one project, even if I have to have the same code exist in them both. (Annoying but not really that bad)

But creating a server project and being able to reference  a 'shared' project would be great.

I also don't mind ifdef's personally, it's how I have always assumed it would be since 2021 builds.  Can you provide some examples on how it complicates rust development/get's you in trouble? (out of sheer curiosity)

Anyways, people have been asking for this for so long I think implementing it at all in any form would bring more eyes to the engine, and platform. Personally, I have been avoiding working on any large scale persistent multiplayer projects in this engine due to it missing this functionality, I don't want to build a bunch of my game without even knowing how this will work (I hate refactoring after the fact) - not even to protect my code/ip, but for ease of mind for multiple potential issues that can come from any client having your full server-sided code (easier to find exploits, not wanting people to see how bad your code is :) , etc)
trophy 996
Oct 2021 112 posts
I'm happy with any server code paradigm in terms of #IFDEF SERVER or a separate server code solution, etc. Does not matter to me.

But I would really love to be able to load .dlls on the server as mentioned. Would enable coupling certain bits of functionality with the server directly instead of forcing an external web server and a communication protocol, which is not necessary in many cases.
trophy 80
Nov 2022 19 posts
Give us the possibility to use nuget package, that will be the best feature you do on the dedicated side <3
trophy 80
Nov 2022 19 posts
I have created an issue for that on github:
https://github.com/Facepunch/sbox-issues/issues/8060
trophy 15
Dec 2022 1 post
3 folders with 3 different csproject. Client, Server, Common. Client and Server have access to common. In the editor Common has access to Client and Server, but when compiled it will create an error if preprocessor directives are not used. For RPC, like a message client->host, you can add a function in common with #if SERVER that will call a function in the Server project. So for the client this function will be empty. When compiled you have like Titanovsky says a Client.dll and a Server.dll. This way Server.dll must not be sent to the client.

For whitelist, you should be able to add random lib or addon to your server. Whitelist must not be disable. There should a config where you can modify the whitelist. On or off, or something more specific that only allow some dll. This config should be specific for each lib or addon. By default using external dll should be forbidden. It should be the owner of the server that modifiy the config to disable whitelist.

In the end you use preprocessor but you don't put an entire function between #if and #endif, you just have the call of a function that is in the Server project.

I know it's not ideal, but the separation of client and server code should be made possible somehow.
trophy 930
Oct 2021 82 posts
dude just described gmod

trophy 80
Nov 2022 19 posts
Bubbies one year ago edited one year ago
Referencing the client projet into the server project is a good idea. That will prevent to call server code from client project. We also need to have the ability to use nugget packages on server project. That will offer a lot of possibilities.

Preprocessors are not really easy to understand for beginners, and using a client project referenced by the server is more easier to do on Facepunch side than checking the abstract syntaxe tree to know what part of code we should compile.

We are all waiting for see features a long time ago, im so happy to read that post

edited:
The problem with referencing the client project into the server is that the server have the client code. To since this, using a common project should avoid this problem. Client code stay on client, server code stay on server and the common code is shared between the client and the server. But, that add more complexity.
trophy 318
Aug 2023 80 posts
We cannot do this already? Also I haven't seen API on the docs for pure messaging system. Is this a thing or we can only rely upon RPC?
trophy 1575
Apr 2021 217 posts
we don't need the gmod nonsense folders, just name the files MyClass.Server.cs
trophy 1978
Sep 2021 248 posts
I don't get it either, why to do x3 folders if you can File.Server.cs? And making two files is not so bad

The main thing is to keep the server code private. In gmod multiplayer it is, and the approach there like it, make sv, cl, sh files and clearly know who communicates with whom, at least I did so, maybe someone and really Server, Client, Shared folders everywhere created. 

There is nothing complicated with preprocessor for beginners, only that it breaks the style, but it can be fix in Visual Studio and Rider. An idea with a default whitelist for the server,  but we can change it. Interesting foolproofing. 
trophy 80
Nov 2022 19 posts
If the server code only exist on the server, how can we call it from the client ? The function doesnt exists anymore on the client assembly because you are splitting client / server code in different assemblies.
trophy 1978
Sep 2021 248 posts
Communication is done via RPC, just signaling. It's two-way, but if you receive it from a client, make checks as it may not be secure. That's it, no magic. How it will be implemented in s&box after the server code is introduced is exactly the same, it's just easier somewhere, somewhere more complicated. The way I see it:

RPC.Send( Client client, string method )
RPC.Broadcast( string method )
RPC.SendToServer( string method )
RPC.Receive( string method, Action OnReceive )
trophy 80
Nov 2022 19 posts
Using this way will increase confusion everywhere :/
You will have to register all callbacks in the awake/start function and passing the server method name to call will be a pain for maintaining the code over time.. That will break quick refactor in the way that we will not have the ability to use nameof.

I think we should have the possibility to have a better way to do that using c# source generators.
For example, we can mark a server function with the [Rpc.Server] attribute, that will generate a function automaticaly for the client.

So if you create the following server function signature, you will have an equivalent function call for the client side that will call the server function for us:

Server code:
[Rpc.Server]
public void SomeFunctionRpc(int someArg);

The auto generated function on the client side:
public void SomeFunction(int someArg)
{
        // An internal generated wrapper that call the server function
        Rpc.Call("SomeFunctionRpc", someArg);
}

That will keep the current Rpc syntax, without needing to code differently when using server code only.
This a bit more complicated to implement on the FP side, but will give a better developer experience, without adding a new way to code Rpc's
trophy 280
Aug 2021 6 posts
with an ifdef couldn't you just do it however you want? in file, another file? basically perfect solution
trophy 1978
Sep 2021 248 posts
Ok, I'm fine with the solution you suggested, so as not to break the syntax. 
trophy 1780
Jul 2022 6 posts
I'm not loving the current 'everything is shared' nor #IFDEF SERVER everywhere, I think designating files as Class.cs for shared, Class.Server.cs / Class.Client.cs is the most straight forward. Done properly, you're writing the same amount of code but it gives the s&box file processing the easiest time to build 2 code libraries.

Also hugely in favor of loading other libraries and having access to nuget for server.

All that said, do not want to rely on every single game requiring dedicated servers for security, both over game authority & for source code privacy.

Dimmer's solution for P2P having to call an external API is not ideal, although he has demonstrated that it works but also requires logging everything and scrubbing all the data in the case of someone as host wanting to bypass/intercept the process and inject their own calls.
trophy 930
Oct 2021 82 posts
Skipin one year ago edited one year ago

You already can make files with Class.Server separation. If this is standardized for all files (somehow), the project structure will turn into crap with a new folder created for each class. I doubt that the syntax will be changed radically at all, 
I don't see any point for this.
trophy 1978
Sep 2021 248 posts
You misunderstood, when we talk about Class.Server or Class.Client we mean that Class.Server.cs won't get on PC players, not just create two files for the same class.

All the ways are not the best, but quite workable:
1. Split into Class.Server and Class.Client
2. #ifdef SERVER
3. Through private projects, essentially two games (honestly, I don't understand how this method will work).

The main thing is that the server code should be private, and out of the hands of clients, any form. 
trophy 930
Oct 2021 82 posts
Skipin one year ago edited one year ago
We are talking about the same thing, I just think its possible to hide it from the client without creating additional files. We now have RPC.Host and RPC.Broadcast, these are requests that can send processing to the server. just completely remove the RPC.Host functions in the client version files and erase in the broadcast implementation if(Network.IsHost) (). This may not be feasible, but it seems to me that there are not so many conventions for processing only on the host that it could cause errors. ( I thought that's what was meant by #ifdef SERVER ). 
with the Class.Server implementation I will have a player class for server code with 2000 lines that relate to different areas of responsibility does not sound good

people
Log in to reply
You can't reply if you're not logged in. That would be crazy.