Nebula is an open-source and free-to-use modern C++ game engine
github.com
github.com
I still remember when I was visiting Skellefteå around March (? it was still deep winter up there though) 2010 to meet the students doing some pretty damn impressive game projects with Nebula even back then and on that same day I got the call from Berlin that our company (Radonlabs) had finally to file for bankruptcy.
Massive props to Johannes (who moved on AFAIK) and Gustav (who just added D3D12^H^H^H (oops looking at the source it's Vulkan!) raytracing and meshlet support - how crazy is that!).
I would love to have such tech nowadays, but focused on 2D/light-3D mobile games :)
A lot of Project Nomads consisted of Tcl scripts which directly called into C++ class interfaces exposed to Tcl. This was extremely flexible, but also put too much power into the hands of gameplay scripters which came up with hair-raising workarounds for missing features in the C++ code heh.
Another design wart was that we also closely integrated Tcl into the asset pipeline (e.g. you could attach small Tcl 'scriptlets' directly to Maya 3D objects which then would be evaluated during the asset export). This means we had to carry a small Tcl interpreter in the Maya plugin all the way to the end even though the actual engine long had dropped any support for Tcl scripting.
Project Nomads scripting left such a deep scar that I removed all scripting features in Nebula3 (which the gscept/nebula version is based off, although I see there is some Python support under addons/scripting), and I remain a big sceptic when it comes to integrating 'scripting languages' into game engines. A probably too extremist pov.
TL;DR: don't expose your low level engine APIs to scripting, and don't use the same scripting API for persistency and/or asset pipeline file formats, it will inevitably end in tears ;)
Another hazy memory is that I contributed to an early reference manual for Nebula. I probably was using the name 'nikos' at the time.
Why did you fall behind with the "missing features"? What complications slowed down gradual rewriting with improved C++ components and smaller, cleaner, higher level scripts with less workarounds? I suspect inertia (the sunken cost of extant scripts) and cumbersome tooling, knowing more would be interesting.
In part it was kind of a vicious cycle, the dynamically typed scripting interface made it impossible to do any real changes to the C++ code, so towards the end of the project we were stuck between a rock and a hard place.
The scripting interfaces were direct mirrors of essential low-level engine C++ classes. Doing any changes to the C++ interfaces which were called by scripts wouldn't result in compiler errors but crashes at runtime.
Tcl scripts were also impossible to properly debug, and even performance profiling was kinda hard (most problems were not crashes or game logic bugs, but performance problems, where a script spent too much time in the script part and too little in the C++ part).
The *actual* main problem in hindsight was that we failed to think about and provide a proper "gameplay vocabulary" right from the start, e.g. identify and split the gameplay elements into small logic blocks which would be implemented in C++ and only combined / glued together via scripting. In typical arrogant junior coder fashion we mostly spent time down in the guts of the engine, and only paid little attention to the gameplay logic problems, that was something for the gameplay scripters to worry about.
Also, for the few 'senior people' on the team this was our second game project, and the first C++ project. And everybody else had no game development experience at all. We still shipped the game somewhat in time, so there's that ;)
PS: I guess the *actual-actual* problem was that I was a fan of "big idea" designs at the time ;) E.g. stuff like "everything is a Tcl-scriptable object", yes it might look elegant, but conceptual elegance only helps so much in real-world scenarios. It's much more important that a code base is malleable, and an entire game codebase built around a single "big idea" is usually not.
I now advocate, when the topic comes up, for the scripting to be strictly used as a configuration language: it can be used to initialize and pass data structures back to the engine, but it shouldn't be controlling the main loop. If you want it to define any specific runtime behavior like an AI policy, it's still more robust to make a targeted micro-runtime and have the scripting language compile to that.
I probably share many of your extremist pov on no extension scripts because I have seen weird build time, and pre-run time scripts cause a lot of issues in projects.
Should also give some cred to Fredrik who's been working on the entity-component setup on the game side.
Looked around the space recently with a focus on "Linux-usable, C++-able, Vulkan-able non-abandoned/non-rather-too-outdated engines today" (license unimportant in my search) and came away with: Unreal 5, Flax Engine, Godot (C++ story shaky / WIP, C++ is not a first-class game-dev scenario here AFAICT), Wicked Engine. (There's more out there that I ruled out for this or that reason and thus forgot about by now.)
Top candidates for me ended up being UE and Wicked, the latter currently preferred due to my actual (somewhat foggy/fuzzy =) code-first & code-mostly use-case idea. UE5 has way more batteries-included but it feels heavy and presses your C++ coding into a cage of its various de-facto-required macros, the whole setup seems to throw off both major VSCode extensions for C++, and its hit-or-miss hot reload thingie. Everything very geared to its authoring environment, understandably. But I really just want "engine as a linked .so library" here for my stuff..
(By Linuxable I don't mean Proton/Wine, but actual compiled-for/compileable-under-and-for Linux.)
General: stb https://github.com/nothings/stb
2D Phys: box2d https://box2d.org/
UI / Editor: imgui https://github.com/ocornut/imgui
Platform: SDL https://www.libsdl.org/
Engine: Quake https://github.com/id-Software/Quake
Ok, Quake is more of an engine than a library - but it is well documented & widely used. Even many current day AAA engines are still originally based on the Q1 engine (though, of course, heavily modified over the years to stay modern).
I don't mean to bring down anyone but I feel like game engine announcements are a dime a dozen these days. As someone who has worked in the industry I'd favor putting together my own simple engine based on libraries for smaller scoped projects. Most open-source engines, I presume, are not really going to be battle tested, well-supported, well-funded etc. There are some exceptions of course (like Godot). If your goal is too complex; why not just use UE5 or Unity? Epic has been in the industry for a long time, Tim Sweeney is a really smart guy, and the engine has been widely used in AAA and indie games.
But if you want 3D objects or game networking etc etc, a game engine will probably be the right thing.
Godot C++ here - works fine so far. I use C++ for the heavy lifting and GDScript for gluing things together. Pretty stable, and the engine compiles in minutes (needed double precision). C++ game logic compiles rather fast. Since the engine is written in C++, that language is right at home.
GDExtention?
https://docs.godotengine.org/en/stable/tutorials/scripting/g...
You only need to make sure your extension API file is in sync with any “main” engine version upgrades. And for major upgrades godot-cpp.
Everything compiles really fast in both Linux and Windows and dependencies are easy to set-up.
However, there is little C++ documentation but that is because once you get the gist of using their Ref<T> wrapper everything is intuitive (functions and methods map one to one from GDScript). Just download their example and have a look around.
Also the engine’s code is _very_ easy to follow if you get stuck and can itself be used as samples.
I am really rusty (even rust can be used btw) with C++ and was able to pick things up quite fast.
Let me know if you have any questions. But really all I needed to start was their example above.
This is one of the best parts of Godot, it's small enough to compile pretty quickly, and simple enough that you can jump in and understand the code and debug any problems with minimal friction.
The maintainers are also good about quickly accepting small bug fix PRs.
And yeah, the development experience with GDExtension is now really nice, though it's best to do a little work to set up a CMake project rather than relying on scons.
But the batteries included are almost always useful. If you don’t really know what you’re doing, you’re likely to make something that sort of works but fails to consider edge cases the engine designers have dealt with other time through trial and error.
I disagree with your take - do as much as possible in C++, and expose functions to be called from Blueprint/UMG.
We have ImGUI integrated so it's easy to use, but considering there are plenty of systems to interface with, it might be hard to deal with content without some content tools.
We mostly work on the core engine side of things. I am still not happy with a bunch of things rendering wise and want to make the engine capable of current gen rendering with GI, raytracing and whatnot.
But it's an open source project, so anyone could build tooling around the engine if they want ;)
The asset pipeline handles FBX and GLTF with regards to models. We read GLTF materials and support the baseline metallic-roughness natively. For FBX:s though, you need to edit the materials manually.
The biggest hole in Nebula is that there are almost no tools, so editing materials is painstakingly done in XML. We basically haven't had time to implement the plethora of UI required to interface with the engine in any meaningful way.
Long term, we plan to do all of this obviously. We used to have a pretty good toolset back before we did a total rewrite of the engine internals to get rid of all the smart pointers and move towards cache coherency and a data driven design.
We support a wide range of image formats as well. They end up getting compressed (or not) to DDS in the end. The import settings is also something we need to implement a bunch of UI for, but currently we look at the file name to reason about compression schemes and whatnot.
I used to use Unity with a third-party 2D framework that bypassed all its game object stuff.
Still happy with it.
That aside, looking at the whole game engine "market", I'm surprised that more game engines in 2024 don't talk about or differentiate on their net-code.
Syncing the physics sim between multiple clients and the server is one of the hardest problems in gaming today.
Are there any game engines or state management frameworks for game engines that really stand out?
Also, if you look closely at the profiler, you'll see that we spend 2.2ms in the frame just waiting for the previous frame to finish. That was a major performance hog at the time.
This frame also basically shows no game logic whatever. So we just spend time waiting on other threads to finish while doing nothing else, which is also not indicative of a real-game scenario.