A lightweight and extensible game-engine built on SDL3 and OpenGL, forked from raynmetal/game-of-ur.
C++
3
204 commits
updated Oct 4, 2026
ToyMaker is an open source, extensible, single-threaded 3D game engine written in C++ on top of SDL3 and OpenGL. Scene data is described in JSON and managed through a combination of ECS and scene tree APIs. Demo projects using ToyMaker have been compiled successfully for Windows and Linux.
ToyMaker is currently in very early alpha; all APIs seen here today are subject to change until an eventual 1.0 release. It also doesn't yet feature a level editor.



Examples/FillContainer -- shows spheres spawning at a steady rate filling an invisible container, with several collision checks
and corrections taking place every frame.

Examples/TriplePendulum -- shows set of granular single degree of freedom position constraints being used to model the behaviour of
a hinge joint in a triple pendulum.

Examples/SlopeFriction -- demos friction forces causing a moving block to slow and come to a stop sliding down a gentle
incline.

Examples/ManyLights -- scene containing 441 point lights and 441 models (2 meshes each) rendered with instancing for both.

Examples/LeftRightCollision -- shows single one-to-one collision between two spheres.

Examples/UILayout -- shows UI elements being dynamically repositioned in response to window resizing.

Examples/CenterText -- demo featuring clickable text that spins on interaction.
Rendering using Blinn-Phong lighting in a fixed deferred shading pipeline.
Scene data organized and updated via the engine's own single-threaded Entity-Component-System implementation.
Extensible resource loading, tracking, and serialization through ToyMaker's Resource Database
Scene management through its scene-tree style API with JSON serialization. Additionally supports:
Multiple viewports through ToyMaker::ViewportNode, where each viewport may share its parent's ECS "World" or create one of its own.
Object-oriented, component based application logic scripting, a la many popular engines, through ToyMaker Aspects
Input abstraction, management, and serialization via the engine's input system.
[!NOTE] Currently requires knowledge of SDL's input event definitions to set bindings correctly.
Observer pattern implementation in the form of ToyMaker Signals, allowing decoupling of event data publishers and consumers.
A spatial query system using octrees for fast retrieval of scene entities based on spatial parameters (e.g., ray casts, bounding volume collisions, etc.)
A physics system using an implementation of Extended Position-Based Dynamics(XPBD) with support for collisions between capsules, spheres, and cuboids.
I spent 2023-2024 studying C++, OpenGL, SDL, and 3D graphics by following the tutorials on learncpp, Lazy Foo, and Learn OpenGL among others. I used my learnings to write Game of Ur, then split this engine out from it. The goal now is to take this as far as I can while learning as much as I can along the way.
See raynmetal/game-of-ur's toymaker-fork tag which holds the commit history leading up to the splitting of the engine project from the game project.
Documentation for the engine is available on this project's github pages.
Open, ongoing, and completed tasks and issues are tracked on this project's Trello board.
[!Caution]
The ToyMaker package requires libraries currently only available on the "sid"/unstable distribution of Debian.
Only experienced users should attempt to install this package, otherwise preferring to build and install ToyMaker and its dependencies from source. The method to install this package's dependencies are beyond the scope of these instructions.
Download the latest Debian package ending in _amd64.deb from here. Install with:
sudo apt install ./libtoymaker-dev_0.5.6_amd64.deb
Download the latest Arch package from here. Extract the package using:
tar -xvf toymaker-0.5.6-x86_64-arch.tar.gz
Enter the freshly extracted directory, then run makepkg to compile the library.
cd toymaker-0.5.6-x86_64-arch
makepkg
Finally, use pacman to install package binaries.
pacman -U toymaker-0.5.6-1-x86_64.pkg.tar.zst
WIP.
This project uses CMake for its build system, so make sure to have that installed.
On your platform, download the following packages and place them somewhere discoverable by your compiler toolchain. This project has been successfully compiled with MinGW-w64 on Windows, and clang on Linux.
SDL3 -- For abstracting away platform specific tasks, like requesting a window for the application.
SDL3 Image -- For loading of images in various formats.
SDL3 TTF -- For loading and rendering fonts.
GLEW -- For exposing OpenGL functionality available on this platform.
Nlohmann JSON -- For serialization/deserialization of data to and from JSON.
GLM -- For linear algebra functions resembling those in GLSL, and for quaternion math.
Assimp -- For importing assets of various kinds, mainly 3D models.
Doctest -- For building and running tests.
If you'd like to generate and tinker with the documentation generated for the project, also install Doxygen.
The project is bundled with a few CMake presets used with cmake --preset ${PRESET}
Examples_FullBuild_Release -- Compiles all example projects under Examples/ and
the ToyMaker library, with optimizations enabled and debug symbols disabled.
Library_Release -- Compiles only the engine library using sources found in
ToyMaker_Main/ and ToyMaker_Builtins/, with optimizations enabled and debug symbols
disabled.
Examples_AppBuild_Release -- Compiles a release version of the projects under
Examples/, linking them to ToyMaker binaries already installed in the local system.
Replacing Release with Debug in any of the above enables the generation of debug
symbols and suppresses many compiler optimizations.
First, clone this repository.
git clone https://github.com/raynmetal/toymaker.git
# OR, using ssh
git clone git@github.com:raynmetal/toymaker.git
Create a directory for storing files generated during the build process. The instructions here assume that the
build directory is ../toymaker_build/ relative to the project root.
# on Linux and Mac
mkdir toymaker_build
Enter the project directory and generate the build configuration using CMake. The instructions here use
the FullBuild_Examples preset (see the Presets section), that generates binaries both for the ToyMaker
library as well as the example projects under Examples/.
[!IMPORTANT] For now, the
toymaker_configure_executableCMake script picks up created and removed data files (JSON scene descriptions, images, models, etc.) only when this command is run.Be sure to rerun it whenever making such a change if you use ToyMaker in a project of your own, or when attempting to modify any of the examples.
cd toymaker
cmake --preset Examples_FullBuild_Debug -B ../toymaker_build
Finally head over to the project directory and actually build the project.
cd ../toymaker_build
cmake --build .
Starting in the build directory root, navigate to the directory containing the demo you would like to run (say, FillContainer).
cd Examples/FillContainer
Then simply run the generated executable (likely prefixed with Example_).
./Example_FillContainer
[!WARNING] This command will not work if you try running it while in a different directory from the executable, as in:
toymaker_build/Examples/FillContainer/Example_FillContainerRunning the above will lead to an immediate crash, as the program won't be able to find the data files it expects to find in the directory where the command was invoked. This is an issue and will be addressed in a future update.
Tests are compiled along with the rest of the library when ToyMaker is itself the project being built (as opposed
to when it is a vendored library in another project). The test sources are found under tests/ under the project
root.
To run them, go to the root of the build directory, then invoke:
tests/TestDriver
ToyMaker uses Doctest for testing. See instructions there to learn how to run tests selectively, or with options besides the default.
I'm not planning to accept contributions to this project any time soon. Feel free to fork it and make it your own, though!
raynmetal/toymaker is distributed under the terms of the MIT License.
This program makes extensive use of the following libraries:
A lightweight and extensible game-engine built on SDL3 and OpenGL, forked from raynmetal/game-of-ur.
C++
3
204 commits
updated Oct 4, 2026
ToyMaker is an open source, extensible, single-threaded 3D game engine written in C++ on top of SDL3 and OpenGL. Scene data is described in JSON and managed through a combination of ECS and scene tree APIs. Demo projects using ToyMaker have been compiled successfully for Windows and Linux.
ToyMaker is currently in very early alpha; all APIs seen here today are subject to change until an eventual 1.0 release. It also doesn't yet feature a level editor.



