<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: IWantToDeleteThisButICant</title>
    <description>The latest articles on DEV Community by IWantToDeleteThisButICant (@mah_doh).</description>
    <link>https://dev.to/mah_doh</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1120468%2Fe978c88d-5915-4b46-9cb8-4264c38f3dfc.jpg</url>
      <title>DEV Community: IWantToDeleteThisButICant</title>
      <link>https://dev.to/mah_doh</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mah_doh"/>
    <language>en</language>
    <item>
      <title>Starting Up The Engine - Nikola Game Engine Devlog 1</title>
      <dc:creator>IWantToDeleteThisButICant</dc:creator>
      <pubDate>Sat, 01 Mar 2025 07:21:58 +0000</pubDate>
      <link>https://dev.to/mah_doh/starting-up-the-engine-nikola-game-engine-devlog-1-26mc</link>
      <guid>https://dev.to/mah_doh/starting-up-the-engine-nikola-game-engine-devlog-1-26mc</guid>
      <description>&lt;h2&gt;
  
  
  Rev The Engine
&lt;/h2&gt;

&lt;p&gt;Game engines are &lt;em&gt;huge&lt;/em&gt; beasts of complexity and intricacies. It is often hard to know &lt;em&gt;which&lt;/em&gt; system to start working on first. Maybe start off with the window system? Input? Logging? Perhaps begin to work on your custom data structures? So, essentially, &lt;em&gt;where to start?&lt;/em&gt; This is a question that vexes me every time I start on a new game engine. If you read the last &lt;a href="https://frodoalaska.github.io/2025-02-24-new-year-new-game-engine/" rel="noopener noreferrer"&gt;devlog&lt;/a&gt;, you'd know that my journey with game engines has not been the most favorable, let's just say. I always truly "fucked it up". Especially at the beginning. And the beginning, I feel, is as important as anything else. &lt;/p&gt;

&lt;p&gt;Mind you, I did not want to go whip up the whiteboard and start to design my system like that. I feel that the method of creating systems--often called "white-boarding"--is somewhat contrived. I do understand it was meant as a way to expect the unexpected, essentially. But, for me, it never sufficed. So, instead, I decided to just &lt;em&gt;outline&lt;/em&gt; the systems that I would create and then go from there. I did not want to put too much thought into how a system would be created, used, and coincide with other systems. I just wanted to know what are the purposes of the system, what I'm planning to achieve with it, and go from there. So far, that way of thinking about systems has worked for me. &lt;/p&gt;

&lt;p&gt;In my last devlog, I outlined exactly how the engine's architecture is going to look. Basically, I split the engine into three modules: &lt;em&gt;Core&lt;/em&gt;, &lt;em&gt;Engine&lt;/em&gt;, and &lt;em&gt;UI&lt;/em&gt;. The &lt;em&gt;Core&lt;/em&gt; part of this project is where I'll start, obviously. It is the core after all. I wanted this part of the engine to be as barebones as possible. I did not want to include any external libraries in the header file at all. In fact, I was pretty successful in achieving that. With the exception of the ol' &lt;code&gt;#include &amp;lt;cstddef&amp;gt;&lt;/code&gt; for &lt;code&gt;size_t&lt;/code&gt;, I did not include any third-party libraries at all. Any custom data structures or engine-specific systems like scenes, resources, or renderers will be instead in the sister &lt;em&gt;Engine&lt;/em&gt; side of the aisle. &lt;/p&gt;

&lt;p&gt;So, what does this &lt;em&gt;Core&lt;/em&gt; part of the engine include, then? Glad you asked, person who is totally real. Mainly, this &lt;em&gt;Core&lt;/em&gt; section is separated into six distinct areas: &lt;em&gt;Logger&lt;/em&gt;, &lt;em&gt;Window&lt;/em&gt;, &lt;em&gt;Events&lt;/em&gt;, &lt;em&gt;Input&lt;/em&gt;, &lt;em&gt;Clock&lt;/em&gt;, and a section I call &lt;em&gt;Gfx&lt;/em&gt; which is just a nice wrapper around OpenGL. I will go in-depth about the first five areas of &lt;em&gt;Core&lt;/em&gt; in this article, while I'll leave the &lt;em&gt;Gfx&lt;/em&gt; area for a later article.&lt;/p&gt;

&lt;p&gt;As you will later see, my code is pretty much as C-style as it gets. I will not go in-depth about why I write code this way (maybe in the future I will), but it is the code style I adapted over the years. It is one that I enjoy very much and find fairly intuitive. So you won't see any &lt;code&gt;class&lt;/code&gt;es, &lt;code&gt;template&amp;lt;typename T&amp;gt;&lt;/code&gt;, or &lt;code&gt;boost::lexical_cast&amp;lt;int&amp;gt;(no)&lt;/code&gt;. I rely heavily upon &lt;code&gt;struct&lt;/code&gt;s and functions. I do not use constructors or destructors. Again, not any particular reason other than I like this style. That does not mean I never use any C++ features, though. I do. Plenty, as well. In the &lt;em&gt;Engine&lt;/em&gt; section, as you will see, I use a lot of the features in the &lt;code&gt;STL&lt;/code&gt; library, as well as some function overloads here and there. So don't be surprised when you see a stray &lt;code&gt;struct&lt;/code&gt; here and there.  &lt;/p&gt;

&lt;p&gt;Okay, with that out of the way, let's start with some printing, shall we?&lt;/p&gt;

&lt;h2&gt;
  
  
  Log, Assert, And Watch Your Step
&lt;/h2&gt;

&lt;p&gt;Whenever I am presented with quite an annoying bug, I often &lt;code&gt;printf&lt;/code&gt; my way into the solution. Having had very little experience with debuggers early on in my programming journey, I printed out many variables and results of functions to overcome bugs. You can say it is an old habit of mine. I never grew out of it. And while I do often use debuggers for the occasional stubborn segmentation fault, my first intuition when I'm presented with a problem is to print everything. And so, with that in mind, my first call to action was to create a helpful logger.&lt;/p&gt;

&lt;p&gt;Well, I wouldn't call it much of a "logger", per se. It is more like a collection of useful macros that print to the console using some pretty colors. I did have in mind to use the &lt;a href="https://github.com/gabime/spdlog.git" rel="noopener noreferrer"&gt;spdlog&lt;/a&gt; library since I do know that it is quite fast and has a lot of useful functionalities. But if you have read my previous devlog, you would know I do &lt;em&gt;not&lt;/em&gt; like to use a lot of dependencies. I felt like logging was something that I could handle on my own without adding another dependency. And so I did. With a lot of help, though. &lt;/p&gt;

&lt;p&gt;This "logging system" I adapted to this engine was influenced a whole &lt;em&gt;ton&lt;/em&gt; by the &lt;a href="https://github.com/travisvroman/kohi" rel="noopener noreferrer"&gt;kohi&lt;/a&gt; engine. If you don't know, the Kohi Engine is quite a robust game engine built in C. The guy who created it also logs his progress on his &lt;a href="https://www.youtube.com/@TravisVroman" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt; channel. Check it out. The series is very fun to watch and very informative. &lt;/p&gt;

&lt;p&gt;Either way, in The Kohi Engine, there is a list of macros he uses to log into the console. Now, he has a more sophisticated system for logging. But I, on the other hand, decided to create something simple instead. I &lt;em&gt;did&lt;/em&gt; just use a bunch of macros to log into the console. Each had its own cool color associated with it. It is nuanced, as well. If the logger were to, say, log a "fail" message status, for example, it would send a "Quit" event to the event manager which someone would hopefully be listening to. That's where the "nuance" stops, though. &lt;/p&gt;

&lt;p&gt;My reason for going for something so simple initially is quite obvious: I, generally, do not care about logging. Here's the thing, logging has, quite often, saved my ass. Excuse my French. It is truly a very important system that will, theoretically, be very crucial to my development. However, that is only what it is: A useful tool for &lt;em&gt;development&lt;/em&gt;. Only a tool. When I do eventually ship a game with this engine, logging will be cut out completely. I sincerely did not see the reason to build an entire robust logging system. &lt;/p&gt;

&lt;p&gt;But, controversial takes aside, let's take a look at the logging system. &lt;/p&gt;

&lt;p&gt;The logging system has a few "statuses" that attach to every message logged to the console.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;LogLevel&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;LOG_LEVEL_TRACE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;LOG_LEVEL_DEBUG&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="n"&gt;LOG_LEVEL_INFO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;LOG_LEVEL_WARN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;LOG_LEVEL_ERROR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="n"&gt;LOG_LEVEL_FATAL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see with beautiful &lt;code&gt;enum&lt;/code&gt;, there are &lt;em&gt;six&lt;/em&gt; levels to logging. The first two are &lt;em&gt;only&lt;/em&gt; present in debug builds. The two after that can be turned on or off as the user pleases. And as for the last two, they are &lt;em&gt;always&lt;/em&gt; turned on, no matter the build configuration or the user's pleasure. With each level, there's an associated macro:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;NIKOLA_LOG_TRACE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TRACE"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;NIKOLA_LOG_DEBUG&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"DEBUG"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;NIKOLA_LOG_INFO&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"INFO"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;NIKOLA_LOG_WARN&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"WARN"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;NIKOLA_LOG_ERROR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ERROR"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;NIKOLA_LOG_FATAL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"FATAL"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each macro is really just a &lt;code&gt;printf&lt;/code&gt; under the hood. Meaning, using variadic arguments (it's the &lt;code&gt;...&lt;/code&gt; you usually find with &lt;code&gt;printf&lt;/code&gt; functions), we can insert variables into each log statement like such:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;NIKOLA_LOG_DEBUG&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"FPS = %i"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fps&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, it is &lt;em&gt;very&lt;/em&gt; much like a &lt;code&gt;printf&lt;/code&gt; statement, but with slightly more variation. Besides the fact that it associates each log level with a pretty color in the console, the macros call a logging function that does a little bit more work.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// The `i8`, by the way, is just a `typedef`ed `char`. &lt;/span&gt;
&lt;span class="n"&gt;NIKOLA_API&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;logger_log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;LogLevel&lt;/span&gt; &lt;span class="n"&gt;lvl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;i8&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The function takes a log level, a message, and the variadic argument I was just talking about. Under the hood, the function will extract the variadic argument using the old C &lt;code&gt;va_start&lt;/code&gt; and &lt;code&gt;va_end&lt;/code&gt;, format the string using &lt;code&gt;vsprintf&lt;/code&gt;, pick an appropriate prefix (&lt;code&gt;NIKOLA-FATAL&lt;/code&gt; for fatal errors, for example), pick a nice color, and then output the final message to the console. While it &lt;em&gt;may&lt;/em&gt; sound complicated, it really isn't. It is only these three functions to extract variadic arguments and then a single &lt;code&gt;printf&lt;/code&gt; at the end. It is very simple, in fact. &lt;/p&gt;

&lt;p&gt;You might wonder how I changed the colors for the output. Well, my friend, I went complete "Unix-mode" on the matter. I used the good ol' &lt;a href="https://en.wikipedia.org/wiki/ANSI_escape_code" rel="noopener noreferrer"&gt;escape codes&lt;/a&gt; to print the colors. The Wikipedia page goes more in-depth about that, but, essentially, the console already has preset colors you can use by using &lt;em&gt;specific&lt;/em&gt; sequence of characters like &lt;code&gt;\033[1;91m&lt;/code&gt;. Go read the Wikipedia page if you are more interested in it. &lt;/p&gt;

&lt;p&gt;I did think that escape codes would not work on Windows. But, to my surprise, they did! Pretty well, too. Although, I would think using the Win32 API to print out to the console would give you more benefits than a simple &lt;code&gt;printf&lt;/code&gt;. But, nonetheless, it is good enough for me. &lt;/p&gt;

&lt;p&gt;Another technique I use to root out bugs is the &lt;em&gt;asserts&lt;/em&gt;. Now, there is a pretty nice assert library already in the C standard. The one that exists in &lt;code&gt;&amp;lt;cassert&amp;gt;&lt;/code&gt;. However, I wanted to have my own control over the &lt;code&gt;assert&lt;/code&gt;s, so I decided to use my own implementation. Once again, I took a lot of liberty from The Kohi Engine. &lt;/p&gt;

&lt;p&gt;Asserts are a way to completely halt the code from any further execution. It is a useful way to know &lt;em&gt;exactly&lt;/em&gt; where and what failed. I usually use asserts to catch the stupid bugs I always end up causing like passing an invalid pointer or going past the current size of an array. If you ever get to see my code (god forbid), you will see that asserts populate my codebase quite a bit. And for good reason, too. Asserts have helped me root out some very stubborn bugs before. &lt;/p&gt;

&lt;p&gt;Now, much like logging, asserts have their own set of macros. Well, not a &lt;em&gt;set&lt;/em&gt;, but just &lt;em&gt;one&lt;/em&gt; macro.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;NIKOLA_ASSERT&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;window&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nb"&gt;nullptr&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;"Wrong window, stupid"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The messages are usually more useful than that, but you get the point. As you can see, the first argument is a condition. This condition &lt;em&gt;must&lt;/em&gt; be true for the assertion not to trigger. Otherwise, you will have a bad time. The output will look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;NIKOLA ASSERTION FAILED]: Cannot initialize GfxShader with an invalid context 
    &lt;span class="o"&gt;[&lt;/span&gt;EXPR]: gfx &lt;span class="o"&gt;!=&lt;/span&gt; nullptr 
    &lt;span class="o"&gt;[&lt;/span&gt;FILE]: gl_backend.cpp 
    &lt;span class="o"&gt;[&lt;/span&gt;LINE]: 420 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Under the hood, the macro calls a function and then another macro. The function,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;NIKOLA_API&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;logger_log_assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;i8&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;expr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;i8&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;i8&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;u32&lt;/span&gt; &lt;span class="n"&gt;line_num&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;will simply propagate into multiple &lt;code&gt;printf&lt;/code&gt; statements that log the given information. No colors involved or anything. I wanted to make it serious to really show how disappointed the engine is with you. Besides the function, &lt;code&gt;NIKOLA_ASSERT&lt;/code&gt; will also call &lt;code&gt;DEBUG_BREAK()&lt;/code&gt;. That macro will be specific to the current operating system running the engine. On Windows, the macro is really just a call to the intrinsic &lt;code&gt;__debugbreak()&lt;/code&gt;. While on Linux, it will call &lt;code&gt;__builtin_trap()&lt;/code&gt;. These intrinsics will halt the code completely at a specific point, just as if you were using a debugger and it halts at a breakpoint.&lt;/p&gt;

&lt;p&gt;Well, that was a bore. Let's get some fresh air, don't you think?&lt;/p&gt;

&lt;h2&gt;
  
  
  Open A Window To Get Some Fresh Air
&lt;/h2&gt;

&lt;p&gt;As I discussed in my previous devlog, I decided to go with &lt;a href="https://github.com/glfw/glfw.git" rel="noopener noreferrer"&gt;glfw&lt;/a&gt; for handling the window creation for this engine. It is a library I used a &lt;em&gt;ton&lt;/em&gt; before. And while I do fancy replacing it later, it will suffice for now. &lt;/p&gt;

&lt;p&gt;In my previous engines, I was actively trying to make the window a global variable that would only have &lt;em&gt;one&lt;/em&gt; instance throughout the whole application. The reason I went for this approach in the past was for the "ease of use". And while it was pretty simple, I wanted to go for something different in this engine. Basically, I did not want to force the user (me, in this case) to work with a global variable. Even though I do not mind global variables, I still did not want to force myself to use that kind of system &lt;em&gt;every time&lt;/em&gt; I would make a game. What if I woke up someday and decided that global variables were bad? What then? Should I change the &lt;em&gt;whole&lt;/em&gt; API? No. I did not want this to happen. But that would mean that I would have a &lt;code&gt;Window&lt;/code&gt; structure out there somewhere with public variables the user can access like the width and height of the window. While these variables can be changed, they need to be changed through an &lt;em&gt;API call&lt;/em&gt; to the specific operating system. Not through using &lt;code&gt;+=&lt;/code&gt; on the variable, for example. Besides that, each operating system has a state that needs to be kept. On Win32, for example, I would have to keep a &lt;code&gt;HWND&lt;/code&gt; variable somewhere. And in the case of GLFW, I would have to keep a &lt;code&gt;GLFWwindow&lt;/code&gt; lying around somewhere. And so, here's my solution:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Window&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Beautiful, isn't it? What's that? What is it, you're asking? Well, in the old C lexicon, we call this an "opaque struct". An "opaque struct" is essentially a &lt;em&gt;promise&lt;/em&gt; made by you to the compiler that, while the implementation is not yet defined, you will &lt;em&gt;eventually&lt;/em&gt;, in some &lt;code&gt;.c&lt;/code&gt; or &lt;code&gt;.cpp&lt;/code&gt; file somewhere, will implement the type. The compiler can pass this "safely" to any function that needs it without any errors. However, if this type were not implemented somewhere you &lt;em&gt;will&lt;/em&gt; have a &lt;em&gt;linker&lt;/em&gt; error. Since the linker will be looking for an exact implementation but won't find it. &lt;/p&gt;

&lt;p&gt;This is actually how GLFW is implemented. It has a main &lt;code&gt;glfw3.h&lt;/code&gt; which will declare an opaque &lt;code&gt;GLFWwindow&lt;/code&gt; struct the user code can use. The &lt;em&gt;true&lt;/em&gt; implementation of this struct lies somewhere in one of the translation units. Either in &lt;code&gt;win32_window.c&lt;/code&gt; on Windows or &lt;code&gt;x11_window.c&lt;/code&gt; on Linux. As long as there is only &lt;em&gt;one&lt;/em&gt; implementation somewhere of the opaque struct, then you're all good. And, seeing how I want to move away from GLFW eventually, I decided to go with this approach. And, you must admit, it is quite beautiful, right? &lt;/p&gt;

&lt;p&gt;Either way, any window-related function will need a pointer reference of this opaque struct in order to do anything useful.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;NIKOLA_API&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;window_is_open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Window&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But how do you open a window?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;NIKOLA_API&lt;/span&gt; &lt;span class="n"&gt;Window&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;window_open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;i8&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;i32&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;i32&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i32&lt;/span&gt; &lt;span class="n"&gt;flags&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The function looks pretty self-explanatory, right? The &lt;code&gt;title&lt;/code&gt; will set the name of the window. The &lt;code&gt;width&lt;/code&gt; and the &lt;code&gt;height&lt;/code&gt; will be the total size of the window. The function will return a &lt;code&gt;Window&lt;/code&gt; pointer if everything goes well. If there's anything wrong with the internal window API, the function will actually assert. So you will know for sure if there's something wrong that happened. But, what about the &lt;code&gt;flags&lt;/code&gt; parameter? &lt;/p&gt;

&lt;p&gt;Windows are, like engines, quite complicated. I want to open a window, yes, but what kind? A fullscreen window? Maximized? Minimized? Do you want decorations (the borders and widgets around the window)? Do you want it to gain focus initially? Do you want the mouse hidden? So, in order to make the code cleaner and my life easier, I put all of these possibilities into one enum:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// There are _a lot_ more flags than these, but I don't want to pollute the article any further.&lt;/span&gt;
&lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;WindowFlags&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;WINDOW_FLAGS_NONE&lt;/span&gt;
  &lt;span class="n"&gt;WINDOW_FLAGS_RESIZABLE&lt;/span&gt;
  &lt;span class="n"&gt;WINDOW_FLAGS_FOCUS_ON_CREATE&lt;/span&gt;
  &lt;span class="n"&gt;WINDOW_FLAGS_FOCUS_ON_SHOW&lt;/span&gt;
  &lt;span class="n"&gt;WINDOW_FLAGS_MINIMIZE&lt;/span&gt;
  &lt;span class="n"&gt;WINDOW_FLAGS_MAXMIZE&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These flags can be &lt;code&gt;OR&lt;/code&gt;ed together into one &lt;code&gt;i32&lt;/code&gt; and then passed to the function. In the function &lt;code&gt;window_open&lt;/code&gt;, it will check which flags are set and act accordingly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;i32&lt;/span&gt; &lt;span class="n"&gt;win_flags&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;WINDOW_FLAGS_RESIZABLE&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;WINDOW_FLAGS_HIDE_CURSOR&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;WINDOW_FLAGS_GFX_HARDWARE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, of course, if the window is opened, it needs to be closed as well. Pretty obvious, I would say.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;NIKOLA_API&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;window_close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Window&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While I do hope to improve upon the window system in the future and perhaps move away from GLFW to reduce any dependencies, this system works pretty well for me currently. It has served me thus far without any hiccups or issues. I do not claim that it is the best system out there, but it is one that worked fairly well for me. &lt;/p&gt;

&lt;p&gt;Besides, the windows, I decided to also use GLFW for any timing-related work. GLFW has a function called &lt;code&gt;glfwGetTime()&lt;/code&gt;, which retrieves the elapsed time since the GLFW library has been initialized. So, in a sense, it also measures the amount of time since the &lt;em&gt;application&lt;/em&gt; started. This is a good way to query for time, and we will be using this a lot. &lt;/p&gt;

&lt;p&gt;I made a clock section as well which includes four functions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="c1"&gt;//Every function has a "ni" prefix to avoid any confusion with the C clock library.&lt;/span&gt;

&lt;span class="n"&gt;NIKOLA_API&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;niclock_update&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// `f64` is just a `typedef`ed `double`&lt;/span&gt;
&lt;span class="n"&gt;NIKOLA_API&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;f64&lt;/span&gt; &lt;span class="nf"&gt;niclock_get_time&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; 

&lt;span class="n"&gt;NIKOLA_API&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;f64&lt;/span&gt; &lt;span class="nf"&gt;niclock_get_fps&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="n"&gt;NIKOLA_API&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;f64&lt;/span&gt; &lt;span class="nf"&gt;niclock_get_delta_time&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first function--&lt;code&gt;niclock_update()&lt;/code&gt;--is to be called internally and therefore has no purpose to be so out in the open. However, since it is working as it is currently, I have no plans to change that. As for the other functions, they are pretty self-explanatory. &lt;/p&gt;

&lt;p&gt;Inside the &lt;code&gt;nikola_clock.cpp&lt;/code&gt; translation unit, there is a secret data structure called &lt;code&gt;ClockState&lt;/code&gt;, which keeps track of various variables. For example, &lt;code&gt;frame_count&lt;/code&gt;, which keeps track of the frames to calculate the FPS later, and so on. The &lt;code&gt;niclock_get_time()&lt;/code&gt; is just a convenient wrapper around the &lt;code&gt;glfwGetTime()&lt;/code&gt; I talked about earlier. Since I plan to have separate delta times for various reasons, it would be nice to have that function available when needed. &lt;/p&gt;

&lt;p&gt;Hang on. I just got an event that you pressed a key. Did you?&lt;/p&gt;

&lt;h2&gt;
  
  
  On Key Pressed
&lt;/h2&gt;

&lt;p&gt;Cute, isn't it? &lt;/p&gt;

&lt;p&gt;Either way, I want to talk about the last two areas of the &lt;em&gt;Core&lt;/em&gt; section: the event and input system. As it goes with the rest of this section, these systems are fairly simple in principle. Once again, they are not the &lt;em&gt;best&lt;/em&gt; systems ever. Neither are they efficient. Yet, they have served me very well over the past few months. With only a few minor changes, these systems were taken from the last engine I created. &lt;/p&gt;

&lt;p&gt;The event system is quite simple.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;NIKOLA_API&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;event_listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;EventType&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;EventFireFn&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;listener&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;nullptr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;NIKOLA_API&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;event_dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Event&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;dispatcher&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;nullptr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the &lt;code&gt;EventType&lt;/code&gt; is just an enum that will tell the event system what kind of event to listen to. The &lt;code&gt;EventType&lt;/code&gt; enum includes values like, &lt;code&gt;EVENT_WINDOW_MOVED&lt;/code&gt;, &lt;code&gt;EVENT_KEY_PRESSED&lt;/code&gt;, &lt;code&gt;EVENT_JOYSTICK_CONNECTED&lt;/code&gt;, and so on. Besides that, the &lt;code&gt;Event&lt;/code&gt; is just a data structure I created to hold &lt;em&gt;all&lt;/em&gt; the possible variables that can be passed around from dispatcher to listener. I took inspiration from the SDL and SFML libraries. They have something similar in their even systems. Except, with their implementation, there lies an &lt;em&gt;event queue&lt;/em&gt;, while mine is more of a &lt;em&gt;fire-and-forget&lt;/em&gt; system. Any event that gets dispatched, will make the system go through all of the events with the same &lt;code&gt;EventType&lt;/code&gt; found in &lt;code&gt;Event&lt;/code&gt; and call the associated callback &lt;code&gt;func&lt;/code&gt;, making sure to pass the given &lt;code&gt;Event&lt;/code&gt; parameter. The event does &lt;em&gt;not&lt;/em&gt; get removed from the system, as it would with an event queue. Rather, it stays there until otherwise instructed. Once again, pretty inefficient, but stable and functional. &lt;/p&gt;

&lt;p&gt;So what is the callback?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="n"&gt;EventFireFn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Event&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;dispatcher&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;listener&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every time someone listens to an event, this function prototype gets passed in, bundled up with the event type as well as a scary &lt;code&gt;const void*&lt;/code&gt; &lt;em&gt;listener&lt;/em&gt;. On the other hand, whenever an event gets &lt;em&gt;dispatched&lt;/em&gt;, meaning, fired, the function expects an &lt;code&gt;Event&lt;/code&gt; with the &lt;code&gt;.type&lt;/code&gt; member filled and with the appropriate variables set. Besides that, another horrifying &lt;code&gt;const void*&lt;/code&gt; &lt;em&gt;dispatcher&lt;/em&gt; is passed. This is done so we can pass the state around on the event callback. Of course, these scary &lt;code&gt;const void*&lt;/code&gt; parameters can be left to be invalid with a &lt;code&gt;nullptr&lt;/code&gt;. That's the default behavior, in fact. But, if otherwise, we can use these pointers and convert them to any type we may know has been passed in. Of course, there has to be some bookkeeping within the listener's callback in order to know for sure if either pointer is valid and if they are the type the listener expects them to be.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Type, function callback, and the listener&lt;/span&gt;
&lt;span class="n"&gt;event_listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EVENT_KEY_PRESSED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key_callback&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;input_state&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;Event&lt;/span&gt; &lt;span class="n"&gt;evnt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;              &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;EVENT_KEY_PRESSED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;key_pressed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;KEY_Q&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// This would be more automated&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt; 
&lt;span class="c1"&gt;// Event and dispatcher&lt;/span&gt;
&lt;span class="n"&gt;event_dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;evnt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;window_state&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, this event system, for the time being, is only used internally by the window system and the input system in order to communicate. I am planning to add a similar event system but to be used by the &lt;em&gt;user&lt;/em&gt; code instead. But that is in the future, and I like to live in the present. &lt;/p&gt;

&lt;p&gt;The input system uses the events extensively in order to communicate with the window. You see, in GLFW, there are two ways to query for input. You can use &lt;code&gt;glfwGetKey&lt;/code&gt; and check if the result is &lt;code&gt;GLFW_PRESS&lt;/code&gt; or &lt;code&gt;GLFW_RELEASE&lt;/code&gt;, depending on what you may want. The other way is to use the various callbacks GLFW provides you. The first method, while quite simple, is not efficient at all in this case. If I used it, I would have to go through a loop of some kind and check if there is a key that has been pressed &lt;em&gt;every frame&lt;/em&gt;. Awfully inefficient. And you know me, I'm all about efficiency. And so, I used the second method. &lt;/p&gt;

&lt;p&gt;In the function,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;NIKOLA_API&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;input_init&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the input system would &lt;em&gt;listen&lt;/em&gt; to various different input events, passing in the internal &lt;code&gt;InputState&lt;/code&gt; data structure of the &lt;code&gt;input.cpp&lt;/code&gt; translation unit in the process. The window system, for its part, would &lt;em&gt;dispatch&lt;/em&gt; any equivalent input events if any key was pressed or released, if the mouse was moved, if the mouse button was pressed or released, and so on. Using the callbacks provided by GLFW, of course. The same story would go for the joystick input events as well. &lt;/p&gt;

&lt;p&gt;I did all of that in order to disassociate the window from the input system completely. I did not want the end user to query for input while passing the window around everywhere. In theory, I would be asking for input from various places in the codebase. I do not know if they could reach the window at all. So, by doing it this way, I can at least be sure that the window and input system can communicate while keeping them effectively separated. It is like a long-distance relationship that is not quite meant to be.&lt;/p&gt;

&lt;p&gt;The input system provides some useful functions as well, of course:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;NIKOLA_API&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;input_key_pressed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Key&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;NIKOLA_API&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;input_key_released&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Key&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;NIKOLA_API&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;input_button_pressed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;MouseButton&lt;/span&gt; &lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;NIKOLA_API&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;input_button_released&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;MouseButton&lt;/span&gt; &lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;NIKOLA_API&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;input_gamepad_button_pressed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;JoystickID&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;GamepadButton&lt;/span&gt; &lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are plenty more functions, obviously, but these are some examples. The &lt;code&gt;Key&lt;/code&gt;, &lt;code&gt;MouseButton&lt;/code&gt;, and &lt;code&gt;GamepadButton&lt;/code&gt; enums are self-explanatory. They are just enums with all the valid keys/buttons that could be queried for. As for the &lt;code&gt;JoystickID&lt;/code&gt;, it is also an enum that goes through all of the possible ids for connected joystick controllers. It goes from 0 to 15, for 16 in total. It is quite standard.&lt;/p&gt;

&lt;p&gt;Now, internally, the input system keeps a data structure to hold both the previous state and the current state of every button. In the &lt;code&gt;InputState&lt;/code&gt; data structure, these states are arrays of &lt;code&gt;bool&lt;/code&gt;s. There are two states in particular: the &lt;em&gt;previous&lt;/em&gt; state and the &lt;em&gt;current&lt;/em&gt; state. The &lt;em&gt;current&lt;/em&gt; state is manipulated inside the event callbacks the &lt;code&gt;InputState&lt;/code&gt; provides to the event system. Depending on which key was pressed or released, we can turn the switch on or off for &lt;em&gt;that&lt;/em&gt; specific key. The values in the &lt;code&gt;Key&lt;/code&gt; enums are actually more akin to &lt;em&gt;indices&lt;/em&gt; that can be used in order to index into the &lt;em&gt;current&lt;/em&gt; state array. Very convenient. The same goes for the &lt;code&gt;MouseButton&lt;/code&gt; and &lt;code&gt;GamepadButton&lt;/code&gt; enums. &lt;/p&gt;

&lt;p&gt;Now, with functions like &lt;code&gt;input_key_down&lt;/code&gt;, we can just return the current state of the given &lt;code&gt;Key&lt;/code&gt;. However, with the function &lt;code&gt;input_key_pressed&lt;/code&gt;, we cannot simply do that. In the first function, we are effectively asking if the given &lt;code&gt;Key&lt;/code&gt; is &lt;em&gt;held down&lt;/em&gt; or not. While with the second function, we are asking if the given &lt;code&gt;Key&lt;/code&gt; has been &lt;em&gt;pressed before&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;For a more applicable example, think about shooting a gun in games. In that case, I want to query the input system to see if the key was &lt;em&gt;pressed&lt;/em&gt; before. Meaning, if, on the previous frame, it was released and on the current frame it was &lt;em&gt;just&lt;/em&gt; pressed. That way, I can fire the gun and then start a cool down. In the next frame, the button would be already pressed and, therefore, it is now being &lt;em&gt;held down&lt;/em&gt;, which does not interest me at the moment. If I were to, instead, check if the shoot key is being &lt;em&gt;held down&lt;/em&gt;, the behavior would not be controlled. These key presses happen almost instantly. There is not much control over that. &lt;/p&gt;

&lt;p&gt;But, on the other hand, let us say we are trying to move a player to the left or the right. If we were to use something like &lt;code&gt;input_key_pressed&lt;/code&gt;, we would have to press the key &lt;em&gt;every time&lt;/em&gt; we want to move the player even in an inch towards one direction (not the band). In that case, we can use &lt;code&gt;input_key_down&lt;/code&gt; to make the player consistently move in one direction. &lt;/p&gt;

&lt;p&gt;That is why the &lt;code&gt;InputState&lt;/code&gt; keeps track of a &lt;em&gt;previous&lt;/em&gt; state and a &lt;em&gt;current&lt;/em&gt; state. Every frame, internally, we update these states so that the &lt;em&gt;current&lt;/em&gt; becomes the &lt;em&gt;previous&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;I never said I could explain things easily. &lt;/p&gt;

&lt;h2&gt;
  
  
  Let's Bitshift Left Out Of Here
&lt;/h2&gt;

&lt;p&gt;Honestly, this part of the engine is not really all that fun. Interesting, perhaps. But not very fun. This section always bores me and I always just try to move on away from it. Nothing wrong with some nice logging and input handling, but there are way more fascinating parts of game engine development than these. I did not get into game engine development because I liked making event systems so much. Thankfully, however, the next part is &lt;em&gt;way&lt;/em&gt; more fun. Orders of magnitude more fun, actually. In the next article, we're going to talk about OpenGL, graphics APIs, and making a whole wrapper around OpenGL. Stay tuned. &lt;/p&gt;

&lt;p&gt;Thanks for reading and have a good day/night.&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>programming</category>
    </item>
    <item>
      <title>New Year, New Game Engine - Nikola Engine Devlog 0</title>
      <dc:creator>IWantToDeleteThisButICant</dc:creator>
      <pubDate>Wed, 26 Feb 2025 15:03:32 +0000</pubDate>
      <link>https://dev.to/mah_doh/new-year-new-engine-nikola-devlog-0-4ik</link>
      <guid>https://dev.to/mah_doh/new-year-new-engine-nikola-devlog-0-4ik</guid>
      <description>&lt;h2&gt;
  
  
  Me And Game Engines
&lt;/h2&gt;

&lt;p&gt;I made &lt;em&gt;so&lt;/em&gt; many game engines. Some were complex, others were simple, but all were horrible. &lt;/p&gt;

&lt;p&gt;These engines always lacked a greater focus and a more scalable model. While I do not care much for abstractions or planning big from the beginning, I do have to say that the engines I created in the past always had a lifetime of one use and then were immediately discarded. The general design of these engines was more "old-school" than anything. By that I mean, the engine itself was embedded into the game. Many of the engine's systems were soldered onto the die (the game in this case). There is a great &lt;a href="https://www.youtube.com/watch?v=mUeNqLcx4eI" rel="noopener noreferrer"&gt;talk&lt;/a&gt; by Bill Clark that goes in-depth about the differences between &lt;em&gt;an&lt;/em&gt; engine and a capital &lt;em&gt;A&lt;/em&gt; engine. Essentially, from my point of view, &lt;em&gt;an&lt;/em&gt; engine is just one that is built with the game itself. The engine is not a separate entity, but rather, it &lt;em&gt;is&lt;/em&gt; the game. While, on the other hand, a capital &lt;em&gt;A&lt;/em&gt; engine is your typical Unity, Unreal, and CryEngine (you thought I would say Godot, didn't you?). And, for the longest time, I built &lt;em&gt;an&lt;/em&gt; engine within a game. &lt;/p&gt;

