#What architecture solutions to adopt for a large 3D open-world coop game?

1 messages · Page 1 of 1 (latest)

hard holly
#

Hi there! We are developing a 3D Open World game with a cooperative element (1-4 players, players versus monsters in the world) with an isometric camera perspective. We are currently in the 3th month of development, and the project will be quite extensive, involving around 15 people, including 5 programming engineers. Ultimately, the project is being done for PC with the possibility of later porting to the latest consoles. I have question that arose during my research:
What code architecture to adopt? Initially, we were thinking of starting with Zenject (I also looked at VContainer and Reflex), but it relies heavily on reflection, which works slowly and has issues with reflection in AOT, plus it creates an invisible architecture with dependency injection. Scriptable Object Architecture, due to its granularity, may cause problems with a larger team, so it's not a preferred option.

Ultimately, I was thinking of something like this:

  • Netcode for GameObjects
  • Scenes loaded additively: meaning we have a Persistent scene that is never unloaded, a Gameplay scene, and loading World Chunks.
  • Attach service locators contextually, somewhat like subsystems in Unreal.
  • Divide the code responsibilities between the Server and Client and further stick to small modules with assembly definitions.
  • Automated tests, including unit tests and integration tests using Unity Test Runner.

I understand that each project will require a different architecture, but using solutions like Zenject, I feel like I'm fighting against the engine. There is also an issue with finding resources on how to scale large projects in Unity, what architecture to adopt, and what options are suitable for Unity. Generally, most samples are either showcase projects or very indie in scale and may not necessarily be suitable for more robust scaling that maintains order in the project, scalability, and portability to other platforms.

Thanks in advance for your help! 🙂

#

What architecture solutions to adopt for a large 3D open-world coop game?

river bolt
#

Hello! Thanks for your question! Reading through your plan, hypothetically this should work! The player amount is definitely viable for NGO's standards! If you keep the world chunk sizing small enough it should work!

We unfortunately do not have a large scale NGO project at this time, but I'll make sure to note down your interest in one!

tranquil finch
#

Definitively within the NGO realm.
Some additional information:

Scenes loaded additively: meaning we have a Persistent scene that is never unloaded, a Gameplay scene, and loading World Chunks.
Some additional things you would want to contemplate:

Automated tests, including unit tests and integration tests using Unity Test Runner.
NGO includes a TestHelpers assembly to help with writing integration tests. If you want to use this with your project, you would want to add this to the end of your project's packages manifest file:

    "com.unity.netcode.gameobjects"
  ],```
The NGO runtime tests assembly includes [IntegrationTestExamples.cs](https://github.com/Unity-Technologies/com.unity.netcode.gameobjects/blob/release/1.7.0/com.unity.netcode.gameobjects/Tests/Runtime/IntegrationTestExamples.cs) .

Netcode for GameObjects' high level components, the RPC system, object spawning, and NetworkVariables all rely on there being at least two Netcode components added to a GameObject:

Netcode for GameObjects Integrated Scene Management

tranquil finch
#

A side note about the integration tests:
This runs within a single instance (i.e. you can make a stand alone test runner build), uses the loopback address (127.0.0.1) for sending/receiving network traffic, and automatically handles scene loading (and being able to differentiate which scene was loaded by which client/server-host).

  • If you plan on writing integration tests, I would highly recommend looking at some of the test project runtime tests to get a feel for how certain things are accomplished.
  • The NetcodeIntegrationTest has a bunch of helper methods that make "life easier".
    • As an example, the NetcodeIntegrationTest.CreateNetworkObjectPrefab method automatically adds all of the base components needed and some additional "helper components" to make identifying NetworkObject instances easier in the hierarchy within the editor.
  • It contains several virtual methods to inject/modify your test (i.e. OnStartup, OnTearDown, etc)

As a final note, once you have written an integration test and verified it works within the editor I would recommend making a stand alone test runner build to verify there are no timing related issues that present themselves when running in a fully optimized dedicated application instance.

GitHub

Netcode for GameObjects is a high-level netcode SDK that provides networking capabilities to GameObject/MonoBehaviour workflows within Unity and sits on top of underlying transport layer. - Unity-T...

GitHub

Netcode for GameObjects is a high-level netcode SDK that provides networking capabilities to GameObject/MonoBehaviour workflows within Unity and sits on top of underlying transport layer. - Unity-T...

torpid mesa
# hard holly Hi there! We are developing a 3D Open World game with a cooperative element (1-4...
  1. I would recommend more scenes, multiple UI scenes etc.. most reasonable sized projects should have many scenes.. Scenes and Prefabs do not merge when working in a team environment. You may even want to enable exclusive locking on them to prevent conflicts.
  2. If you decide not to go with Unity NGO, you should probably use Photon Fusion and start with the asteroid simple host sample to learn from. Photon has proven multiplayer server systems.. not sure what/if any major games use NGO yet. The Unity offerings are improving for sure, and i'm sure they will catch up at some point.
  3. You will want to add learning unity Addressables to your list. Addressables are something you would need to know up front and what it means to your project. You may even want a separate unity project to place/copy assets into so you can build the addressables from there for publishing. Depends on how large your assets are, or you may not even need or want addressables if you don't have many art assets and they aren't very large.
  4. RE: dividing code responsibilities.. Possibly not overthink the code structure? I could see enforcing better encapsulation. The modern pattern is have one code base.. you build the game and check the "Server" box to build a headless server for the clients to connect to.. no separation of code or multiple assemblies, or separate server, although if you were building an MMO that is probably reasonable. You may want a .NET backend server for user authentication, microtransactions, database access, or something like that in a separate server project and expose whatever it needs to the client via web services (but I would recommend the clients talk to the dedicated game server/headless server and have the headless server talk to the backend instead of the clients doing that directly) but none of that within the game project. You use Unity Gaming Services to upload the headless build and run servers as necessary, and use the matchmaking to arrange matches.. it depends on your game type and whether you are doing full server auth or client auth networking but this is the modern pattern. If you don't need matchmaking etc you would still build one code base and use a headless build as your dedicated server. If you use UGS or PlayFab server environment, your headless server would just securely talk to whatever backend server you make - you do want to avoid all the authentication needs and issues of having a client talk directly to the server's web services.
    It sounded like you just want a typical co-op game where someone can just decide to locally Host a game and friends join that local server.. so a bunch of the above info is may not be necessary here although you did mention "server" code so I wasn't sure. I would probably still recommend using UGS with headless servers and matchmaking services though, so that your 4 player game has stable connections for all players and you could even do full server auth to prevent some casual cheating even if it's a co-op game. It would result in a stabler multiplayer experience and keep a lot of long term options available versus allowing locally hosted games.
  5. Unity has some new offerings for player authentication and player data but if you don't go with those, then probably add PlayFab for cross-platform user authentication and user data, metrics, web dashboard and all that.. PlayFab is such an easy recommendation
#

not sure what to say about DI.. I would be careful there.. certainly static things like managers and UI controllers can use it but not anything on gameobects being created/destroyed in real time etc.. but then again you should be pooling objects so maybe it shouldn't be much of a concern anyways. regarding "fighting against the engine". yes DI may be overkill, you may just want to use a unity singleton pattern and carefully plan out your list of Manager types as singletons. But you still don't want your code littered with XXX.Instance everywhere so once you have the list of managers, you want to plan how to inject them or when injection is reasonable just to inject references to them as local properties on classes that need them

#

it's better to approach building the game as "building a game and writing code within Unity paradigms" first rather than writing C# code, that will be a game, that will just so happen to run under Unity and use the Unity UI.

#

I've seen a few different code bases so far, great C# programmers but new to Unity that wanted to continue developing in the classic C#.NET paradigms they have been using and not understanding why they don't fit within Unity or why they aren't even needed, or maybe they cause problems