Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Resolved Make a build that enables both UNITY_CLIENT and UNITY_SERVER

Discussion in 'NetCode for ECS' started by WAYNGames, Nov 21, 2023.

  1. WAYNGames

    WAYNGames

    Joined:
    Mar 16, 2019
    Posts:
    974
    Hello,

    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 :
    Code (CSharp):
    1. #if UNITY_CLIENT && !UNITY_SERVER && !UNITY_EDITOR
    2.             throw new NotImplementedException();
    3. #else
    4.  
    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...
     
  2. CMarastoni

    CMarastoni

    Unity Technologies

    Joined:
    Mar 18, 2020
    Posts:
    873
    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)
     
  3. WAYNGames

    WAYNGames

    Joined:
    Mar 16, 2019
    Posts:
    974
    ok now I see I got confused by the distinction between

    Multiplayer > PlayMode Tools and set the PlayMode Type to Client & Server


    and

    Project Settings --> Entities --> Build --> NetCode Client Target is set to [I]ClientAndServer[/I]


    :rolleyes:
     
  4. optimise

    optimise

    Joined:
    Jan 22, 2014
    Posts:
    2,106
    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

    Unity.NetCode.NetworkStreamDriver:SanitizeConnectAddress(NetworkEndpoint&, Int32)

    Unity.NetCode.NetworkStreamDriver:Connect(EntityManager, NetworkEndpoint, Entity)
     
  5. NikiWalker

    NikiWalker

    Unity Technologies

    Joined:
    May 18, 2021
    Posts:
    285
    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.
     
    BackgroundMover and WAYNGames like this.
  6. optimise

    optimise

    Joined:
    Jan 22, 2014
    Posts:
    2,106
    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.
     
  7. CMarastoni

    CMarastoni

    Unity Technologies

    Joined:
    Mar 18, 2020
    Posts:
    873
    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).
     

    Attached Files:

    Last edited: Nov 29, 2023
  8. optimise

    optimise

    Joined:
    Jan 22, 2014
    Posts:
    2,106
    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

    Unity.NetCode.NetworkStreamDriver:SanitizeConnectAddress(NetworkEndpoint&, Int32)

    Unity.NetCode.NetworkStreamDriver:Connect(EntityManager, NetworkEndpoint, Entity)
     
  9. CMarastoni

    CMarastoni

    Unity Technologies

    Joined:
    Mar 18, 2020
    Posts:
    873
    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.
     
  10. CMarastoni

    CMarastoni

    Unity Technologies

    Joined:
    Mar 18, 2020
    Posts:
    873
    Tried myself and there is something a little odd in the build indeed.

    The options are passed correctly:
    Screenshot 2023-11-29 at 09.52.19.png

    But then:
    - The first build pass (that does only some asset processing) does not set the define
    Screenshot 2023-11-29 at 10.11.39.png

    - But the second step does (that make both assets and script compilation)
    Screenshot 2023-11-29 at 10.14.26.png

    And indeed in the final build the define is set:

    Screenshot 2023-11-29 at 10.21.50.png

    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).
     
  11. CMarastoni

    CMarastoni

    Unity Technologies

    Joined:
    Mar 18, 2020
    Posts:
    873
    And also no error trying to connect to the local server
    Screenshot 2023-11-29 at 10.46.01.png

    So, given all this, @Optimize, I'm really curious to understand what are the difference in the way we are building the player.
     
  12. optimise

    optimise

    Joined:
    Jan 22, 2014
    Posts:
    2,106
    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.
     
    Last edited: Nov 29, 2023
  13. optimise

    optimise

    Joined:
    Jan 22, 2014
    Posts:
    2,106
    @CMarastoni Have u tried this?
     
  14. CMarastoni

    CMarastoni

    Unity Technologies

    Joined:
    Mar 18, 2020
    Posts:
    873
    If you write your own custom build system, it is up to you to call something like this:

    Code (csharp):
    1.  
    2. var dotsSettings = var instance = DotsGlobalSettings.Instance;
    3. if (dotsSettings.GetPlayerType() == DotsGlobalSettings.PlayerType.Server)
    4. {
    5.     //If a server provider is not present use at least the default setting for the client build.
    6.     var provider = instance.ServerProvider;
    7.     if (provider == null)
    8.         provider = instance.ClientProvider;
    9.     opts.extraScriptingDefines = provider.GetExtraScriptingDefines();
    10.     opts.options |= provider.GetExtraBuildOptions();
    11. }
    12. else
    13. {
    14.     opts.extraScriptingDefines = instance.ClientProvider.GetExtraScriptingDefines();
    15.     opts.options |= instance.ClientProvider.GetExtraBuildOptions();
    16. }
    17.  
    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.
     
    optimise likes this.