&lt;p&gt;And why wouldn't I? I wanted to make a game, after all. And, perhaps, with the scale of the games I was making at the time, it worked. It did serve me well for a bit. However, as my ambitions grew to create games on a bigger scale, &lt;em&gt;an&lt;/em&gt; engine was not sufficient anymore. I could not just load &lt;em&gt;all&lt;/em&gt; of the resources that I would ever need in the game at initialization and keep them alive for the entire runtime of the game. My levels were bigger now. They had &lt;em&gt;way&lt;/em&gt; more resources. They could not simply live in memory all at once without problems. On top of that, I needed a better and more intuitive way of creating and prototyping levels. I could not just place all of the objects into the world programmatically. I had to find a serialization system of some sort, and one that would handle hundreds, if not, thousands of entities. Suffice it to say, &lt;em&gt;an&lt;/em&gt; engine had to leave and a new capital &lt;em&gt;A&lt;/em&gt; engine had to take its place. One that would ease the creation process of my games while still being "out of my way" enough not to annoy me. I'll get into more about that later.&lt;/p&gt;

&lt;p&gt;And, before &lt;em&gt;truly&lt;/em&gt; starting to work on the engine, I had to decide my goals, ambitions, and, most importantly, my &lt;em&gt;intentions&lt;/em&gt; with this engine. And, as you would come to know, my goals and ambitions with this engine are, quite frankly, fairly selfish. Well, let me back up a bit.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Intentions
&lt;/h2&gt;

&lt;p&gt;Previously, whenever I started a new game project, I would start &lt;em&gt;completely&lt;/em&gt; from scratch. From zero. I would not carry &lt;em&gt;any&lt;/em&gt; line of code from my previous projects. The reason is that I, simply, could not. The systems I "designed" at the time were very dependent on each other. Moreover, they were dependent on &lt;em&gt;specific&lt;/em&gt; data structures only created in &lt;em&gt;that&lt;/em&gt; game. While I could have perhaps changed some code around or written my systems to be game-agnostic from the beginning, I chose not to. You could call it inexperience since it was. I was constantly learning at the time. I would make a "renderer" only to find a better and more efficient way to make another renderer. I would make an entity system and then scrap it all because I wanted to experiment with another system. On top of that, I liked to switch genres all the time. Yet, if you go to my itch page (which I will not link out of shame), you can see that all my games are, ironically, one genre. Arcade-y games. It is not because I love arcade games so much. I would simply give up halfway through my original idea and decide to make an arcade-style game instead. The "engines" I made at the time were not thought through, as I have said before. They were lackluster at best. A mish-mash of different ideas and implementations that I had suddenly decided to add. But that was only a testament to my lack of experience and lack of patience. &lt;/p&gt;

&lt;p&gt;While I &lt;em&gt;could&lt;/em&gt; have used something like Godot or Unity, I did not really want to. I will not go into the reasons why I dislike game engines (&lt;a href="https://frodoalaska.github.io/2023-07-13-why-make-a-game-from-scratch/" rel="noopener noreferrer"&gt;because I already did&lt;/a&gt;) but just know that I dislike the GUI nature and the restricted workflow that all game engines seem to share. Understand, I am &lt;em&gt;not&lt;/em&gt; trying to bash on game engines. I think they are fantastic tools for game developers. However, they are certainly not for me.&lt;/p&gt;

&lt;p&gt;I believe that not all games are equal. Does every game have common components? Of course. That is quite obvious. However, not every game has the same &lt;em&gt;game creation&lt;/em&gt; flow. The flow of prototyping and creating levels for a racing game is not the same as for a real-time strategy game. They share &lt;em&gt;technical&lt;/em&gt; components, yes, but not &lt;em&gt;everything&lt;/em&gt; is the same. I think that lumping all games in a general sense might hurt experimentation and might hinder the innovation of game design. Many game studios end up creating specialized tools for their games anyway even if they are using an already-existing engine like Unreal. And so, after somewhat of a long-winded rant, my intention with this project is &lt;em&gt;not&lt;/em&gt; to create a general-purpose game engine. At the same time, as I said before, making &lt;em&gt;an&lt;/em&gt; engine with each game might, in the long run, be inefficient as well. So, what then? Well, let's take a trip down memory lane, shall we? There's no special hat for that, don't worry. Just hop in.&lt;/p&gt;

&lt;p&gt;You see, back in the day, developers used to &lt;em&gt;also&lt;/em&gt; start from scratch. Unlike me, their reason was more valid. The hardware scene at the time was rapidly changing. CPUs were getting stronger and faster every clock cycle (or what seemed like it, at least). Every new game &lt;em&gt;had&lt;/em&gt; to be rewritten since a new and better CPU entered the scene. Now, developers did not remove &lt;em&gt;every&lt;/em&gt; piece of code they wrote and start &lt;em&gt;literally&lt;/em&gt; from zero. Yet, &lt;em&gt;most&lt;/em&gt; of the code was thrown out and replaced with code that adhered to the newer CPU's architecture. Code that could, in some way, bend the CPU to the developer's will by using some exploit or some special feature the CPU had. Not all the code was like that, of course. &lt;/p&gt;

&lt;p&gt;But, as the growth and speed of CPUs started to plateau, developers started to keep their old tools and code to be reused. Every project now had a base to comfortably be built upon. Level editors, graphics tools and renderers, and even multiplayer code. Yet, these tools were never in one place. They were always separate programs that had some kind of output that would be fed into the game itself. The &lt;em&gt;game&lt;/em&gt; was the main hub these tools would output to. Compare this to game engines of today, where most of the tools are built &lt;em&gt;into&lt;/em&gt; the engine while the game is just a &lt;em&gt;result&lt;/em&gt; of all of these tools working together. The engine is like the main hub for everything. The overworld, if you will. The engine will import the assets, compress the textures, edit the world, handle all of the gameplay scripting, and do other things like create animations or particle effects. &lt;/p&gt;

&lt;p&gt;There is a reason for this--it is, simply, &lt;em&gt;much&lt;/em&gt; easier for everyone involved. But, it does come with drawbacks. Mainly, as I said before, it locks you into an ecosystem that you are &lt;em&gt;heavily&lt;/em&gt; relying upon. It somewhat limits you to what you can do. That is just not what I wanted to create. I wanted to create an engine to have all the basic &lt;em&gt;needs&lt;/em&gt; and the setup to get a game up and running, but I did &lt;em&gt;not&lt;/em&gt; want to limit any experimentation or any, perhaps, additional features or tweaks that can be made on the fly. I wanted the engine to be lightweight yet still have a robust set of features. I wanted the &lt;em&gt;game&lt;/em&gt; to be the central hub of everything and not the &lt;em&gt;engine&lt;/em&gt;. The engine is only there in the passenger seat, helping the game with directions rather than being the driver and ordering the game around. &lt;/p&gt;

&lt;p&gt;Now, of course, the game &lt;em&gt;still&lt;/em&gt; needed a set of tools to help speed up development. Level editors, for example, would have to be created. The meaning of a "level editor" differs from game to game. For an open-world RPG, that might mean a whole-world editor, while for a Mario-style game, that would mean a top-down 2D tile editor. Do understand that this is not &lt;em&gt;the&lt;/em&gt; perfect way of making a game. But, for my use cases, it might as well be. It allows me to reuse tools and code while still giving me the freedom to experiment with different ideas and genres. It does not limit my flow in any way. &lt;/p&gt;

&lt;p&gt;My intentions for this game engine are quite selfish now that I think about it. I do not care if other people use it or not. I do not care if it has the best and prettiest GUI editor. I do not want to use things like ECS (Entity Component System) for better entity management. I, frankly, only want to make this game engine for myself. I want to make games at the end of the day. But I want to make games the way &lt;em&gt;I&lt;/em&gt; like to make them. More work, yes, but also way more fun. &lt;/p&gt;

&lt;p&gt;The purposes for this engine's existence are a) Make it easier for my style of game development, b) Learn a great deal from the technical challenges, and c) A good show off for my portfolio. Of course. Why not?&lt;/p&gt;

&lt;p&gt;In order to capture my vision for this engine, however, I have to use the right tools for the job. I did not want to choose a tool that would end up wasting my time and energy while not benefiting my intentions with this engine whatsoever. And so...&lt;/p&gt;

&lt;h2&gt;
  
  
  The Tools And Dependencies
&lt;/h2&gt;

&lt;p&gt;You see, for the past several years I have used many programming languages and many more game frameworks and libraries. Programming languages like Java, C#, C++, and even, sadly, JavaScript (I know...). Game frameworks like &lt;a href="https://www.lwjgl.org/" rel="noopener noreferrer"&gt;LWJGL&lt;/a&gt;, &lt;a href="https://libsdl.org" rel="noopener noreferrer"&gt;SDL2&lt;/a&gt;, &lt;a href="https://raylib.com" rel="noopener noreferrer"&gt;Raylib&lt;/a&gt;, &lt;a href="https://monogame.net/" rel="noopener noreferrer"&gt;MonoGame&lt;/a&gt;, &lt;a href="https://www.sfml-dev.org/" rel="noopener noreferrer"&gt;SFML&lt;/a&gt;, and many more. Essentially, I have seen it all. Out of all of them, I think SDL2 was closer to what I was looking for, though, Raylib was the one I used the most at the beginning. And the reason I liked SDL more was because it was more"lower-level" than Raylib or SFML. Additionally, it had that C-style of programming that I have always been fond of. However, despite that, I decided to go &lt;em&gt;against&lt;/em&gt; any of these libraries. &lt;/p&gt;

&lt;p&gt;The one thing I &lt;em&gt;knew&lt;/em&gt; I wanted to do in this engine was to reduce the amount of dependencies as much as possible. I would not dare to go full &lt;a href="https://hero.handmade.network/" rel="noopener noreferrer"&gt;Handmade Hero&lt;/a&gt;-style, but I still wanted to use the minimum amount of required dependencies to get me started. I wanted the engine to be as lightweight as I could make it be. And while SDL does have a multitude of systems that would be beneficial for me, it still included a 2D renderer that I would for sure &lt;em&gt;never&lt;/em&gt; use. I wanted to design and implement my own renderer, and having a "ghost" dependency in there just felt wrong to me. Besides that, SDL had its own way of handling textures, fonts, and audio files. While useful, it was very much unnecessary for me. I had in mind to create my own resource binary format which would, essentially, deprecate any need for &lt;code&gt;.png&lt;/code&gt; files or the sort. Now, of course, I still need loaders to decode these image and audio files, but I already had a way better and smaller dependency for that in mind. &lt;/p&gt;

