3
\$\begingroup\$

As I'm reading Uncle Bob's Clean Architecture I keep wondering how all the advice presented can be applied in game development. Games are nothing more that highly interactive real-time simulations and shouldn't really differ that much from any other complex systems. Good practices in architecture design should be as much help here as anywhere else.

That said I have some doubts whether obtaining a high level of coupling between game engine and its logic can be easily obtained. Game engine is basically a framework so "Frameworks Are Details" rule should be of use here but from what I see games are practically inseparable from their underlying engines. I haven't seen any use of Clean Code rules in most projects I've encountered. I've heard than even unit testing is a rare occurrence.

How can I even achieve loose coupling if all important subsystems like event handling, physics, renderer and even main loop itself are baked in the engine?

Or should I ignore this since an engine is not a database and it'd be highly unlikely to think about changing it as the project goes by?

\$\endgroup\$
4
\$\begingroup\$

As a general rule, switching to a different game engine is not something that is likely to ever happen past early development. I can literally count on one hand the number of games I've seen do this after shipping, and in almost all cases it was a change from a third-party engine to one that was developed in-house to specifically meet the needs of the game in question (for example, World of Tanks recently did this). Given this, you can treat it in much the same way you would treat the operating system if you're programming for a single platform and not ever going to port your software, namely, use all the features to the extent you need them, and don't worry about writing your code in such a way that it's trivial to use on a different game engine.

The one exception I would make to this is if you're developing the engine alongside the game. In this case, it's very easy to get the two into a state where you can't ever hope to use the game engine for anything else, and that's generally a bad thing, and you should try to avoid letting that happen.

Now, technically, a game engine is a 'framework'. However, a much better way of describing it is a platform. I mentioned above that you can treat a game engine like an operating system, and this is because it largely does the same thing that an operating system does. The easiest way to understand this is to look at what game programming was like for older console systems that did not have a conventional operating system (for example, any Nintendo system before the Wii or DS, the PS1 and PS2, the original Xbox, and most of the early Sega systems). On those platforms, the game engine was the operating system. It provided all the hardware abstractions that were present (and there weren't many), and also defined the 'platform' that the game was written for. There are of course more layers of indirection now, but the same general principles are there. If you write something on, for example, Unity, you can easily get it running on a number of different systems, because Unity handles almost all the work for you.

\$\endgroup\$
1
\$\begingroup\$

A Game Engine is, as you said, just a framework. but depending on the amount of 'services' the engine delivers, its arguable how dependent your game really is, when you work with this frame work.

Most Game Engines have their Main class to instantiate, some manager classes to inherit and fill. You instantiate objects, maybe with a graphical representation, sounds, some game rules attached to it. When you start your final game, everything works, because the engine does most of the work.

This basically as decoupled as it can get. You only import some small scripts into the game, most likely not even in the same programming language as the engine was written with.

That said, if you would want to change your game engine mid development, yo could do that. If both engines have the same 'services', maybe the new one even more, all you do is change your function calls for the framework you are using now. Maybe you can't use the same graphics objects (no jpgs or different 3d models), maybe the script language is different, but in the end, you only call the interface of you frame work.

How would you even want to make unit tests on these? Maps, models, animations dont need unit tests. Developers of game engines SHOULD do unit tests, mock components and stuff, but from the view of the end user (the one working the the framework), you have basically no need for that. And unit tests with scrips may be a bit to much.

\$\endgroup\$
1
\$\begingroup\$

You should definitely keep as much of your game logic separate from the game engine as possible.

Create libraries and reference them from the main program.

Its easier to see why if you think about a more abstract game than a FPS.

Chess for example, you would want all your, 'is this move valid' and 'whats the best move' code completely decoupled from your 'display the chess piece being moved' code so that it could be fully tested in isolation. Indeed you would probably just want to plug in an existing chess engine to your game.

Even a simple FPS will still have some abstract logic. How many shots can the player take before dying? what damage does a gun of type X do?

Sure, leave the physics in the engine, but your life will be easier if you can just call Player.IsWearingRollerSkates from your player library rather than having everything embedded in ,for example, unity behaviours

\$\endgroup\$
0
\$\begingroup\$

I think you should view a game engine as a chunk of reusable code, not as a replaceable component of your software which you could decide to change on whim.

Most of the time, choosing an engine is equivalent to committing to it. If you start building your game with Unreal/c++, you'll have a hard time switching to Unity/c#. Switching midway will require a lot of planning and work.

Also, keep in mind that games are often "disposable code": make the game, release the game, release a bug-fix patch, release a couple of DLCs and never touch this game code again because you'll be working on the next game. Switching engine midway is often only relevant in contexts where the game will be running for years (as you've illustrated with world of tanks).

Is it advisable to maintain a separation between the engine and the game?

You'll have to figure that out before you start. If you want to be able to switch engine during the development (for any reason), you'll have to make sure that the underlying services that these engines offer are roughly architectured the same way. You'll then be able to abstract these services into your own layer, thus eventually replacing only that layer with the engine.

How can I even achieve loose coupling if all important subsystems like event handling, physics, renderer and even main loop itself are baked in the engine?

You add another layer that handles all of this. Yes, you'll have to re-code a lot of stuff, but your game will ignore (mostly) completely what engine it uses.

Or should I ignore this since an engine is not a database and it'd be highly unlikely to think about changing it as the project goes by?

Although you raise valid questions here, yes, I think you should ignore this :)

If you can't really justify all the overhead that would imply wrapping Unity's Vector3 class into your own vec3 class because you don't want to couple your game to Unity, then stick to one engine, make the game, release it, make a post-mortem and decide if it was the right engine for you and if it is the right engine for your next game, then produce the next game and make money.

\$\endgroup\$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.