A little open-source game engine, written in C# (.NET 6.0), which features some of the most common game programming techniques built-in. It is based on the Vulkan rendering API, which provides support for Windows 7-11, macOS, Linux, Android, iOS, tvOS and other operating systems, though the engine has only been tested on Windows 10, 11 and macOS Monterey. All of its features are listed below.
WARNING: The project is a finished prototype. Development has been moved to this link where it will be rewritten in C++ and extended! This repository will no longer be updated!
Clone the repository in your IDE of choice (Visual Studio, Rider, etc.) Now, you will have to run a Python script what will configure the project for you. Obviously, this will require your machine to have Python 3 installed, so make sure you have that. Navigate over to the folder where you cloned the repo and run the following two commands in your command prompt or terminal:
$ cd Scripts/
$ python3 UpdateProject.py --Release
You can then proceed and run the program in your IDE. Make sure you are in RELEASE mode, because Debug mode will not be configured by the script. However, if you are feeling like working on the project yourself, feel free to change the --Release argument with --Debug, which will configure it for Debug mode.
All functionalities of the engine - its built-in classes, objects, and their usages are thoroughly explained in the documentation page which you can find here.
Every object has a field called "transform" and, you guessed it, it is capable of changing the position, rotation, and scale of each object in the 3D space. Here is an example on how to do just that:
someObject.transform.position = new Vector3(10.0f, 0.0f, -5.0f); // Changes the position in the world
someObject.transform.rotation = new Vector3(0.0f, 0.0f, 90.0f); // Changes the rotation of the object
someObject.transform.scale = new Vector3(10.0f, 0.0f, -5.0f); // Changes the scale of the object
You could, for example, put a tank in your world and make its turret rotate like so:
float upTimeSin = (float) Math.Sin(Time.upTime); // The sine of the time since the program started
turretObject.transform.rotation = new Vector3(0.0f, upTimeSin * 45.0f, 0.0f);
gunObject.transform.rotation = new Vector3(0.0f, upTimeSin * 45.0f, 0.0f);
Hold on a second! Is that a custom 3D model?
That's right! How can a game engine be an engine and... not allow importing custom 3D models? In Sierra Engine it is as simple as:
MeshObject model = new MeshObject.LoadFromModel(FILE_NAME_HERE);
MeshObject model = new MeshObject.LoadFromModel("Models/Train.obj"); // <-- Example
Loading models is cool, but what is the point of it if they are not going to be colored, right? Well, when importing your model, the program automatically picks all textures applied to it and loads them into the renderer. Here is what the following code results in:
MeshObject model = MeshObject.LoadFromModel("Models/Chieftain/T95_FV4201_Chieftain.fbx");
What is that? The tank's lower plate is very dark... strange, right? Nope, not at all. There is Directional Lighting implemented, which, combined with Phong Shading, allows for pretty accurate results. The lighting is calculated based on the normals of each mesh's vertices and acts as a light source, emitting rays at a single direction - pretty much like the sun does. Its intensity and color can be changed at any time. Shadows, however, are yet to come... but will be added, for sure!
However, our tank's light reflections do not look quite right... This is because we have not yet fully made use of the Texture System. We can use the model's specular maps to get a realistic result as shown:
Because I doubt anyone likes pixelated images, there is a MSAA (Multisample Anti-Aliasing) system in place to get rid of all those pesky pixelelated fragments. Here is a comparison between no MSAA and MSAAx8:
There is also Mip Mapping, which, not only gets rid of MoirΓ© patterns in textures, but also greatly increases the frame rate. What it does is lower the quality of textures when the camera is far from the object. It is barely noticable to the user, but saves a lot of computing resources on textures. Here is an example:
Note: the second picture is zoomed in a lot to show the effect. In reality, you cannot even see the quality being lowered due to how far the object is from you.
Seeing things drawn to our screen is great. But being able to interract with them is a whole new level of fun! With the help of the implemented UI system's elements (such as sliders, buttons, trees, etc.), the user is able to manipulate stuff in the game scene. Here is a simple demo of it:
The UI of the application will be extended greatly to provide easy access to the game engine's core. This is only a test of the system.
The program is packed with numerous useful classes. Let's say you wanted to maximize the window. This is how you would do it:
window.Maximize();
If you want to get the current position of the cursor over the window:
Vector2 cursorPosition = Cursor.cursorPosition;
And if you want to check whether a key on the keyboard is pressed:
bool spacePressed = Input.GetKeyPressed(Key.Space);
Wait, you want to detect the GPU model of the machine? Easy:
string gpuModel = SystemInformation.gpuModel;
There are many other similar utility classes that make the gathering of data within your game/program/app incredibly easy. All of this - in a single namespace:
using SierraEngine.Engine;
Graphics applications are usually very heavy and run slowly. Thankfully, this is not the case with Sierra Engine. Despite all of its features, it still manages to do about 1,800 frames per second (FPS) and 2,000 GPU draws per second on a system equipped with a Ryzen 5 3600X CPU and a NVIDIA GeForce GTX 1070 TI GPU.
There are many other features planned. Some of them are:
- UI
- Point Lights
- Performance Monitoring
- Vulkan Abstracting
- Shadow Mapping
- Post-Processing
- Multi-Threading π₯
- Camera System
Frameworks used:
- Vulkan - For both cross-platform and pefromant-friendly rendering. Note: the latest version of Vulkan is not used, as 1.2.198.1 is the last to support all platforms.
- GLFW - For creating window interface and connecting it to the Vulkan renderer.
- Assimp - For the loading of all kinds of 3D model formats (.obj, .fbx, .dae, etc.).
- Stb - For loading image data from all kinds of image formats (.jpg, .png, etc.).
- ImGui - For the user interface implemented.
- My Brain - There is not much left of it, actually...
Software used:
- JetBrains Rider - A cross-platform IDE used to develop the .NET project on both my macOS and Windows systems.
- Blender - For the testing of 3D models and textures functionality.
- Trello - For pretending to have an organized list of things to implement next.
Total lines of code: 8847
Last updated: 10/09/2022