&lt;p&gt;So what did I use, then? Well, I separated the engine dependencies into five categories. The categories are laid out as such: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Operating System Dependencies&lt;/em&gt;: This is for things like window creation, input handling, the file system, console logging, and any operating system-specific operation &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Graphics&lt;/em&gt;: This is, as the name implies, anything to do with rendering and graphics. So the graphics API (OpenGL in this case), any UI libraries, and so on. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Audio&lt;/em&gt;: Obviously, it has anything to do with audio. Not &lt;em&gt;decoding&lt;/em&gt; or &lt;em&gt;encoding&lt;/em&gt;, but &lt;em&gt;playing&lt;/em&gt; audio by giving the audio card samples and having an audio thread active in the background.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Math&lt;/em&gt;: This might be a stretch but, besides the obvious math library, I also added physics dependencies in this category. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Resource Loaders&lt;/em&gt;: Image loaders, audio files decoders, 3D model format parsers, and so on.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Out of all of these, the first category--the operating system dependencies--is probably the one I thought about the most. Since SDL was out of the picture, I saw &lt;a href="https://github.com/glfw/glfw" rel="noopener noreferrer"&gt;GLFW&lt;/a&gt; as a potential choice for handling window creation and input. An obvious choice, by many. And, seeing how I already had used it before, I thought it was obvious to me as well. Yet, there was a feeling I did not need it. After all, I decided from the start that I would &lt;em&gt;only&lt;/em&gt; support Windows and Linux. Not for any particular reason other than I use Linux on a daily basis and Windows has the bigger market. I did not have a Mac machine lying around somewhere (poor. I'm poor, basically). And as for consoles, well, that was a long stretch. I did not see the possibility of me &lt;em&gt;ever&lt;/em&gt; needing to port my games to consoles. At least not for the time being. And so, that means I only had to deal with the Win32, X11, and Wayland APIs. I say it as though it is an easy affair. It is not. Far from it. Especially if you had never dealt with these APIs before and had to start learning them, which was my case. So, instead, I picked a middle ground. I would use GLFW but I would design my API in such a way that would be easier to switch away from it in the future if needed. I'll write a more in-depth article about the window system and whatnot in the future. &lt;/p&gt;

&lt;p&gt;As for the graphics, well, that was a point of contention, too. The only graphics API I &lt;em&gt;truly&lt;/em&gt; know by heart is OpenGL. I had used it plenty of times before so it would not be difficult for me to integrate it into the engine. Yet, like the case with GLFW, I was torn. OpenGL is not, well, the most &lt;em&gt;modern&lt;/em&gt; of graphics APIs out there at the moment. A better and more "modern" choice would, of course, be something like Vulkan. But Vulkan is a &lt;em&gt;big&lt;/em&gt; beast. One that would take quite a long time to deal with. And, frankly, I had the itch to make a game for a long time. I did not want to be held by Vulkan any longer. So, once again, I decided to find a middle ground. I would create a more robust and "open-ended" graphics API that would wrap around OpenGL so that I can, in the future, substitute it if needed. That was the intention at least. I did, briefly, try to integrate DirectX11 at some point, but I ultimately failed. Miserably, I might add. You can still see some remnants of my attempts at implementing DirectX11 in the engine, in fact. But, again, I will go more in-depth about that in a future article.&lt;/p&gt;

&lt;p&gt;Audio is another similar issue to graphics. There are plenty of audio APIs out there. Different APIs support different audio cards. I, however, had made up my mind on this one a long time ago. I decided to use &lt;a href="https://miniaud.io/" rel="noopener noreferrer"&gt;MiniAudio&lt;/a&gt;, which is the audio library used by Raylib under the hood and one that I used plenty of times before. It is a single-header library that is &lt;em&gt;super&lt;/em&gt; easy to integrate.&lt;/p&gt;

&lt;p&gt;As for math, that was the easiest choice as of yet. No doubt, &lt;a href="https://github.com/g-truc/glm" rel="noopener noreferrer"&gt;GLM&lt;/a&gt; is a "gold standard" at this point. For OpenGL it is, at least. But, like with a lot of the other APIs, I decided to build a wrapper around it rather than directly reference the library in the engine's code. And for physics, well, I had not come upon that answer just yet. I did try to make my own physics logic at some point. And while it was, surprisingly, successful, I wanted &lt;em&gt;more&lt;/em&gt; than just a simple physics layer. I wanted something more complex and, more importantly, &lt;em&gt;faster&lt;/em&gt; than my implementation. I have not decided upon a physics library yet. But I'll cross that bridge when I come to it. &lt;/p&gt;

&lt;p&gt;And, finally, resource loaders. I have worked with many resource loaders in the past. That's to say that I know my way around them. For image loaders, I decided to go with the obvious &lt;a href="https://nothings/stb" rel="noopener noreferrer"&gt;stb_image&lt;/a&gt;. It is small, easy to use, and has only a single header. Meaning, like MiniAudio, I can easily integrate it into the engine. Besides that, it supports a wide array of image formats. Even &lt;code&gt;HDR&lt;/code&gt; which was surprising. Audio file loaders are next. For this one, I decided to use a few small libraries. Specifically, the Mp3 and WAV loaders from &lt;a href="https://github.com/mackron/dr_libs" rel="noopener noreferrer"&gt;dr_libs&lt;/a&gt; and the OGG loader from STB once again (Sean Barret to the rescue!) Each of these are a single-header library as well. Once again, very small and very easy to integrate. As for 3D models, I decided to use a huge dependency named &lt;a href="https://github.com/assimp/assimp" rel="noopener noreferrer"&gt;ASSIMP&lt;/a&gt;. For me, that was a very hard sell. ASSIMP is &lt;em&gt;huge&lt;/em&gt; but it supports plenty of 3D model formats. And besides that, none of the resource loaders are going to be present in the engine itself. But, rather, there is going to be a separate tool--one that I dubbed NBR (Nikola Binary Resource)--that would take only the minimum required data from these loaders and save it into a binary file (&lt;code&gt;.nbr&lt;/code&gt;) which then would be read accordingly by the engine. &lt;/p&gt;

&lt;p&gt;If you think that's weird, well...&lt;/p&gt;

&lt;h2&gt;
  
  
  The Design
&lt;/h2&gt;

&lt;p&gt;In my dependencies talk earlier, I mentioned a lot of libraries that were "single-header". I'm sure you noticed I used a lot of them. But, what are they exactly? &lt;/p&gt;

&lt;p&gt;In the most simple of terms, a "single-header" library is what it sounds like: There is &lt;em&gt;only&lt;/em&gt; one header file (&lt;code&gt;.h&lt;/code&gt; or &lt;code&gt;.hpp&lt;/code&gt;) in the &lt;em&gt;whole&lt;/em&gt; project. These libraries also have their implementation code (&lt;code&gt;.c&lt;/code&gt; or &lt;code&gt;.cpp&lt;/code&gt;) in the header file itself. Usually, the implementation code is hidden behind a &lt;code&gt;#ifdef&lt;/code&gt;. So, in the case of &lt;code&gt;stb_image&lt;/code&gt;, you would create a translation unit (&lt;code&gt;.c&lt;/code&gt; or &lt;code&gt;.cpp&lt;/code&gt;...  you should know this by now) which only has the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;#define STB_IMAGE_IMPLEMENTATION 
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stb_image.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The implementation code would effectively be &lt;em&gt;copied&lt;/em&gt; into the translation unit and then compiled normally. I &lt;em&gt;love&lt;/em&gt; these kind of libraries. They are usually easy to use, very easy to integrate, and a lightweight dependency overall. I even created a &lt;a href="https://github.com/FrodoAlaska/Socrates.git" rel="noopener noreferrer"&gt;library&lt;/a&gt; or &lt;a href="https://github.com/FrodoAlaska/Ishtar.git" rel="noopener noreferrer"&gt;two&lt;/a&gt; in the same vain just for fun. But why am I talking about single-header libraries now? Besides the fact that &lt;em&gt;most&lt;/em&gt; of my dependencies are single-header, I wanted to &lt;em&gt;somewhat&lt;/em&gt; imitate the &lt;em&gt;spirit&lt;/em&gt; of single-header libraries while avoiding the need to jumble all my code into one header file. While it is convenient to have all the code in one place and, once again, it would be very easy to integrate by other folks, but, seeing how I am already an unorganized person, I will refrain from the complexity that comes with such a design. Instead, I wanted to have separate translation units for every module, but keep the idea of a single-header file for the &lt;em&gt;definitions&lt;/em&gt;. Let me explain. &lt;/p&gt;

&lt;p&gt;This engine really has three parts.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Core&lt;/em&gt;: This is the &lt;em&gt;base&lt;/em&gt; of the whole engine. This is where the window, input, and event-handling systems live. The graphics API wrapper exists here as well. The logger, the asserts, many core typedefs, and so on. It is more of a "game engine-maker" if you will. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Engine&lt;/em&gt;: This is where mostly all of the code that will be used directly by the user (me) lives. The entities, the scenes, the resource manager, the application callbacks, the camera, the renderer, and so on. &lt;/li&gt;
&lt;li&gt;
&lt;em&gt;UI&lt;/em&gt;: I have yet to make this part of the engine but it is essentially a wrapper around ImGui to handle the UI for any custom editors and such.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;For each part of the engine, there exists a &lt;code&gt;.hpp&lt;/code&gt; equivalent. There is a &lt;code&gt;nikola_core.hpp&lt;/code&gt;, a &lt;code&gt;nikola_engine.hpp&lt;/code&gt;, and a yet-to-be-created, &lt;code&gt;nikola_ui.hpp&lt;/code&gt;. The &lt;code&gt;nikola_engine.hpp&lt;/code&gt; depends on &lt;code&gt;nikola_core.hpp&lt;/code&gt;, and &lt;code&gt;nikola_ui.hpp&lt;/code&gt; depends on both. &lt;/p&gt;

&lt;p&gt;Now, the &lt;em&gt;great&lt;/em&gt; thing about this is that all the definitions of the project live in three places. I do not have to include &lt;em&gt;twenty&lt;/em&gt; or so header files in each translation unit when I want to do such a trivial thing as rendering a cube mesh for example. However, there are, as I came to discover, two very important cons to this approach. The first is the obvious &lt;em&gt;length&lt;/em&gt; (be mature, damn it) of these header files. For example, the &lt;code&gt;nikola_core.hpp&lt;/code&gt; header file alone is &lt;em&gt;2000&lt;/em&gt; lines of code. And there are &lt;em&gt;still&lt;/em&gt; features to be added to it. Yet, with some thorough documentation and some separator comments (one of these bad boys, &lt;code&gt;/// ----------------------&lt;/code&gt;), it could be managed pretty well. The main issue and the one that annoys me the &lt;em&gt;most&lt;/em&gt; is that if there is &lt;em&gt;any&lt;/em&gt; small change in any of the header files it means, potentially, a whole recompile of the engine. Now, the &lt;code&gt;nikola_core.hpp&lt;/code&gt; does not have any heavy dependencies that would require a long time to recompile (in fact, this is the only section of the engine that compiles surprisingly &lt;em&gt;fast&lt;/em&gt;). However, &lt;code&gt;nikola_engine.hpp&lt;/code&gt; &lt;em&gt;does&lt;/em&gt; have heavy dependencies. Specifically, since GLM is exclusively templated, the "engine" part of the project takes quite some time to compile. It isn't &lt;em&gt;slow&lt;/em&gt; by any means. But it is frustrating to change something in the renderer definitions only to have the whole math section be recompiled. Perhaps I could have handled it in a better way, but, honestly, I do not mind it. The ease of use this approach gives me is well worth the recompilations. And, besides, the header files are not often changed anyway. So I do not have to recompile &lt;em&gt;all&lt;/em&gt; the time.&lt;/p&gt;

&lt;p&gt;The other important design decision I had to make was with resources. As I talked about before, I created a custom binary resource format specifically for the engine to use instead of the so-called "middle-man" formats. Or, the PNGs, JPEGs, OGGs, and so on. It is quite a common practice in the game engine space to handle resources that way. It keeps the engine separated from any need for these formats while giving the engineers room to approve the load times and compression of these resources. Quake used its proprietary format &lt;code&gt;.mdl&lt;/code&gt; for model files. The Source Engine used the format &lt;code&gt;.vtf&lt;/code&gt; for handling textures. And, of course, every modern engine packages its resources in some way or another so that the runtime (the exported game, essentially) can use it as efficiently as possible. &lt;/p&gt;

&lt;p&gt;Now, I am not smart. Far from it. However, I decided to &lt;em&gt;also&lt;/em&gt; partake in this "tradition" and make my own resource binary format that will, in the future, be subject to better optimizations for loading at runtime. Of course, as discussed before, there is no "runtime" concept in my engine. The runtime in these engines usually means the final exported game. Well, in my case, the engine &lt;em&gt;is&lt;/em&gt; the game. So, effectively, I am always in runtime. So, I decided to make a small command line program to convert any given supported resources into the &lt;code&gt;.nbr&lt;/code&gt; format. Keep in mind, the engine does &lt;em&gt;not&lt;/em&gt; understand nor does it care about any other resource format. It can only parse and decode the &lt;code&gt;.nbr&lt;/code&gt; resource format. &lt;/p&gt;

&lt;p&gt;I will talk in-depth about the whole resource management system of my engine in a future article. But, for now, know that it is very primitive in its current state. I do not claim that &lt;code&gt;.nbr&lt;/code&gt; compresses files to seemingly nothing. In fact, &lt;code&gt;.nbr&lt;/code&gt; files do &lt;em&gt;no&lt;/em&gt; compressing whatsoever. But, it is a start. And, surprisingly, I have noticed better startup times whenever I'm loading &lt;code&gt;.nbr&lt;/code&gt; files as opposed to regular &lt;code&gt;.obj&lt;/code&gt; files for example. But, I would have to test that theory later in the future.&lt;/p&gt;

&lt;h2&gt;
  
  
  Current Progress And The Future
&lt;/h2&gt;

&lt;p&gt;So, where am I? And where am I going? &lt;/p&gt;

&lt;p&gt;Currently, as I'm sure you can tell, the engine is still in its infant state. It can do a lot. Currently, it can open a window, accept input, render pixels, load models, and images, and render them even. But there is still a &lt;em&gt;long&lt;/em&gt; way to go. For example, audio and fonts are still not fully implemented. While things like entities are not even a thing yet. However, if you are interested I do have some interesting showcases in the &lt;code&gt;projects&lt;/code&gt; section of this website. You can also go to the &lt;a href="https://github.com/FrodoAlaska/Nikola.git" rel="noopener noreferrer"&gt;engine&lt;/a&gt;'s repo to check the code for yourself if you are interested. &lt;/p&gt;

&lt;p&gt;It is hard to say what the future of this project is. I can say, though, that I am planning to stay with this engine for a &lt;em&gt;while&lt;/em&gt;. Once again, my intentions are fairly selfish when it comes to this engine. And, by extension, the planned future for this engine is quite selfish as well. While you can use the engine for your own projects, I will not advertise it as such. In fact, I will not advertise it at all. Show some interesting demos and progress reports here and there, sure. But I will not go out of my way to market this engine as a product. At the end of the day, I'm making this engine solely for my own enjoyment and based entirely on my own philosophies. And, naturally, not everyone will share these sentiments. &lt;/p&gt;

&lt;p&gt;Thanks for reading and have a good day/night&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>programming</category>
    </item>
    <item>
      <title>A Self-Taught Programmer's Take On Computer Science Degrees</title>
      <dc:creator>IWantToDeleteThisButICant</dc:creator>
      <pubDate>Mon, 10 Feb 2025 20:54:26 +0000</pubDate>
      <link>https://dev.to/mah_doh/a-self-taught-programmers-take-on-computer-science-degrees-i88</link>
      <guid>https://dev.to/mah_doh/a-self-taught-programmers-take-on-computer-science-degrees-i88</guid>
      <description>&lt;h2&gt;
  
  
  I Have Heard It All
&lt;/h2&gt;

&lt;p&gt;Throughout the few years that I have been part of the programming echo system, I have heard a great deal of discussion about computer science degrees. And although I don't see myself as a veteran who has seen it all, I do have to say that I might have heard it all. &lt;/p&gt;

&lt;p&gt;Sometimes, these discussions go on for hours on end, with both sides making strong &lt;em&gt;and&lt;/em&gt; weak arguments with the occasional death threats here and there. But that's the internet. You know how it is. I am by no means a professional. Neither am I a "good" programmer to any extent. However, I think I have a lot to say about this topic since I was directly affected by the lack of a computer science degree and, most importantly, a lack of mentorship. So, I will go in-depth on the pros and cons of both arguments. I will not advocate for one over the other. It is not my intention--neither should it be yours, in all honesty. I'm only here to give my two cents on the matter. &lt;/p&gt;

&lt;h2&gt;
  
  
  The Separation Between Degree And Education
&lt;/h2&gt;

&lt;p&gt;Whenever the topic of computer science degrees comes into fruition, whether it is good or useless, the argument always seems to stick to one point: The degree itself. While having a congratulatory paper forever cementing your efforts at staying awake for 4 years is a great cosmetic possession, it is a great misconception and a cunning lie. A lie that the student believes and takes to their heart that it is true. Well, what is this lie? The lie is that all will be good after this degree. The student believes that they will go out in the world prepared for any software problem they might encounter. Companies will be all over them, trying desperately to gain their attention because they have a piece of paper with their name on it. Some take it as a prideful endeavor. Something that makes them stand out among others. That argument, I do not and will never understand. &lt;/p&gt;

&lt;p&gt;You do not go to school for a piece of paper; you go to school to learn. While that does sound nice, it might not entirely be true. In some countries (like mine), that piece of paper is &lt;em&gt;the&lt;/em&gt; only way to get a job as a software engineer. It is not a question of &lt;em&gt;whether&lt;/em&gt; you should go to school or not, but rather, it is &lt;em&gt;when&lt;/em&gt; you should go to school. While that might not be the case in your country, it is true elsewhere. However, despite that, that piece of paper is of no use to you. To you, as a &lt;em&gt;programmer&lt;/em&gt;.  Will it get you a job? Perhaps it will improve your chances, yes. But it is not a guarantee. It is only a promise. A promise that you held near and dear to your heart, hoping it is true. In the current job market, this kind of plus is very much welcomed. But do you really want to spend 4 years of your life and flush thousands of dollars down the drain for a &lt;em&gt;maybe&lt;/em&gt;?&lt;/p&gt;

&lt;p&gt;You see, while a degree might help initially in your efforts to secure a job, it, by no means, will make you a better programmer. It will not give you magical programming powers that will turn you into John Carmack and give you a million-dollar idea. Once again, it is only a promise. There is nothing magical about a promise. What &lt;em&gt;will&lt;/em&gt; make you a better programmer, however, is &lt;em&gt;consistency&lt;/em&gt;. It is the key to achieving anything. It is the key to improving any skill. It sounds cliche, but if you do something long enough and hard enough, it will pay off... that did sound like a sexual joke, but I will not dig deeper into that. &lt;/p&gt;

&lt;p&gt;A degree will not give you consistency. A degree will not give you the will to learn and keep improving. A degree will certainly not give you all the solutions to your programming problems. And this is where I need to establish a separation between a &lt;em&gt;degree&lt;/em&gt; and &lt;em&gt;education&lt;/em&gt;. A degree is useless, yes, but the education is not. Education is the teachers, the students, the friends, the community, the environment, and anything in between. It is an experience that might very well be worth the effort and the money. Education is what matters, not the piece of paper you will attain at the end of your struggles. The books, the papers, the lectures, the assignments. All of these are valuable tools to a programmer at the onset of their journey. While, yes, the internet is riddled with &lt;em&gt;thousands&lt;/em&gt; of learning materials about programming and whatever else, it still will not be of use to you if you find it hard to focus and study. For some people--like myself--it might seem daunting and scary. A mountain so big, you can't even see the very top.&lt;/p&gt;

&lt;p&gt;In a way, completing a computer science degree is fueled by peer pressure. Perhaps you are financially strained, and spending money on a degree is a risk, so you are pressured--in a way--to finish it. Perhaps you have very hard-to-please parents, and you wish to make them proud. Perhaps you have friends who also go to the same school, and you don't want to be left out and fail. There are many reasons to feel pressured about this. However, it is in this pressure that a programmer in you is born. With the excess of learning material out there, it is sometimes very hard to find a path and stick to it. You would constantly ask yourself questions. Am I going down the right path? Am I doing the correct thing? Is this really how you would do it? What should I do next? Where should I go after this? Questions that, for a long time, might not have answers. With education, though, these questions might not exist at all. With education, it is like walking down an already-existing carved path neatly laid out for you. Without it, it is like carving &lt;em&gt;your&lt;/em&gt; own path that might or might not lead to a dead end. Besides, you are not pressured to finish--or even start--your own path. That might sound like a relief, but for some people, starting out might be the hardest thing to do. While with education, you don't need to think about &lt;em&gt;how&lt;/em&gt; to start. You just start. &lt;/p&gt;

&lt;p&gt;But carving out your own path sounds enticing, does it not? Adventurous. It feels like you are giving a middle finger to a system that has existed for hundreds of years and more... or it might not sound so exciting to you.&lt;/p&gt;

&lt;h2&gt;
  
  
  To Each Their Own
&lt;/h2&gt;

&lt;p&gt;School, by nature, is a collective system made to ensure an effective, easy, and cheap method to teach the masses. In the days of old, Socrates, Plato, and other great thinkers used to gather a big circle of young and old disciples eager to hear and learn from great philosophers. It is a public endeavor meant to teach everyone equally. And while that might have worked in the past, we as a society have shifted towards a more individualistic nature. One that adheres to a saying, "To each their own." For example, Sally might like to learn on campus together with her friends and fellow colleagues. She thrives in this environment. She seems to be more focused and enthralled by the material when she is present in that setting. On the other hand, Micheal hates the idea of learning with others. He likes to learn at his own pace in his room, with the lights dimmed and a song by Pantera playing in the background. Even though these two might have vastly different methods of studying, they are both, at the end of the day, achieving the same goals. They are both going down the same road but on different lanes. There is no right or wrong. &lt;/p&gt;

&lt;p&gt;Now let us say we decided that Micheal is wrong. His method is clearly terrible, and we should not let him study that way. Instead of leaving him be, we decide to force Mike to study like Sally. The "correct" way of studying. What will happen to Mike? Will he fall in love with Sally and go on to have a loving relationship that will last decades? No. Stop watching rom-coms. Rather, Mike will fail. He will not focus. He might even start to hate everything about the topic he studied. A topic he might have previously enjoyed and adored. &lt;/p&gt;

&lt;p&gt;Now, let us switch the roles. What if we forced Sally to study the same way Mike did? The result will be catastrophic. She will fail. She will hate everything about the topic. Just like Mike did. Maybe they can be lovers after all.&lt;/p&gt;

&lt;p&gt;There is no denying that schools have benefited our society in many ways throughout the centuries. Yet, we still cannot ignore the fact that it did and will fail many students who adhered to a more "unorthodox" method of studying, much like Mike. Schools force a certain style and path upon students, and they would just have to accept it. That might be fine for you if the style being forced is more akin to you. The same cannot be said for those who do not like that style. Even though a student might be very smart and passionate about computer science, they might very well find it difficult to pass through university. It is not necessarily because they are stupid or they do not have discipline, but rather, it is because they are students who like to learn at their own leisurely pace. They thrive when they are alone and confined to a "studying" space.&lt;/p&gt;

&lt;p&gt;However, it is illogical to think that schools should be modeled after these self-isolating students. Not only because they are the exception but also because you would be leaving out the students who do not conform to such a studying style; you would be making the same mistake except in the other direction. Besides, it is way cheaper to have schools that teach in a general style rather than a specific one. Once again, I am not trying to take sides here. To each their own. And even though I see myself more of a Mike, I do not condone or look down upon the Sallys out there. &lt;/p&gt;

&lt;p&gt;It is not the &lt;em&gt;way&lt;/em&gt; we study that matters, but it is the knowledge we attain that matters. If being a better programmer means you need to be more like Sally, Mike, or Gunther for all I care, then go ahead. So long as you focus on becoming a better &lt;em&gt;programmer&lt;/em&gt; and not a person with a degree, then go ahead. &lt;/p&gt;

&lt;h2&gt;
  
  
  I'm More Of A Mike
&lt;/h2&gt;

&lt;p&gt;The path I took was not out of rebellion. Instead, it was out of necessity. I did not have the money nor the support to go to a computer science school. I hail from a family of teachers and lawyers. We are scared of computers and anything that makes a &lt;em&gt;beep&lt;/em&gt; sound. And while my parents were supportive, they did not have the capital to support such an endeavor. So, I decided to try out for a short course that will teach me the basics of programming. Financially, it was a more viable option. The course was only 2 months long. It was only an introduction to programming. The teacher very briefly went over the components of a computer and then immediately moved to teach us basic C++ syntax as well as broader programming topics like variables, loops, conditional statements, and so on. When it was all said and done, it was a good course. I liked the teacher since he was very supportive of all of us. However, even though I enjoyed my time there, I cheated a bit since I knew a lot about programming even before attending the course. &lt;/p&gt;

&lt;p&gt;You see, I learned over time that I cannot feasibly focus on a topic unless I do it my own way. If you wanted to teach me something, then you would have to tell me the same thing over and over again until it sticks. And if it is a topic I do not care about, then good luck because &lt;em&gt;nothing&lt;/em&gt; is going to stick. Since I know of that, I thought I could dabble a bit on the basics of programming before the course starts. I enrolled in the course in June, and it was supposed to start in July. Meaning I had a whole month to feed myself as much programming information as I could so as not to look like an idiot when I attended. However, to my fortune or misfortune, the course kept getting delayed. In fact, it got delayed for 6 months. The course started in December rather than July. And, frankly, I forgot I was even enrolled in a course. But, throughout that time, I kept studying. Videos, books, and a multitude of useless Java projects. And when the course did finally start, I was equipped with knowledge that many of my peers did not have. I thought the course would be a bore. I already knew everything. What else could I possibly learn from an introduction to programming course? Well, I never said I was smart. &lt;/p&gt;

&lt;p&gt;I misspoke earlier when I told you I liked the teacher of this course. I, in fact, &lt;em&gt;love&lt;/em&gt; him. He instilled in me the confidence that I still carry with me to this day. He knew that I clearly had an idea of how to write code. And, to be honest with you, I was showing off more than I should have. So, instead of just ignoring me and focusing on the other students, he decided to give me special assignments that were harder. I would go back home, solve the problems he gave to the students, and then focus on the special assignments he tasked me to finish. In retrospect, those problems did not seem hard at all, but, at the time, they were almost impossible. Surprisingly, though, I solved them. Every single one of them. I would submit all the assignments to the teacher, he looked over them, praised me, and then gave me something even harder. I never felt more alive.&lt;/p&gt;

&lt;p&gt;Previously, on my initial 6 months journey, I was dismissive of any hard problem. If I encountered even the most simple of problems, I would turn away and leave. That might be more of a personality issue rather than a programming issue, but nonetheless, that was the case. Any problem I came across would be solved using StackOverflow or whatever came up on my &lt;a href="https://www.google.com/search?q=this+is+google+in+case+you+dont+know&amp;amp;oq=this+is+google+in+case+you+dont+know&amp;amp;gs_lcrp=EgZjaHJvbWUyBggAEEUYOTIGCAEQLhhA0gEINDc1OGowajGoAgCwAgA&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8" rel="noopener noreferrer"&gt;Google&lt;/a&gt; search. There was no AI at the time, but I would imagine that would have been used as well. However, with the pressure to perform and the enticing feeling of a challenge, that old way was all but gone. I would sit down with a pen and paper and scribble through the problem as I tried to implement it on my laptop. I felt like I unlocked a new way of thinking I did not know about previously. And it is all thanks to that teacher. &lt;/p&gt;

&lt;p&gt;I find myself thinking of the alternate reality where the course never started. I never met that teacher, and I never got that confidence or discovered that new way of thinking. Would I have been the same programmer as I am today? Would I have kept programming at all? I was never pressured by anything to start programming. It was my own volition, curiosity, and interest that got me started in the first place. Perhaps my interest would have dried up, and I would have just given up on it. I truly do not know.&lt;/p&gt;

&lt;p&gt;So, am I more of a Mike or a Sally? Frankly, I still think that I'm more of a Mike. I might very well &lt;em&gt;be&lt;/em&gt; Mike. Yet, I cannot just decline Sally's way of studying. It was clearly beneficial for me to be constantly challenged by that teacher. To be constantly pushed me towards a problem I could have just ignored otherwise. But, at the same time, that teacher was able to do such a thing because the course only had six students. He could focus on each one of us individually without actively hurting any of the students' performances. But I would assume that the same method would not have worked if it were in a class packed with tens of students.&lt;/p&gt;

&lt;p&gt;As I'm sure you noticed, I am very stubborn. It is either my way or no way. I prefer it most when I carve my own path. Not only is it more enjoyable for me, but it is also more beneficial. I hate the idea of ever following a certain curriculum and delivering on deadlines. I find that I work best when I'm on my own. Yet, I must admit, there are &lt;em&gt;many&lt;/em&gt; paths up this mountain top and I don't mind trying each just to see how it feels.  &lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution Is Not Here
&lt;/h2&gt;

&lt;p&gt;I am not a scholar. Neither am I a politician. I do not understand nor do I care about the intricacies of the ministry of education. My point here was not to find a solution. It never was. I just wanted to give you a fresh new perspective on a matter that I have seen discussed plenty of times. So if you came here hoping to find a solution, then, I'm sorry, the solution is not here. Despite that, I do have a suggestion. &lt;/p&gt;

&lt;p&gt;Even though software engineering is a vast topic with a web of complexities, the university should &lt;em&gt;not&lt;/em&gt; be the place where you learn &lt;em&gt;everything&lt;/em&gt; about programming. It should only provide a starter kit. It shouldn't spend a whole year on data structures. Data structures and algorithms are &lt;em&gt;very&lt;/em&gt; important tools in programming, yes, but even the most complex of algorithms can be taught in a few days. It takes a couple of months, perhaps, to get an idea of what they are and what are the most useful, but that is about it. Why spend more time learning about more data structures and algorithms when I can apply what I have learned already to projects I care about? Projects that I am passionate about. It is, I believe, a ridiculous matter to spend &lt;em&gt;4 years&lt;/em&gt; on a computer science degree. Perhaps it might take &lt;em&gt;you&lt;/em&gt; 4 years to learn everything. But remember, the university only serves the purpose of getting the engine started. It is not a tome that contains every piece of knowledge you will ever need to know. It is safe to say most of the things you will learn about in university will eventually fade away unless you put that knowledge to the test. The preservation of that knowledge and the improvement of your programming skills should be something &lt;em&gt;you&lt;/em&gt; need to work on. And therefore, I believe 4 years is just way too much. It takes &lt;em&gt;decades&lt;/em&gt; to become a good programmer, I agree, but it does &lt;em&gt;not&lt;/em&gt; take 4 years to learn the basics.&lt;/p&gt;

&lt;p&gt;But should you go to university? Should you get a computer science degree? Well, I don't know. All I can tell you is that I learned how to program on my own and make a decent living as a freelancer. If you do have the stable foundation to attend a computer science university, then do it. At least try your hand at it. Yet, if you lack that, then fear not, for there are many other paths to take. The path might be harder and less fine-grained, but it is available. Life will not end for you as a software engineer if you do not have a computer science degree, nor does that degree grant you magical powers. Still, like all things in life, it is not always black and white. &lt;/p&gt;

</description>
      <category>programming</category>
      <category>computerscience</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>The Case Against Realistic Graphics</title>
      <dc:creator>IWantToDeleteThisButICant</dc:creator>
      <pubDate>Mon, 03 Feb 2025 23:29:07 +0000</pubDate>
      <link>https://dev.to/mah_doh/the-case-against-realistic-graphics-1d8p</link>
      <guid>https://dev.to/mah_doh/the-case-against-realistic-graphics-1d8p</guid>
      <description>&lt;h2&gt;
  
  
  Let Me Explain
&lt;/h2&gt;

&lt;p&gt;In the past several years, the game industry has been solely focused on improving the visual aspect of games—a bold statement, perhaps, but a true one. If you go back to 15 years ago, you can see that the graphical capabilities of games have improved significantly. If you go back even further--say 5 years ago, the games look like they have been washed in a cloth that uses the bloom effect way too often. And if you go back even further than that, the games look almost unrecognizable. &lt;/p&gt;

&lt;p&gt;However, the gap between technological advancements seems to get smaller and smaller. Tighter and tighter. That's mainly because we have reached the limit or close to the limit of what our current machines can do. How can you possibly get better than realistic? Intergalactic? &lt;/p&gt;

&lt;p&gt;Despite that, AAA game companies seem like they don't get the memo. They keep trying to push ray tracing, realistic shadows, or shinier-looking boots onto an audience that clearly doesn't care. And while these technologies are fairly impressive in their own right and they do present amazing results, they ignore a very crucial part of what makes a game fun in the first place... the gameplay. It's in the name. You can't have a game without gameplay. If games were judged solely on their graphics, then the little red plumber we all know and love would have never made it past the beginning. The visuals are never the end all be all of any game. Instead, it is only a mask that is made by these larger companies to hide the fact that their games are a shallow, lifeless, cash grab that never had a chance to compete with others in the market were it not for their "extra crispy and realistic-looking sandwiches". &lt;/p&gt;

&lt;p&gt;Now there's no arguing that the visual aspect of a game is a selling point to some people. Yet, these game companies believe that it is &lt;em&gt;the&lt;/em&gt; only reason why people buy games in the first place. In fact, I would argue the "realism" of a game's graphics is always an afterthought. An extra plus people talk about after the gameplay, the story, the art, and/or the musical score. For example, take a look at this very happy and definitely real reviewer after buying the very famous game &lt;a href="https://www.google.com/search?q=I+was+talking+about+call+of+duty+by+the+way&amp;amp;oq=I+was+talking+about+call+of+duty+by+the+way&amp;amp;gs_lcrp=EgZjaHJvbWUyBggAEEUYOTIGCAEQLhhA0gEINzMxMmowajGoAgCwAgA&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8" rel="noopener noreferrer"&gt;People With Guns Fight Other People With Guns 2&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What a &lt;em&gt;great&lt;/em&gt; game. Fantastic story and I have a crush on the main character. How can I get in contact with her? Do you guys have like a number I can perhaps call? "&lt;br&gt;
    &amp;gt; "Some Weird Guy on Metacritic"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Well, that's not a real review but you get the point. &lt;/p&gt;

&lt;p&gt;There are several examples of games (both modern and old) that break this mantra of "realistic games are better." Games that have sold millions and continue to do so. So, let's take a look then, shall we?&lt;/p&gt;

&lt;h2&gt;
  
  
  Stylistic VS. Realistic
&lt;/h2&gt;

&lt;p&gt;In the past few years, there was a series of games that you might have heard of called &lt;em&gt;Call Of Duty&lt;/em&gt;. It is a &lt;em&gt;massive&lt;/em&gt; series and genre that has spanned two decades of games. Billions (yes &lt;em&gt;billions&lt;/em&gt;) of copies were sold across many of the games in the series. Some people started their careers and companies because of &lt;em&gt;Call Of Duty&lt;/em&gt;. And when you look at the graphical capabilities of these games (even at the time), it was always subpar at best. Sure, they didn't have the &lt;em&gt;worst&lt;/em&gt; visual aspect ever, but they didn't use the most "bleeding-edge" technology either. Still, people didn't care. &lt;/p&gt;

&lt;p&gt;Even though not as big as &lt;em&gt;Call Of Duty&lt;/em&gt;, &lt;em&gt;Minecraft&lt;/em&gt; was another monumental game from that same era. A game constructed from only cube meshes. The whole design and aesthetic of &lt;em&gt;Minecraft&lt;/em&gt; is the cube. Despite that, &lt;em&gt;Minecraft&lt;/em&gt; sold millions of copies and completely changed the course of the gaming market. &lt;/p&gt;

&lt;p&gt;If you &lt;em&gt;still&lt;/em&gt; don't believe me (come on, man), let's take a look at a recent example. That's right, &lt;em&gt;Fortnite&lt;/em&gt;. Even though I can't say that I enjoy &lt;em&gt;Fortnite&lt;/em&gt; as much as the masses seem to do, there is no denying that it was a monumental phenomenon that hit the gaming market with force. Does &lt;em&gt;Fortnite&lt;/em&gt; have advanced ray tracing algorithms that make everything look realistic and human-like? Well, no. That would take away from the stylistic look of the game. While &lt;em&gt;Fortnite&lt;/em&gt; does perhaps use ray tracing in some capacity,  the game has a cartoony visual representation of its characters and world. Unrealistic as it can get. And, yet, it's a game that sold and still sells millions of copies. &lt;/p&gt;

&lt;p&gt;I haven't even talked about the indie games yet. &lt;em&gt;Balatro&lt;/em&gt;, &lt;em&gt;Stardew Valley&lt;/em&gt;, &lt;em&gt;Lethal Company&lt;/em&gt;, and, of course, &lt;em&gt;Palworld&lt;/em&gt;. These games are inherently made with a unique stylistic look that gives the game identity. No one really talks about how realistic &lt;em&gt;Balatro&lt;/em&gt; looks or how cool it is to see the realistic gory details of &lt;em&gt;Palworld&lt;/em&gt;. Instead, people talk about the gameplay, the art style, the music, the story, the uniqueness. Realism has nothing to do with the success of these games. They didn't need it either. That's because they had something that many of the modern AAA games sadly lack: fun gameplay.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Tech Grind
&lt;/h2&gt;

&lt;p&gt;Games are really hard to make. Everyone knows that as a fact of game development. This is true now more than before. In the days of Quake and Doom, a 1-year development cycle was looked upon as a &lt;em&gt;long&lt;/em&gt; period of time to develop a game. Nowadays, games can easily be in a 6, 8, or even 10-year development cycle. It's normal to have such a long development time. That's in part because the demand for larger games has gotten... well, larger. Not only that, trying to make a game look "realistic" might take more time and effort than you might think. &lt;/p&gt;

&lt;p&gt;Some game studios might have a team whose only purpose is to handle the lighting in the game. Yes, that's it. That might &lt;em&gt;seem&lt;/em&gt; like a useless job, but, annoyingly, it is not. &lt;/p&gt;

&lt;p&gt;Since games are so large nowadays, many teams are created to handle different tasks. Despite the large number of people and teams working on a game, there might still be ground that can't be covered since there are already a lot of things to do. The 3D modelers might know how to set up lighting in the game, but they are too busy grinding on making the 1000th rock model that the player will trip on in level 36. The animators surely know how to handle lighting, right? Well, yes of course they do. But, they are too busy trying to make the dancing monkey on the main menu dance as realistically as possible. And the programmers, well... they're programmers. They barely know the difference between a circle and a cylinder. Therefore, a "lighting" artist makes sense. We do want the game to be realistic after all. &lt;/p&gt;

&lt;p&gt;However, that is not the only problem. "Realistic graphics" is an area of study that can take &lt;em&gt;years&lt;/em&gt; to master or even to get partially good at. Graphics are already hard as it is, trying to make it look realistic takes it to the next level. The graphics you see nowadays were thanks to the efforts of brilliant programmers and graphics engineers who spent years pounding their heads against the wall just to try and achieve such a look in an efficient and performant manner. It is no easy task to render &lt;em&gt;thousands&lt;/em&gt; of geometric elements on the screen with barely a noticeable frame rate drop. It is a &lt;em&gt;monumental&lt;/em&gt; achievement.&lt;/p&gt;

&lt;p&gt;Moreover, it is not so simple to just take the algorithms created by other graphics programmers and apply them to your game. The current state of graphics programming is a mess of graphics APIs that are specific to each platform. For example, OpenGL and DirectX (9 through 11) were used to render most of the graphics back in the day. These APIs are, however, not as popular nowadays since they don't support most of the modern features required by most games like ray tracing. Or, rather, they aren't &lt;em&gt;optimized&lt;/em&gt; to handle such tasks. That might not be necessary for you, but for AAA games that have &lt;em&gt;massive&lt;/em&gt; worlds, every drop of performance that can be milked from the operating system is more than welcomed. To address this problem, newer graphics APIs were created. Vulkan, DirectX12, and Metal. Why are there 3 graphics APIs rather than one? Well, capitalism, my friend. Not really. Each API is specific to a platform. DirectX12, for instance, works only with the Windows operating system and even Xbox. While Metal, the new kid on the block, works best with any new Apple product. And Vulkan, well, Vulkan works with everything... except not really. While you can use Vulkan to render graphics on Linux, the Nintendo Switch, and even Windows, it is usually best to use the API of the specific platform to squeeze every last drop of performance. And, again, for AAA studios, that is a requirement. &lt;/p&gt;

&lt;p&gt;Alright so that's the PCs but what about consoles, though? Well, those are a bit more complex. Each console has its own graphics API to communicate with the graphics chip of the console. While the Nintendo Switch did adapt Vulkan, Nintendo still has its own API that would be more efficient to use since it is designed precisely for Nintendo consoles. Sony has its own in-house API as well they use for the PlayStation consoles. And you get the point. &lt;/p&gt;

&lt;p&gt;On top of that, GPU vendors like NVIDIA and AMD don't give the programmers the &lt;em&gt;exact&lt;/em&gt; implementation of these graphics APIs. In fact, the "APIs" are actually just specifications. Guidelines the programmers are expected to adhere to. This makes it difficult for programmers since some algorithms might work very well on NVIDIA GPUs but not so well on AMD GPUs. Put all of that together and you get a nested web of complexities and unnecessary bloat that plagues the current state of graphics programming.&lt;/p&gt;

&lt;h2&gt;
  
  
  Not Always Black And White
&lt;/h2&gt;

&lt;p&gt;Listen, I'm not trying to undermine the immense efforts of the genius engineers who worked tirelessly in order to produce such beautiful graphics. The efforts are much appreciated, as they also have contributed to making games faster. However, my problem is with the overuse of these realistic graphics and the weird obsession the industry has with them. In a way, it almost relinquishes the efforts of these engineers since it just became the "norm" to add realistic graphics to every game. &lt;/p&gt;

&lt;p&gt;I'm not suggesting completely stopping the advances of the graphics sector and firing all of the graphics programmers from every game studio out there. The opposite, in fact. Any technological advancement is a great achievement. Besides, while games are not &lt;em&gt;strictly&lt;/em&gt; a graphics medium, other industries are. The animation industry and the movie industry use graphics for various tasks. And for these industries, graphics matter &lt;em&gt;way&lt;/em&gt; more than it does in game development. &lt;/p&gt;

&lt;p&gt;Instead, I suggest we shift our attention even for a little bit into other facets of game development that could perhaps largely benefit from the same effort, manpower, and money that is poured into graphics. Physics, audio, AI, procedural generation, or even discovering a new genre for games. Many of these areas have little or no care put into them by the game industry as much as graphics. If anything, I believe many of these areas are barely developed. Even if there were amazing advances in those areas of game development, you and I would have not known about them since no one talks about or even considers them. Even though there are engineers who are as smart and as hard-working as the ones in the graphics field. Sure AI is a growing market, but not &lt;em&gt;game&lt;/em&gt; AI. The AI in games has been at a plateau for many years. It's usually the same look, shoot, die, and repeat. Some games do have some nice and advanced AI but they are so far and in between they might as well be invisible. &lt;/p&gt;

&lt;p&gt;So many talented people pour hours and even &lt;em&gt;years&lt;/em&gt; just to make games more fun. Why? Because they like it! Instead of using these people to move the needle forward, we instruct them to watch very pretty and realistic paint dry with promises that in the next 10 years, it will dry 20% faster.&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>programming</category>
      <category>graphics</category>
    </item>
    <item>
      <title>I Made My Own Standard Template Library</title>
      <dc:creator>IWantToDeleteThisButICant</dc:creator>
      <pubDate>Tue, 12 Nov 2024 21:10:19 +0000</pubDate>
      <link>https://dev.to/mah_doh/i-made-my-own-standard-template-library-45m9</link>
      <guid>https://dev.to/mah_doh/i-made-my-own-standard-template-library-45m9</guid>
      <description>&lt;p&gt;Check out the library if you're interested: &lt;a href="https://github.com/FrodoAlaska/Ishtar" rel="noopener noreferrer"&gt;Ishtar&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  The Story Of Steve
&lt;/h1&gt;

&lt;p&gt;Once upon a time, there was a man named Steve. Steve--like many of us--was a programmer. He specifically programmed in the lord's language C++. He was obsessed with C++, in fact. He woke up every day just to kiss a photo of Bjarne's very shiny scalp. Now even though I like to take it up the ass (as some would say), I still think that's kind of homo not gonna lie. However, that was all to change. One day Steve was programming in his favorite language, and his curiosity took over him. He was using the best-named container of all time &lt;code&gt;std::vector&lt;/code&gt;. He wanted to know what the &lt;code&gt;push_back&lt;/code&gt; function &lt;em&gt;actually&lt;/em&gt; did. And even though his mind was telling him no, his body, was indeed, telling him hell yeah. And, since Steve is a genius and used the best editor to ever exist NeoVim, he went to see the definition of the &lt;code&gt;push_back&lt;/code&gt; function... what followed was a cry for help. &lt;/p&gt;

&lt;p&gt;Steve was not the same after that. He was devastated. Beaten. He felt betrayed. On a rainy and dark day, Steve decided to end it all. He brought a buffer of memory with him to the park. He found a nice tree and... thankfully, the memory was segmented and he survived... so anyways, I replaced C++'s horrendous Standard Template Library. &lt;/p&gt;

&lt;h1&gt;
  
  
  But Why?
&lt;/h1&gt;

&lt;p&gt;Now if you're an intellectual like myself, you'd probably be asking, "Why do this?". Well my dear... ah... dude, there are a few reasons that I decided to jump into this venture. I have 3 reasons in particular for starting this project. &lt;/p&gt;

&lt;p&gt;The first is that I think this is &lt;em&gt;extremely&lt;/em&gt; fun and interesting. I learned programming because it's fun in the first place. It piqued my interest and gave me an unbelievable sense of enjoyment. Yes, even more than sleeping with your mom. So, why not keep on that tradition and make projects that I find enjoyable and intriguing? And also, tell your mom to call me back. I didn't mean to call her fat. &lt;/p&gt;

&lt;p&gt;The second reason is that I think doing such a thing is a &lt;em&gt;great&lt;/em&gt; learning experience overall. Even though this library of mine is not efficient or performant by any means, I still think that it gave more appreciation and knowledge when it comes to data structures. I'm not oblivious to what the function &lt;code&gt;insert&lt;/code&gt; does on a &lt;code&gt;std::unordered_map&lt;/code&gt;. I know the costs of calling that function. I know how to make that function faster. Now, of course, every library has a different implementation of these data structures. Though, still, at least I have an idea of &lt;em&gt;how&lt;/em&gt; this might be implemented. &lt;/p&gt;

&lt;p&gt;The third and final reason is control. I love to control every byte of memory that is given to me by my computer. I vied to control every piece of data ever since I can remember. I want to control the world and the people and make them do... oh wait. No sorry. Wrong script. Excuse me. &lt;/p&gt;

&lt;h1&gt;
  
  
  The Rules
&lt;/h1&gt;

&lt;p&gt;So before I get into my beautiful piece of code, I need to go over the rules and the inspiration of this library. I decided to set a few small rules for &lt;em&gt;thyself&lt;/em&gt; before starting this library. Essentially I was not to use &lt;em&gt;any&lt;/em&gt; piece of code from the standard template library. So no &lt;code&gt;std::string&lt;/code&gt;, no &lt;code&gt;std::array&lt;/code&gt;, no &lt;code&gt;aids::uh_uh_ah_push_into_butt&lt;/code&gt;, and so on. Any of the code of the data structures that will be implemented will be &lt;em&gt;my&lt;/em&gt; code and only my code. Now, I did permit myself to use things like &lt;code&gt;malloc&lt;/code&gt;, &lt;code&gt;free&lt;/code&gt;, &lt;code&gt;realloc&lt;/code&gt;, &lt;code&gt;memcpy&lt;/code&gt;, and so on. However, those are mandatory at this point since I &lt;em&gt;will&lt;/em&gt; need to allocate memory and I can't do that... unless I write my own operating system. And no that would be silly. I would never do that. Hey, google, how do I go to Finland? &lt;/p&gt;

&lt;h1&gt;
  
  
  Inspirations And Architecture
&lt;/h1&gt;

&lt;p&gt;Now another thing we'll need to talk about is the architecture of this library. Even though I can go all &lt;code&gt;boost&lt;/code&gt; style with this library and make &lt;code&gt;dlls&lt;/code&gt; that are the size of your mom's left elbow, I will refrain from that. Instead, I'll take inspiration from the &lt;code&gt;stb_&lt;/code&gt; collection of libraries. If you don't know, the &lt;code&gt;stb_&lt;/code&gt; libraries are single-file-only libraries. Meaning, you don't have to link them or take cocaine in order to use them. All you have to do is copy the header file, make a &lt;code&gt;.cpp&lt;/code&gt; or &lt;code&gt;.c&lt;/code&gt; equivalent put this definition before the include statement &lt;code&gt;STB_IMAGE_IMPLEMENTATION&lt;/code&gt;, make sure to build that translation unit with your project, and voila. You're using the library now. Obviously, there might be some cons with this approach but I think it's the simplest and most headache-free solution to the mess that is the C++ dependency hell. Now, by default, my library will be templated, meaning I'll be forced to use a header file-only approach anyway. However, not &lt;em&gt;everything&lt;/em&gt; in the library is going to be templated and we'll see that shortly. So, in the name of simplicity and ease of use, I'll be going with the &lt;code&gt;stb_&lt;/code&gt; single-file approach. &lt;/p&gt;

&lt;p&gt;Okay, so, without further ado, let's get riiiiiight into the code... here's a formal letter of apology for that. I'm very sorry.&lt;/p&gt;

&lt;h1&gt;
  
  
  Lists
&lt;/h1&gt;

&lt;p&gt;The simplest kind of data structure is the &lt;code&gt;Linked List&lt;/code&gt;. It is probably the most primitive of data structures. If you ever want to learn a programming language, linked lists are probably the first thing you'll implement since it's very simple. They aren't really hard to understand either. It is just a series of nodes that are connected via links--or pointers in this case. A list of linked nodes. Linked list. Now, there are two types of linked lists: Singly linked and doubly linked. Singly-linked lists mean that each node is only connected to the node next to it. While--as you would have guessed--in a doubly linked list, a node is connected to the next &lt;em&gt;and&lt;/em&gt; previous node to it. Here's how I implemented nodes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typename&lt;/span&gt; &lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Node&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;public:&lt;/span&gt;
    &lt;span class="n"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Node&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;*&lt;/span&gt; &lt;span class="n"&gt;next&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;nullptr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Node&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;*&lt;/span&gt; &lt;span class="n"&gt;previous&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;nullptr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;value&lt;/span&gt;          &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;previous&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;previous&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
    &lt;span class="n"&gt;Node&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;*&lt;/span&gt; &lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;Node&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;*&lt;/span&gt; &lt;span class="n"&gt;previous&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, each node has a &lt;code&gt;next&lt;/code&gt; and &lt;code&gt;previous&lt;/code&gt; pointer. Now, even though a linked list is easy to conceptualize, it is &lt;em&gt;very&lt;/em&gt; annoying to implement. Not because it is difficult, no. Because there are so many small edge cases that you have to account for. Still, they aren't very hard to implement even then. &lt;/p&gt;

&lt;p&gt;There are some basic operations a linked list has. Like &lt;code&gt;append&lt;/code&gt; which pushes to the back of the list, &lt;code&gt;prepend&lt;/code&gt; which pushes to the front of the array, &lt;code&gt;pop_back&lt;/code&gt;, and &lt;code&gt;pop_front&lt;/code&gt; which &lt;em&gt;removes&lt;/em&gt; a node either from the front or the back of the list. Believe me, I can make a lot of sexual jokes here but I won't because I'm a changed person now. There are other operations obviously like 'remove', &lt;code&gt;insert&lt;/code&gt; (I'm a changed person now), and &lt;code&gt;get_at&lt;/code&gt; which are all self-explanatory.&lt;/p&gt;

&lt;p&gt;Here's how these roughly look in the library:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;    &lt;span class="n"&gt;Node&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;*&lt;/span&gt; &lt;span class="nf"&gt;get_at&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;sizei&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Node&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;*&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;prepend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Node&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;*&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Node&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;*&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Node&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;*&lt;/span&gt; &lt;span class="n"&gt;prev&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Node&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;*&lt;/span&gt; &lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Node&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;*&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;remove_at&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;sizei&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are also &lt;code&gt;emplace_&lt;/code&gt; operations as well which are equivalent to the &lt;code&gt;append&lt;/code&gt; and &lt;code&gt;prepend&lt;/code&gt; operations except that they take in a value of type &lt;code&gt;T&lt;/code&gt; instead of a &lt;code&gt;Node&lt;/code&gt; structure.&lt;/p&gt;

&lt;p&gt;Now, the next two data structures are essentially just linked lists but with constraints. &lt;/p&gt;

&lt;p&gt;Oh and here's a fun fact, the doom engine used a linked list to link the menu scenes in the game together. You know, just a cool fact from a pretty cool guy I would say. &lt;/p&gt;

&lt;p&gt;Here's a working example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;ishtar&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;LinkedList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// First default value for the head&lt;/span&gt;

&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;emplace_back&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Pushes the value '42' to the tail&lt;/span&gt;
&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;emplace_front&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;69&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Pushes the value '69' to the head &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Queues
&lt;/h1&gt;

&lt;p&gt;Imagine you're at the only operational toilet in a Billie Eilish concert. You stand in line, trying to hold in your poop and wonder why you ate that obviously suspicious-looking burrito earlier. In that situation, the first person in the line will go to the toilet, use it, and then leave. The person behind them will be next in line so they go to the toilet, use it, and then leave. This is what we, definitely big pp programmers call a &lt;code&gt;queue&lt;/code&gt;. And queues are a "FIFO" or a First In First Out data structure. &lt;/p&gt;

&lt;p&gt;Queues have two very useful operations: &lt;code&gt;pop&lt;/code&gt; and &lt;code&gt;push&lt;/code&gt;. Other programmers call them differently. But I'm not like other programmers. I'm extremely in debt. &lt;/p&gt;

&lt;p&gt;When we &lt;em&gt;push&lt;/em&gt; to a queue, we push to the back. When we &lt;em&gt;pop&lt;/em&gt;, we pop from the front. Pretty simple. But don't let their simplicity fool you. Queues are a &lt;em&gt;very&lt;/em&gt; powerful data structure that was implemented in &lt;em&gt;so&lt;/em&gt; many applications at this point.&lt;/p&gt;

&lt;p&gt;Here's an example of an event Queue in action:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;ishtar&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Queue&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;EventType&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;event_queue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;event_queue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;emplace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EVENT_KEY_PRESSED&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;event_queue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;emplace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EVENT_KEY_RELEASED&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="n"&gt;event_queue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;emplace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EVENT_APP_QUIT&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;event_queue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;emplace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EVENT_WINDOW_RESIZED&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;event_queue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pop&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Will pop `EVENT_KEY_PRESSED`  &lt;/span&gt;

&lt;span class="n"&gt;event_queue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pop&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Will pop `EVENT_KEY_RELEASED`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Stacks
&lt;/h1&gt;

&lt;p&gt;Something similar to a Queue is the &lt;code&gt;Stack&lt;/code&gt;. Stacks are the opposite of queues. They are a "LIFO" or a Last In First Out data structure. Imagine if you were a loser dweeb (which you are) who had a lot of anime pillowcases. Since you're a degenerate, you &lt;em&gt;finally&lt;/em&gt; decided to wash these cases that you have definitely slept on and nothing else. You put the first case down and then the second on top of it and then the third on top of that. Now, since you were dropped on your head as a kid and barely use your brain, you sit and think about how you can take out the pillowcases one by one to wash them. "Aha", you exclaim. "I'll just take the last one I placed and remove it from the stack". You &lt;em&gt;definitely&lt;/em&gt; need some help. I don't even know how you're still alive. But yes. That's what we call a &lt;code&gt;Stack&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Much like a queue, the stack also has the &lt;code&gt;push&lt;/code&gt; and &lt;code&gt;pop&lt;/code&gt; operations. However, this time, when we &lt;em&gt;pop&lt;/em&gt; from the stack, we'll pop from the back and not the front. Pushing is still the same. &lt;/p&gt;

&lt;p&gt;Here's a simple example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;ishtar&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Stack&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;num_stack&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 

&lt;span class="n"&gt;num_stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;emplace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;101&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;num_stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;emplace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;202&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;num_stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;emplace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;303&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;num_stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;emplace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;num_stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pop&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Will pop '404'&lt;/span&gt;
&lt;span class="n"&gt;num_stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pop&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Will pop '303'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Dynamic Arrays
&lt;/h1&gt;

&lt;p&gt;If I had to name two of the greatest inventions known to men (and women, too), I would immediately name sandwiches and &lt;code&gt;Dynamic Arrays&lt;/code&gt;. Mostly sandwiches, though. &lt;/p&gt;

&lt;p&gt;Unlike you're ever-mounting depression, regular arrays are fixed-size. They can't grow any larger than the initially agreed-upon size. In fact, it is illegal to go past that point. You'll get a segmentation fault and probably a slap on the face by me. However, there are many instances where the size of the array is not known priori. And yes, I did use a fancy word there. And so, dynamic arrays were invented... in some guy's moldy dungeon probably.&lt;/p&gt;

&lt;p&gt;The basic idea of dynamic arrays, or if you're retarded, &lt;code&gt;std::vector&lt;/code&gt;, is that they grow as the elements are pushed into them. Dynamic arrays have two very important properties: size and capacity. The size (or more like the count) signifies the number of elements in the array currently. While capacity is the... ah... well, capacity of the array. The number of elements the array can hold before it needs to allocate more memory essentially.&lt;/p&gt;

&lt;p&gt;Now in the default constructor of my dynamic array, the size gets set to 0 and the capacity gets set to 5. This means the array will need to have 5 elements before it can be resized again.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;ishtar&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;DynamicArray&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Default constructor will have a capacity of 5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And this is where &lt;em&gt;truly&lt;/em&gt; understanding data structure makes you a better programmer. Say you decide to push 5 elements into the array. When the array sees that the size is now equal to the capacity, it will grow the array by half the current size of the array. Meaning, that it will grow by 2 since this will be an &lt;code&gt;int&lt;/code&gt; and we'll ignore the decimal part. Now our capacity is 7. But then you push 2 extra elements which means the array has to grow again. You can see how this can be very terrible on performance. Allocating memory is not as easy as watching that hentai that you kids watch nowadays. Back in my day, we watched real porn. Like gay porn.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Must grow the array if the size is greater than the capacity &lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;capacity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Re-allocate the buffer of data by the new capacity&lt;/span&gt;
      &lt;span class="n"&gt;capacity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;realloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;capacity&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So what would you do? Simple. There is another kind of constructor the dynamic array has. One that takes in an initial capacity. You don't have to set this initial capacity to a big number. But you just set it to something respectfully sizeable so that you don't have to allocate memory and move the pointers all the time.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;ishtar&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;DynamicArray&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// The array's initial capacity will be '24'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are many operations that a dynamic array possesses. They include but are not limited to &lt;code&gt;push_back' and&lt;/code&gt;push_front', 'pop_front' and 'pop_back', &lt;code&gt;remove&lt;/code&gt;, &lt;code&gt;insert&lt;/code&gt;, &lt;code&gt;slice&lt;/code&gt;, and many more. &lt;/p&gt;

&lt;p&gt;The most expensive operation out of all of these is probably the &lt;code&gt;remove&lt;/code&gt; and &lt;code&gt;insert&lt;/code&gt; functions. Since they do require to shuffle the whole array in order to account for the change in elements. And again, I would have never known the &lt;em&gt;true&lt;/em&gt; precautions of such operations until I implemented them myself.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;ishtar&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;DynamicArray&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reserve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// Reserves 50 elements in the array. This is an alternative to passing an initial capacity to the constructor&lt;/span&gt;

&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;

  &lt;span class="c1"&gt;// We can also take a slice of the array and copy it to another array&lt;/span&gt;
&lt;span class="n"&gt;isthar&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;DynamicArray&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;slice_arr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Slice from the first index till the 4th index inclusive. &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Strings
&lt;/h1&gt;

&lt;p&gt;Strings are probably the most complicated data structure out there. In theory, it is simple. An array of characters that you can push into. Essentially a dynamic array of &lt;code&gt;chars&lt;/code&gt;. However, it's not so simple. There are so many operations associated with strings. Not to mention they can potentially be very large and therefore expensive to operate on. A simple comparison of two strings can, potentially, be &lt;em&gt;very&lt;/em&gt; expensive. I haven't even talked about localization. Where you'll need to account for various languages with different writing styles and notations. &lt;/p&gt;

&lt;p&gt;In general, there are a few types of strings. And they all are concerned with the size of each character in a string. For instance, a UTF-8 string can only hold 8 bits per character. And it doesn't take a bald genius with glasses to know that 8 bits is not big. However, UTF-8 strings are still sufficient enough for European languages and English of course. There are also UTF-16 and UTF-32 strings. Obviously, each holds either 16 bits or 32 bits per character in a string.&lt;/p&gt;

&lt;p&gt;Despite having a wide array of choices (huh array), I decided to use what's known as "ASCII" or Unicode strings. Which can &lt;em&gt;only&lt;/em&gt; support the English language. And, unless you're some guy from Montana, that's not gonna suffice. However, for the sake of my sanity, I decided to use ASCII strings for now with plans to implement UTF-8, UTF-16, and UTF-32 in the future. Hopefully. If I don't get blown by that guy from Montana.&lt;/p&gt;

&lt;p&gt;Besides the complexity of localization, strings also hold a massive arsenal of operations. Even larger of an arsenal than the arsenal of guns that guy from Montana has. Things like &lt;code&gt;reverse&lt;/code&gt;, &lt;code&gt;append&lt;/code&gt;, &lt;code&gt;find&lt;/code&gt;, &lt;code&gt;replace&lt;/code&gt;, &lt;code&gt;equality&lt;/code&gt;, and so much more. You can do infinite things with strings. I just touched the surface. &lt;/p&gt;

&lt;p&gt;Now, strings are actually the only data structure in the library that isn't templated. It is just a simple class with two properties: length and data. I &lt;em&gt;could&lt;/em&gt; have made it a template class, but I didn't see any benefit from that so I decided to keep it simple. &lt;/p&gt;

&lt;p&gt;You should expect these at this point:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;ishtar&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;str1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"hello"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Implicit constructor&lt;/span&gt;
&lt;span class="n"&gt;ishtar&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;str2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;", world"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// We can append the strings together&lt;/span&gt;
&lt;span class="n"&gt;str1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Wow, how original&lt;/span&gt;
&lt;span class="n"&gt;ishtar&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;palindrome&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"racecar :emordnilap"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;palindrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reverse&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Speaking of length, the strings in this library are length-based and not null-terminated. You see, in C ("see" what I did there. Okay), each string has a "null" character (which is just a 0) appended to it. That's how the compiler will know &lt;em&gt;where&lt;/em&gt; the string ends. However, that is a stupid approach. Why? Because... fu.. ah... fuck you. So, instead, I went with the length approach. We don't have to go through the entire string until we find a null-terminator character. We can just store the length of the string right there in the data structure. This obviously has a lot of performance benefits since I don't have to calculate the length of the string &lt;em&gt;every time&lt;/em&gt; I need to do something with it. I can just recall it immediately.&lt;/p&gt;

&lt;p&gt;I don't necessarily like my approach as I still use &lt;code&gt;strlen&lt;/code&gt; to calculate the length of my string on &lt;em&gt;some&lt;/em&gt; occasions. However, it will do for now. I never claimed this is the best library ever. So leave me alone. Now wait. Don't leave me alone. I was just joking come on.&lt;/p&gt;

&lt;h1&gt;
  
  
  Hash Tables
&lt;/h1&gt;

&lt;p&gt;Now, this is probably my favorite data structure ever. It's so useful for many different reasons. I have used it plenty of times and it never let me down. Unlike you. You always let me down. &lt;/p&gt;

&lt;p&gt;Hash tables work in a very magical way. They use a key-value pair to store each entry. Meaning, that in order to access any value in the table, you'll need to use its key. So essentially it's like indexing into an array except you can use any kind of primitive data types as indices, not just &lt;code&gt;int&lt;/code&gt;s. This works by using a process called &lt;code&gt;hashing&lt;/code&gt;. You basically scramble the key into an integer that can then be "modded" (&lt;code&gt;%&lt;/code&gt;) with the size of the table to retrieve the index of the value in the array. You can, for example, use strings. This is, in fact, how many game engines create their resource managers. Or how YouTube stores its users. Everything is a hash table. Seriously. You're a hash table right now. So it's very useful to know them. &lt;/p&gt;

&lt;p&gt;Hash tables are also &lt;em&gt;extremely&lt;/em&gt; efficient. Their access time is almost as close as a regular array. Which is constant time. Which is, like, &lt;em&gt;extremely&lt;/em&gt; fathst. Now I say "almost as" because access time on hash tables is not &lt;em&gt;always&lt;/em&gt; constant and I'll get into that in a bit.&lt;/p&gt;

&lt;p&gt;So, before we start looking at the implementation of the hash table, we need to start talking about hash functions. Now there are so many hashing functions out there. But, we only care about the hash functions that are a) fast and b) deterministic. Fast as in they should never be the bottleneck. They should be &lt;em&gt;lighting&lt;/em&gt; fast. And deterministic as in they should always produce the &lt;em&gt;same&lt;/em&gt; output &lt;em&gt;every time&lt;/em&gt; we give it the &lt;em&gt;same&lt;/em&gt; input. So if I decide to hash the number 0 and it produces the number 100 then it should &lt;em&gt;always&lt;/em&gt; produce the number 100, for example. I picked out a hashing function from the &lt;a href="https://craftinginterpreters.com/" rel="noopener noreferrer"&gt;Crafting Interpreters&lt;/a&gt; book. It's not the best but it'll do for now. It looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typename&lt;/span&gt; &lt;span class="nc"&gt;K&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; 
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;u64&lt;/span&gt; &lt;span class="nf"&gt;hash_key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;K&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;u32&lt;/span&gt; &lt;span class="n"&gt;hash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2166136261u&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;hash&lt;/span&gt; &lt;span class="o"&gt;^=&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;hash&lt;/span&gt; &lt;span class="o"&gt;*=&lt;/span&gt; &lt;span class="mi"&gt;1677719&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I don't understand it. You don't understand it. Jared over there doesn't understand. But it doesn't matter. What matters is that it works. &lt;/p&gt;

&lt;p&gt;And once we hash a specific key, we can &lt;code&gt;%&lt;/code&gt;ed it with the capacity of the table (and yes tables are just arrays under the hood). That should produce the index with which we can retrieve our value. However, there's a problem here. You smell like shit. But there's another problem. &lt;/p&gt;

&lt;p&gt;With hash tables, there's quite an infamous problem. When we hash a key and retrieve the index, we can potentially have two values that take up the same spot in the array. Meaning, they will produce the same index. This is called a &lt;em&gt;collision&lt;/em&gt;. And it happens more times than you think, especially if you have a terrible hashing function. So a bunch of old white people cuddled together in a room and found a solution to this problem. Well, actually, multiple solutions but we'll look into two of them. &lt;/p&gt;

&lt;p&gt;The first is called an "open table" solution. In this method, we can use a linked list to store all of the values that produce the same index. Anytime we want to retrieve a value, we just get the index and if that index doesn't match the key, then we'll walk the linked list until we find our key. While this approach might &lt;em&gt;seem&lt;/em&gt; good, it's actually not the best. It does take up a lot of memory since every node in that linked list is a &lt;em&gt;required&lt;/em&gt; allocation. And traversing a linked list is not constant time so it kind of defeats the purpose. However, it is still very much faster than a regular linked list and those lists won't be that long anyway. &lt;/p&gt;

&lt;p&gt;The second solution to collisions is something called a "close table". Sometimes, this method, confusingly, is called "open addressing". In this method, something called "probing" is used. Essentially, whenever we encounter a collision, we just look for the next index. If that spot is empty, we'll just place the value there. But, if it's not empty, we just look to the next index and then the next index and then the next index and so on until we find an empty slot. Of course, if we do reach the end of the table we will wrap around to the beginning. &lt;/p&gt;

&lt;p&gt;In my opinion, the second solution &lt;em&gt;is&lt;/em&gt; better. However, it is much more headache-inducing to implement. Trust me, I tried. And so, even though I think it's an inferior solution, I used the open table method for resolving collisions. If you think that's stupid, then... I swear I'll break up with you. Like, I'm not even joking.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;HashTable&lt;/code&gt; in action:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Creating a table with a capacity of '12'&lt;/span&gt;
&lt;span class="n"&gt;ishtar&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;HashTable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ishtar&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 

&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Buddy Guy Jones"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;83&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Abigail Jack JR."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Salem Yunich Euler"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Jackson Free Darnell"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;512&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Ian Long Bundy"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Randall Axel Jones"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Retrieve the name at index `1024`&lt;/span&gt;
&lt;span class="n"&gt;ishtar&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;randall&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Now that I think about it, using ints as keys wasn't the best idea. &lt;/span&gt;
&lt;span class="c1"&gt;// But you can imagine the key being a string, for example. I'm dumb sometimes. On occasion. &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;So what are you supposed to take away from all this? Well, let me ask you a counter-question. Why are you... why are you dumb? Like. &lt;/p&gt;

&lt;p&gt;No, but seriously, the reason I made this library in the first place was to show you how simple and easy all of this is. I &lt;em&gt;highly&lt;/em&gt; encourage you to try out this on your own. You'll be a better programmer overall. Trust me, dude. Like, come on. &lt;/p&gt;

&lt;p&gt;Data structures are a &lt;em&gt;crucial&lt;/em&gt; part of any application. Understanding them will be of benefit to you. Are you gonna make a library that is better than C++'s STL? Obviously no. Is it gonna be more efficient or performant? Well, you never know maybe. But that's not the point. The point is that you'll learn a &lt;em&gt;ton&lt;/em&gt; of things. You'll appreciate these libraries more. You'll even have an idea of how things work under the hood so you can use them more efficiently in the future. &lt;/p&gt;

&lt;p&gt;Now, as for me, I plan to use this library for some time. My plan is to grow it and expand upon it. Fix some of the bugs and make it more performant. I'll see how far I can go with this library without losing faith in humanity. &lt;/p&gt;

&lt;p&gt;Well, actually, the joke's on you. I already lost faith in humanity.&lt;/p&gt;

&lt;p&gt;But seriously though, tell your mom to call me back because like...&lt;/p&gt;

</description>
      <category>cpp</category>
      <category>programming</category>
      <category>tutorial</category>
      <category>algorithms</category>
    </item>
    <item>
      <title>Gamedev Math: Not Just A Tool But A Necessity</title>
      <dc:creator>IWantToDeleteThisButICant</dc:creator>
      <pubDate>Tue, 15 Oct 2024 02:52:06 +0000</pubDate>
      <link>https://dev.to/mah_doh/gamedev-math-not-just-a-tool-but-a-necessity-eok</link>
      <guid>https://dev.to/mah_doh/gamedev-math-not-just-a-tool-but-a-necessity-eok</guid>
      <description>&lt;h1&gt;
  
  
  Math, My Love
&lt;/h1&gt;

&lt;p&gt;I never liked math. My everlasting enemy in school wasn't the bullies (I was the bully). It wasn't the drugs (I was the drugs). It certainly wasn't Becky (I was, in fact, Becky). It was the maths. You can put me up on a podium, tell me to talk about history the rest of the day with a slim jim up my ass, and I will happily oblige. However, if you ask me to find the square root of your mother's abdominal area... I wouldn't have a clue (but your mom is so fat anyway so that would be impossible to calculate such a thing). I thought I was finally done with math when I left school. I did not want to see those symbols ever again in my life... but then I fell in love. I fell in love with a little thing called game dev. You might have heard of it. &lt;/p&gt;

&lt;p&gt;Even though I used Unity throughout my first year of game development, I still had to use so much math. It was an engine for god's sake! Why did I have to get the tangent of the angle between the mouse's position and the player's position! I did not care! I just wanted to make the game. Despite my best efforts to escape the hell that was math, I still used math as much as you use hair gel to hide the fact that you're slowly getting bald. And I had forgotten almost everything! I did not pay any attention to school when it came to math. I felt like I was a monkey trying to use piano keys as a way to wipe my bottom area. &lt;/p&gt;

&lt;p&gt;I watched tutorials whenever I was stuck with a particularly annoying math-intensive problem. Especially if it had something to do with rotations. I watched some &lt;a href="https://www.youtube.com/@Brackeys" rel="noopener noreferrer"&gt;Brackeys&lt;/a&gt; here and some &lt;a href="https://www.youtube.com/@CodeMonkeyUnity" rel="noopener noreferrer"&gt;CodeMonkey&lt;/a&gt; there. Yet, I still had issues. Perhaps it was an issue that I did not find an immediate answer to (although those were very rare). Or, and this was the most common, I just did not remember the solution because I did &lt;em&gt;not&lt;/em&gt; understand it fundamentally. &lt;/p&gt;

&lt;p&gt;It was really frustrating. It made me hate maths even more than I already did. Something had to change... and I'm not talking about your drinking habits. &lt;/p&gt;

&lt;h1&gt;
  
  
  Socrates
&lt;/h1&gt;

&lt;p&gt;What the bald guy? No, not him, silly. I'm talking about the greatest math library ever created. &lt;a href="https://github.com/MohamedAG2002/Socrates.git" rel="noopener noreferrer"&gt;Shameless plug&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Yes, I made a math library completely from scratch using nothing but my own two hands (C++) and a few pictures of your mom to keep me company. The person who was having a problem with rotations back in Unity is dead now. I killed him... no, officer, I meant figuratively.&lt;/p&gt;

&lt;p&gt;After reading a few books and watching a couple of &lt;a href="https://www.youtube.com/watch?v=fNk_zzaMoSs&amp;amp;list=PLZHQObOWTQDPD3MizzM2xVFitgF8hE_ab" rel="noopener noreferrer"&gt;amazing tutorials&lt;/a&gt;, I was able to manifest myself a small and simple math library. Is it the best math library out there? Absolutely not. Is it the most optimal and fastest? What? Are you kidding? Of course not! But I don't really care. I made it because I wanted to learn and boy did I learn a lot. &lt;/p&gt;

&lt;p&gt;Not only did I understand what libraries like &lt;a href="https://github.com/g-truc/glm.git" rel="noopener noreferrer"&gt;glm&lt;/a&gt; do under the hood, but it also gave me an appreciation for these kinds of libraries and just the general math of it all. Getting deeper (that's what she said) into the maths and really understanding what makes a projection matrix work the way it works was really fascinating and incredible. If I told my 15-year-old self that I would be making a math library from scratch... well, first, I would ask what the hell a math library is and then probably be amazed. I would also punch my 15-year-old self because he was a fucking moron.&lt;/p&gt;

&lt;p&gt;But wait. Was it necessary? Did I really have to go that far for math? Couldn't I just use something like glm and go about my day? Well, obviously yes. In fact, that was the case for so long. So why? Well...&lt;/p&gt;

&lt;h1&gt;
  
  
  Useful Is Not Necessary
&lt;/h1&gt;

&lt;p&gt;Math is a very useful tool to have in your toolbelt as a game developer. Personally, it has helped me to manifest my sick ideas into reality (a game about Donkey from Shrek getting trapped in Alcatraz). It made me a better programmer overall. Especially when I'm programming in a lower-level environment. Yet, a useful tool is not a necessity. It's a cool thing to have. It'll help you in your journey. But will you die from dehydration if you don't have it? No. Not drinking water will do that to you. &lt;em&gt;That&lt;/em&gt; is a necessity. And while we can argue about how nothing is really a necessity in the current landscape of game development where engines are available in the thousands. However, I would argue that--even with engines--math is a &lt;em&gt;very&lt;/em&gt; necessary tool to have. It won't kill you if you don't have it, but you will suffer without it. &lt;/p&gt;

&lt;p&gt;I've been on both sides of the coin. I knew next to nothing about math and I also, now, know a lot about it. I can tell you for sure that I enjoyed my time, making games with the math knowledge than without it. Things were easier to interpret. I could intuitively understand and implement things like camera projection, plane vs. line intersection, or even finding the intersection point between your mom's belly and infinity. &lt;/p&gt;

&lt;p&gt;Listen, I am not telling you to go out, reincarnate Issac Newton from the dead, and demand from him to teach you the meaning of life using an apple. However, knowing even a little bit of math goes a long way. At the end of the day, we--game developers--are trying to become the best damn game makers we can possibly be. We are not here to make a couple of bucks out of a cheap rip-off and call it a day. We are here to &lt;em&gt;learn&lt;/em&gt;. You need to understand that game development is a complex and difficult endeavor. And, if you're not prepared for it, you will get fucked in the ass more than I would if a goth... well, let's move on from that. &lt;/p&gt;

&lt;p&gt;Math is not just a useful tool, believe me, it's a &lt;em&gt;necessary&lt;/em&gt; tool to have. But how much math do you need? &lt;/p&gt;

&lt;h1&gt;
  
  
  Too Much Or Too Little
&lt;/h1&gt;

&lt;p&gt;I can give you a short answer and I can give you a long answer. Since this is my property, I will give you a long answer. So sit down. &lt;/p&gt;

&lt;p&gt;Not everyone enjoys programming. I get it. For a lot of people, it doesn't make sense, it's very unintuitive and very hard. And, if you're specializing in another field in game development, it's totally okay. Not every game developer &lt;em&gt;has&lt;/em&gt; to be John Carmack (all hail Carmack). Especially if you have a programmer to help you, you don't really need to know much of the math. Not really at all. It's cool if you know &lt;em&gt;some&lt;/em&gt; of it but you're not forced to learn it. &lt;/p&gt;

&lt;p&gt;However, if you're a programmer, then things are different. You need the math. If you program your game on your own or for someone else, you &lt;em&gt;need&lt;/em&gt; the math. Hey, I'm not saying you need to learn matrices. But, I'm saying that you need to know more than just the basics of math. The dot product, the cross product, tangents, cosines, sines, getting the distance between two vectors, the length of a vector, and so much more. You &lt;em&gt;need&lt;/em&gt; to know these things. Even if you're not gonna make a renderer from scratch using only OpenGL and some tears, you &lt;em&gt;need&lt;/em&gt; to learn the math. &lt;/p&gt;

&lt;p&gt;For example, let's say that you're an unoriginal bastard who did not have a single productive day in his life. You decide one day to make a Dark Souls clone. Wow, how original. You really like it when you can sneak up on enemies and get the orgasmic backstab. Now, you'd like to implement that. How would you implement something like that? Well, easy enough. Just go on YouTube and type in the search bar with your useless fingers, "Backstab tutorial Unity". A video pops up, you follow it through, and you somehow--finally--make something work and implement it correctly. Now you have backstabbing in your very original game... but it doesn't feel right. For some reason the movement is stiff. The backstabbing is weird. There are some weird edge cases where the backstab should work but it doesn't. Why? It's because you're a lazy bastard that's why. I'm sorry, though. I still love you. &lt;/p&gt;

&lt;p&gt;Math, my friend. It's the savior of all. You would know how to solve that problem without the need to look up a video on YouTube if you knew the math. Do understand, however, that I'm not making a slight at the tutorials on YouTube. No no. Absolutely not. But, these tutorials are only a temporary solution. A short-term and low-effort answer to a much more complicated question. &lt;/p&gt;

&lt;p&gt;You don't need to know why &lt;em&gt;exactly&lt;/em&gt; the dot product works the way it does, for example. But it would be useful to know &lt;em&gt;what&lt;/em&gt; it does and &lt;em&gt;when&lt;/em&gt; to use it. Intuitively understanding basic trigonometry and geometry will help you a long way to implement these gameplay features. Who knows, perhaps you'll even be able to make something way better than anyone ever did. And while there are many things you'll need to enhance in order to be a better game programmer, math is certainly on the list. &lt;/p&gt;

&lt;p&gt;But what if you want to go further? Further than any Unity programmer has ever gone. Well, unless you're making a game from scratch or you're interested, then you don't really need to venture &lt;em&gt;that&lt;/em&gt; far. But, hey, I can show you the way if you want. For a little favor if you know what I mean... anyway. &lt;/p&gt;

&lt;p&gt;One word: Matrices. Well, and quaternions. And maybe more than that. Whatever, you get the point. While in game engines we have many tools to help us along our journey, when you're on your own, that is not the case. &lt;/p&gt;

&lt;p&gt;If you want to venture deeper into the mines of game development and perhaps make your own game engine, then you'll need to know more than the dot product or the cross product. In this level of game development, you are &lt;em&gt;forced&lt;/em&gt; to learn math. Projection matrices, view/clipping matrices, and even physics. But, again, you do have libraries like glm to help you along your journey. However, I still believe you should venture deeper than glm. &lt;/p&gt;

&lt;p&gt;Here's the thing about gamedev math in general: it's all there. You just have to implement it. Making a physics library is not hard because of the math. Absolutely not. The formulas are all there. They have been there for hundreds of years. The hard part about making a physics library or a math library is the performance. Making these expensive calculations multiple times in a frame can be and will be very costly. Your job (at this level at least) is to make sure everything runs smoothly while still making the right calculations at the right time. &lt;/p&gt;

&lt;p&gt;It helps to know what the &lt;code&gt;glm::perspective&lt;/code&gt; function in glm does under the hood to know if it is costly to compute or not. Again, I'm not saying to meditate under your neighbor's balcony naked to truly understand &lt;em&gt;why&lt;/em&gt; a perspective matrix works the way it does. That's not your job as a game programmer. That's a mathematician's job. &lt;em&gt;Your&lt;/em&gt; job is to take the formula and make it work fast. That would require you to understand what the formula &lt;em&gt;really&lt;/em&gt; does under the hood. How does an orthographic matrix get built under the hood? How can I make a skew matrix? How do quaternion rotations work? How do I get RAM for free from GTA 5? &lt;/p&gt;

&lt;p&gt;Maths at this level is not only a necessary tool, but it is a &lt;em&gt;crucial&lt;/em&gt; step to take. &lt;/p&gt;

&lt;h1&gt;
  
  
  The Bottom Line
&lt;/h1&gt;

&lt;p&gt;Game development is not a race. Making games requires a wide set of skills harmonizing together at the perfect moment to make a semi-decent game. All we can do here is learn. Learn about the math, the game design, the art, the music, the story, and every other skill required to make a game. I'm not saying you need to be the jack of all trades. But do understand that learning the art of making games is more important than your stupid Legend Of Zelda and Skyrim clone. Take your time. Learn the fundamentals. Don't rush it. You &lt;em&gt;will&lt;/em&gt; regret it.&lt;/p&gt;

&lt;p&gt;Keep learning. Keep making games. You might make it or you might not. But hey, at the end of the day, you learned a shit ton of skills and made some pretty nice games. Fuck it. That's something worth living for. &lt;/p&gt;

&lt;p&gt;Credits: Me.&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>cpp</category>
      <category>programming</category>
      <category>maths</category>
    </item>
    <item>
      <title>The Failures Of API Design</title>
      <dc:creator>IWantToDeleteThisButICant</dc:creator>
      <pubDate>Fri, 04 Oct 2024 20:13:37 +0000</pubDate>
      <link>https://dev.to/mah_doh/the-failures-of-api-design-ebb</link>
      <guid>https://dev.to/mah_doh/the-failures-of-api-design-ebb</guid>
      <description>&lt;p&gt;It would be very easy to come on here and write about my absolute hate for modern APIs and how I completely despise them. I could tell you about the terrible state of modern APIs and how we got to this point. I love drama. I can go on about this for hours... but I will not. While sure, there will be a &lt;em&gt;tinge&lt;/em&gt; of drama, my main focus here will be on the failures of these APIs rather than going on a tirade about them. So, without the need to stall, let's get riiiiight into the post. Sorry about that. Oh just a note, though. When I'm talking about "APIs" I mean libraries and/or frameworks. Keep that in mind. So if you think that this doesn't apply to your project because it's a "framework" not an API, I would advise you to go see a doctor because you clearly have a lot of brain damage. Okay now let's start.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Ghost Problems
&lt;/h1&gt;

&lt;p&gt;Why would any software developer use an API? Well, it's not to get rid of that shirt stain you had for the last three days that's for sure. Instead, we crazy bunch use APIs to progress our software development at a faster rate. I don't really want to work with the Windows API nor do I care to open the rotten can of sardines that is the X11 API. But, thankfully, I don't have to. There are plenty of APIs that handle that for me. And they handle it very nicely too. &lt;a href="https://github.com/glfw/glfw.git" rel="noopener noreferrer"&gt;GLFW&lt;/a&gt; is one of these APIs. Easy to use, fast to set up, and overall doesn't have any overhead. Handles window creation, input, and any operating system-specific stuff. It solves a clear and appropriate problem. Left pad, however, is the complete opposite. Does it solve a problem? Sure it does... if you were hit on the head with a baseball bat 17 times. Can't I at least add padding to any direction? No? Does it just have to be the left? Even though we C++ folks can say that the JavaScript weirdos are the only ones who would do such a heinous thing, that wouldn't be the entire story. It would be hypocritical even to assume that all of the useless APIs exist only in the JS ecosystem. Although being hypocritical is my strong point, even I would stop you right there. If there is an ecosystem that would be perfect for breeding unnecessarily complex, widely inefficient, and completely useless libraries, it would be C++... Rust would come at a close second but C++ is the mother of all useless and complex libraries. &lt;/p&gt;

&lt;p&gt;I pray for the soul who has tried to go into the STL code and read it. I envy those who haven't seen the pile of dog shit that is the Standard Template Library. However, STL has a purpose for its existence. Perhaps there are no justifications for its complexity but hey it gets the job done pretty well. It saves a lot of time and effort. And that's what APIs are for. To save time and money. Even though we can make fun of left-pad all day every day, we can't ignore the fact that it's a small API that would not cause any harm. However, there are a slew of APIs that do not contribute to the ecosystem in any sort of useful way. Yet, these APIs get used by people like you because you're too busy jerking yourself off under the table rather than adding a bit of padding to the left. There's nothing harmless about trying to create an API much like GLFW. Perhaps you really like math and you would like to make a math library specifically for games. Is it going to be the most performant math library out there? Probably not. Is anyone going to use it for their project? Maybe. Who knows? But that doesn't matter. You made something that you enjoy and you learned a lot from it. No one can take that away from you. However, the problem arrives when you try to make a library that has &lt;em&gt;absolutely&lt;/em&gt; no reason to live and market it to programmers. Some programmers might have eaten from the same bogger restaurant that you go to every day and actually &lt;em&gt;use&lt;/em&gt; your useless API.  &lt;/p&gt;

&lt;p&gt;Let me ask you a question. If I didn't use your API in my next project, how &lt;em&gt;fucked&lt;/em&gt; will I be? Is your API going to save me time? Is it going to save me from debugging some annoying bug? Is it going to help my crumbling marriage? If your immediate answer to all of these questions is yes then congratulations! You're API is useful! On the other hand, if the answer was no or you tried to twist the question to your liking, then I have news for you, buddy, you have a very rare syndrome called Bjarne Stroustrup. &lt;/p&gt;

&lt;p&gt;Don't try to solve non-existing problems. Make an API that solves real problems that thousands of programmers have to deal with every day. Can't find these problems? Then go and make projects. Create projects that you actually enjoy in the real world and you'll discover an array of these problems all the time. Why do you think the creators of GLFW created it in the first place? Because they probably were sick of programming for the Windows API and the X11 API and whatever other OS-specific API all the time. A problem exists and you come in and solve it. Like stealing money from my ex-wife. Easy. &lt;/p&gt;

&lt;h1&gt;
  
  
  The Adventure Is More Fun Than The Journey
&lt;/h1&gt;

&lt;p&gt;While that might be a true statement if you were traveling to East Somalia with your imaginary girlfriend, it is &lt;em&gt;not&lt;/em&gt; the case in API design. Too many programmers think about the implementation rather than the actual API. They think about algorithms and performance rather than the naming convention. Don't get me wrong, those things are &lt;em&gt;very&lt;/em&gt; important. I'm not saying they aren't. Yet, focusing on them &lt;em&gt;too&lt;/em&gt; much will make your API look and feel unprepared. Functions that take in multiple parameters, types that don't make any sense, absolutely no documentation (I'll &lt;em&gt;definitely&lt;/em&gt; get to that later), and just a general lack of care for the design. &lt;/p&gt;

&lt;p&gt;While this is not an API, Gimp is a very &lt;em&gt;powerful&lt;/em&gt; photo editing tool. I use it daily for different tasks. It's free, robust, and open source. You really can't go wrong with it. Yet, the UI is worse than that day you spent with your uncle back in 1998. The UI is extremely unintuitive, bland, hard to look at, and hard to navigate. &lt;/p&gt;

&lt;p&gt;Listen, I get it. I &lt;em&gt;hate&lt;/em&gt; UI. I can't stand it. That's one of the reasons why I didn't want to be a web programmer. Well, that and the fact that I hate money. But, for the love of Bill Gates's knees, when you're trying to ship a product where the main focus &lt;em&gt;is&lt;/em&gt; UI, then you at least need to put &lt;em&gt;some&lt;/em&gt; effort into it. Take a UI/UX course. Talk to your UI friend and let them help you. Let's be honest, though, you probably don't have friends. But do anything I don't know. &lt;/p&gt;

&lt;p&gt;At the end of the day, the users who will use your API and/or application don't care about how you implemented a brush that draws nudes. Maybe the programmers using your API will care about the performance but many of the same programmers will be encouraged to use another API if what you created is completely hard to work with. &lt;/p&gt;

&lt;p&gt;I can give many examples of APIs that have this exact problem... but I won't. Instead, I'll be making an example of myself. Long ago (like, maybe 4 months ago), I made an API called &lt;a href="https://github.com/MohamedAG2002/Gravel.git" rel="noopener noreferrer"&gt;Gravel&lt;/a&gt;. It was supposed to be a game framework that abstracts away all of the window creation code, input handling, rendering with OpenGL, and so on. I thought I was the king. I was getting ready to become bald, wear glasses, and call myself Bill Jobs III. I thought the API was &lt;em&gt;so&lt;/em&gt; good. I thought it was so good, in fact, that I decided to use it and create a game. The game was called &lt;a href="https://frodoalaska.itch.io/the-problem-solver" rel="noopener noreferrer"&gt;The Problem Solver&lt;/a&gt;. The game was supposed to be simple. I made a 3D game from scratch before. Pfft. How hard can it be? Especially now that I have this amazing API that I created... I hope you can tell there's gonna be foreshadowing here. &lt;/p&gt;

&lt;p&gt;Not only did it prolong the development cycle of the game, the API also went out of its way to fuck every single little gameplay feature I was adding. It was a nightmare. Besides the fact that the API's design itself was retarded beyond belief, there were a lot of spelling errors, functions that didn't work the way they were supposed to, and many more fun adventures. &lt;/p&gt;

&lt;p&gt;I never really thought about how the API would be used. I never really thought how convoluted and unnecessarily complex everything was. I just thought about the implementation. How can I load an OBJ file? How can I draw text? How can I make a resource manager? Instead, the questions I should have been asking were how would the &lt;em&gt;user&lt;/em&gt; load OBJ files? How would the &lt;em&gt;user&lt;/em&gt; handle resources? How would the &lt;em&gt;user&lt;/em&gt; &lt;strong&gt;use&lt;/strong&gt; the API? &lt;/p&gt;

&lt;p&gt;While I still think that excessive planning of a project without any coding being done is completely wasteful, I also think that you can't go into a project with absolutely &lt;em&gt;no&lt;/em&gt; planning whatsoever. Perhaps that would be true if you were just testing the waters and seeing if something works or not. However, that is not the case when you're planning to release an API to the public for people to use. &lt;/p&gt;

&lt;p&gt;No planning will lead to a terrible API design. Yet, no planning can also lead to a &lt;em&gt;bloated&lt;/em&gt; API &lt;/p&gt;

&lt;h1&gt;
  
  
  Doing Everything That I Can Do
&lt;/h1&gt;

&lt;p&gt;Having an all-in-one API that does everything sounds pretty neat. I wish there was an API that could load JSON files, render pixels to a screen, fix my libido, and make me a cup of tea. That would be great! Or would it? Welcome into another episode of trying to break your dreams and increase doubt in yourself. &lt;/p&gt;

&lt;p&gt;Let's take a look at an API that I extremely love and enjoy working with, &lt;a href="https://github.com/nothings/stb" rel="noopener noreferrer"&gt;stb&lt;/a&gt;. And specifically, &lt;a href="https://github.com/nothings/stb/blob/master/stb_image.h" rel="noopener noreferrer"&gt;stb_image&lt;/a&gt;. This is a library that will help you with loading image files like PNG, TIF, JPEG, and so on. It is a &lt;em&gt;necessity&lt;/em&gt; if you're trying to make a game engine or any photo-related programs for that matter. It has one purpose: give you the pixel data--plus some information like the width and height--of the image loaded. That's it. Does it try to add some nice effects? No. Does it try to write pixel data to an image? No. Stb has another library for that single purpose. Does it try to sleep with your mom? No. That's my purpose. &lt;/p&gt;

&lt;p&gt;Let's take a look at another API. &lt;a href="https://github.com/raysan5/raylib.git" rel="noopener noreferrer"&gt;Raylib&lt;/a&gt;. Now Raylib does a little bit more than just load images. Raylib is more of a game framework than a single-purpose library. It will create a window, handle input, load images, render pixels, handle loading and rendering fonts, and so on. Even though Raylib does multiple things, it doesn't go overboard. It tries to be simple yet robust. There's a clear &lt;em&gt;vision&lt;/em&gt; for the library. They didn't try to force a GUI editor into the API or an alternative string type. It had one goal and that is to become a game framework. What happens when Raylib has added all the features it needs to add? Well, call it feature-complete and just move on. There's no need to bloat an API for no reason other than you "felt like it".&lt;/p&gt;

&lt;p&gt;Now, let's take a look at an API that is worse than the devil: &lt;a href="//boost.org"&gt;boost&lt;/a&gt;. What is boost you might ask? Everything. Boost is you, me, and that guy over there probably. Is it an API? A standard? A committee? I don't really know. Once you start losing vision of what your API truly is, you start to lose interest as well. How many times have you tried to include an API into your project only to discover it has a buttload of dependencies because the API does 1001 things at once. &lt;/p&gt;

&lt;p&gt;Besides these bloated APIs being slow and too large to even add to your project, they would also lack the efficiency and performance of other APIs that decided just to stick to one thing. Jack of all trades, master of none. Stb is just a single header file that I can &lt;em&gt;easily&lt;/em&gt; add to &lt;em&gt;any&lt;/em&gt; project. Why would I not use it and instead opt to use another library that uses thousands of dependencies and does &lt;em&gt;way&lt;/em&gt; more than I'm asking for? &lt;/p&gt;

&lt;p&gt;However, not everything is black or white. Not &lt;em&gt;too&lt;/em&gt; much is bad, yes. But, also, doing too &lt;em&gt;little&lt;/em&gt; is bad, too. If you're API just adds padding to the left of a UI element then I don't really need to use it. I'll just do that myself. But sending and handling HTTP requests? Well, that's a different story. Adding APIs/dependencies in the C++ landscape is a hassle. You'll have to think about &lt;em&gt;every&lt;/em&gt; dependency you're adding since it'll be something that you and the user will &lt;em&gt;have&lt;/em&gt; to deal with. I can't just do "npm install" or "dotnet install" and everything will work magically. This is not a kid's programming language. This is a language for the mentally-derained. We like to torture ourselves. &lt;/p&gt;

&lt;p&gt;Just don't use Boost. Please.&lt;/p&gt;

&lt;h1&gt;
  
  
  Not A Word Spoken
&lt;/h1&gt;

&lt;p&gt;Would it hurt your fingeys so much if you tried to write what this function does and what the parameters mean? It probably won't. It'll probably take the same amount of time as when you're searching for weird hentai porn that you watch daily. Or just about longer than you last in bed. &lt;/p&gt;

&lt;p&gt;I'm a strong believer in documenting with code. Meaning, instead of writing comments, you actually make your code sensible and understandable. So instead of writing, &lt;code&gt;V2 V2a(V2 n, V2 m)&lt;/code&gt; which you would if you were hit by a bus full of cement that gives brain aneurysms, you can just write, &lt;code&gt;Vector2 vector2_add(Vector2 v1, Vector2 v2)&lt;/code&gt;. See how easy that is? Simple, straight to the point, and doesn't need a single line of explanation. Always remember that code lives, but comments do not. You might change something in your code but forget to change the comments, confusing the user completely.&lt;/p&gt;

&lt;p&gt;However, that might not always necessarily be the case. Sometimes, there's just code that is hard to explain. You can't understand it immediately by just looking at it. Even if you try to make the names of the variables, functions, and types quite cohesive and sensible, you might still need to explain your code using comments. For example, here's a function definition from the GLFW library: &lt;code&gt;GLFWwindow* glfwCreateWindow(int width, int height, const char* title, GLFWmonitor* monitor, GLFWwindow* share)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Even though the function might &lt;em&gt;look&lt;/em&gt; sensible, there are still a couple of missing pieces here. What's a &lt;code&gt;share&lt;/code&gt;? Why do I need to pass in a &lt;code&gt;monitor&lt;/code&gt;? What does this function return if GLFW fails to create a window? Are there any errors that will be printed? Since GLFW is documented &lt;em&gt;thoroughly&lt;/em&gt; you can easily find that out by just going to the function's definition (did I fail to mention that I'm using NeoVim btw?). However, not all APIs have the same privilege. You might find a library, for example, that has the function &lt;code&gt;gymagf()&lt;/code&gt;. You'll get the wrong idea. All you have to work with here is a comment that says, &lt;code&gt;// get string&lt;/code&gt;. What does that mean? What can you do with this? Why is Jared naked? Then you discover that it's just a function that returns a string with the value "Give Your Mom A Good Fig".&lt;/p&gt;

&lt;p&gt;As with everything in the world, this isn't really a one-and-done answer. If you don't document your code, then you end up losing and confusing the user and even yourself if you haven't used the API in a while. Yet, when you document &lt;em&gt;everything&lt;/em&gt; you end up putting a huge load (heh) on yourself. You need to find a fine line between what's enough documentation and what's excessive documentation. That's a boring answer I know but it's the truth.&lt;/p&gt;

&lt;h1&gt;
  
  
  It Works On My Machine, Though
&lt;/h1&gt;

&lt;p&gt;Even though most of the points above can be applied to any ecosystem of any programming language, this point is just specific to C/C++. And don't worry, it's going to be brief believe me... just like your mom--okay, I'll stop.&lt;/p&gt;

&lt;p&gt;It's no secret that the building and compilation process in C/C++ is just awful. These languages have no build system at all. We might have a cheap "build system" that we hate called CMake. But that's not really a "build system" per se. It was made so you didn't have to work with Makefiles and Make was made so you didn't have to work with raw CLI commands. The build system scene in C++ is truly heinous and needs to be put down ASAP (if I hear anyone of you saying to move to Rust I swear I'll stick a needle so far up your asshole...). But, in the meantime, it's the only thing we have. Therefore, trying to set up nice building instructions for C++ APIs is quite a hassle. &lt;/p&gt;

&lt;p&gt;Not only do you have to think about which build system you'll use (believe me, it's not always CMake), but you're going to need to think about being cross-platform too. What if there's a user that wants to use your API on Windows? What are the building instructions there? What about Linux? Mac? Who uses a Mac anyway? You can't just expect everything to work because it worked on your machine. You need to test it. &lt;em&gt;A lot&lt;/em&gt;. Many times. With different machines, with different projects, with different settings. You need to give it care since you're going to be delivering a product to people. What would people think about your API when they try to build it for the Apple 2 and it doesn't work? You have a terrible reputation in real life you don't want to ruin your digital reputation as well.&lt;/p&gt;

&lt;p&gt;This is one of the points where there aren't any gray lines. It's just completely on one side. I'm not saying to support &lt;em&gt;every&lt;/em&gt; platform out there. But do give some clear and simple instructions of how one would use your API and include it in their projects. &lt;/p&gt;

&lt;h1&gt;
  
  
  The Final Verdict
&lt;/h1&gt;

&lt;p&gt;Listen, at the end of the day, I'm not your dad (unless you want me to be). You can do the opposite of what I've been saying here. I don't really care. It's just a frustrating problem that I've seen being done over and over again. There are a lot of points I even left out for the sake of brevity. For example, how these API creators don't really test their APIs in real applications and instead opt to show off the API "working" in some dummy project. Or how a bunch of APIs force you to use a coding style that you might not be familiar with or you don't enjoy. &lt;/p&gt;

&lt;p&gt;There's a lot I could have said but, really, at the end of the day, you're going to end up jerking off under that table and leave your API looking like a 2$ toy from the local garage sale. So hey, you do you. Just please don't use Boost. &lt;/p&gt;

</description>
      <category>programming</category>
      <category>api</category>
      <category>cpp</category>
      <category>discuss</category>
    </item>
    <item>
      <title>My Bad Experience With Fiverr</title>
      <dc:creator>IWantToDeleteThisButICant</dc:creator>
      <pubDate>Sat, 31 Aug 2024 13:18:11 +0000</pubDate>
      <link>https://dev.to/mah_doh/my-bad-experience-with-fiverr-maf</link>
      <guid>https://dev.to/mah_doh/my-bad-experience-with-fiverr-maf</guid>
      <description>&lt;h1&gt;
  
  
  Who? What? Why?
&lt;/h1&gt;

&lt;p&gt;So for the past 2 years, I've been freelancing on Fiverr. Game development freelancing in particular. &lt;br&gt;
I'm a 21-year-old self-taught programmer from the land of the sands and sometimes Pharoahs, Egypt. I thought that Fiverr would be a good pick since I heard good things about it (yeah. I know). I also didn't have much professional experience at the time nor did I have a good portfolio to show to people. So, in my ignorance, I thought I could make a Fiverr gig and try to reap the benefits, as I was low on cash at the time (not much has changed honesty). Given that I had no experience in freelancing, I thought I could watch a couple of videos about Fiverr and freelancing in general. I'll get to this later, but those videos really did not help much nor did they stick with me &lt;em&gt;at all&lt;/em&gt; when I was actively freelancing. &lt;/p&gt;

&lt;p&gt;In short, however, I did not know what I was getting myself into. I have never done anything similar before. Not even close. A shot in the dark, if you will.&lt;/p&gt;

&lt;p&gt;Strap in, feelas. I have a lot to say and I know nothing about discipline. Be warned.&lt;/p&gt;

&lt;h1&gt;
  
  
  Some Things To Keep In Mind
&lt;/h1&gt;

&lt;p&gt;Before I start delving deep into my PTSD, I need to preface a few things. &lt;/p&gt;

&lt;p&gt;First, you have to remember, that this is &lt;em&gt;my&lt;/em&gt; experience. Not yours. Not that guy's experience over there. Not even Jared's experience. It's &lt;em&gt;my&lt;/em&gt; experience. Your experience might be different from mine. It might be better or it might be worse. But I'm only talking about my experience here. What I went through. This is why the post is called "&lt;em&gt;My&lt;/em&gt; Bad Experience With Fiverr". Not "Fiverr Is Shit, Dude" or something like that. &lt;/p&gt;

&lt;p&gt;Second, even though I will go on a tirade about a few clients I worked with on Fiverr, I do not mean any harm and I do not condemn them either. With some of these stories I'll be getting into, I'm going to be solely responsible for the mistakes made. I don't shift the blame to anyone. I don't blame any of these clients nor do I hold them responsible. It was just a combination of unprofessionality, high expectations, and terrible management on my part.&lt;/p&gt;

&lt;p&gt;Third, I am not making this post in the hope of discouraging you from starting out on Fiverr. Fiverr can be great if you know what you are doing. If you have done it before and you know what you are getting yourself into. Take it as a lesson of what &lt;em&gt;not&lt;/em&gt; to do. Not as a reason to dismiss or avoid Fiverr just because you read about it on the internet by some random Egyptian guy. &lt;/p&gt;

&lt;p&gt;Fourth, and finally, don't come here expecting any advice from me. I barely "succeded" on Fiverr. I don't even call what I did on Fiverr a "success". More of a wet fart at the end of a very hard-working day. Useless but it happened. &lt;/p&gt;

&lt;p&gt;Fifth, just wanted to say you are beautiful. &lt;/p&gt;

&lt;p&gt;Okay, let's start. Just watch for some vulgar language.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Big Bang
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;First there was nothing. But then he farted and unto us came someone who wanted to make a game.&lt;br&gt;
    - Some drunk guy I know&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Before I even started my Fiverr journey, I watched a couple of videos. I don't remember which videos exactly since it was over 2 years ago. And, frankly, I don't care to remember. I just remember a couple of videos vaguely talking about how you should keep your gigs simple and straight to the point. Have the thumbnails of the gig be interesting and captivating so the customer will be excited to press on your gig and all that bullshit you probably heard a hundred times before. Now, initially, I spent a &lt;em&gt;long&lt;/em&gt; time setting up my first Fiverr gig. I made sure to have the best-looking pictures on there and the best-written and most professional-sounding intro you have ever read. Even though these "tips" might be useful if you're making a Steam page for your game. But, honestly, in the Fiverr landscape, none of that shit mattered. Not even a little bit. What matters is only one thing: money. Do you have a huge price on your gig? Too bad, buddy. Go find a job instead. You ask for almost nothing in exchange for your services (ew)? Give me a hug. I'll talk about the usual clients I met on Fiverr, but that gives you the gist.&lt;/p&gt;

&lt;p&gt;If there is one thing I learned from Fiverr is this: niche is the best. If you are really good at one niche, then you're golden. Make sure it's not &lt;em&gt;too&lt;/em&gt; niche, though, since that will make your gig essentially invisible. I know this because me and my sister started our gigs at the same time. Her gig was &lt;em&gt;way&lt;/em&gt; too general while mine was much more niche. The result? She never got a single client while I got some. &lt;/p&gt;

&lt;p&gt;I specifically decided to focus on making games using C++ and libraries like Raylib, SDL, and SFML, which are the libraries I knew at the time. Now you might have a clue of the clients I'll be getting but I didn't know shit at the time. &lt;/p&gt;

&lt;p&gt;My pricing was not all that crazy either. I'm a simple man after all. There were 3 tiers to my gig. The first was 10$, then 15$, and finally 20$. I did change these prices as I went along but that's what I started with. I did do some "market research" beforehand. And by "market research" I mean I just searched "Raylib" or "SDL" or something like that and saw the results. Both the results and the prices were pretty low. So, as I am a marketing genius, I decided to adjust my prices accordingly. &lt;/p&gt;

&lt;p&gt;Now, if you want to get clients on Fiverr, there are two things you need to do: find a niche and forget about your ego for the first dozen or so orders. You are nothing. You are a programming machine. You will do whatever the client says and that's it. You will have to lower your prices just to &lt;em&gt;hopefully&lt;/em&gt; match the competition. I was (and still am) broke. As mentioned, I'm a self-taught programmer too, so not much credibility there. I had no other choice. But even then, the amount of work I put in did not say 10$ or even 15$. I did learn to adjust the price based on the amount of work being tasked but I didn't know shit, man. Besides, I wanted to stand out from the others since I had no reviews. I had to lower my prices drastically just to get those first juicy reviews. &lt;/p&gt;

&lt;p&gt;However, after waiting for 2 fucking months, I finally got it. A client. A message from someone. That actually gets me too... &lt;/p&gt;

&lt;h1&gt;
  
  
  The Population
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;Hey, man. Can you make Doom using C++? And can you also make it in 2 days because I need to deliver the project to my professor haha. &lt;br&gt;
    - Some dude who wants to make Doom in 2 days&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you come to Fiverr expecting to meet some professionals, artists, other programmers, or any sort of "serious" work, then, man, you're fucked. Like, hard. Raw. No lotion even. Do you wanna who I got? College students. That's all I got. I mean I only blame myself with that one. My gig essentially screamed college assignments. &lt;/p&gt;

&lt;p&gt;I made so many snake clones. So many asteroid clones. So many fucking geometry dash clones. I swear to god I'll be ready to suck the homeless drunk guy under the bridge, get Aids, and then die in a car crash before I ever make another endless runner game in Raylib or SDL2 ever again. They are mind-numbingly boring. &lt;/p&gt;

&lt;p&gt;Once upon a time, not so long ago. I had a client who wanted me to make some stupid endless runner in SDL2. I thought, sure why not? Made it before. Easy 20 bucks, right? Oh, sweet summer child. How ignorant. I told him to give me the requirements. Apparently, his professors at his college cracked the Da Vinci code and decided to not use SDL2 directly. But, instead, have a thin wrapper around SDL. Fully-fledged with every terrible decision a human can make. Now, a thin wrapper around SDL doesn't sound too bad, right? NOPE! Wrong answer, buddy! You're out!&lt;/p&gt;

&lt;p&gt;I had to deliver the project in 2 days and I didn't understand shit. And also, the kid was from Bangladesh so all the comments were fucking French to me. I had to go through the code and try to figure out what the fuck this function did. There were also classes you just &lt;em&gt;had&lt;/em&gt; to inherit from. It was necessary. Part of the requirements actually. So I had to get on my boat and take to the seas trying to figure out what the fuck does what and what goes where. And trying to ask the client was useless since he could barely speak English. I tried to find the code but I couldn't since  I deleted it from the frustration. The funny thing is, I think the thin wrapper was actually made throughout the course just to teach the students how such a thing is done. But I didn't know shit! Do you know why? Because I wasn't in some college in Bangladesh! No slight against the Bangladeshi bros. Love you, my dudes. But Jesus fucking Christ I was livid. And, on top of all of that, it was only for a mere 20$... how wonderful. &lt;/p&gt;

&lt;p&gt;There was even someone who wanted to use SDL1! Like SDL1??! Really??! Who the fuck uses that anymore in the year of our lord 2024??&lt;/p&gt;

&lt;p&gt;That wasn't the worst of all, however. Pretty much all of the projects I delivered were in either C or C++. Mostly C++, though. You know what that means? That's right. CMake!&lt;/p&gt;

&lt;p&gt;Usually, what I would do with these orders is the following: &lt;br&gt;
    - 1: Get the requirements and any assets that might be used&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- 2: Start making the project 

- 3: Take a video or maybe a few screenshots to show the current development state of the game and send it to the client 

- 4: Give the client an executable that they can run to see if everything "feels" good

- 5: Once everything is okay, I send the client a custom order which they will accept after which I'll send the source code zipped up like a good boy

- 6: Wait...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Throughout my Fiverr... um... "career" I've had in total of 15 orders. 13 of which are "unique" clients. Since I did have a client (or maybe two?) order the same gig again. Of the 13 unique clients, I've had &lt;em&gt;one&lt;/em&gt;. One fucking guy who knows how to compile the code by himself. That's it. The rest? Oh well, I had to &lt;em&gt;fucking&lt;/em&gt; babysit them and tell them what an IDE is! Most of them were already using Visual Studio. But, also, most of them never coded on their own. It was always with a professor or using college computers. Or that's the impression I got since they didn't know shit about Visual Studio. They knew the code. Understood it even but just didn't know how to set it up. And, hey, I understand. I went through that shit too. Everyone did. But Jesus H fucking Christ I feel like slitting my wrist and cremating my body into some guy's balls every time I try to help them out with setting up the code. &lt;/p&gt;

&lt;p&gt;A lot of times I would just say fuck it and let them send me the project folder and I would just do it for them. I work on Linux (not Arch btw), so I can't really open Visual Studio and edit their solution files. And even if I could, I don't think it'll work since they had to edit their own Visual Studio to point to the libraries and the correct directories and all that jazz (great movie btw).&lt;/p&gt;

&lt;p&gt;There were also the lost tarnished. Those who have lost the way or can't fucking read apparently. My gig strictly says I do &lt;em&gt;2D games&lt;/em&gt;. I couldn't do 3D games (or barely could) since my laptop was bought when King George III was still dancing naked in his little bathhouse. Despite that, I've had people approach me about making 3D games. I had one guy even come to me 3 fucking times!!! Asking me to do 3D... in WebGL... using JavaScript. I mean fool me once shame on you, fool twice shame on me, fool me thrice just fuck you. He had a very urgent assignment I guess and he couldn't pay for the other freelancers and he desperately wanted me to do it. Like, take me on a date first jeez. I wanted to help believe me. But I genuinely did not know anything about 3D at the time and sure as shit did not know anything about WebGL. And, again, my laptop is in a retirement home. I can't bother it with all this new hip and cool 3D stuff. It needs to rest. &lt;/p&gt;

&lt;p&gt;Now, you might be asking, "Why didn't you charge extra for these services?" Weeeeeelll....&lt;/p&gt;

&lt;h1&gt;
  
  
  The Moon And The Stars
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;Terrific guy. Would definitely work with him again.&lt;br&gt;
    - Some pretty cool dude&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That's right. The reviews. I couldn't risk it. I wanted a good review throughout. I didn't want to have some fucker fuck up my good boy score and bring me back to the depth of Fiverr hell. I wanted to please the client (ew) as much as I could. Looking back, this part really sucked. Just when I was done with the project and I could finally focus on my own game or side project that I would be making, the client came in with, "Hey, can you compile this for me? I can't do it.". I could have just said, "But it'll cost ya extra, hon". (Yeah that just straight up sounds sexual I'm sorry). But I did not know how the client would have responded. Again, it was my fault. I wasn't experienced. I did not know what I could have and could have not said. And besides, these clients were fucking college students. A lot of them were also from third-world countries where 10$ is just a lot of money. Or at least somewhat sizable for a college student. I know because I live in a damn third-world country. You don't choose the clients on Fiverr. You take what you get. &lt;/p&gt;

&lt;p&gt;I felt like I was lucky to have this opportunity. I couldn't just kick the chance away and say no. I know more now. Fuck that shit. Opportunity my goddamn hairy ass. &lt;/p&gt;

&lt;p&gt;And, believe me, they know. They know they have the upper hand in this relationship. If you don't want to do what they ask for, they can just leave and find someone else. You're the loser here (you heard that before huh?). They know you want them more than they want you. You're replaceable, they are not. Perhaps on other freelancing platforms, you have more of an advantage. Choosing the clients and the projects and not waiting for scraps. &lt;/p&gt;

&lt;p&gt;And maybe you can do that too on Fiverr. If you are a big enough seller with lots of reviews (oh man I just missed the dick joke bus shit), then perhaps you can pick and choose from the clients who message you. But I wasn't like that. I only had those 13 clients come to me and review my gig. Now I only had 9 out of those 13 clients review my gig. Why? Well, Fiver, my friend. That's why. &lt;/p&gt;

&lt;p&gt;Essentially, the way it works on Fiverr is you create an order, deliver the product, and wait for the client to mark the order completed &lt;em&gt;or&lt;/em&gt;, if they're idiots or new, wait for 3 days until the order gets marked automatically for completion. However, if the order was &lt;em&gt;not&lt;/em&gt; marked completed &lt;em&gt;by&lt;/em&gt; the client &lt;em&gt;themselves&lt;/em&gt;, then you won't get a review. And for 4 out of these 13 unique clients, they didn't. Why? Well, it's basically because they didn't know or they just didn't care. I could have asked them, sure. But, again, I did not want to risk it. Call me paranoid or egotistic but I just couldn't bring myself to do it. It's like asking to like and subscribe down below (even though you can't). I mean, like, I used to be like you but then I took an arrow to the knee. &lt;/p&gt;

&lt;p&gt;Honesty, though? I couldn't care less. I just wanted to be done. I wanted it to end. I didn't care about the reviews I got. I didn't care about the money I got. I just wanted to end it. The order not the... yeah. I was &lt;em&gt;so&lt;/em&gt; done with the project when I delievered it. I couldn't look at it anymore. If the client wanted me to go back and change something, I wanted to barf. It was like going to a crime scene where two people got killed by butt fucking each other with a Swiss army knife. Like, I didn't want to see that again. I didn't care to see it again. If I had to endure the smell for 2 hours and personally remove the army knives myself, then I would do it if it meant I was gonna be out of there. I mean I hated the projects so much that I couldn't even keep them on my system when I was done. It was like bringing me ever-growing anxiety or just hatred. Pure frustration. I deleted every project I made on Fiverr. I have no trace. You might think that's sad but I couldn't be much happier. I didn't want to look at them. At all. I just wanted to get back to whatever game or side project I was doing at the time. I didn't care about their stupid college assignments. I just wanted to do &lt;em&gt;my&lt;/em&gt; project. I would suddenly get bursts of anger and frustration building up as soon as I saw that stupid green app notify me that someone messaged me. I wanted to throw my phone against the wall and delete that app. I wanted to remove my account completely and never come back. &lt;/p&gt;

&lt;p&gt;I think the reason for that anger was mainly because the project required very &lt;em&gt;specific&lt;/em&gt; ways of completing it. Again, they were all college assignments so they had to be using whatever they were learning at the time. I had one project where you just &lt;em&gt;had&lt;/em&gt; to use a Singleton class. Fine. Whatever. But then you also had to create a very specific 'Scene' base class that had very specific members and that class had very specific functions that took very specific arguments and then there needs to be another class that inherits from this class and then another class that inherits from that sub-class. I also had to use a very specific version of C++... like I wanted to fucking scream my lungs out and kill Andrew Ryan from BioShock because what the fuck! &lt;/p&gt;

&lt;p&gt;Maybe I'm acting like a spoiled brat here. Maybe I ought to be more grateful for this "opportunity". And, in an attempt to not seem like a brat, I will discuss a few of the "positives" of Fiverr. &lt;/p&gt;

&lt;h1&gt;
  
  
  Heaven And Hell
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;I hope you realize that these quotes are actually fake. You do? Okay cool &lt;br&gt;
    -Dude&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This has been quite the negative post I do realize that. And I do apologize. Initially, I did not mean to come off as negative but I could not help it, to be honest with you. However, I will make this right. I promise. It's not that I can't find any positives. Rather, the positives are just so few that I was embarrassed I couldn't find more. &lt;/p&gt;

&lt;p&gt;First, the money. Or rather, the lack thereof. In my 2 years of doing this, I made a little over 100$. But, honestly, that's my fault and I will get into that. You do have to remember, however, that Fiverr does take away 20%. Plus, in my case, when I transfer the money from Fiverr into Payoneer (Egypt doesn't have Paypal), it deductes 3$ from that. AND, because fuck me in the ass and call me Janice I guess, Payoneer takes 12% of the amount. But that's not all, Payoneer doesn't withdraw any amount less than 50$, you peasant. Hawk tuah. Buuuuut, it was the first time that I had ever made any resemblance of income from programming... like ever. I was able to buy a couple of things for me and my sisters which was nice at least. Was it a lot of money? No. Was it money though? Yes. And that's a plus I guess. &lt;/p&gt;

&lt;p&gt;Second, you can basically start on Fiverr even if you're an intermediate. I wouldn't say start at it as a beginner since that will be difficult. But you don't need much work experience or an impressive portfolio to start. At least in the criteria I started on, it was mainly university assignments which you can do if you know what you're doing. &lt;/p&gt;

&lt;p&gt;Third, not a lot of scams. From the 2 years I spent there, I only came across, like, one scam. So that's nice. (I'm running out of positives to say as you can tell).&lt;/p&gt;

