Well, hello there.

Remember on my last post when I said: “First things first, I’m not going to stop with development logs”? – Good times. But fret not, my child. After 216 days I am back! As a smart man once said, I am only alive if I write and if there is a thought, there is a writing. Now, I don’t know who is that “smart man” – These are just sentences that are in my head but I’m pretty sure I’m not the one who came up with them, I must have read that somewhere, anyway.

I’m back mostly because looking back at your progress for the past weeks is just a very good thing to do?! And now I am just going back to the roots of this devlog – I will do whatever I feel like and then I will come here and write about what I’ve done, problems I’ve faced, what I’ve learned and, of course, add some Michael Scott gifs.

Ha. Now. What I’ve been up to recently? Well, the biggest thing I’ve been working on is making a really simple 2D Game Engine using SDL2 and OpenGL called Realiti2D. I wanted to address my weaknesses as a programmer/engineer, which, in my point of view, are: (1) Lack of understanding of low level technologies like: How does a renderer work? How does a collision system works? How does a UI system or a good Input System look like?

And going through the development of an engine, even if simple, is very challenging. A lot of things does not have right or wrong answers, just different approaches, things that perform better in some circumstances and things like that. Which, to be fair, is really close to real life problems engineers are going to solve.

And then, (2) There is a certain process to problem solving which I believe I have a good grasp on, but I believe I could learn some patience, you know, research more options, think about other solutions, understand the impact that this problem has in the project and the impact that my solution will have for future features.

I spent a lot of money on books for that

In this last month I added two new features to Realiti2D: (a) A Collision System; and (b) a Load Level feature from a .json file.

The Collision System

The collision system was an interesting one. It was not the first time doing one, and I opted to do axis-align bounding-boxes (AABB) which is the most simplified way of handling collisions. The biggest questions that arise when doing collisions are: (i) When are all the collisions being checked?; and (ii) How an individual entity handles a collision when it happens?

For the first question, I went with what the book “Game Engine Architecture” by Jason Gregory says, which is to have a Collision World that will, at the end of the application update, check for collisions on all registered Colliders.

Image
How do they work?

And for the second question, I created a callback on the box collider component, like this: std::function<void(BoxCollider*)> CollisionCallback;

And the following macro helps with binding a function to the callback: #define BIND_COLLISION(…) std::bind(VA_ARGS, this, std::placeholders::_1);

And then you have the freedom to create a component that will access the box collider and bind a function to the callback.

m_Collider = Owner->GetComponentOfType<Realiti2D::BoxCollider>();
m_Collider->CollisionCallback = BIND_COLLISION(&PlaneInput::ExecuteThis);

void ExecuteThis(Realiti2D::BoxCollider* Other) {
DEBUG_INFO("Tappy plane collided with {0}", Other->Owner->Name);
}

I do think this is a weird workflow, but come to think of it, it is very similar to how Unity does things, you inherit the functions from a collider and have to define their behavior on your own components.

A lot of work still has to be done here, Circle Colliders and Raycasts are next on my list.

Load Level feature

This was actually a lot of busy work and reading. The system takes in a .json file, but I’m actually using .r2d as the extension. I’m using rapidjson (https://github.com/Tencent/rapidjson), by Tencent, to process the json files. Here is how one entity looks on the json file:

{
   "name":"Plane",
   "components":[
      {
         "type":"Transform",
         "properties":{
            "position":[
               -465.0,
               0.0
            ],
            "rotation":0.0,
            "scale":[
               1.0,
               1.0
            ]
         }
      },
      {
         "type":"Sprite",
         "path":"assets/tappyplane/PNG/Planes/planeBlue1.png",
         "drawOrder":5
      },
      {
         "type":"AnimatedSprite",
         "properties":{
            "animationFPS":24,
            "textures":[
               "assets/tappyplane/PNG/Planes/planeBlue1.png",
               "assets/tappyplane/PNG/Planes/planeBlue2.png",
               "assets/tappyplane/PNG/Planes/planeBlue3.png"
            ]
         }
      },
      {
         "type":"BoxCollider",
         "properties":{
            "min":[
               -32.0,
               -32.0
            ],
            "max":[
               32.0,
               32.0
            ]
         }
      }
   ]
}

And then on the application level all you have to do is have a simple function call, such as Realiti2D::LevelLoader::LoadLevel(this, "assets/SampleLevel.r2d"); – The function that loads the level gets the application reference (illustrated by “this”) so it can add entities to the game.

It is still possible to create entities/components in C++ code, as well as get a reference to an entity created by a file and add other components to it. But my intention is the future is to have a scene editor that will generate those json files correctly.

As for the logic, it’s actually simple, it just reads the json using rapidjson, processes the version, global properties, and then iterates over every entity, and on each entity iterates over its components, and this raises an interesting question: “How to efficiently map a component entry in json to the creation of a new class?”

The approach I’m taking currently is:

if (ComponentType == "Transform") { ComponentFactory::AddTransformComponent(e, Component); }

Which is basically mapping a string to a function on a factory class. The big question when doing something like this is: “If I create a new component, what do I have to do for it to be recognized by the Level Loader?” – In my implementation, I have to create a function on the Component Factory and add an if-else case on the Level Loader, which is sort of annoying and error-prone. I might look into better solutions on a later date.

Also, Realiti2D source code can be found at: https://github.com/guilhermepo2/realiti2D

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s