Rebuilding the Untold Engine: Two Years of Progress and What’s Next

Hey everyone,

It has been two years since I began rewriting my game engine, and while development has been slow, it has been steady. In this post, I want to share the current status of the Untold Engine.

What is the Untold Engine?

For those who are unaware, the Untold Engine is a 3D game engine designed for macOS and iOS devices, which I started developing in 2013. The original version was built using C++ and Metal, following an object-oriented approach.

What has changed?

Fast forward to today, and the Untold Engine has transitioned to an Entity-Component-System (ECS) architecture, with its primary languages now being Swift and Metal. The engine includes the following systems:

  • Rendering System
  • Physics System
  • Steering System
  • Animation System
  • Collision System (coming soon)
  • PBR (Physically-Based Rendering) support
 
 

Although the rewrite is not yet complete, the Untold Engine has reached a stage where you can create simple games. One significant improvement in the new Untold Engine is its documentation. I have made it a priority to keep the GitHub Readme thoroughly documented and up-to-date.

What’s next?

Development of the engine will continue, but my main focus will be on creating simple games and tutorials to help developers get acquainted with the Untold Engine. One of the reasons the first version of the engine had so many bugs was due to insufficient testing with actual games. This time around, that won't be an issue.

Where can I get the Untold Engine?

The Untold Engine is open-source and you can get it from our Githup repo:

https://github.com/untoldengine/UntoldEngine

Thank you for reading!

Nearing the Finish Line: Rewriting the Untold Engine

I’ve been knee-deep in rewriting the Untold Engine, transitioning it from C++ to Swift. After months of coding, tweaking, and testing, I’m thrilled to share that the rewrite is almost done. Moving to Swift has been a game-changer, making the engine not only faster and more modern but much easier to work with.


Built on ECS Architecture

The Untold Engine is powered by Entity-Component-System (ECS) architecture. This design keeps the engine modular and scalable, separating the game logic into three straightforward parts:

Entities: These are the game objects (think players, cars, obstacles). Components: The data attached to entities, like meshes, physics, or animations. Systems: These handle the logic, such as rendering, animations, or physics calculations. This modular approach keeps everything clean and efficient, allowing developers to focus on their game logic instead of wrestling with tangled code.


Simplicity is Key: The API

When I started this rewrite, one of my biggest goals was to make the API as easy as possible to use. I’ve always believed that developers shouldn’t have to fight with the tools—they should just work.

With the new API, everything is intuitive and consistent. If you can remember createEntity() and setEntityMesh(), you can pretty much guess how the rest of the API works.

Here’s how you might set up a playable character:

// Step 1: Create the entity
let player = createEntity()

// Step 2: Add a mesh for the player
setEntityMesh(entityId: player, filename: "playerModel", withExtension: "usdc")

// Step 3: Enable physics for movement and gravity
setEntityKinetics(entityId: player)

// Step 4: Add collision detection
setEntityCollision(entityId: player)

// Step 5: Add animations for walking and running
setEntityAnimations(entityId: player, filename: "walkAnimation", withExtension: "usdc", name: "walking")
setEntityAnimations(entityId: player, filename: "runAnimation", withExtension: "usdc", name: "running")

The API is intentionally predictable. Want to add physics? setEntityKinetics(). Want collision? setEntityCollision(). It’s all designed to make game development as smooth as possible.


One Last Piece: The Collision System

With almost every system in place, I’m now working on the Collision System—the last big piece of this rewrite. This system will handle detecting interactions between entities, like when a player hits an obstacle or collides with another object.

Once the Collision System is complete, the engine will have everything it needs to handle realistic interactions, complementing the existing Physics System seamlessly.


What’s Next?

After wrapping up the Collision System, my focus will shift to finalizing the documentation and writing tutorials. I want to ensure that anyone—even those new to game development—can pick up the Untold Engine and start creating right away.

Rewriting this engine has been a long, challenging process, but it’s been worth every line of code. Moving to Swift has made the engine simpler, faster, and a joy to work with. I can’t wait to see what developers will create with it.

Stay tuned—big things are coming!

Check out the Untold Engine

Thanks for reading

Making my PBR Renderer more user-friendly - Part II

Last week, I wrote an article about making my renderer more user-friendly. If you haven't had a chance to read any of my previous two articles, here are some videos to catch you up.

 
 

This week, I decided to work on the Lights User-Interface. I was unhappy with how the lights were added or manipulated in the scene, so I worked on them this week.

One of the first things I did was to make the Lights an ECS component. I also implemented a Light System that manages different types of lights, such as Directional, Points, Spot, and Area Lights.

I then removed the previous Light UI implementation and started all over again. I added a drop-down menu that allows the user to add a particular light type, such as Directional and Point Lights.