&lt;p&gt;Fourth, I don't know. Pretty good-looking site I guess. &lt;/p&gt;

&lt;h1&gt;
  
  
  This Is The End
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;If you had one shot. One opportunity. &lt;br&gt;
    -Guy who's named after a chocolate&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In retrospect, I came at this with the wrong mindset. I came into this with a little bit of naivety and a &lt;em&gt;lot&lt;/em&gt; of inexperience. I wanted to be a part of cool projects that would be pretty fun to program for. I wanted to actually deliver a project that I was happy with and I could be proud of. Working hard on it and getting somewhat of a reward out of it. Even if it's not a financial reward. Just being proud of the project is a good enough reward for me.  I can tell you for sure, that was the absolute worst mindset I could have had at the time. &lt;/p&gt;

&lt;p&gt;I turned down a lot of projects from clients because I thought I couldn't do them. I wanted to deliver something pristine and perfect. I wanted to accept a project that I knew &lt;em&gt;absolutely&lt;/em&gt; I could do. I wanted to learn something new. Something that I would have never learned otherwise. But what I got instead was the same project over and over again just with a different skin. &lt;/p&gt;

&lt;p&gt;It's crazy but I learned &lt;em&gt;way&lt;/em&gt; more from just doing game dev on my own than freelancing with it. I was moving forward as a programmer but I was stuck doing the same fucking projects for some client. I mean I made a whole ass 3D game from scratch on my own. I barely was able to do it because of my laptop but god damn it I did it. I learned so much from it. I was happy every single fucking second while I was programming that game. I just didn't give a shit about anything or anyone. But, as soon as I see someone message me on Fiverr, it's back to programming space invaders clone once again. I had to give all my time to these projects since they usually had a 2 or 3-day deadline. So I had to completely abandon my own projects just to make theirs. And I felt like sucking Bill Clinton off at the end. Fucking disgusting. &lt;/p&gt;

