I’m managed to make a build of my project that works if I make a dedicated server and client build.
The client connect to the server on the DefaultConnectAddress.
What I’d like to make is an option for the client to host and then connect to itself.
Then other client can use a join option to join the first hosting client.
I made it work in the editor. But when a Imake the client build, I can use the ClientServerBootstrap.CreateServerWorld() because of the :
#if UNITY_CLIENT && !UNITY_SERVER && !UNITY_EDITOR
throw new NotImplementedException();
#else
The question is how can I make a client build that also enables the UNITY_SERVER define constraint ?
I tried adding it to the player settings but then the client build ends up switching platform and making a dedicated server build…
To have a build that work as client/server you just need to remove both UNITY_CLIENT and UNITY_SERVER define.
They are and must be used only for making either a client-only or server-only build respectively.
Enabling both is considered an error, because of some #ifdef logic that would break apart (they are not designed for that in first place).
Usually you don’t need to add any in your build workflow. They are automatically added for you as necessary (depending on the Entities/Build settings)
UNITY_CLIENT define is not automatically added for client build that u will get the following warning and failed to connect to server even u set to Client at Project Settings - Entities. I think currently only dedicated server build will automatically add UNITY_SERVER define.
Trying to connect to a server at address xxx.xxx.xx.x:xxxx using an IPCNetworkInterface. IPC interfaces only support loopback address. Forcing using the NetworkEndPoint.Loopback address; family (IPV4/IPV6) and port will be preserved
This is an editor-specific bootstrapping flow designator. I.e. You set this to define editor bootstrap behaviour. It has zero impact on builds, as it only defines how the editor should behave. You can even ignore it when writing your own bootstrapping.
This is a build setting, only applicable to non-dedicated server build targets (e.g. Windows Standalone, Xbox etc). This dropdown determines what kind of client build to make:
ClientAndServer - Will make a build containing both the Client and Server code assemblies (you must pass these .asmdef’s in, for them to be stripped). This is useful for games that let players (clients) host their own lobbies, and invite friends to said lobbies. This client executable can create client, thin client, and server worlds.
Client - Will remove (strip) the Server assemblies (again, only the ones you pass in), and add the UNITY_CLIENT define to your build, and you’ll be unable to call ClientServerBootstrap.CreateServerWorld.
If you make a dedicated server build, UNITY_SERVER define will be set, and you’ll be unable to call ClientServerBootstrap.CreateClientWorld (nor CreateThinClientWorld).
I’ll make a PR improving the tooltips, to make this distinction more clear. It’s a common question.
I need to clarify about this client build part. Until latest 2022.3.14f1 editor, UNITY_CLIENT define still won’t auto add into build and only dedicated server build will auto add UNITY_SERVER define into build. It’s always behave like that since the first 1.0 release until now that I think it’s bug. Not sure this needs to fix at dots netcode package or need engine fix.
You need to change the Entities/Build settings in the project setting to make a client-only build. Otherwise, the build is made client/server and by default does not have any define set.
And, of course, if you are using your custom build or invoking manually the build pipeline, then it is another story.
Entities register a BuildPlayerOptionsHandler on the IntializeOnLoad in the Editor via BuildPlayerWindow.RegisterGetBuildPlayerOptionsHandler, and this is used when the build is invoked by clicking the Build button.
The handler invoke the GetExtraScriptingDefines method defined by the IEntitiesPlayerSettingProvider (we have three for Netcode).
The UNITY_CLIENT is added by the ClientSetting class that is used if the Cliient mode is selected
However, if you run the build pipeline manually these extra defines are not added. In that case you need to add the options by yourself (sorry, about that).
Yes. I changed to Client at Entities/Build settings in the project settings and it’s still not working. You will just get the following warning.
Trying to connect to a server at address xxx.xxx.xx.x:xxxx using an IPCNetworkInterface. IPC interfaces only support loopback address. Forcing using the NetworkEndPoint.Loopback address; family (IPV4/IPV6) and port will be preserved
mmm… I think something build side got broken somewhere. The build does two compilation steps:
One before asset processing (still recompile scripts, because the EDITOR define is removed).
One that build the player scripts.
I presume, and this is just one assumptions, that one of the two does not pass the correct defines and that is affecting the whole compilation somehow.
So, indeed there is an odd behaviour in this first compilation (when the target is switched) but then it looks like to me the defines are properly set (because only the JOIN options is there).
I just found the issue. When writing your own build menu to build client player runtime instead of using regular File - Build Settings… to build player runtime, it will break client build. Not sure about whether it will also break build server player runtime or not. Need to test.
If you write your own custom build system, it is up to you to call something like this:
var dotsSettings = var instance = DotsGlobalSettings.Instance;
if (dotsSettings.GetPlayerType() == DotsGlobalSettings.PlayerType.Server)
{
//If a server provider is not present use at least the default setting for the client build.
var provider = instance.ServerProvider;
if (provider == null)
provider = instance.ClientProvider;
opts.extraScriptingDefines = provider.GetExtraScriptingDefines();
opts.options |= provider.GetExtraBuildOptions();
}
else
{
opts.extraScriptingDefines = instance.ClientProvider.GetExtraScriptingDefines();
opts.options |= instance.ClientProvider.GetExtraBuildOptions();
}
The way entities hooks up with build system is to react to the press of the build button. If that does not occur, all these settings are never applied correctly, nor will do baking or any other particular step potentially.
What if I want to connect the client to the dedicated server, Do I have to do anything differently? I am trying this workflow using the MegaCity sample project.
I have followed the below steps for the Dedicated server build
Converted the target platform to a Dedicated server
For the client-only build, I have followed the below steps
Project Settings → Entities → Build → NetCode Client Target is set to Client
Created the build on the Windows platform
But when I test it on the editor by setting the play mode type to the client, matchmaking is working as expected and also getting the log that connected to the server But in the Playmode tools it’s showing that “Connecting” after sometime game comes back to the main menu. The same thing is happening with window build as well. I think the server is not accepting the client’s request. I am not sure what am I missing here. I have also checked the logs on the server side on Game Server Hosting but didn’t find anything there as well.
What logs did you get indicating a successful client connection to the DGS? Be careful not to conflate “Called connect on addresss xx.xx.xx.xx” with “Connected to …” as verbiage can be misleading. Look for concrete signs the player connected, like netcode’s debug logs, or some server ship spawning logic that logs the NetworkId of the player.
I sat this because clear a lack of error logs (on client and server) implies no connection was established by the client.