TheEngine
TheEngine is a custom game engine built in C++20, powered by SDL3 and OpenGL.
This website contains basic information on how to use TheEngine. We do not go into detail about engine internals here.
TheEngine
Note
You do not need to read this section if you do not intend to build TheEngine from source.
Both Linux and Windows binaries for TheEngine are available on the repo.
However, if you really want to build it from source, instructions are provided below.
Requirements
- CMake (>=3.10)
- Ninja (>=1.10)
- A C++ compiler (Clang, MSVC, g++)
Cloning the repo
# Clone the repo
git clone https://thorn.veritius.dev/engine/TheEngine
# Get the submodules
git submodule update --init --recursive
Windows
Warning
When building on the school PCs, only .wav files will play as SDLMixer’s vendor script will not run.
After opening up x64 Native Tools Command Prompt For VS2022:
# Navigate to the root folder and then
cmake --preset release
cmake --build --preset release
The resultant binary will be in the App folder.
Linux
# Navigate to the root folder and then
cmake --preset release
cmake --build --preset release
The resultant binary will be in the App folder.
Objects
Objects in TheEngine are empty containers on their own - they hold no behaviour by default. Functionality comes entirely from the components you attach to them.
Every object has a transform component by default, storing position, rotation, and scale. Objects can form parent-child hierarchies: a child’s transform is defined relative to its parent, so moving or rotating the parent moves and rotates the child with it. Children can be referenced from their parent object through the Lua scripting API.
Working With Objects
Adding objects
You can add objects by clicking the Add Object button in the scene graph.
Adding components to objects
You can add components to objects by pressing the Add Component button in the properties panel. You can read more about components here
Copying objects
You can copy an object by right clicking it in the scene graph and hitting the copy button.
Note
Copying an object currently does not copy all its children, nor are all components currently copyable. This will be addressed shortly.
Removing objects
You can remove an object by right clicking it in the scene graph and hitting delete.
Adding children to objects
You can add a child to an object by selecting in the scene graph and hitting the Add Object button.
Renaming objects
You can rename an object by selecting the object in the scene graph Rename.
Components
Components attach to objects to give them functionality. Every object starts with just a transform (position, rotation, scale); everything else - rendering, animation, physics, and more - is added through components.
Transform Component
Defines an object’s position, rotation, and scale in the world. Every object has one by default, and it forms the basis of the parent-child hierarchy. Child transforms are relative to their parent’s.
Mesh Component
Attaches a static mesh to an object for rendering. Works with the deferred PBR pipeline, with material properties like albedo, roughness, and metallic.
Skeletal Mesh Component
Attaches a rigged, animated mesh to an object. Bones are skinned on the GPU, and are driven by an animation clip and the object’s bone hierarchy.
Point Light Component
Emits light from a single point in all directions, falling off with distance.
Script Component
Attaches Lua behaviour to an object via the scripting API. Gives objects custom logic - input, gameplay events, or interacting with other objects and their children.
Camera Component
Defines a viewpoint for rendering the scene, which can be switched to at runtime.
Physics Component
Gives the object physics functionality powered by Jolt.
Shape Components (Box, Sphere, Heightmap, etc)
Gives the object a collision shape that is used by the physics system to handle collisions.
Terrain Component
Creates a terrain mesh for the object that is generated GPU-side. Note that an object cannot have both a mesh and terrain component.
Enemy AI Component
Gives the object AI that moves based on a flowfield.
Navigating TheEngine
Basic camera controls
The controls for the camera are very similar to Unreal Engine.
While holding right click:
- WASD - Movement
- Mouse - Pan camera
- Up Mouse Wheel - Increase camera speed
- Down Mouse Wheel - Decrease camera speed
Transform Controls
The keybinds for translation, scale and rotation is the same as Unreal Engine.
While an object is selected:
- W - Translation
- E - Rotation
- R - Scale
- X - Toggle grid snapping
Play Controls
- P - Start/stop simulation
Materials
Note
We are in the process of changing the format of materials, but the process for creating materials should remain largely the same.
Materials in TheEngine are very basic. You just need to specify the textures (albedo, normal, etc) and hit save.
Creating Materials
Creating materials is relatively straightforward. Once a material is created, it will be immediately available to apply.
Applying Materials
Materials can be applied to mesh components and skeletal mesh components.
Deleting Materials
There is currently no way to delete materials in-engine. To delete a material, navigate to Content/Materials and delete the material’s .mat and .meta file.
Caution
Before deleting a material, ensure that it isn’t being referenced anywhere!
Scenes
Levels in TheEngine are called scenes.
Internally, scenes are just JSON files, so they are human-readable.
Caution
Avoid editing scene files in a text-editor. It is very easy to break things.
Saving and Loading Scenes
Saving and loading scenes is very simple.
Animations
To add an animation, you need to add an Animation Player Component. In order to add this component the object must already have a skeletal mesh component.
Animations are supported to up 100 bones, and have a max bone influence of 4.
Applying an Animation
Caution
Be very careful when applying an animation. If the number of bones between the animation and the skeletal mesh do not match, the engine will (currently) crash!
Removing an animation
Caution
Do NOT remove the skeletal mesh component before removing the animation player component. This will cause the engine to crash!
Simply remove the animation player component from the object.
Physics
Physics in TheEngine is powered by Jolt physics. Objects in TheEngine do not have physics by default, and it must be set up using a physics component.
Warning
If you intend to use a Lua script to manually transform the object, then ensure that the object has its motion type set to “kinematic”.
Adding physics to objects
Physics functionality can be added to objects by simply attaching a physics component.
Physics Parameters
A summary of the physics parameters editable in the properties panel is given below:
| Parameter | Usage |
|---|---|
| Motion Type | Motion type, determines if the object is static, dynamic or kinematic |
| Object Layer | The collision layer this body belonds to (determines if two objects can collide) |
| Mass | The mass of the object. If not provided, Jolt will generate a mass value based on the collision shape. |
| Friction | Friction of the body. Should be between 0 and 1 |
| Restitution | Restituion of the body. Should be between 0 and 1, where 0 is a fully inelastic collision and 1 is a fully elastic collision |
| Angular Damping | Angular damping \(\frac{d\omega}{dt} = -c\omega\). Must be between 0 and 1, but is usually closer to 0 |
| Linear Damping | Linear damping \(\frac{dv}{dt} = -cv\). Must be between 0 and 1, but is usually closer to 0 |
| Gravity Factor | How much to scale gravity for this object |
Shape Components
Shape components are used to give physics object a collision shape.
Caution
You should only ever attach one shape component to a physics object. Furthermore, a shape component must not be degenerate. That is, it must have a non-zero volume.
The following is a list of shape components currently supported in TheEngine:
- Box
- Sphere
- Heightmap
Vehicles
TheEngine supports physics-based vehicles via the vehicle component.
Setting up a vehicle
Caution
TheEngine only supports one active vehicle at a time. There is currently no way to switch between which vehicle is active. The most recently added vehicle is the active one.
For an object to become a vehicle, it must already have an existing physics component and shape component. The motion type of the object must be set to dynamic, and the object layer must be set to MOVING.
If these conditions are met, then the object can become a vehicle by attaching a vehicle component.
Lua Scripting
Lua is a lightweight, high-level, multi-paradigm programming language designed mainly for embedded use in applications.
You can add Lua scripts to objects by attaching a Lua Script Component
TheEngine’s Lua API can be found here
Attaching Lua Scripts
Reloading Lua Scripts
Note
Due to limitations, objects that share a script will have to have their scripts manually refreshed individually.
You can reload a Lua Script by hitting the Refresh Script button.
ModelLoader
Note
ModelLoader is now integrated into TheEngine, and future releases of TheEngine will have it bundled.
ModelLoader is used to convert your normal model and animation files (.fbx, .obj, etc) to .mesh and .anim files that the engine can read. This is very much like what Unreal does with its UASSET files.
ModelLoader is also used to compress game textures into the BCn format so they can be directly loaded to and decompressed on the GPU. You can read more about the BCn file format here.
The latest version of ModelLoader can be downloaded from the repo.
Using ModelLoader
You can use ModelLoader by dragging a compatible file into TheEngine.
| Type | Supported Formats |
|---|---|
| Models | .fbx, .obj |
| Textures | .png .tga .jpg |
Caution
If TheEngine does not find ModelLoader on startup, it will warn you when you try to convert files.
Compressing Textures
It is important to use the correct BCn compression for a given texture type.
A guide for this is provided below:
| Type | Use For |
|---|---|
| BC1 | Colour maps |
| BC4 | Height maps, font atlases, grayscale images |
| BC5 | Normal maps |
| BC7 | High-quality colour maps |
Building ModelLoader
Both Linux and Windows binaries for ModelLoader are available on the repo. Furthermore, all releases of TheEngine should have ModelLoader bundled.
However, if you really want to build it from source, instructions are provided below.
Requirements
- CMake (>=3.10)
- Ninja (>=1.10)
- A C++ compiler (Clang, MSVC, g++)
Cloning the repo
# Clone the repo
git clone https://thorn.veritius.dev/engine/ModelLoader
# Assimp is given as a submodule
git submodule update --init --recursive
Building the binary
We use CMake as our build system and Ninja as our generator.
If you’re on Windows, use the x64 Native Tools Command Prompt installed with Visual Studio.
# From the root directory
cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release
cmake --build build