&lt;p&gt;What can you take from this? I don't really know. Entertainment? Joy? Relatability? I just wanted to express my anger somewhere and this seemed like the best place. &lt;br&gt;
I'm sorry if this was too dark or bleak. I'm sorry if this was too bitchy. I just wanted to talk about it. That's it really. &lt;/p&gt;

&lt;p&gt;However, I would loooove it if you could tell me about &lt;em&gt;your&lt;/em&gt; experience with Fiverr. Perhaps freelancing as a whole. Whether that would be game dev freelancing or just freelancing in general. Perhaps you have a better story than mine. Come on! Share your stories! Share them... or else. Or else I'll cry like really hard, dude.&lt;/p&gt;

&lt;p&gt;Cheers.&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>freelance</category>
      <category>fiverr</category>
      <category>programming</category>
    </item>
    <item>
      <title>My Dream Game Engine</title>
      <dc:creator>IWantToDeleteThisButICant</dc:creator>
      <pubDate>Sun, 25 Aug 2024 22:23:48 +0000</pubDate>
      <link>https://dev.to/mah_doh/my-dream-game-engine-3peh</link>
      <guid>https://dev.to/mah_doh/my-dream-game-engine-3peh</guid>
      <description>&lt;h1&gt;
  
  
  Is That Even A Dream?