Examples/FillContainer -- shows spheres spawning at a steady rate filling an invisible container, with several collision checks
and corrections taking place every frame.

Examples/TriplePendulum -- shows set of granular single degree of freedom position constraints being used to model the behaviour of
a hinge joint in a triple pendulum.

Examples/SlopeFriction -- demos friction forces causing a moving block to slow and come to a stop sliding down a gentle
incline.

Examples/ManyLights -- scene containing 441 point lights and 441 models (2 meshes each) rendered with instancing for both.

Examples/LeftRightCollision -- shows single one-to-one collision between two spheres.

Examples/UILayout -- shows UI elements being dynamically repositioned in response to window resizing.

Examples/CenterText -- demo featuring clickable text that spins on interaction.
Rendering using Blinn-Phong lighting in a fixed deferred shading pipeline.
Scene data organized and updated via the engine's own single-threaded Entity-Component-System implementation.
Extensible resource loading, tracking, and serialization through ToyMaker's Resource Database
Scene management through its scene-tree style API with JSON serialization. Additionally supports:
Multiple viewports through ToyMaker::ViewportNode, where each viewport may share its parent's ECS "World" or create one of its own.
Object-oriented, component based application logic scripting, a la many popular engines, through ToyMaker Aspects
Input abstraction, management, and serialization via the engine's input system.
[!NOTE] Currently requires knowledge of SDL's input event definitions to set bindings correctly.
Observer pattern implementation in the form of ToyMaker Signals, allowing decoupling of event data publishers and consumers.
A spatial query system using octrees for fast retrieval of scene entities based on spatial parameters (e.g., ray casts, bounding volume collisions, etc.)
A physics system using an implementation of Extended Position-Based Dynamics(XPBD) with support for collisions between capsules, spheres, and cuboids.
I spent 2023-2024 studying C++, OpenGL, SDL, and 3D graphics by following the tutorials on learncpp, Lazy Foo, and Learn OpenGL among others. I used my learnings to write Game of Ur, then split this engine out from it. The goal now is to take this as far as I can while learning as much as I can along the way.
See raynmetal/game-of-ur's toymaker-fork tag which holds the commit history leading up to the splitting of the engine project from the game project.
Documentation for the engine is available on this project's github pages.
Open, ongoing, and completed tasks and issues are tracked on this project's Trello board.
[!Caution]
The ToyMaker package requires libraries currently only available on the "sid"/unstable distribution of Debian.
Only experienced users should attempt to install this package, otherwise preferring to build and install ToyMaker and its dependencies from source. The method to install this package's dependencies are beyond the scope of these instructions.
Download the latest Debian package ending in _amd64.deb from here. Install with:
sudo apt install ./libtoymaker-dev_0.5.6_amd64.deb
Download the latest Arch package from here. Extract the package using:
tar -xvf toymaker-0.5.6-x86_64-arch.tar.gz
Enter the freshly extracted directory, then run makepkg to compile the library.
cd toymaker-0.5.6-x86_64-arch
makepkg
Finally, use pacman to install package binaries.
pacman -U toymaker-0.5.6-1-x86_64.pkg.tar.zst
WIP.
This project uses CMake for its build system, so make sure to have that installed.
On your platform, download the following packages and place them somewhere discoverable by your compiler toolchain. This project has been successfully compiled with MinGW-w64 on Windows, and clang on Linux.
SDL3 -- For abstracting away platform specific tasks, like requesting a window for the application.
SDL3 Image -- For loading of images in various formats.
SDL3 TTF -- For loading and rendering fonts.
GLEW -- For exposing OpenGL functionality available on this platform.
Nlohmann JSON -- For serialization/deserialization of data to and from JSON.
GLM -- For linear algebra functions resembling those in GLSL, and for quaternion math.
Assimp -- For importing assets of various kinds, mainly 3D models.
Doctest -- For building and running tests.
If you'd like to generate and tinker with the documentation generated for the project, also install Doxygen.
The project is bundled with a few CMake presets used with cmake --preset ${PRESET}
Examples_FullBuild_Release -- Compiles all example projects under Examples/ and
the ToyMaker library, with optimizations enabled and debug symbols disabled.
Library_Release -- Compiles only the engine library using sources found in
ToyMaker_Main/ and ToyMaker_Builtins/, with optimizations enabled and debug symbols
disabled.
Examples_AppBuild_Release -- Compiles a release version of the projects under
Examples/, linking them to ToyMaker binaries already installed in the local system.
Replacing Release with Debug in any of the above enables the generation of debug
symbols and suppresses many compiler optimizations.
First, clone this repository.
git clone https://github.com/raynmetal/toymaker.git
# OR, using ssh
git clone git@github.com:raynmetal/toymaker.git
Create a directory for storing files generated during the build process. The instructions here assume that the
build directory is ../toymaker_build/ relative to the project root.
# on Linux and Mac
mkdir toymaker_build
Enter the project directory and generate the build configuration using CMake. The instructions here use
the FullBuild_Examples preset (see the Presets section), that generates binaries both for the ToyMaker
library as well as the example projects under Examples/.
[!IMPORTANT] For now, the
toymaker_configure_executableCMake script picks up created and removed data files (JSON scene descriptions, images, models, etc.) only when this command is run.Be sure to rerun it whenever making such a change if you use ToyMaker in a project of your own, or when attempting to modify any of the examples.
cd toymaker
cmake --preset Examples_FullBuild_Debug -B ../toymaker_build
Finally head over to the project directory and actually build the project.
cd ../toymaker_build
cmake --build .
Starting in the build directory root, navigate to the directory containing the demo you would like to run (say, FillContainer).
cd Examples/FillContainer
Then simply run the generated executable (likely prefixed with Example_).
./Example_FillContainer
[!WARNING] This command will not work if you try running it while in a different directory from the executable, as in:
toymaker_build/Examples/FillContainer/Example_FillContainerRunning the above will lead to an immediate crash, as the program won't be able to find the data files it expects to find in the directory where the command was invoked. This is an issue and will be addressed in a future update.
Tests are compiled along with the rest of the library when ToyMaker is itself the project being built (as opposed
to when it is a vendored library in another project). The test sources are found under tests/ under the project
root.
To run them, go to the root of the build directory, then invoke:
tests/TestDriver
ToyMaker uses Doctest for testing. See instructions there to learn how to run tests selectively, or with options besides the default.
I'm not planning to accept contributions to this project any time soon. Feel free to fork it and make it your own, though!
raynmetal/toymaker is distributed under the terms of the MIT License.
This program makes extensive use of the following libraries: