From 240acf093e3ad869d532a42385cf3428a9d17723 Mon Sep 17 00:00:00 2001 From: JackCarterSmith Date: Sun, 10 Sep 2023 17:37:18 +0200 Subject: [PATCH] First game engine post --- .../2023-09-10-build-a-game-engine.markdown | 242 ++++++++++++++++++ static/images/thumbnails/build_an_engine.jpg | Bin 0 -> 34658 bytes static/images/thumbnails/directx.jpg | Bin 0 -> 8085 bytes 3 files changed, 242 insertions(+) create mode 100644 _posts/2023-09-10-build-a-game-engine.markdown create mode 100644 static/images/thumbnails/build_an_engine.jpg create mode 100644 static/images/thumbnails/directx.jpg diff --git a/_posts/2023-09-10-build-a-game-engine.markdown b/_posts/2023-09-10-build-a-game-engine.markdown new file mode 100644 index 0000000..da54eec --- /dev/null +++ b/_posts/2023-09-10-build-a-game-engine.markdown @@ -0,0 +1,242 @@ +--- +layout: post +title: Build a game engine from scratch +author: JackCarterSmith +categories: Programming C++ GameDev +thumbnail: build_an_engine +highlight: true +--- + +* Contents +{:toc} + +Creating a game inevitably involves choosing an engine to support our assets and +mechanics. In 2023, the numbers of moderns game engines are quite large: Unity, +Unreal, Godot, Cry, Source, idTech, OGRE, Monogame etc. +Each one came with it's own features, and also it's own **weakness**. When I talk about +benefits or consequences of an engine implementation, can be anything from what you +can do with it to design rules. + +When I started to look for an engine for my game rewrite idea, there are two questions +that came up to me: + +- should the engine adapt to the game, or the game to the engine? +- and why not design an engine? + +To these questions, I've found many opinions and explainations, not a really precise answer. +So after some comparisons and a pinch of personal opinion, I can now answer an "engine selection" +checklist: + +1. You have an idea of your game concept, artistic touch, mechanics and features. +2. Search for an existing engine that suits your game's needs. Check not only the advantages, but also the constraints. +3. If there is no matching engine, can you adjust your game's specifications to select a candidate? +4. If the previous answer is always no, then you should consider making your own game engine. + +Just as your game exploits its engine, the engine exploits your skills to produce a +game that more or less *run* So don't underestimate the importance of **working your coding-skills**. +The advantage of having so many game engines today is that you can find engines to +suit all levels! If you have already practiced programming, [Unity][link_unity] or +[Godot][link_godot] can do the job for you. And if you didn't, [GameEditor][link_gameeditor] +could be an option, but keep in mind that it's your programming skills that open up +game design possibilities. + +You can also choose **to design your own engine** just for the *state-of-the-art* aspect +or as a personal technical challenge. It's not a bad choice, and it's the job of +this series of articles to explain why I chose this option. + +> Be **patient**, really! Don't give up on setbacks. + +### Why use your own game engine? + +Freedom! Since you define the **design rules** using your own engine implementation, you can +create many more aspects than texture or shaders, such as physics or rendering methods. +This is the major point in favor to make your own engine. There are several points +that follow more or less directly from this: + +- better game specific optimizations, +- mastering/how-its-work low-level aspects (fast debugging), +- no time spend reading engine documentation to find out how to implement our feature, +- no generic features overhead you didn't need in your game (like multiplayer protocol on singleplayer game), +- no engine licensing constraints (others than the lib you used inside of it). + +From my personnal opinion, the biggest flaw I see in existing engines, which is ironically +their strength, is their *versatility*! In order to enable a wide range of uses for their engine, +these come with an abstraction layer that not only makes the engine (and the game as a result) +heavy in terms of disk size, but also in terms of performance. Some allow you to modify the +rendering engine to a certain limit, in order to adapt to the needs of devs, but this requires +work that is not negligible when compared to the dev time of an engine. And when it comes to +file size, you have to bear in mind that the size of the Unreal Engine (UE), compiled on its own, +is close to **a gigabyte of disk space**... + +Indirectly, you'll learn more than any *engine users* as you need to develop others +aspects you may not have thought of before like geometric computation and physics +algorithms. As you build your own implementation of physics and rendering pipeline, +you feel more confident about what your game is going on, you know what's going +on behind the scenes! Yes, you'll take time to develop (again) all the basics elements, +but it's an advantage you'll keep throughout your development for this and future projects. + +> Like athletes, warming up with small exercises helps you keep up the pace during the real effort. + +Yeah but... It's not all benefits either. And these are all good reasons that should be taken +into account when choosing between a *home-made* engine and an existing one. + +Firstly, the biggest problem is the time. Making a game engine from scratch require +a lot, a loooooot of time before displaying your first image on screen (as you'll see in +the following articles, it took me almost **one year to display something** that suited me!) and an +another waiting after that to make it playable through an unoptimized release! So... Another advice: +be patient, really! Don't give up in the face of setbacks, because yes, you'll have them, +and it's even important to have them in order to understand and better manage what comes next. + +You've an impressive numbers of features to implement in order to make just the game +rendering something on screen. And the less comfortable you are with the language, the +operation of a GPU and its drivers, memory management, 3D on a 2D surface... The more +you'll have to retrace your steps to code these interfaces rather than the game itself. +I think, this is why creating an engine is quite *complex*. + +> All vast subjects like 3D engine require discipline and rigor to understand and to master it. + +### Engine development choices + +For any engine, you need to interface with your GPU. Long time ago, every GPU vendors implements +its own interface to allow user to make thing on screen. For each GPU in the worlds you need to +have a portion of code to implement it! That's really annoying... And that's why, a few years later, +OpenGL and then Microsoft DirectX, have set up an API to standardize everything and every GPU since +feature an interface level for OpenGL, Vulkan and DirectX. All the low-level hardware interface with +GPU is done through these APIs, like memory transfer at chip-level and others DMA access. + +And for my first engine, I have choosen as API... DirectX... **DX-12** yup. + +I can't say today if it's a good or very bad choice, I've read everywhere about starting with +OpenGL as a first engine for a lot of good reasons: + +- easy to handle +- lot of documentations +- portable between OSs + +Because yes, DirectX is **proprietary to Microsoft** and can be used only on Windows environnement! +And as if that weren't enough: the version 12 is considered to be the most complicated to apprehend +because of the redesign of the graphic pipeline to take full advantage of a multi-threaded environment. +And why not older *simple* version like DX9? Even if I learned DX9, I'd to spend more time unlearning +a lot to adapt to DX12. Bearing in mind that, with the exception of DX11 and 12, the other versions +are considered obsolete for a new design. Although this goes against what I was saying about the +importance of doing small exercises before the big effort, I can explain it. + +I really want to focus on the mechanics of a game engine, and how it do the things. DX12 leaves memory +management to the developer and you need to understand how the resources are shared between GPU, +CPU and RAM. Since I'm primarily interested in designing a *state-of-the-art*, technically challenging +engine, using DX12 ask more times and efforts but it's worth it! I get a better management of what the +GPU and CPU does rather than letting the driver "do its thing". And it's always possible to add a +handler to manage both DirectX and OpenGL in function of the running OS or the user's choice. We'll +talk about that in a future post. + +No matter the API you choose, you need one more important things: a **good programming language**! And +no, Python is **not**. Making a game in Python may be fun, but it's not really technically interesting, +it's not designed for that. Python will slow your game, your dev and it's not adapted to debug properly +DX or GL interface. Java can do the job, like Minecraft using OpenGL, but it's a *virtual-machine language*. +The optimization level is a pain in ass. C# can have it's chance, used by MonoGame, the performance are +greats and compatible with DX (also know as SharpDX). But C# is a proprietary language of Microsoft. +If I choose C#, I'll get more troubles to debug my code and I definetly close the door for porting code to other OSs. +And C++? A lot of books about DX use this language, it's cross-platform, always documentated and in +development, multi-threads ready, objects oriented and have a lot of existing usefull library like [Boost][link_boostlib]. +In addition a lot of examples of games codes are made in C++. + +Here's a list of the others tools I used during my development, which I will detail if necessary: + +- Visual Studio 2022 - IDE with graphics oriented tools +- [CMake - Build manager][link_cmake] +- [Conan - Dependencies manager][link_conan] +- [Git - File version control][link_git] +- [PIX - GPU rendering debugger and analyzer][link_pix] +- [RenderDoc - Another GPU rendering debugger][link_renderdoc] + +Let's go for a ~~sadomasochistic~~ adventure with C++ and DX12. What could go wrong?! + +**Now let's talk less and code more! See you in next post ==>** + +### Some books to begin + +Rather than list books like that without much explanation, I'll mention which books I've read +and what they've brought me. + +The first book I've read and revisit most often is [3D Game Programming with DX12 by F.D.Luna][link_gameprogdx12]. +This book cover all the mains topics about DX12 usage with some examples. The only downside, +is that it's not easy to know exactly what functions all the elements indicated as structures +or methods perform. I needed to read again several times and experiment directly in a program to +understand the use of a feature. But beside of that, the book is very comprehensive for +running a rudimentary engine, with simple lighting, shadows and textures. + +I've got the DX9 and DX11 editions of this book for comparison and... Same topics, just adapted +for DX11 and DX9 pipeline. DX9 has far fewer subjects because of its lack of shaders prior to +9.0c version. + +The second book is not really related to game engine, because it's the [Holy Bible of C++11 by B.Stroustrup][link_holycpp]! +A complete dictionary of all the C++ features and keywords, really usefull when I need to fully +exploit a function from this language. Or maybe choose an another option to my issue than the one +I thought earlier. *B.Stroustrup* said that C++ was a language that had to respond to a problem +with a language feature! + +I plan to buy the new edition of C++17 soon to benefit from interesting multithreading features. + +I also read two other books: [Game Engine Architecture 3rd Ed. by J.Gregory][link_gameenginearch] and +[Game Programming Patterns by R.Mystron][link_gameprogpatterns]. Both doesn't explictly show **what to code**, +but **how to code** a good game engine. The first book describe each parts of a "modern" game engine, +like physics, audio, user inputs, files management, graphics (with DX in my case), etc. +The second one talk about the abstracts concepts of game engine like object memory management, +pointers good practice, game loop, and others importants things that we don't necessarily think about, +but which are necessary for the proper operation of a game engine. + +On top of that, you have the [online DX12 documentation][link_d3d12doc] which will go into greater +detail than F.D.Luna's book. Same advice for the Windows API to manage the window and the system messages. + +All these books have helped me a great deal in clarifying aspects of a game engine that I couldn't see +at first. But there's **no one right way to design a game engine**. Unlike a calculator program, where the +sole aim is to perform calculations as efficiently as possible, our engine must meet several needs in +terms of functionality to match the game we want to make. Most books and examples only give us one way +of doing things, although sometimes there's no other way than to go through this or that method to achieve +a task, the rest is up to our own judgement. + +> I really like the low-level programming because it's like a puzzle-game to make a game. + +My last piece of advice is to **take inspiration from existing engines**. And if the source code is available, +try to understand **why it's implemented the way it is**. Others previous developers have run into the same problems +you're about to encounter. For the time being, it would be a waste of time (and possibly of motivation) +to repeatedly get *our feet stuck in the carpet*. Above all, the aim of this blog is +to share successes and mistakes, that's what knowledge is all about. + +### It's (not) a trap! + +> This is a recurent chapter in a large part of my topics to describe, from my own experience +> and point of view, the points on which I may have found myself stuck, or which at some point +> required me to pause and reflect. +> +> Use them as you like! + +When I choose to use DX12 as my first API for a 3D engine, the price to pay for that is to take +even more time to complete the first draw on screen. That's part of the reason why it took me a +year to achieve this result. Today I'm on the 4th attempt/iteration, and that's not counting tests +on test code apart from the engine sources. I'll give you all details in upcoming posts! + +So why not using Vulkan if I wanted a challenge? Some reasons for that: **Vulkan isn't so well documented** +than DirectX, or at least it was easier to find DirectX docs and books. And it's for me a good +sign to avoid or to limit the *demotivation effect*: the more time and energy you invest in +something that doesn't bring you any satisfaction within the limits of your patience, the more +you give up or *make a break* on the project. The greater the challenge, the greater the risk +of *breaking*. This is normal, and it's through this kind of failure that we learn to know our +limits. So I keep Vulkan as a next feature or evolution for now. + + + +[link_gameeditor]: http://game-editor.com/static/Main_Page.html +[link_unity]: https://unity.com/fr +[link_godot]: https://godotengine.org/ +[link_boostlib]: https://www.boost.org/ +[link_cmake]: https://cmake.org/ +[link_conan]: https://conan.io/ +[link_git]: https://git-scm.com/ +[link_pix]: https://devblogs.microsoft.com/pix/download/ +[link_renderdoc]: https://renderdoc.org/ +[link_gameprogdx12]: https://amzn.eu/d/9aTUE79 +[link_holycpp]: https://amzn.eu/d/cN7pZ7Q +[link_gameenginearch]: https://amzn.eu/d/bEcBNXE +[link_gameprogpatterns]: https://gameprogrammingpatterns.com/ +[link_d3d12doc]: https://learn.microsoft.com/en-us/windows/win32/direct3d12/directx-12-programming-guide diff --git a/static/images/thumbnails/build_an_engine.jpg b/static/images/thumbnails/build_an_engine.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6c89c901158404b2dccb258e084da9e7f3a3a79b GIT binary patch literal 34658 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%0APwCX-Hz&MNNb63|rgA*T@nMaViHBr}4ot0zh~_ zJ-ZqB{PND^ zrnuhH%r(Rb!?e~X?O#N2vr^c+pTB5r z#<9Y<yo-ave+Yc%(*(jQx>HB*2nR(i#~`GiYh4B^ ziVcFcqUNk6JluB1*8EDn9R`dtONZeM=Q#8Dn2dd~p7;2;Pn>7GeenF_?f6_$?UXn0 zc|NnKqx=a*Bq0FcF<-*|E|0*s7Gl6$2hJYYdw+2E&3nQ-&z2tedtp7{7$XE27+kIo zEARvZR0cnJ5CCWb1`jXr5Ai-v#d%+e{6mFv_!o+~zc|;7uQ;zcesOPj`(y2m_n$0s UYrJc``TqcM3(g_`0QMjM*=>$2rvLx| literal 0 HcmV?d00001 diff --git a/static/images/thumbnails/directx.jpg b/static/images/thumbnails/directx.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ce3eceadb6fb658ab7eb4fdc1cd788a9649394c9 GIT binary patch literal 8085 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 literal 0 HcmV?d00001