&lt;/h1&gt;

&lt;p&gt;We always hear about the dream game. The game every game dev hopes to make. Whether it be an Open-world RPG with Dark Souls mechanics and cute characters like Animal Crossing or a Legend Of Zelda clone with horror elements, but we never hear about dream game engines, do we? &lt;/p&gt;

&lt;p&gt;There's a big reason for that: you use what's available. If you're an indie dev, you probably just use Unity, Godot, or Unreal. Nothing wrong with that obviously. But, if you are like me--mentally deranged, then you probably make your own game engine or even make your games from scratch. &lt;/p&gt;

&lt;p&gt;So, in this post, I'll be talking about that. The game engine of my dreams. The one I wish to use for all eternity. The one I wish to marry and have little game kids with. The one game engine I wish to die with... &lt;/p&gt;

&lt;p&gt;Wait, what we were talking about?? Oh... &lt;/p&gt;

&lt;p&gt;Before I outline to you my perfect big tiddy Goth game engine that I want to choke me, I'll first get into my ideas for the "perfect" game engine. Everyone's idea of a perfect game engine is different. So, it is only fair that I give you &lt;em&gt;my&lt;/em&gt; own philosophies regarding libraries and their uses and, specifically, game engines. I also want to preface this by saying that this is &lt;em&gt;my&lt;/em&gt; opinion. You might have a different opinion, and that is &lt;em&gt;completely&lt;/em&gt; okay. You might think I am wrong. No problem. Would love to hear why. But always remember, I am only stating my &lt;em&gt;opinion&lt;/em&gt; and not just hard &lt;em&gt;facts&lt;/em&gt;. Those opinions are subject to change so don't take this as the bible of making game engines.&lt;/p&gt;

&lt;p&gt;Good? Okay good. Now let's start.&lt;/p&gt;

&lt;h1&gt;
  
  
  UI Or No UI. That Is The Question
&lt;/h1&gt;

&lt;p&gt;Using the UI of the engine to make your game is great! One single button to add an entity to the scene. One button to add a child node. A few buttons to animate. Some other buttons to add a camera. However, I am a programmer. And that's a sentiment that is going to be echoed throughout this post. I like doing things the dirty way. Get down on my knees and... you get the point. Pressing on a button to add a scene is not intuitive to me. Making a &lt;code&gt;class&lt;/code&gt; or a &lt;code&gt;struct&lt;/code&gt; to hold the information of the scene &lt;em&gt;is&lt;/em&gt;, however, intuitive to my programmer's brain. &lt;/p&gt;

&lt;p&gt;It might seem illogical to completely get rid of the UI and... it is. Having no UI for your engine at all is not the greatest idea. It is especially bad if you want your engine to be used by a wide variety of workers. Artists, musicians, designers, and what have you. Making the artist (who never coded in their life before, by the way) go for a deep-dive into your shitty codebase just to add an entity is, save to say, an absolutely &lt;em&gt;terrible&lt;/em&gt; idea. However, I don't want to make the prestigious programmer to get too comfortable and use the buttons to do the work either. So, what's the solution here? &lt;/p&gt;

&lt;p&gt;In my view, there are two separate parts to an engine: &lt;br&gt;
    - &lt;em&gt;Core&lt;/em&gt;: This is where all of the fundamental logic of the engine exists. The rendering, the window creation, the event pooling, the input, the entity and scene management, and so on. &lt;br&gt;
    - &lt;em&gt;Editor&lt;/em&gt;: This is where the front end of the engine lies. This layer will call functions from the &lt;em&gt;Core&lt;/em&gt; layer of the engine when a button is clicked, for example.&lt;/p&gt;

&lt;p&gt;Therefore, in my opinion, you should give access to that core part of the engine to whoever desires to go that deep. You might even split the engine up into &lt;em&gt;three&lt;/em&gt; layers instead of two. The first is just the core (core rendering, window management, allocators, logging, input), the second layer which we will call the engine (lighting, shadows, entities, scenes, particles), and, finally, the third layer which is the editor as we discussed earlier. This might be more complex but it will make the user be able to choose the core framework of the engine if they don't like the way we handle entities for example (what assholes). &lt;/p&gt;

&lt;p&gt;There are already examples of this. Godot lets you access its own C++ layer so you can make your game without the need for an editor. Unreal, while not the same as Godot, does have its source code freely available on GitHub which you can just take and add or edit whichever you please. And Unity has... well, let's not talk about Unity. &lt;/p&gt;

&lt;p&gt;This way, you can appeal to Joe the programmer, and Abby the artist. Do you want to use the UI? Go ahead. You were dropped on your head as a child and now you're retarded and use this engine without UI? Sure, you can do that. And you shouldn't make the non-UI part of the engine hard to get up and running. Even though Godot has that GDNative plugin, it is a hassle to set up. The core engine is already a library. You can just give that library to the user and they can use it as they please.&lt;/p&gt;

&lt;h1&gt;
  
  
  You, Me, And The User
&lt;/h1&gt;

&lt;p&gt;Now, what is the most important thing about a library/framework? That's right. Say it with me now. Your mom. Yes. The user. Whoever is using this library or framework is the most important to you. &lt;/p&gt;

&lt;p&gt;Long ago (maybe like a week ago), I finished a 3D game of mine. Before starting the game, I went out of my way to make an engine for it. It was more of a template than an engine. It didn't have an editor or anything like that. However, it did make it easier to make games with OpenGL. I didn't have to touch one line of OpenGL or GLFW. Do you want to create a window? Just use this function: &lt;code&gt;window_create&lt;/code&gt; done. Do you want to load a texture? Done. Get input? No problem. I thought everything was perfect. I thought I was the smartest person alive! But, as with everything in my life, I was wrong. It was the most horrendous library I ever used. Even worse than your mom yes.&lt;/p&gt;

&lt;p&gt;It was called Gravel (the engine, not your mom). I only thought about the implementation of the engine. How could I load a 3D model? How can I make a texture rotate? How can I render text (cue Vietnam flashbacks)? I thought about it and then implemented it. No thought of the actual API. I didn't care how my code would be &lt;em&gt;used&lt;/em&gt;. I only cared about how it will be &lt;em&gt;implemented&lt;/em&gt;. In fact, with a lot of my libraries and frameworks, it was the same problem. The only thought I put into them was just the implementation.&lt;/p&gt;

&lt;p&gt;That's why, in my opinion, it is &lt;em&gt;much&lt;/em&gt; better to outline the way you want the library to be used rather than focus on the implementation. You need to think about who will use this engine and what they are going to be using it for. If you have a solid foundation, you can always change the implementation later. Premature optimization is the devil. I don't know if that's true but Jared always tells me about it. &lt;/p&gt;

&lt;p&gt;For example, let us assume you have a function called something like this: &lt;code&gt;render_model&lt;/code&gt;. This function, as the name implies, will render a 3D model at the specified transform position. Now, how is that function implemented? Doesn't fucking matter. Rather, the question you &lt;em&gt;should&lt;/em&gt; be asking is how will this function be used by the user. Is this function suitable the way it is set up currently to render a model without hassle? Try it. Make a game or two with it. Perhaps it doesn't make sense. Perhaps this function needs an extra parameter. Perhaps it doesn't. You &lt;em&gt;need&lt;/em&gt; to use your library in order to get a feeling of how the user will be using it. Stop thinking about the implementation for once and just think about the user. Take all of the hate and anger you endured from the C++ STD library and try to be the good guy here. &lt;/p&gt;

&lt;h1&gt;
  
  
  Everything Or Nothing
&lt;/h1&gt;

&lt;p&gt;As programmers, we &lt;em&gt;love&lt;/em&gt; to overscope everything. We shall add lighting to this engine. Also, we will add some Navmesh pathfinding. And, after breakfast, we shall conquer that juicy ass. Calm down. You are not Unity. You are not Godot. And you are &lt;em&gt;not&lt;/em&gt; Unreal for damn sure. You are just one guy who is trying to allocate some free time to make a game engine. A game engine no one asked for. &lt;/p&gt;

&lt;p&gt;Let's assume you are trying to make a racing game. You have two choices: use Unity (shoot me in the balls) or use this other engine. Now, since I know you more than I know myself, I know you would have just picked Unity right? I'm right. I'm always right. However, that other engine is actually an engine specifically made for racing games. Many games were made and tested with this game engine. It has all the specifics and tools to help you make a racing game. Now, can you make a first-person shooter with this engine? Well, yes. You still have a camera that might be set to first person anyway. There's a way to render models and meshes, check collisions, fire events, and so on. Nothing is stopping you from making a FPS game with this engine. However, you'll be using its absolute &lt;em&gt;full&lt;/em&gt; potential if you make a racing game with it. &lt;/p&gt;

&lt;p&gt;And that's the problem with Unity. Unity is trying to be too many things at once. It's trying to appeal to the indie market (arguably, its biggest user base to date) &lt;em&gt;and&lt;/em&gt;, at the same time, it is trying to emulate Unreal. Unity is trying to pull too many strings at once which is hurting its potential. At least with Unreal, it knows what it is: a pretty capable and strong game engine, ready to make any 3D game you have in mind. And, with Godot, it's trying to appeal to that indie audience. Making small simple games that don't require the complexity of many tools Unreal provides you with and at the same time being quite capable. &lt;/p&gt;

&lt;p&gt;Am I saying you should &lt;em&gt;not&lt;/em&gt; make a general-purpose game engine able to do every game in existence? No. What I &lt;em&gt;am&lt;/em&gt; saying, however, is to focus your attention on one area of the game engine. There are millions (too many but fuck you) of game engines out there. So many to even count. Each and every single one of them has a quirk. Something that makes it stand out from the others. Anyone with a sizable amount of experience can create a general-purpose game engine. What makes yours so special? &lt;/p&gt;

&lt;p&gt;Maybe your engine is really good at making grand strategy games. Maybe it is an engine that is specifically designed for ASCII games on the terminal. Perhaps your engine has a weird name like Game Maker. Ew. &lt;/p&gt;

&lt;h1&gt;
  
  
  Pick Your Battles, Son
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;Write once and run everywhere.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That's a sentence you probably heard before. Java, the all-great programming language, was marketed as a language that could run on any and all systems. And, to their credit, it was correct. You see, Java was made on top of a Virtual Machine (VM). This meant, to grossly oversimplify, it didn't have to write its own implementation on every CPU out there. You could just write the Java application and it &lt;em&gt;will&lt;/em&gt; run. &lt;/p&gt;

&lt;p&gt;If you ever tried to make a game with Unity, you would know that Unity could build and package up your game to multiple platforms. Windows, Linux, Mac, Switch, Android, IOS, and the Web. Now that's amazing! Any game you make you can play it anywhere! Expect that's not really the case. &lt;/p&gt;

&lt;p&gt;As you and I know, cross-compilation sucks major ass. I mean you can build for these systems, but then you will have to get a Linux VM up and running, get a Mac computer somehow, have both an Android &lt;em&gt;and&lt;/em&gt; an IOS device, know how to use emscripten or something similar to build for the web, and, finally, you will have to get a SDK for the Switch from Nintendo. Yeah. That's not possible. Perhaps (maybe), you can get Windows and Linux up and running. Maybe even Mac if you have the hardware (which I doubt). But building for mobile? Well, you &lt;em&gt;have&lt;/em&gt; to have a Mac computer in order to build for an IOS device. Android has its quirks that you will have to learn and worry about. And the web... well no cares about that. We can just give it a cookie. It'll be happy.&lt;/p&gt;

&lt;p&gt;You have to pick and choose your battles. For example, currently, I can build for both Windows and Linux. Web and Android if I can be bothered. And, even though it is a pain in my Henry Tudor, I can still do it with no problem. However, the other platforms? No thanks. I will not risk my time or sanity for 2.5% of the desktop market. &lt;/p&gt;

