2
\$\begingroup\$

I'm a .NET Core web developer trying to learn Unity. In web development, if I want to perform more than one domain function at a time, I either want to run it as a totally separate service (disjointed/microservice) or as a separate process (sidecar). In .NET Core we have IHostedService and other varying hosting abstractions, so creating small sidecar processes is fine, and in 3.0, even ASP.NET Core is considered a sidecar process because it's building on top of IHostBuilder for Generic Host support. My web development experience is primarily focused on distributed backend systems.

In my process of trying to learn Unity, I'm trying to understand how networking works in Unity. I was looking at their NetworkManager documentation, it seems most helpful for integrated host/client systems. I like that I can provide custom implementations of NetworkManager, and I think that will be most helpful. I've been reading up on asynchronous programming in Unity, and looking at their ECS Job System. It looks useful, but it also doesn't seem to be quite what I'm looking for. I'm looking for a background/sidecar process architecture the main Unity thread can call into as needed, but that doesn't interact with the main Unity thread at all, only it's lifecycle is tied to the main Unity thread.

In the asynchronous multiplayer game I am learning to create, the game's world is going to be a dedicated server running remotely, and the client will have to connect to it to load it's internal state. As the game's remote state is primarily near real-time, I was thinking about implementing a mixture of real-time and cached network managers. Something like this:

// Used for strongly consistent, real-time communication, talks to the remote server
// directly. The main Unity thread never calls this directly.
public RealtimeStateNetworkManager { }

// Used for GameObjects. Tries to load from cache before making real-time networking
// calls. Cache items are instantiated when GameObject makes initial call,
// then background threads keep the cache updated during the lifecycle 
// of the GameObject.
public CachedNetworkManager : NetworkManager { }

For my CacheHostSidecar, I want to run it outside of the main thread as a sidecar process, so it doesn't affect the game client's core performance. The primary goal of the internal cache is to handle the network sync so client updates are real-time once the cache has been warmed, and then the cache updates it's internal state separate from the main unity thread on a ticking basis.

The process would like this:

CachedNetworkManager

My understanding of NetworkManager and it's function may be wrong. My core goal is to understand how I could intialize and run the CacheSidecarHost as a background/sidecar process when the main Unity thread starts so I can decouple networking from the main Unity thread.

My hope is that by decoupling the core networking functionality from the main Unity thread, it helps folks with poor network connections have an agreeable experience as the networking stack is implemented in a more sustainable/modern way, ensuring they can still play well enough in a game requiring an internet connection.

\$\endgroup\$
  • \$\begingroup\$ Do you strictly need this to be a separate process, or would a separate thread suffice for your needs? \$\endgroup\$ – DMGregory Dec 9 '19 at 17:36
  • \$\begingroup\$ A separate thread would be okay, I think. I don't really need control over it's lifecycle beyond starting when Unity starts and stopping when Unity stops - I can implement desired behaviour (IDisposable, etc.) from there. \$\endgroup\$ – mxplusb Dec 9 '19 at 17:44
  • \$\begingroup\$ One other angle to look into: have you verified that networking is actually occurring on the main thread in Unity and impacting gameplay experience negatively for your use case when you use the vanilla/built-in features? It wouldn't surprise me if the engine already implements a separate networking thread under the hood, rather than blocking the main update & render loop. So you might get "good enough" decoupling of gameplay & network communication out of the box. \$\endgroup\$ – DMGregory Dec 9 '19 at 17:56
  • \$\begingroup\$ I don't know where to look for that information. It also seems like the entire networking engine is being totally overhauled, so I don't really know what I should do vs what I could do. \$\endgroup\$ – mxplusb Dec 9 '19 at 18:02
  • 1
    \$\begingroup\$ I'd say the most reliable way to find out is to build a quick test using the built-in features and profile it. If the profiling results are adequate for your needs, you might be able to save yourself a lot of engineering work and code complexity. \$\endgroup\$ – DMGregory Dec 9 '19 at 18:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.