Search Unity

Question Server-Client worlds, and preventing duplicate work when running both worlds in one process

Discussion in 'Entity Component System' started by Shinyclef, Aug 20, 2020.

  1. Shinyclef

    Shinyclef

    Joined:
    Nov 20, 2013
    Posts:
    505
    Hello,
    I was excited by the prospect of running servers and clients in the same process as demonstrated by the netcode sample. But I have an design question on how to avoid duplicate work.

    Suppose I have a server world, and a client world. The game could be deployed in server mode, or in client mode (connect to a server elsewhere), or both (host a game or play by yourself).

    In this game, I want to procedurally generate some voxel content. The server will supply things like random seeds, and both the server and client will generate the content (the server mainly for physics for simulation, the client at least for visuals).

    This makes sense if the server and client are in separate processes/machines. But if the server and client are running in the same process, I'd like to generate the content only once, and share the results with both the sever and client worlds.

    My thoughts so far:
    - One code base with separate server and client worlds seems like a really clean idea, easy to test, maintain and deploy, so it seems like a natural start.
    - Could both server and client worlds delegate to a third world that does this generation and passes results to server/client worlds? I actually don't know how this would work if it's a good idea, but it seems like it might come with complications and overhead?
    - What about not having separate worlds for server and client, but rather just, disabling systems only needed by a disabled server or client? This path seems like it won't be quite as structurally clean.

    As you can see, my thinking is not very progressed on this yet. I'm unsure of how I might go designing this architecture, so I'm looking for advice if anyone has some thoughts.

    Cheers :)
     
  2. JesOb

    JesOb

    Joined:
    Sep 3, 2012
    Posts:
    1,109
    Hi
    Just first thought :)

    Voxel game have chunks. Add some version to chunk and advance it on change.
    Delegate chunk mesh generation to separate singleton that actually make job done.
    In singleton store last chunk and version that was processed and if this version already processed return result, if it in process now return may be job handle (or something).

    So when client and server worlds ask for new content one will start process of generation content and another just receive result. :)
     
  3. Shinyclef

    Shinyclef

    Joined:
    Nov 20, 2013
    Posts:
    505
    So if I understand correctly, you're saying to have the client and server systems both delegate to a generation manager. The server would request a the generation, which would update a version number. The client would request an update, and the manager would know to return what it already has, thus avoid the duplicate work.

    In this example, the chunk data itself would be stored not in components/buffers of the worlds (as you would need a copy for both server and client worlds?), but in centralised plain old C# objects to avoid double memory usage? In that case, the client and system worlds wouldn't be able to access the data via components in jobs right?
     
  4. JesOb

    JesOb

    Joined:
    Sep 3, 2012
    Posts:
    1,109
    Mostly right
    The only thing is store chunk data in separate memory allocated with like persistant and pass ptr to it into components on both worlds and have access to it lake always.
     
    Shinyclef likes this.