&lt;p&gt;And this is not just about being platform-agnostic either. This is about everything you will come across on your engine-making journey. In a perfect world for me, I don't need any libraries. I don't have to import or compile any libraries I need for my project. I can just build &lt;em&gt;my&lt;/em&gt; project and that's it. However, I can't be bothered to load in and read PNG or JPEG files. So just use &lt;code&gt;stb_image&lt;/code&gt; for that. Same thing with audio. Same thing with font loading. However, there are a few things &lt;em&gt;I am&lt;/em&gt; willing to spend time on. Dealing with the different OS libraries to create and handle window creation. Physics, math, rendering, and entity management. All of these things I am fond of and I wish to learn more about. I actually &lt;em&gt;do&lt;/em&gt; want to spend time delving deeper into t these topics. &lt;/p&gt;

&lt;p&gt;Let &lt;code&gt;stb_image&lt;/code&gt; handle my textures for me. It is a pretty trusted library that I have used for &lt;em&gt;many&lt;/em&gt; of my projects. I don't care much about image loading either so why not?  &lt;/p&gt;

&lt;p&gt;You have to pick your battles. You can't just do everything by yourself. Make sure to &lt;em&gt;not&lt;/em&gt; waste your time on something that you do not care about. Making an engine is a hobby after all. Treat it that way. Forever.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Dream Game Engine
&lt;/h1&gt;

&lt;p&gt;So, after all of that, what's the point? What's the point of all that rambling I meant not the... yeah. Well, these are thoughts I have had for the better part of a year. I wanted to make my &lt;em&gt;own&lt;/em&gt; game engine but I never found a good fit. I wanted to make something that I could be proud to show to people. An engine I can actually use for my own games without vomiting from disgust and anger. &lt;/p&gt;

&lt;p&gt;Perhaps this is the best opportunity to announce my new series in this blog. The Panda Engine devlog series. This is an engine I have been preparing to make for a long time. An engine I thoroughly thought about. I can't tell you it will be the best engine in the damn world, but it is an engine that I am very passionate and excited about. &lt;/p&gt;

&lt;p&gt;The upcoming devlog series will be somewhat educational. As I will try to explain the concepts I have learned and know along the way. Hopefully, you will get something out of it. And if you didn't... then I will seriously cry, dude.&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>programming</category>
      <category>devlog</category>
      <category>cpp</category>
    </item>
    <item>
      <title>Our Only Hope - Devlog 3</title>
      <dc:creator>IWantToDeleteThisButICant</dc:creator>
      <pubDate>Wed, 18 Oct 2023 12:31:55 +0000</pubDate>
      <link>https://dev.to/mah_doh/our-only-hope-devlog-3-484b</link>
      <guid>https://dev.to/mah_doh/our-only-hope-devlog-3-484b</guid>
      <description>&lt;h2&gt;
  
  
  The Scope Creep Demon
&lt;/h2&gt;

&lt;p&gt;I fell into the trap. The trap every game developer falls into. The scope creep trap. Even though I told myself this game was going to be small, short, concise, and to the point, I still went big. I kept adding ideas to the game that were just too big for me. Perhaps if I had motivation for this type of game and/or I was a better programmer, I would have put more effort into making these features come true. But, in fact, I had no motivation for this type of genre &lt;em&gt;and&lt;/em&gt; I was not experienced enough to implement the different features I had thought of. &lt;/p&gt;

&lt;p&gt;If you play the game, you'll see how simple it is. In fact, you don't even need to play the game. Once you read this article you'll understand how simple this game is. However, I tried to make it complicated and big for no reason other than: "It would be cool if there were chicks with tits, bro". Is it still fun, though, despite cutting out a lot of features? I think so. But that's not the point. My goal with this project was to tackle a game that actually was my own. Maybe it doesn't have the most innovative techniques of game design, but I still tried to make a game that was fun. Not just a clone of Pong or Space Invaders. I wanted to make a game that I designed and thought about. A game that had inspirations from other titles. A game I would not call a &lt;em&gt;clone&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;But, I'm not a good programmer. Not even close to it. Perhaps in a year or two or three but not now. If you read the first devlog, you'll know that, for some months, I did not make a game just because I kept trying to think big. I wanted to make a DOOM clone without even having the knowledge or the expertise in how that particular tech works. I wanted to make an investigation game without actually knowing how the various systems of a game like that are going to be implemented. Sure, it is normal to go into a project without knowing how certain parts of the code are going to be implemented. However, what's not normal, is trying to make a game that has systems you absolutely have &lt;strong&gt;no&lt;/strong&gt; clue how they work. That's fine if it's one system or two, but when 90% of the systems that need to be implemented are not in your domain of knowledge that's when it becomes a problem. If you read the devlog where I talked about the engine of this game you would know that a lot of the systems and components of the engine were already thought of and even implemented in previous games. The problem came in the gameplay code.  &lt;/p&gt;

&lt;p&gt;Ever since I went into the lower-level side of game programming, I always sacrificed the gameplay code. The thing that I focused on the most was the engine code. The rendering, the scenes, the UI, the collisions, and so on. I never stopped to think about the player's controls, a different way to handle enemy spawns, or even how to make the game fun. All I thought about was the engine of the game and not the game itself. However, that's still not a problem if you try to just focus on learning new things. Making a game just for the sake of learning how the camera system works is totally justifiable. And that's what I was trying to do for the past year and a half. I wanted to learn how the different lower-level systems work in games. I was interested and intrigued by them. I wanted to learn more about them. But expecting to make a full and enjoyable game out of it was not the healthiest thing to do. &lt;/p&gt;

&lt;p&gt;The challenge I faced while making this game was not the technical aspect. But, rather, the gameplay aspect. How do you make a fun game while being handicapped by your own abilities? Well, you just have to keep your scope to a limited degree and use what you know. And that's &lt;em&gt;completely&lt;/em&gt; not what I did. &lt;/p&gt;

&lt;h2&gt;
  
  
  The Original Design
&lt;/h2&gt;

&lt;p&gt;In the first devlog, I said that I prototyped the hell out of this game. And I did... to some degree. I had a very specific idea of what the core gameplay loop of this game was going to look like. The main idea is that you fight zombies with medieval weapons. That's what I prototyped. A simple player controller, some zombies that followed the player around, and a very simple melee system. I tried to make the zombie kills as juicy as possible. I imagined there being particles, some sound effects, and some text flying all over the place. While some of these things stuck around, I still didn't make the zombie kills as juicy as I wanted. But, nonetheless, that was the main idea that I wanted to hewn in. A satisfying way to kill zombies. Even though I got distracted trying to implement various different features for the game, that part never really escaped me. And I kept it even after removing so many features. &lt;/p&gt;

&lt;p&gt;However, that was the only part that I prototyped. Of course, that wasn't the only thing I thought about making in the game. In order to make the game have more personality than just a satisfying zombie-slayer game, I wanted to add a shop system.&lt;/p&gt;

&lt;p&gt;The shop system in this game was going to have three categories the player can buy from. Each category had four items the player could buy. The categories were weapons, armor, and potions. Not very innovative I know. Each item had a leveling system. The player could level up an item by killing a thousand zombies while using it. Each item in the shop has four tiers. The final tier is considered to be very powerful but very hard to obtain. For example, one of the potions in the game was the durability potion. If the player manages to level that potion up to the last tier, both the armor and the weapon the player equips will have unlimited durability. The theme is like that for all of the items in the game. Originally, I had thought about having multiple items in the game with more crazy and outlandish ideas for each one. But, thankfully, I backed down and decided to just have four items for each category instead.&lt;/p&gt;

&lt;p&gt;But how can the player equip these items? Well, with blood, of course. Every time the player kills a zombie, they will get a random amount of blood. The player can then use the blood accumulated from each wave and buy the desired equipment they would like to use. However, the items change their cost when upgraded. The player can still buy a weaker version of the item at a lower cost if they wish, though. If the player dies, they will lose a big chunk of their blood. Effectively making them equip weaker items and restart them from scratch. However, death won't reset the items' level. Death will only make the player restart from the first wave with a lot less blood than what they had. &lt;/p&gt;

&lt;p&gt;As I said before, every category has four items to choose from. The weapons category had the light sword, the medium sword, the heavy sword, and the spear. The armor category has light armor, medium armor, heavy armor, and naked armor. The potions category has the health potion, the damage potion, the durability potion, and the dexterity potion. Each had their own tiers, of course. And each had a different play style. For example, going for the light sword and armor, the player will be quite nimble and fast but very weak both in offense and defense. On the extreme end, if the player went with the heavy sword and armor, the player will be very slow but very hard-hitting and will have a lot of protection. If the player goes the crazy route, choosing to pick the spear and the naked armor, the player will be very vulnerable but it will also be somewhat fun and challenging.&lt;/p&gt;

&lt;p&gt;A normal game would first take the player to the shop scene, where they would need to make a choice for the items they will use to fight the zombies. The player will initially be given a small deposit of blood in order to get them started. When the player chooses the items they desire, they will be taken to the game scene where they will be immediately prompted to fight the oncoming waves of zombies. In every wave, there are a limited amount of zombies. The first wave starts out with only 50 zombies. Any other wave will increase 10 to that number. You'll have to kill all of the zombies in the wave in order to end it, of course. Once the wave is over, the player will be taken back to the shop scene again and the cycle continues. &lt;/p&gt;

&lt;p&gt;However, that was not all. Since this game is heavily inspired by COD Zombies, I wanted to put in a small easter egg to have somewhat of an ending to the game. I can't find the details of the easter egg anywhere and I don't remember it exactly but I do remember that it was very simple in theory. &lt;/p&gt;

&lt;p&gt;For a professional game dev who has made many games beforehand (maybe even games similar to this one), this is not a complicated or even out-of-scope idea. It seems very small and manageable. However, I'm &lt;em&gt;not&lt;/em&gt; a professional game dev who made many games beforehand (and I definitely didn't make a similar game to this). While thinking of the design of this game, I had a voice in the back of my head occasionally telling me that I would not be able to tackle any of these features. They're cool features (at least I think so) and they can be done... but I still knew that I couldn't do them.&lt;/p&gt;

&lt;p&gt;But how much of this original design changed? What stayed and what didn't?&lt;/p&gt;

&lt;h2&gt;
  
  
  The Current Design
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;A lot&lt;/em&gt; of things had to be cut from the original design. There were some features that were cut out very early and some that stayed till the end but still got cut out, nonetheless. There were even features that stayed only in the design doc. I never even tried to code it up because I was just ready to finish this game and get it over with. &lt;/p&gt;

&lt;p&gt;One of the first features to be cut out from the original design was the item tier system. I had a general idea of how to make a shop system and how to tweak the different values of the items. I knew that putting all of the values of the different items directly into the code was not going to be a good idea. The solution that I thought of was YAML. I could just write the names of each item in a YAML file, have different values for each of the nodes, and read them in when it came time for initialization. Originally, I had put a little indicator for each of the items that told of their tier. But every tier had different values. And every item had a different interpretation of tiers. Should I make different entries in the YAML files for each tier of the item? Should I take the number of the tier and try to create the logic of the tiers in the code instead? Should I add a chick with big tatas that would cheer the player in his zombie-slaying ventures? All questions that were hard to answer. &lt;/p&gt;

&lt;p&gt;As time went on, I started to get more and more disinterested in the project. Every time I came across a bug caused by the leveling system, I would just close my laptop and not work on the project for the whole day. There were days when I completely refrained from touching the project whatsoever. I would procrastinate and not think about the project at all. And, during that time, my mind started to think of the worst thing ever. The question that I feared so much. The question I knew would come up: Should I become a web dev? &lt;/p&gt;

&lt;p&gt;At that point, I knew that trying to add a layer of complexity to a project that was supposed to be simple was not going to help me finish it. I decided to just abandon the feature altogether. But that wasn't the only feature I cut out. &lt;/p&gt;

&lt;p&gt;Even though that feature was part of the original design, I never went far with it. It was very easy to remove it completely from the codebase without having any problems whatsoever. But, there was a feature that I went very deeply with. The shop scene. &lt;/p&gt;

&lt;p&gt;In the final design, the shop scene looks very different from the initial design. There is no concept of weapons or armor. There are just potions. However, I did not remove this feature because it was hard to implement. In fact, I implemented this feature and it was in the game for so long that I doubted I'd ever remove it. Everything was fine and dandy with this feature. However, as I was playing the game, I noticed that I would always gravitate towards a specific item in the game: the spear. &lt;/p&gt;

&lt;p&gt;As I said before, the core idea of the game is to make the zombie killing satisfying. It should feel juicy and invigorating. Killing the next zombie coming towards you should never feel dull. But, despite that, I felt very bored and uninterested when I used the different items in the game. The spear seemed to be very fun when I first thought of it. And it was very fun when I implemented it in the game. You see, with every other weapon in the game, the player will have to get close to the zombies and swing their sword at them. With the spear, however, the player can just throw the spear and see it penetrate a line or a group of zombies all at once, killing them in the process. When I was hunting for a specific bug that was making me pull my ass hair out, I found myself playing more of the game while I had the spear equipped. Playing with the swords felt awkward and dull. Using the spear, however, felt right. It was the exact feeling I wanted to convey. Seeing the spear flying in front of you and penetrating a line of zombies in one hit was one of the most satisfying feelings I had while playing any of my games. It felt right... it felt fun. &lt;/p&gt;

&lt;p&gt;Perhaps removing the different weapons and armor in the game was a mistake, but I don't regret it since it made for a very fun game. I felt the other weapons and armor were useless. Why would anyone choose the medium sword if the spear is way more fun? I could perhaps have made it necessary for the player to choose the earlier swords in the game. Maybe make the spear very expensive and hard to get. Or perhaps I could make the other swords fun as well by giving them a certain twist or fun idea. But, again, I refrained from that as I had no motivation to do it.&lt;/p&gt;

&lt;p&gt;As you can see the game changed a lot from the original design. I had in mind to have a camera system, some joystick controls, an easter egg, and many other things but I decided that these systems are better off implemented in another game. Other games that I would make specifically to implement these features. I already had to learn and implement a lot of new features. Features I never even knew how to start with. Putting on top of that other new systems and features I never implemented would have been overkill and would perhaps have been enough to abandon this project altogether.&lt;/p&gt;

&lt;p&gt;So was this project useless? Had I wasted my time with it? The simple answer is no.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Experience Was Amazing
&lt;/h2&gt;

&lt;p&gt;Despite the project being small in size, it still gave me a lot of big lessons (IS THAT A DICK JOKE??!!). Lessons that I would have never learned if I didn't do it. I knew this project was way over my head when I first started it but I still did it because I knew that I was going to learn a lot from it. I now know my limits. I know my strengths and weaknesses. I now know the areas I have to get better at. I now know how to implement the basic forms of the new systems and features I made in this game. How else would I have learned these lessons without making this game? I had very big ideas for this game. Sure I did not stick with those ideas but I now know what ideas to stick to. Ideas that I will feel motivated for even if I'm limited in my knowledge. Games that will give me motivation to learn a new thing just to implement it in the game. Games that will make me keep going despite the setbacks. &lt;/p&gt;

&lt;p&gt;Knowing your current limits and capabilities, as I have found, is the most important thing you &lt;em&gt;need&lt;/em&gt; to do before entering a new project. And you'll never know these limits and capabilities without testing yourself and pushing yourself to the limit. How else are you supposed to know if you know how to make a rendering pipeline without trying to make one? It was hard trying to accept the fact that I'm still not good enough to make my dream games but it was a fact I needed to know. And, now that I know my limits and capabilities, I can try to adhere to them and make the games that I can make, learn new things by pushing my limits, and understanding that, while I might be a better programmer than the one I was a year ago, I still have a lot to learn.&lt;/p&gt;

&lt;p&gt;And always remember, Huzzah!&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>cpp</category>
      <category>programming</category>
      <category>development</category>
    </item>
    <item>
      <title>Our Only Hope - Devlog 2</title>
      <dc:creator>IWantToDeleteThisButICant</dc:creator>
      <pubDate>Mon, 09 Oct 2023 05:41:41 +0000</pubDate>
      <link>https://dev.to/mah_doh/our-only-hope-devlog-2-2e6n</link>
      <guid>https://dev.to/mah_doh/our-only-hope-devlog-2-2e6n</guid>
      <description>&lt;h1&gt;
  
  
  My Problem With Collisions
&lt;/h1&gt;

&lt;p&gt;Ever since I started my journey in the lower-level stage of game programming, collisions have been the bane of my existence. Even when I used Unity, I had problems with organizing collisions. But I really felt the pain of collisions when I delved deep into game programming. I even once quit making games from scratch entirely and decided to use Godot twice just because of collisions. I ultimately went back and decided to give collisions another try but it still was difficult. Every time I decide to make a proper game that isn't a clone of a classic game like Pong or Space Invader, I always give up when collisions come around. I always stand up and tell myself that I'll do it this time but I just end up suffering for a week and then giving up. I decided to learn Rust just to procrastinate collisions on a game I was working on. I don't regret learning Rust, of course, I still learned something at the end of the day. However, I eventually decided against using Rust (that's a new article idea right there) which, in my eyes at least, was just a waste of time. But why? Why are collisions so hard for me? Well, my friend, it's simple: I slept during math classes. &lt;/p&gt;

&lt;p&gt;Geometry and trigonometry are the &lt;em&gt;most&lt;/em&gt; important concepts you &lt;em&gt;should&lt;/em&gt; learn if you want to delve deep into the lower-level game programming environment. You will benefit a lot from learning them. Collisions, rendering, and even gameplay code will require you to have geometry and trigonometry knowledge. They are &lt;em&gt;very&lt;/em&gt; important subjects every game programmer should know about. And, as you can see, I'm suffering currently because I dismissed them as being nothing more than stupid concepts I'll never use in my life. &lt;/p&gt;

&lt;p&gt;That's why engines exist. To make you not care about these concepts. The engine takes care of all of these things for you. You don't have to worry about anything. If you just want to make games and you're not a programmer by trade, then who cares? Let the engine do these things for you. But, if you &lt;em&gt;are&lt;/em&gt; a programmer by trade then you have to... no, &lt;em&gt;need&lt;/em&gt; to learn these concepts. They are fundamentals. Always learn the fundamentals. Even if these fundamentals will make you gouge out your brain from your ear holes, you still need the fundamentals.&lt;/p&gt;

&lt;p&gt;"Alright then," you might say, "why not use a physics engine?" That's a good question, my friend. Truly, why &lt;em&gt;don't&lt;/em&gt; I use a physics engine?&lt;/p&gt;

&lt;h1&gt;
  
  
  The Anatomy Of A Physics Engine
&lt;/h1&gt;

&lt;p&gt;Physics engines are plenty. Box2D, Chipmunk, Physac, Bullet, and Havoc are just some of the physics engines that are out there. Every game engine out there has a physics engine running under the hood, be it a custom or third-party physics engine. There's a physics engine for both 2D and 3D. But what are physics engines? If you made a player character stop after hitting a tile does that mean you made a physics engine? Well, the short answer is no. Physics engines are much more than basic collisions. Physics engines are what they sound like &lt;em&gt;they try to simulate real-world physics.&lt;/em&gt; They have a range of functionalities. Rigid bodies, chains, cloth physics, car physics, hair physics, and many many more. They try their best to simulate real-life physics just like the one that Issac Newton guy made up. Of course, not everything that happens in real life gets replicated one-to-one in games. That's why the word &lt;em&gt;simulate&lt;/em&gt; is there. They aren't trying to make a replica of real-world physics, rather, they try to make the player &lt;em&gt;feel&lt;/em&gt; as though the physics are real. &lt;/p&gt;

&lt;p&gt;Even though it might seem shocking, the most crucial part of a physics engine isn't actually the physics, it's actually the optimizing that occurs under the hood to be able to handle potentially multiple bodies colliding and bouncing with each other. The physics are all there. They are all just formulas you can find on Wikipedia, articles, scientific papers, or books. You can find YouTube videos of physics professors explaining the concepts to you. However, making sure that the game runs on a smooth 60 FPS despite there being one thousand bodies actively colliding with each other is something you cannot find so easily. Usually, these physics engines break the bodies up into a quadtree or some other kind of data structure. The bodies only check collisions with other bodies that have a possibility of colliding with them. If a body is on one end of a map and another body is on the other end, then there is absolutely no use in checking for collisions between these two bodies since, obviously, they will never collide, or at least not in this frame. But that's not the only optimization a physics engine will have to do. There are also the complex and computationally heavy calculations the physics engine will have to make. These calculations are filled with sines, cosines, tangents, and many more expensive operations that need to be carried out. How could a physics engine make all of these calculations while steadily keeping a smooth frame rate? That's the difficult part of a physics engine. Not the physics formulas but the optimizations it has to make. &lt;/p&gt;

&lt;p&gt;But why am I telling you all of this? Why is the anatomy of a physics engine relevant to what this article is about? Because you need to understand how big of a package a physics engine is. &lt;/p&gt;

&lt;h1&gt;
  
  
  Why You Should And Shouldn't Use A Physics Engine
&lt;/h1&gt;

&lt;p&gt;If you decided to make a game where the main focus is the physics then you have to use a physics engine. Games like Gish or Angry Birds have too many physics elements in them, making them perfect candidates for games that need a physics engine. The main draw of those games is that the character moves (or flies in the case of Angry Birds) using physics simulations. In these games, the characters move in a very satisfying manner all thanks to the physics engine. Car games where tires and car pieces fly all over the place after a collision are also another example of games that simply &lt;em&gt;need&lt;/em&gt; a physics engine. The developers of those games had to either make their own physics engine or use a third-party one like Box2D or Havoc. While making a physics engine is a very fun-sounding idea, making it in the middle of making your game is not a very fun-sounding idea. A game where the main draw is satisfying physics just simply needs a robust and optimized physics engine. There are just too many edge cases and calculations these games would have to handle if they weren't using a physics engine. Let the math do the physics, not you. &lt;/p&gt;

&lt;p&gt;But what if you're not making a physics-focused game? What if you just want to make a simple 2D top-down RPG like Zelda or Earthbound. "Physics" in these games is only collision-based. Check if a character is colliding with an entity, if that entity is static then stop the character from moving on that axis, and that's it. The only "physics" that matters in these games is stopping the player or any other character from walking over a static tile. Perhaps there's a knockback effect when the player hits the enemy or when the enemy hits the player but that can be accounted for. It can easily be programmed by hand. Do you need a physics engine in &lt;em&gt;that&lt;/em&gt; case? Of course not! That's the reason I explained to you the anatomy of a physics engine before. I wanted to let you know that integrating a whole physics engine just for a simple, "stop the player if they collide with a rock" is just &lt;em&gt;way&lt;/em&gt; too much. It's an overkill. A physics engine is so much more than just a collision resolution tool. It's a whole-ass engine. It can handle &lt;em&gt;sooooo&lt;/em&gt; many edge cases. Again, if making a "physics game" is your intention, then, by all means, use a physics engine. But if all you care about is basic collision resolution between a static tile and a "moving" entity then a physics engine is just way too much. &lt;/p&gt;

&lt;p&gt;"But wait," you say, "aren't &lt;em&gt;you&lt;/em&gt; using a physics engine?" Well of course I am! I'm using Box2D in particular. Why? Because I'm a hypocrite!&lt;/p&gt;

&lt;h1&gt;
  
  
  Why Am I Using Box2D?
&lt;/h1&gt;

&lt;p&gt;Box2D is the physics engine I decided to use because I have the most "experience" with it. I never use it to finish a game but I still dabbled in it a lot to know enough about how it works. I tried to use other 2D physics engines of course but none of them quenched my lust as much as Box2D did. However, that still doesn't answer the question: why am I using a physics engine? Am I trying to make a "physics-based" game? &lt;/p&gt;

&lt;p&gt;If you read the first devlog then you would know that Our Only Hope is far from a physics-based game. It's way simpler than that. As discussed before, however, I always had a problem with collisions in my past games and this game is no different. I tried, in a small prototype of the game, to make collisions work without a physics engine but what I discovered was that I was going to spend too much time on it and I wanted to finish this game before the end of October. That's the personal deadline I set for myself. However, one day when I didn't particularly feel like working on the game, I decided to jump into an empty project and try my hands at collisions once again. And, in a surprising turn of events, I actually managed to pull it off. I had two rigid bodies colliding with each other and made static vs rigid body collision resolution work as well. The code wasn't the best and it needed a lot of optimizing but it didn't matter as I had made an accomplishment that I never thought I would make. I now have an example of how to do collision resolution. However, I could not put it in the actual game. At that point, I was too deep into the Box2D rabbit hole. If I had decided to abandon Box2D and go with my implementation of collision resolution, then I would have added at least another week or two into the project's lifetime. That might seem trivial but it wasn't. If I decide to abandon a system in favor of a better and more robust system than the one I had just made, then I would never finish this game. If I changed the physics system why not change the camera system as well? I always hated the scene system why not change that as well? I don't like how Raylib handles audio then why not make a 2D audio framework? The examples might be too extreme but you get the point. Programming at such a low level will make you get your hands dirty a lot. You would have to touch so many horrible and disgusting things in your journey (like math, YUCK!). So, having a tool like Box2D which makes you forget about a major part of the game's infrastructure is a great thing. It will save you time for the time being and it will help you get to the parts that you like faster. &lt;/p&gt;

&lt;p&gt;Simply put, I used Box2D because I wanted to finish this game. I wanted to make this game in 2 months with no excuses. There are a lot of other things in this game that I've never implemented before and if I had to think about another big problem like collisions (a problem I never solved up to that point), I would have probably quit the project immediately just how I quit the other projects in the past. It's weird to say, but it's true. Box2D was a deal-breaker. I would have either not used it and risked abandoning the project or used it and put up with the extra load it carried. My choice was obvious. I did not want to put this project on the shelf just like its brothers and sisters. I wanted to finish it. &lt;/p&gt;

&lt;p&gt;Even though Box2D is a great tool and it did help me a lot and saved me a lot of time, I would probably never use it again. &lt;/p&gt;

&lt;h1&gt;
  
  
  Why I'll Never Use Box2D Again
&lt;/h1&gt;

&lt;p&gt;There's a reason why I never finished a game with Box2D before. It's a great tool, of course. It's robust and &lt;em&gt;very&lt;/em&gt; well-optimized. There are also a lot of games that used Box2D throughout the years. However, despite that, I never had a use for it. I never made a physics-based game before and, while it does sound fun, I don't have the intention of ever making a physics-based game. The collisions in my game are always very simple. Collisions that are more akin to older 2D games like Metal Gear, Castlevania, Metroid, and the like. That's all I need and all that I require. Despite that, I still went with Box2D as discussed before. &lt;/p&gt;

&lt;p&gt;This project, as you can tell, is very small. It's a game that can be made in a month with no external help. Very simple and very small. Deciding to bring Box2D into the project was a difficult decision to make. As said before, physics engines carry a lot of weight. They aren't behemoths per se, but they are still big. And what made it even worse was my usage of Box2D. Right now, as it stands, I only use Box2D for basic collision resolution. That's it. Nothing more. Gravity is turned off since this is a top-down game. There's no need for gravity in a top-down game obviously. The reason why I decided to leave game engines and develop games from scratch is because I thought that using a game engine--an engine that has a lot of features you will not need--was overkill for the games I wanted to make. Despite that, I still have the same problem but just on a smaller scale. &lt;/p&gt;

&lt;p&gt;But that's not the only problem. Box2D has a lot of nuances that make me want to kill Jeff Bezos. For example, Box2D uses real-world measurements as its unit system. Not pixels but meters and kilograms. This means any value you pass into Box2D will need to be converted into meters and any value you receive from Box2D will need to be converted into pixels. I understand it's perhaps better for the calculations but it can get &lt;em&gt;very&lt;/em&gt; annoying when working with it. Besides that, there are a lot of little problems that Box2D has. For example, you need to have at least one class that inherits from a &lt;em&gt;b2ContactListener&lt;/em&gt; class in order to know which bodies collided with whom. That might not seem like a problem but if you're trying not to use any OOP features then it can be annoying having only one part of your codebase using OOP while everything else is using a different paradigm. That's the reason Our Only Hope is object-oriented. I wanted to use the &lt;em&gt;b2ContactListener&lt;/em&gt; class but I also wanted a consistent paradigm for the codebase. But then there's the &lt;a href="https://www.iforce2d.net/b2dtut/ghost-vertices" rel="noopener noreferrer"&gt;Ghost vertices problem&lt;/a&gt; that Box2D has. Which I won't go into here.&lt;/p&gt;

&lt;p&gt;Despite the nuances, Box2D is still like any other tool. It has its pros and cons. No tool out there is perfect and Box2D is no different. &lt;em&gt;You&lt;/em&gt; are the one who has to decide if the tool is perfect for &lt;em&gt;your&lt;/em&gt; needs or not. They're your problems and you're the only one who will need to decide on which tool is the best for the job. Just remember to always make those games no matter the tool you're using. If the tools help you to make your game, then go ahead. Even though if that tool doesn't make the game-creation process faster but you still enjoy it, then why not? Just make games and enjoy it.&lt;/p&gt;

&lt;p&gt;Huzzah!&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>cpp</category>
      <category>development</category>
      <category>programming</category>
    </item>
    <item>
      <title>Our Only Hope - Devlog 1</title>
      <dc:creator>IWantToDeleteThisButICant</dc:creator>
      <pubDate>Sat, 23 Sep 2023 20:38:11 +0000</pubDate>
      <link>https://dev.to/mah_doh/our-only-hope-devlog-1-4kp4</link>
      <guid>https://dev.to/mah_doh/our-only-hope-devlog-1-4kp4</guid>
      <description>&lt;h1&gt;
  
  
  Where The Hell Have You Been?
&lt;/h1&gt;