For Directional Light, I added visual feedback so the user can determine the direction of the light. I also allow the user to set the light's intensity through a slider.

For Point Light, I allow the user to set its intensity radius. And of course, you can manipulate the transformations and rotation through sliders.

So, here is what I have as of now:

 
 

So, what's next?

As you noticed in the video above, the point lights are not casting any shadows. Some bugs need fixing. I'm also wondering if I should add a Gizmo for translation/rotation. But my main objective is to add Ray-Tracing to the renderer. That is where I'm heading. For the time being, I want to focus on setting up a user-friendly UI. So, be ready for a part III.

Making my PBR Renderer more user-friendly

One of the activities that I strongly dislike is creating a User-Interface. For a long time, the first version of my game engine lacked a UI. The only reason it had one was out of necessity, not because I enjoyed developing one.

As you may recall, my last blog post mentioned my interest in learning about BRDF. Thus, I ended up developing a BRDF renderer. If you didn't get a chance to read the article, here are some screenshots of what I accomplished with my renderer.

 
 

The UI in my renderer is simple. It lacks several UI interactions such as transforming operations through a slider, adding new models to the scene, adding point lights, etc.

Since my goal is to learn more about the interaction between light and surfaces, i.e. BRDF, it became apparent that I needed to add more features to the renderer's UI.

And that is what I did. For about two weeks I dropped my Renderer Engineer hat and worked as a UI designer. This is what I was able to accomplish:

 
 

First, I added sliders that control the model's transformations, such as translations and rotations.

Next, I added the ability to add point lights to the scene. I'm not completely happy with this, but it will do for now.

Next, I implemented a Mouse-Picking with Ray Casting algorithm that allows users to select a model with a click. If you are wondering how to do so, here is a way to do it.

Up to this point, all models' names were listed in a drop-down menu. This was not intuitive, since the user could not get a preview of the model before adding them to the scene. So, I spent a day learning about NSCollectionViews and was able to show a preview of all the models in a collection view.

Another issue with the UI was a lack of visible feedback when selecting a model. The user had no way to determine when a model was selected or not. So, I implemented a bounding box for visual feedback purposes.

So, this is where I am right now.

My goal for next week is to focus on fixing the Disney shaders and Lighting.

Thanks for reading.

I built a PBR Renderer

I was completely immersed in rewriting my game engine when I stumbled upon these captivating images.

 
 

The author experimented with the properties of various metals and demonstrated how to create them in a Physically-Based Renderer through renderings.

They looked so cool that made me wonder if I could build a Physically-Based Renderer myself and render these metals.

I was a bit hesitant to take a detour from my engine and modify the renderer.

See, there were several things that I needed to change in my engine. For starters, I was using non-physically-based shaders. Thus, I was not using any material properties from a model. My engine would also require a user interface to manipulate material properties such as Roughness, Metallic, etc.

So, I listed the things that I had to do and after looking at the list, I decided to take a little detour and build a PBR Renderer.

My plan of action was super simple:

  1. Become more familiar with PBR and BRDF functions
  2. Modify the current code base to use material properties and PBR functions instead of non-physically based functions.
  3. Implement a User-Interface for the material properties

So, I began my new project by reading a bunch of amazing BRDF papers, articles, presentations, and everything I could get my hands on. I knew the role of BRDF in PBR but if I was going to build a PBR renderer, it made sense to do a deep dive and understand every aspect of it.

I used most of my existing code base in the renderer. The biggest changes I made were to the shaders. I kept my non-physically based shaders and added BRDF shader functions. I found a nice list of several functions here.

The UI implementation was super simple and it is not worth talking about it but here is an image of the UI.

 
 

It allows the user to manipulate several material properties, set tone maps, enable Image-based lighting, and set the direction of the light. One cool thing that I added was the ability to select different BRDFs. You can see in real-time the effect of choosing different BRDFs functions such as Cook-Torrance, Disney, etc.

So, everything seemed to be going well; however, I still had a major problem. The metals were not being rendered as metals; something was off. The rendering below shows my attempt to render Gold.

 
 

At this time, I decided to take a break from coding and focus on something that was bothering me, the "Fresnel Function." I didn't quite understand its role in BRDF, so I spent a weekend getting familiar with it. While reading about this topic, I realized that metals don't reflect any diffuse component. I ran to my computer, removed the diffused component, and BOOM!!!!

I had rendered GOLD.

 
 

In conclusion, I'm glad I got distracted to build a PBR Renderer. I learned much more than I imagined and had a lot of fun. Also, it wasn't that difficult at all. Here are renderings of other metals.

 
 

Thanks for reading