&lt;p&gt;If you read my last devlog, you'd probably remember that I was going to do a devlog about collisions. If you read my last devlog, you'd also remember that it was a month ago, which was not my plan. What happened? Have I abandoned this game? Have I forsaken the great idea that is this game? Am I dead? All good questions that have the same answer: &lt;em&gt;no&lt;/em&gt;. Even though the devlog about collisions is coming soon, the time between this devlog and the last was filled with a series of unfortunate events. Events that led me to rewrite the whole project. Events that made me halt any progress on the game. What are those events you may ask? Well, there were a lot, some personal some not. However, the one thing that I learned throughout the last month is to always keep a backup of your project. A piece of advice I always heard but never bothered to actually listen to. &lt;/p&gt;

&lt;p&gt;However, even though my laptop decided to fuck me over and delete my progress (like wtf?!), I still have a lot of updates to give you. The progress has been slow but steady. Throughout this month I have written the engine for this game twice. I have implemented collisions, an asset system, an event system, a scene system, and many others that I'll talk about shortly. The game is chugging along slowly. Don't worry, everything is going well... he said, shortly before getting killed by an angry mob of tarantulas. &lt;/p&gt;

&lt;h1&gt;
  
  
  Why Raylib?
&lt;/h1&gt;

&lt;p&gt;In my last devlog, I said I was going to use SDL2 and C++ to make this game come to reality. While I am still stuck with C++, the same is not true with SDL2. Don't get me wrong, I &lt;em&gt;love&lt;/em&gt; SDL. It gives me a level of freedom I adore and the code is also very professional and very well documented. Yet, as I was writing out the game's engine, I discovered a lot of mildly infuriating features that made me want to pull my hair out. One thing to keep in mind is that I know Raylib way more than SDL. I have used it for a year up until that point. And, while I want to stick with SDL2 in the future, I decided to abandon it in favor of a faster tool to finish this game without any hiccups. But why leave Raylib and go to SDL2? Why not stick with Raylib? While Raylib is by far the best C++ game framework I used out there, it very much feels like I'm using a game engine without an editor. I want to dedicate my learning effort to graphics programming and the inner workings of that field. If I'm going to spend all that time using Raylib--which is very much made for beginners and students--then I'm never going to learn what I want. &lt;/p&gt;

&lt;p&gt;Nonetheless, Raylib is pretty much the fastest tool to get this game done in time and without any hardships along the way (so far at least).&lt;/p&gt;

&lt;h1&gt;
  
  
  The Engine
&lt;/h1&gt;

&lt;p&gt;Now that you understand the context, let's get into the actual meat of this devlog: the engine. But, before I tell you the anatomy of this engine, I need to tell you a secret: I actually worked on this engine for a year before using it here. Let me explain. &lt;/p&gt;

&lt;p&gt;In the beginning, in the early dark ages, I did not understand anything that I was doing. I would pretty much just watch videos or read articles and copy whatever they were doing. However, through slowly hitting my head against the wall I started to learn and understand what's good and what's bad. I now know which system to use and I know when and how to use it. The engine that I'm about to spill all the secrets of just in a few minutes is one that I've used for the past year. I completed many games while using it. But I also reiterated over the engine &lt;strong&gt;a lot&lt;/strong&gt;. This engine looks vastly different from the engine I used to make my first game with it. Some systems stayed the way they are (I'll talk about why later, don't worry), but there are also many things that did not stay around. &lt;/p&gt;

&lt;p&gt;This engine, as you will see, also uses a style and paradigm that I do not necessarily like. I decided to use it, however, just because I knew I could make it in a short amount of time and with little effort. As I said I made this engine many times before, in fact, a lot of the code is just copy-pasted completely line by line from other games that I made. I think you're starting to see a pattern here, right? You'd be right to think that I'm not putting any effort into making this engine big, strong, and girthy (is that a dick joke? So immature), that's because I &lt;em&gt;am&lt;/em&gt; not putting any effort into it. I want to get this game done before the end of the next month and for that to happen, I need to sacrifice the quality of either the engine or the gameplay and, for the longest time, that sacrifice was always the gameplay. I am planning to think about engine architecture and design after I finish this game but, currently, all I'm concerned about is the gameplay and only the gameplay. &lt;/p&gt;

&lt;p&gt;Nonetheless, I'll stop talking about some nonsense you probably don't give a shit about and I'll start discussing how I made this engine and why I took the design decisions that are present in the engine. This engine is broken up into multiple pieces, each piece has its own sets of functionalities and responsibilities. Besides very few exceptions, every system of the engine is decoupled from everything else. No system in the engine knows about the existence of any other systems (again, besides a few exceptions). If one system needs to communicate with another system, I use events to message that part of the engine. Without further ado, let's start with the first and most important system of the engine: the event system.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Event System
&lt;/h2&gt;

&lt;p&gt;While perhaps not the first thing that was implemented in the engine, the event system is probably one of the most important parts of this engine. &lt;em&gt;Everything&lt;/em&gt; in the engine communicates with the event system in one way or another (One Direction is that you?). Do you want to switch the current scene to another scene? Events. Do you want to play audio? Events. Do you want to solve a collision between two entities? Events. Did your grandma fall down the stairs and you want to get some help? Events! The event system is what makes the engine so decoupled which, therefore, makes it easier to work with. Before, I would have to inject dependencies into every system in the engine, making it very hard to work with and a chore to debug. However, with events things have gotten way easier. This is why this article is sponsored by events. Events, keep your head clean from blood.&lt;/p&gt;

&lt;p&gt;But how did I implement an event system? Since this engine uses OOP as its main programming paradigm, I did not shy away from any OOP ideas that might help me at the moment. That's why I used singletons to create an event system. In fact, the event system also uses templates and, besides one function, is completely implemented in the header file. Later, you'll see that I adopted the same design to implement asset loading. I am aware that this implementation is far from perfect and I am planning to make it better in the future, but for the time being, this is what worked for me.&lt;/p&gt;

&lt;p&gt;If you go deep and think about what an event system really is, you'll find it to be a very simple concept. All an event system does is hold function pointers and call them when the time is right. In a header file somewhere in the project, there is a list of function pointer definitions to be used by the caller and the callee of any event. When some part of the engine "listens" to an event, a function pointer is specified and the event system will store this type of function pointer in its appropriate container for later use. Once one of the systems of the engine "dispatches" an event, the event system will once again take the function pointer that was specified (this is where templates are useful) and call every single instance of it in the appropriate container.&lt;/p&gt;

&lt;p&gt;For example, this is the list of all of the "events" that can be listened to and dispatched currently in the engine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="n"&gt;OnEntityCollision&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="n"&gt;OnSceneChange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SceneType&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="n"&gt;OnSoundPlay&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="n"&gt;OnMusicPlay&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="n"&gt;OnMusicStop&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="n"&gt;OnQuit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And, if you want to listen to an event, you would have to call the event manager class, get its instance (since it's a singleton), and call the &lt;em&gt;ListenToEvent&lt;/em&gt; function, specifying the event type and pass in a lambda or a function with the same signature as the event type that was passed into the template argument.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;EventManager&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;ListenToEvent&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;OnEntityCollision&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;entityID1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;entityID2&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;entityID1&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"Player"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;entityID2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"Enemy"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;playerHealth&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function call above would have to be done in the constructor of the class that will listen to the event. However, with dispatching events, you can do it anywhere in the engine. And, by the way, nullptr functions are accounted for, so no segmentation faults could happen.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;EventManager&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;DispatchEvent&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;OnEntityCollision&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Player"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Enemy"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same thing goes with dispatching any type of event, just pass in the event type into the template and the appropriate arguments. But, you're probably wondering how can I pass in arguments to dispatch an event function call without knowing how many arguments (if any) the event takes? Well, with variadic types, of course. I think they're called something different (an argument pack?) in C++, but the same idea is there. Just let the function take in ellipses into the second template argument and forward it into the function pointer so that it can unpack the arguments there and use it. In fact, I'll just show you. What you're about to see below is the modern C++ way of making you puke. It sure is ugly but it works like a charm.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typename&lt;/span&gt; &lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;typename&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="nc"&gt;Args&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;DispatchEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Args&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first template argument is the event type and the second is just an unknown number of arguments that will be forwarded to the function pointer later. While this implementation does make you pass in any function signature that takes in a different number of arguments, it does not account for an event that has a return value. I actually never implemented an event system that has events of different return values. However, this system has worked for me so far and, till now, I have not needed an event type with a return value anyway. This event system allows for any place in the engine to dispatch any type of event it wants. While convenient, it can cause problems with debugging later, and that's precisely why a lot of the event systems out there don't allow for multiple places to dispatch any type of event. Only the "creator" of the event type &lt;em&gt;can&lt;/em&gt; dispatch &lt;em&gt;that&lt;/em&gt; event and no one else. There's always one publisher but multiple subscribers.&lt;/p&gt;

&lt;p&gt;But how are the functions implemented anyway? That is something that I'm not going to show you. Not because I'm afraid of code being stolen or anything (why would you steal a piece of crap?) but, rather, because I don't want this article to cause you an excruciating eye sore that you've never felt before. As I said before, the implementation of the &lt;em&gt;DispatchEvent&lt;/em&gt; function and the &lt;em&gt;ListenToEvent&lt;/em&gt; function are completely done in the header file (since I am working with templates) but that's not the problem, the problem is the hundreds of if statements that are present in those implementations. Why you ask? To deduce the type of the template given, of course. In the &lt;em&gt;EventManager&lt;/em&gt; class there are vectors of every type of event in the engine. A vector for the &lt;em&gt;OnEntityCollision&lt;/em&gt;, another for the &lt;em&gt;OnQuit&lt;/em&gt;, and another for the &lt;em&gt;OnSoundPlay&lt;/em&gt; and every time one of the above functions is called, I try to guess every type of event the template could be and, when I guess the type correctly, I add the event type given into its appropriate vector. That way, whenever I need to call that event type, all I need to do is try to deduce the type of the template given again and call every event type in the appropriate vector, checking for nullptrs along the way. If you're really curious, you can go to the GitHub page here: &lt;a href=""&gt;OurOnlyHope/Managers/EventManager.hpp&lt;/a&gt; and check for the code yourself.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Handaling The Assets
&lt;/h2&gt;

&lt;p&gt;While I can be given all credit for all of the systems that are in this engine, the &lt;em&gt;AssetManager&lt;/em&gt; is one that I completely &lt;em&gt;cannot&lt;/em&gt; take any credit for. This implementation of an asset handler is shamelessly taken from the amazing javidx9. Of course, this system has changed a lot throughout the times I've implemented it but the idea and spirit still go back to that one implementation I saw on Youtube: &lt;a href=""&gt;Code-It-Yourself! Role Playing Game&lt;/a&gt;. Many of the systems in this engine do take "inspiration" from other implementations of the same idea, but this one is just more than inspiration. However, while the implementation of this system does work for my game and javidx9's game, it will not work for everyone or every type of game. As you will see in a second, this system loads all of the assets at once, even ones the player might not need in their current playthrough. For a small game with a few amount of assets, that's fine, but with a big game with a lot of assets, this system will completely not work. Obviously, you'd need to find a better, more sophisticated system.&lt;/p&gt;

&lt;p&gt;But how does it work, anyway? As I said before, this system will load all of the assets at once at the beginning of the game. Music, sound, textures, and fonts all will be taken from the disk and completely loaded into the game. Even if you might not need a specific asset this playthrough, the asset will get loaded either way. So, for that reason, an appropriate function needs to be called at the beginning of the initialization stage of the engine. That function looks looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;AssetManager&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;LoadAssets&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Oh yeah, did I forget to say that the &lt;em&gt;AssetManager&lt;/em&gt; is also a singleton? Well, now you know. This function actually calls several other functions that will then load the assets. I made specific Load functions for every type of asset for better visualization, for both myself and other people who might read the code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;AssetManager&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;LoadAssets&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;LoadFonts&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="n"&gt;LoadSprites&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="n"&gt;LoadSounds&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="n"&gt;LoadMusic&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, the &lt;em&gt;LoadAssets&lt;/em&gt; function calls 4 different functions that will each load different assets. And, when the game is closed, the &lt;em&gt;UnloadAssets&lt;/em&gt; function of the &lt;em&gt;AssetManager&lt;/em&gt; needs to be called to, as the name says, unload all of the assets from memory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;AssetManager&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;UnloadAssets&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;UnloadFonts&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="n"&gt;UnloadSprites&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="n"&gt;UnloadSounds&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="n"&gt;UnloadMusic&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And, like the &lt;em&gt;LoadAssets&lt;/em&gt; function the above function will also call to other functions that will unload the appropriate asset type. Ok great, but how are assets &lt;em&gt;actually&lt;/em&gt; loaded and unloaded? The &lt;em&gt;AssetManager&lt;/em&gt; singleton class has a bunch of &lt;em&gt;unordered_map*s with a key and value pair to denote the name (or ID) of an asset and the value which is the asset type (Music, Sound, Texture2D, etc.). This will make it easier to retrieve the appropriate assets when needed. For example, if, somewhere in the code, a system needs the "Zombie_Grunt" sound, that system only needs to call the *GetSound&lt;/em&gt; function, passing in the appropriate string and the function will return the appropriate Sound (if it exists, of course).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;AssetManager&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;GetSound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Zombie_Grunt"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And, as you can imagine, all of the asset types are handled this way. Besides &lt;em&gt;GetSound&lt;/em&gt; there is also &lt;em&gt;GetMusic&lt;/em&gt;, &lt;em&gt;GetSprite&lt;/em&gt;, and &lt;em&gt;GetFont&lt;/em&gt;. Every function will return the appropriate asset type depending on the given string. Now, the horrible thing about this system is that there is no error handling if the wrong string is passed into one of the functions. If the string that was passed in did not exist in the database or a misspelling of an already existing asset occurred, there would be no errors at all. But why? My only defense to this is that I work on my own on this engine and there has never been a need to implement such a feature since I never make a mistake in my life. In all seriousness though, this sort of error can be really terrible and it should be handled. However, I will add this feature to the list of features I need to add to this engine once I finish this game.  &lt;/p&gt;

&lt;p&gt;As for the actual loading of the assets, all I do is add the appropriate key with the appropriate value (using LoadSound() from Raylib, for example) to the map and that's it. The function I'm about to show you might look complicated but all it does is make a utility lambda that takes the name of the asset ID and its path, it then creates a new entry and adds it to the map with the given ID and passes the path to the appropriate Raylib asset loading function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;AssetManager&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;LoadSounds&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="n"&gt;load&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;sound&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="n"&gt;m_sounds&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;sound&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;LoadSound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;c_str&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; 
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="c1"&gt;// Adding sounds&lt;/span&gt;
  &lt;span class="n"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Button_Click"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"assets/audio/button_click.wav"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Sword_Swing"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"assets/audio/sword_swing.wav"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Zombie_Death-1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"assets/audio/sword_kill_zombie-1.wav"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Zombie_Death-2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"assets/audio/sword_kill_zombie-2.wav"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Zombie_Grunt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"assets/audio/zombie_grunt.wav"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again, this system was taken from javidx9. It has saved me a lot throughout the times that I've used it. And, until I find a more sophisticated one that doesn't require an OOP mentality, I will gladly use it for the time being.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scenes And The Scene System
&lt;/h2&gt;

&lt;p&gt;The scene system is possibly one of the worst systems in this whole engine. It is unintuitive, unscalable, and a heap of garbage that has infested my workflow ever since I implemented it. When I finish this game, the scene system is &lt;em&gt;the&lt;/em&gt; first thing I'll completely remove from this engine. But how bad is it? &lt;/p&gt;

&lt;p&gt;Every scene in the engine inherits from a &lt;em&gt;Scene&lt;/em&gt; interface. The &lt;em&gt;Scene&lt;/em&gt; interface has two functions: &lt;em&gt;Update&lt;/em&gt; and &lt;em&gt;Render&lt;/em&gt;. Seems good so far. In the engine, there is a system that will handle the different scenes and the loading and unloading process. The scene system has an &lt;em&gt;unordered_map&lt;/em&gt; of scenes where the key is an enum called &lt;em&gt;SceneType&lt;/em&gt;, where all of the possible scenes are stored. And the value of the &lt;em&gt;unordered_map&lt;/em&gt; is a &lt;em&gt;unique_ptr&lt;/em&gt; of a &lt;em&gt;Scene&lt;/em&gt; interface. Also, the scene system has another &lt;em&gt;Scene unique_ptr&lt;/em&gt; which denotes the current scene. The scene system will use the current scene variable to call the &lt;em&gt;Update&lt;/em&gt; and &lt;em&gt;Render&lt;/em&gt; functions. This means the current scene variable will &lt;em&gt;point&lt;/em&gt; to the desired scene in the &lt;em&gt;unordered_map&lt;/em&gt;. The scene system also listens to the &lt;em&gt;OnSceneChange&lt;/em&gt; event where it proceeds to load the desired scene that was given by the event parameter. But what seems to be the problem? Loading the scenes isn't the problem in this implementation. Rather, the problem comes whenever I want to create a new scene. &lt;/p&gt;

&lt;p&gt;The process of creating a new scene goes as follows: create a new class, make the class inherit from the &lt;em&gt;Scene&lt;/em&gt; interface, override the virtual &lt;em&gt;Update&lt;/em&gt; and &lt;em&gt;Render&lt;/em&gt; functions, and proceed to add whatever functionality you want in the scene. Doesn't seem too bad, right? It doesn't... so far. I have used this system a lot throughout the last few months. I made a lot of games using this system. It has served me well... with small games. You see, the previous games I made with this system have all been small. At maximum, there were only three scenes that the game had. But, and this is where the problem arrives, when you start to have more scenes, way more scenes--more than 3 at least--you begin to have a problem. For example, in this game, I would like to have more than 3 scenes. In fact, I &lt;em&gt;do&lt;/em&gt; have more than 3 scenes. All in all, I have 7 scenes. And, in the future, I would like to have more than just 7 scenes. So if I have to make a class (a .h and a .cpp) for &lt;em&gt;each&lt;/em&gt; scene, my hair will start to go gray. A better implementation and a new system would have to be made... just not now. Add it to the list of things that need to be done after finishing this game. &lt;/p&gt;

&lt;p&gt;Currently, the main scene I work with is the &lt;em&gt;GameScene&lt;/em&gt; which has everything to do with... well, the game. The player, the zombies, the score, the waves, the pausing, and everything else that has to do with gameplay. So, more often than not, the &lt;em&gt;GameScene&lt;/em&gt; is my central hub of development in this engine. Later, once I get to it, I'll start working on UI which is where I'll give the other scenes more love and attention. &lt;/p&gt;

&lt;h2&gt;
  
  
  Audio
&lt;/h2&gt;

&lt;p&gt;Currently, I don't have any control over any audio system in the game. Pretty much everything is interfaced with Raylib and its audio system. The only thing I do is use the &lt;em&gt;LoadSound/LoadMusic&lt;/em&gt; function to load the sound/music, the &lt;em&gt;PlaySound/PlayMusicStream&lt;/em&gt; function to play the sound/music, and &lt;em&gt;SetSoundVolume/SetMusicVolume&lt;/em&gt; to control the volume of the sound/music. There is only the &lt;em&gt;AudioListener&lt;/em&gt; class which sets some arbitrary volume values for the sounds and music. It also listens to all of the appropriate sound/music events. Essentially, the &lt;em&gt;AudioListener&lt;/em&gt; will listen to the sound/music events, set the appropriate volume (which can be set by the player later on), and play the appropriate sounds/music. &lt;/p&gt;

&lt;h2&gt;
  
  
  Entities
&lt;/h2&gt;

&lt;p&gt;Ever since I decided to take the plunge and make games from scratch, organizing entities has been one of the many things I struggled with. Of course, it is not the only thing I struggled with but it was--and still is--one of my major struggles. Previously, long ago, I had my entities broken up into two types: a dynamic entity and a static entity. However, I soon discovered that the two entities approach can lead to a lot of headaches, especially when you learn that a dynamic entity is actually a child class of the static entity class and the static entity class is a child of &lt;em&gt;another&lt;/em&gt; base entity class. So you can see why I stopped using that complicated system. Right now, I have an entity system that, while good, is still lacking in some areas. But how does it work? &lt;/p&gt;

&lt;p&gt;Like the scenes, every entity inherits from an &lt;em&gt;Entity&lt;/em&gt; class. The &lt;em&gt;Entity&lt;/em&gt; class is a pure virtual class, meaning the functions that it has &lt;em&gt;must&lt;/em&gt; be implemented by child classes. The &lt;em&gt;Entity&lt;/em&gt; class has the &lt;em&gt;Update&lt;/em&gt; and &lt;em&gt;Render&lt;/em&gt; functions, just like the &lt;em&gt;Scene&lt;/em&gt; interface. But, unlike the &lt;em&gt;Scene&lt;/em&gt; interface, the &lt;em&gt;Entity&lt;/em&gt; class has three variables. In the previous entity system, I had a lot of variables in the base entity class. Variables that not every entity needs. Learning from that mistake, I made the base entity class have as few variables as possible. Only the bare minimum every entity will need. Or, at least, what I think is the bare minimum an entity needs relative to this engine. Essentially, the entities in the engine only inherit a &lt;em&gt;Transform&lt;/em&gt; component (oh, we'll get to that later), an ID which is a string, and a boolean flag which indicates if the entity is active or not. &lt;/p&gt;

&lt;p&gt;I have another section for components so I'll not get into it now. What I'll talk about here, though, is the other two variables: the ID and the active flag. I'll start with the ID as it is probably the least useful and it's pretty much used in one area of the engine. At the initialization stage of every entity, they can assign a unique ID that will help later with knowing which entity collided with whom. However, this ID is not necessarily unique for &lt;em&gt;every&lt;/em&gt; entity in the game. Rather, the ID is used to denote the &lt;em&gt;type&lt;/em&gt; of the entity. If the entity that is currently being initialized is the player, then the ID of the entity will be "Player". If that entity was a zombie, then the ID would be "Zombie". And so on. But could you not have a better way to handle that? Perhaps an enum? Passing a reference of the type somehow? I think you know what I'm going to say next. That's right, put it in the things-to-fix-after-finishing-this-game pile. But what about the active flag? Well, to explain that, I have to tell you about the way entities are managed in the engine.&lt;/p&gt;

&lt;p&gt;In the &lt;em&gt;GameScene&lt;/em&gt;, there is a class called the &lt;em&gt;EntityManager&lt;/em&gt; which, as the name implies, manages every entity in the game. The &lt;em&gt;EntityManager&lt;/em&gt; class has an &lt;em&gt;Update&lt;/em&gt; and a &lt;em&gt;Render&lt;/em&gt; function just like every entity. As you can see, the &lt;em&gt;EntityManager&lt;/em&gt; is quite similar to the &lt;em&gt;SceneManager&lt;/em&gt; so far. However, that is where the similarities end. Unlike the &lt;em&gt;SceneManager&lt;/em&gt;, the &lt;em&gt;EntityManager&lt;/em&gt; does not have an &lt;em&gt;unordered_map&lt;/em&gt; of all of the entities. Instead, it has a &lt;em&gt;unique_ptr&lt;/em&gt; of individual entities. A pointer to the Player, a pointer to a &lt;em&gt;ZombieManager&lt;/em&gt; class which just manages all of the zombies in the game (I'll talk about it in depth in a later devlog), and so on and so forth. In the initialization stage, the &lt;em&gt;EntityManager&lt;/em&gt; will initialize all of the entities that need to be initialized. In both the &lt;em&gt;Update&lt;/em&gt; and the &lt;em&gt;Render&lt;/em&gt; functions, a check is made before any of the entities get updated or rendered. Every entity that currently has its active flag set to true can be updated and rendered. Otherwise, the entity will be ignored completely. Doing things this way will ensure I don't have to delete and reallocate new entities during the runtime. All of the entities in the game--like the assets--get allocated and initialized once at the beginning of the game. If the player or a zombie dies, they will not be updated or rendered. They will simply be ignored. The only problem with this system is that I have to manually decide how to reset each entity. But, at the cost of fewer allocations, it is a very much welcome side effect. &lt;/p&gt;

&lt;p&gt;But what happens inside those &lt;em&gt;Update&lt;/em&gt; and &lt;em&gt;Render&lt;/em&gt; functions? In fact, how are the entities getting rendered? For that, I use components. Or, rather, composition.&lt;/p&gt;

&lt;h2&gt;
  
  
  Composition Over Inheritance
&lt;/h2&gt;

&lt;p&gt;If I ever decide to stick with OOP (for some reason) I will definitely value composition over inheritance every time. As I said before, organizing entities and giving them only the bare minimum that they need at a base level was always a struggle for me. I always had the dilemma of "what if". What if there is an entity that needs a texture? Don't all of the entities need textures of some sort? What if there is an entity that needs a collider? Don't all entities need colliders of some sort? At the end of these existential thoughts, I just end up with a base entity class that has a bunch of variables that some--but not all--entities need. But what happens when an entity doesn't require a collider or a texture? Should I just set them to null? What if these entities have different parameters and the collider has a fixed size across all entities? I think you understand where I'm coming from. I value composition over inheritance because I hit my head against the wall too many times from excessive inheritance. But what are the components in my engine anyway?&lt;/p&gt;

&lt;p&gt;Previously, I talked about there being a &lt;em&gt;Transform&lt;/em&gt; component in the base &lt;em&gt;Entity&lt;/em&gt; class. The &lt;em&gt;Transform&lt;/em&gt; component is just a class that holds three variables: a position, a rotation, and a scale. There are some functions associated with the &lt;em&gt;Transform&lt;/em&gt; component but they aren't used as much as the variables. Besides the &lt;em&gt;Transform&lt;/em&gt; component, there is also the &lt;em&gt;Sprite&lt;/em&gt; component which gives an entity the ability to add a texture and draw that texture. The &lt;em&gt;Sprite&lt;/em&gt; component has only one function: the &lt;em&gt;Render&lt;/em&gt; function which takes in an lvalue reference to a transform component. Since, most of the time, you need the position, rotation, and scale of an entity to render a sprite in the exact position, with the specified rotation, and an applicable scale. The &lt;em&gt;Sprite&lt;/em&gt; component itself only has a texture, the size of the sprite, and an origin. The constructor of the &lt;em&gt;Sprite&lt;/em&gt; component takes a sprite ID and the specified size of the sprite. The &lt;em&gt;Sprite&lt;/em&gt; component takes the sprite ID and retrieves the texture from the &lt;em&gt;AssetManager&lt;/em&gt; using the sprite ID given. It then assigns the size of the sprite to be used later and sets the origin to the middle of the texture.&lt;/p&gt;

&lt;p&gt;There are also two other components in the engine and those are the &lt;em&gt;PhysicsBody&lt;/em&gt; and the &lt;em&gt;Collider&lt;/em&gt;. These I will talk about in depth in the next devlog where everything physics and collisions will be present.&lt;/p&gt;

&lt;h2&gt;
  
  
  Box2D, The Contact Listener, And Debug Draw
&lt;/h2&gt;

&lt;p&gt;Since I will be making a devlog specifically about physics, Box2D, and collisions, this section will be quite short I promise. The integration of Box2D is not the easiest of things to do. Box2D uses real-world measurements (cm, m, kg, etc.) instead of pixels to assign its values. I had to extensively use conversion utility functions I made specifically to convert all of the real-world metrics into pixels. Basically, I had to cut a lot of corners in order to make Box2D a part of the engine. But, since I used Box2D before, I made these utility functions in hindsight before writing a single line of the &lt;em&gt;PhysicsBody&lt;/em&gt; or &lt;em&gt;Collider&lt;/em&gt; components.&lt;/p&gt;

&lt;p&gt;After finishing these rather small but very useful functions, I went on to implement the Box2D world, Contact Listener, and Box2D's Debug Draw. Box2D makes it easy for you to create a physics world. All you have to do is declare a &lt;em&gt;b2World&lt;/em&gt; class somewhere, pass a gravity value into it, call the &lt;em&gt;Step&lt;/em&gt; function every frame and then that's it. I made &lt;em&gt;b2World&lt;/em&gt; a global variable to make it easier to add bodies to the world and to get the head of the quadtree for the &lt;em&gt;ContactListener&lt;/em&gt;. It's horrible I know but I'm ready to sacrifice true software engineering values in order to make a game.  Now that I had an easier way to add bodies into the world, I went on to create the &lt;em&gt;ContactListener&lt;/em&gt; which will help with knowing exactly &lt;em&gt;which&lt;/em&gt; body collided with which. &lt;/p&gt;

&lt;p&gt;Box2D stores its bodies in a quadtree. So, as is often the case, when you want to iterate over that quadtree to check which of the bodies are colliding with each other, you need to get the head or the beginning of the quadtree in order to go down the tree body by body. And, in order to get the beginning of the tree, you need to get a reference of the world and call a function called &lt;em&gt;GetContactList&lt;/em&gt; which will return a &lt;em&gt;b2Body&lt;/em&gt; pointer which you can use to go down the tree. In order to get the next node in the quadtree, you need to call the &lt;em&gt;GetNext&lt;/em&gt; function that exists in the body. I'm not going to go over the implementation of the ContactListener for now since, again, I'll be making a specific devlog for all things collisions. &lt;/p&gt;

&lt;p&gt;And, finally, the last system of the engine is the &lt;em&gt;DebugDraw&lt;/em&gt;. All it does, as the name suggests, is draw lines around the active bodies in the world. This is great for debugging purposes only and nothing else. It has become one of the best tools for me whenever I use Box2D. Again, I'm not going to go over it in this devlog. However, if you're curious, you can go look at it on the GitHub page of this project. &lt;/p&gt;

&lt;h1&gt;
  
  
  What's Next?
&lt;/h1&gt;

&lt;p&gt;So, now that the engine is finished, what's next? Currently, the game is in a very stable state. Even though I'm currently writing about the engine, I actually moved on to other things in the game. My concern with the game right now is the player movement and the combat, which I will make devlogs about in the future. Keep in mind that I do these devlogs way after I finish whatever I'm talking about. So, don't worry, development is (currently) going smoothly. Unlike last time, I promise that the next devlog is going to be about collisions and my fight with Box2D and physics as a whole (man I wish that apple was an anvil). And, as usual, I actually already implemented collisions and the various Box2D systems as you can see above. But, nonetheless, I hope you're having a wonderful day and always remember...&lt;/p&gt;

&lt;p&gt;Huzzah!&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>cpp</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
