What I like is that this engine actually have a demo which is more than few cubes and sprite: A full tiny game. Game engine should have more tiny games as it's a good way for newcomers to have something they can start to hack (change gravity/texture/lighting effects) and understand what a game engine is and how it work.
The code is quite clean and it also provide scene editor with dedicated UI widgets.
The game and the editor are massively helps to find right approaches in development. All my previous attempts to write engines (in other languages) were bad because all they had is just some very simple demos with some meshes and lights. You never know which features engine should have until you need them. Many engines trying to have best possible graphics and does not pay attention to other very important things, like sound, animation, physics, resource management, save/load, editor, etc.
HMH is kind of special though in that its author, Casey Muratori, has many years of experience in gamedev. I think the saying of the parent commenter to yours is mostly applying to people who are trying to make game engines for the first time with little or no past experience in actually shipping complete games.
Not really... All great game engines were spawned out of AAA titles. You should never try to build an engine without a set of games that stretch its limits in all directions, otherwise something will always go wrong. There isn't a single person alive who can manage the complexity of a game engine. As soon as you start splitting things up, you run into problems of distributed development. Getting this right without eating your own dog food is unlikely, at best, no matter how experienced your team is...
What makes the difference between an experienced engine developer, like CryTek and Unreal, and a hobbyist or a company who does it for the first time, is mostly that while both of them will definitely build a game with the engine while creating the engine, the experienced team will actually produce a re-usable, well designed engine, while the inexperienced team will produce a hunk of junk that doesn't fit together and doesn't extend past the game they were trying to develop.
Seems like it. Still the tons of games that are and have been MADE with Unity over time have led it to become what it is now.
"Unity was founded in Copenhagen by Nicholas Francis, Joachim Ante, and David Helgason. Its story began on an OpenGL forum in May 2002, where Francis posted a call for collaborators on an open source shader-compiler (graphics tool) for the niche population of Mac-based game developers like himself. It was Ante, then a high school student in Berlin, who responded.
Ante complemented Francis’ focus on graphics and gameplay with an intuitive sense for back-end architecture. Because the game he was working on with another team wasn’t going anywhere, they collaborated on the shader part-time while each pursued their own game engine projects, but decided to combine forces upon meeting in-person. In a sprint to merge the codebases of their engines, they camped out in Helgason’s apartment for several days while he was out of town. The plan was to start a game studio grounded in robust tech infrastructure that could be licensed as well."
Sort of - the original developers made a game which failed commercially and they decided to sell their tools instead. But the engine has changed a lot since those days, and Unity's lack of real dog fooding is a common complaint from people who use it professionally. Unity don't see the problems that only come up when you try to ship a real game in a team, on console or mobile in particular.
Wow, this is a lovely, pragmatic, no nonsense game engine! And it has a non-trivial example project and an editor! This is such a breath of fresh air for game engine announcements.
I don't know if mrDIMAS is on HN but big congrats to him for this great project.
It takes some parts of ECS but the UI is OOP-ish. I wonder if there is a good ECS UI architecture. I have been exploring this lately in Rust, and right now I have settled on jquery style selectors (don't laugh) where you have a generic entity builder and associate a selector (id + class list) with each entity. When an event fires, you check what selectors are associated with the focused entity and call the associated callbacks. I also do this for rendering. I'm not too crazy about this though. But I'm having a hard time figuring out how to do behavior composition in Rust.
In ECS, one system can touch the innards of multiple kinds of components directly, and one kind of component can be touched by multiple systems. Components only hold data and no logic, so in most ECS designs systems will know about the internals of components intimately. This shows a design can ECS-compliant while violating a key part of OOP methodology: encapsulation.
You can use ECS and OOP in tandem by re-introducing encapsulation, as well as any other parts of OOP lost, but you need to be careful not to violate key parts of ECS, such as component not being allowed to have any “logic” (I out logic in quotes because it’s not well-defined: does logic mean ANY code or just... non-boilerplate code?)
One must consider how a codebase will evolve over time, which requires putting yourself in the shoes of those who will be working on the codebase. What benefits does strictly confirming to both ECS and OOP bring? Does the introduction of ECS bring enough structure that the codebase can remain clean, performant, maintainable, portable, etc even without OOP? Is there some kind of hybrid of ECS and OOP where the rules of each are relaxed to create an even better structure? How do all of these potential designs actually look in practice, and is there clear mappings from problems in the problem domain to the philosophical structure being imposed?
In games, it’s hard to map some of the problems to OOP structures (while remaining conformant, clean, performant, maintainable, portable). ECS isn’t perfect, but it’s much better.
I find using C-style, OOP, Actor model, and ECS structuring for different bits of code the best solution. There isn’t a one-size-fits-all when it comes to those things, unfortunately. Though I believe there will be one day (that is: a language arrives which has a model that everything maps to nicely and we’re all happy using and we all say “Wow everything’s so simple now”)
ECS is just game developers discovering about protocols from 1986, made popular in three well known languages with OOP support, and giving other name just because they don't get OOP has many ways of being implemented.
Entities are a collection of component instances and nothing more.
Components in ECS are data-only.
Systems in ECS are logic-only.
If you follow this strictly, then you cannot support encapsulation or data-hiding. There is no sole definition of OOP, but it is widely accepted that the ability to do encapsulation, including data-hiding, is a key part of OOP.
Therefore, ECS is not OOP.
QED
If you’ve not seen the Overwatch team’s talk in which they discuss ECS, I can highly recommend it as a good resource to learn about ECS: https://youtu.be/W3aieHjyNvw
There may be models commonly used in those languages you mentioned that are similar to ECS, but you seem to be implying that ECS is a form of OOP; it is not.
Even if you implemented OOP using Structs of Arrays, a thread per object, or whatever you like, you cannot strictly conform with ECS’s requirement that “components have no logic” while also strictly conforming with OOP’s requirement that “objects should not know about each others’ internals” (object hierarchy).
ECS is definitly OOP, just not for those that don't bother reading SIGPLAN papers from the 80 and 90's and the multitude of approaches to OOP and the object, prototype or component based variants thereof, and are stuck with the concept that OOP == Smalltalk-80 as they learned C++ OOP from some C with Classes book.
I guess I need to find some time to prove my point, port ECS examples to Objective-C, Eiffel and CLOS, and provide links to some of those papers as well.
A bit more love for ACM and IEEE goes along way in acquired knowledge.
What I love about this engine, is that I can really easily read the code and reason what it does. I'd guess that given an hour or so of study I would feel reasonably confident in trying to modify it.
The same is also true of the author's previous engine [1], written in C99. Would love to get the author's take on the costs and benefits of switching to Rust on the basis of what's effectively a reasonably sized real world case study, at least as far as individual projects go.
Thanks for the link!
I am going to look more into rg3d, but the C99 engine is interesting to me, because I use Raylib[0] for my C gamedev explorations. I will never fully leave C, because I will be dead before C is fully, or largely, displaced by the likes of Rust or another PL. I have also been playing with Zig, and there is a Tetris demo done by Andrew Kelley the creator of Zig, but no game engine I know of yet [1,2].
C++ is incredibly verbose (STL) and carries a lot of baggage and mental overhead. Rust has improved ergonomics in nearly every area except lifetime handling, which is a concern you want to think about and make explicit.
I predict in ten years the gravitas for new projects will have shifted entirely to Rust. C++ is just too much of a burden to write and verify. C++ will still have plenty of healthy projects, but I think it'll be hard to attract new projects when Rust has come so far.
Theoretically yes, practically it's a different story.
Sure you can write clean modern cpp (the act of which is harder than writing clean Rust), but if your dependencies are still "C with classes", you are forced to particular patterns.
It's also not nearly as prevalent as people from outside the ecosystem seem to think it is. I read a lot of "any non-trivial Rust code will have to use unsafe" and I guess that means that all of the code I've worked on is trivial.
I believe if we dug into things deeper, we would find that "non-trivial code" here means "code that doesn't need unsafe". Developers of rust and std do a great job to cover all the "non-trivial" cases by the std types. Everything covered by them doesn't seem non-trivial anymore. So... here we are.
The work being continuously done to improve the state of unsafe on crates.io proves otherwise.
That is my point, people continue to use "C with Classes" because they don't know better or were poorly taught, likewise many reach out to unsafe as they cannot make it work otherwise and leave the code like that.
In a world with a very thin standard library and an npm like dependency tree, every crate might be full of unsafe surprises that one is only aware if going through all of them.
And this in a scenario where cargo doesn't do binary dependencies.
Only about 1% of Rust code is unsafe. We can still expect that 1% to be just as full of memory safety bugs as C++, so it's obviously important to clean those crates up, but that's a pretty huge improvement. It's also much easier (actually tractable, in many cases) to completely review a dependency's uses of unsafe, compared to doing a thorough code review of an entire dependency as you would have to do in C or C++ to get the same guarantees.
As someone that has enough C and C++ experience going back to 1992, worked at CERN and Nokia in very complicated C++ codebases and still has issues with the borrow checker and when to annotate what, I beg to differ how easy it is to use Rust, although I do conceed it has gotten much better.
I am well aware of your opinions on this matter. None of what you just said has anything to do with Frama-C. You can't throw that out there as a Rust alternative (which, as I noted, it is not, or at least not a complete one) and then compare how easy "vanilla C++" is compared to Rust (like I said, I disagree with you on that, but it's not even relevant here).
The truth is that for people who care about safety (as I know you and I do), want to use an unmanaged language (for whatever reason), and don't want to use Ada (no accounting for taste, I guess), the "correct" comparison is C and C++ with a load of static analysis tools that don't quite work, miss plenty of bugs, enable dynamic protection that slows down your program, are not easy to install, and can be terribly noisy when not configured extensively for your project... vs. Rust which works out of the box, has the analysis integrated into the typechecker, has a simple installation and upgrade process, and catches everything. In that competition, Rust wins every time.
Almost fully agree, just the ergonomics are fully there and while static analysis tools aren't fully there, nor ever will, as you well point out, the likes of Google and Microsoft seem quite minded to bring Rust into C++, despite their ongoing adoption of Rust.
As the latest posts from Visual C++ seem to imply,
Because the language alone isn't enough, the existing eco-system and tooling also plays a big role.
Since we are speaking about games here, C++ just hit the jackpot with GPGPU programming, even though other languages are also supported in PTX and SPIR-V.
So I am actually curious how far the companies with seat at ISO C++ are actually going to adopt Rust on their platforms, versus briging Rust learnings into C++.
Microsoft, sure--nobody has worked harder than they have to try to make C++ safer. And there are other big companies seriously investing in making C++ safer (e.g. Facebook, bad as they are otherwise).
But I've also talked to many of the researchers actually working on these projects--they'll freely tell you how hard the task is and how impossible it is to really apply Rust's straightforward solutions to the massive existing legacy of C++ code. And let's be honest--if your tool requires people to rewrite everything anyway, they might as well choose Rust, so it's not acceptable for your tool to only work on modern stuff, or require annotations everywhere you use std::string_view, etc.
And I should be very clear that this is quite specific to C and C++. Ada, for example, has been able to adopt solutions from Rust with ease, and even add some interesting improvements, because the safe subset of their language was conservative and the borrow checker allows them to extend it. So I'm not saying other languages cannot copy Rust, it's very much specific to unsafe by design languages like C++.
They're trying to make their existing codebases safer, and I think that's great, but unless there's a massive breakthrough in the next few years these aren't going to be general purpose solutions and they are definitely not going to be close to sound. For example, pretty much everything I'm aware of for C++ that tries to do memory safety, punts on thread safety, because it's just virtually impossible with all the other stuff going on; many of them punt on recursive function calls, and a bunch don't even do anything but very basic interprocedural analysis, focusing all their energy on "local" intraprocedural bugs that are much easier to catch. The tools would just be too noisy to be useful otherwise.
As for Google... they resisted investing in static analysis tools for years and I don't take them seriously at all when they talk about this sort of thing.
Google is at least serious on Android with all the mitigations that have been added, inclusive being able to write drivers in Java (as per Project Treble), and it is thanks to them that Linux no longer uses VLAs.
But for example, in spite of using Rust on ChromeOS, Fuchsia and now thinking of introducing Rust on Android 12+, there are no plans to expose it in any of the OS SDKs for userspace applications.
I didn't say Google didn't care about security, just that they have shown almost no interest in static analysis, and have shown a clear preference for runtime mechanisms like sandboxing and garbage collection for memory safety. That's why I find it weird that you're bringing them up here as some sort of leader in C++ static analysis, they very much aren't and have been quite dismissive of related work like verification as well.
I'm also not sure what you mean by "exposing Rust in the userland SDK." Rust doesn't have a stable ABI, how would that even work? It's not like they're exposing system calls as C++ classes or anything like that, either. The choice of programming language for an operating system is, at least from the perspective of API design, mostly an implementation detail.
c++ is a bit more verbose than rust. think about all the stdlib functions that take begin and end iterators for containers. there's an overload for std::set_difference that takes six arguments, five of them being iterators.
that's true and I am very excited for ranges. sadly I am still waiting for c++17 to be switched on in my build system :/
still there's lots of other stuff that's more verbose in c++ than rust, often because it was bolted on much later. think about getting individual elements out of a tuple.
in c++: `std::get<0>(tuple)` for each desired element or `std::tie(elt0, std::ignore, elt2) = tuple;`
in rust: `tuple.0`, not sure if there's an equivalent to the std::ignore/std::tie combo
40 years of IDE tooling, libraries, GUI toolkits, GPGPU designed for its memory model, shader language dialects with graphical debuggers, tier 1 support on the OS SDKs from Sony, Nintendo, Apple, Google, Microsoft, Arm, Samsung, Huawei, certified compilers for industrial deployments, an international standard independent of US sanctions.
Probably by using a third-party library, with a pre-concepts-based implementation which is heavy on compile times. Unlike Rust, where they're built in and don't really have that cost.
The context here is comparison between Rust and C++, for a side project begun over a year ago. Citing pre-standard C++ features with partial/experimental third party implementations doesn't really make the difference you seem to think, in that context.
Maybe what you're using isn't ranges. But, they seem to work well enough that you think they're ranges, so who cares whether they're ranges or not? They work!
I love rust but one pet peeve of mine is that projects can unfortunately get very hard to follow / libraries very hard to use once too much generics start to get poured into.
I can't quantify it, but I get the impression that the Rust community is starting to turn against unnecessary use of generics and proc macros of late, albeit largely because of their impact on compile/link times rather than readability.
I think macros are incredibly powerful when used parsimoniously, but can make code completely inscrutable and surprising when overused.
There's probably an unavoidable trade-off between the flexibility and expressiveness of a language and readability (and possibly compile times). It's part of the reason I would recommend a more restrictive language like Go in a professional setting, even if I would rather program in Rust at home.
This feels a little harsh. A huge community effort has gathered behind Bevy, and there are a lot of interesting projects that people have made with it so far. Check out the showcase channel of the Bevy discord.
This looks really impressive! Given that Rust -> WebAssembly is at least a thing, would it be plausible for someone to make that rusty-shooter demo work in a browser?
There is also a problem with rg3d-sound - it supports only Windows and Linux right now. So there will be no sound on other OSes. I've tried to add at least macOS backend by myself, but I failed all attempts to install macOS on virtual machine :(
The graphics code would have to be ported to WebGL, and then there might be an extra hurdle getting WASM to talk to WebGL directly. But it's doable, yes.
It makes use of ‘glow’, a Rust library that lets you write regular OpenGL code that runs across desktop, mobile, and web: https://github.com/grovesNL/glow
Wow, there are a lot of solid game engines coming out in Rust. Most are still pretty early, but it's really impressive how much of the gamedev community has such an interest in Rust.
In Rust projects where you want to be developing multiple highly related modules in tandem with each other, it can be helpful to just use a single repository and a Cargo workspace[1].
You can still build and publish them individually, but it can make development and testing much simpler.
This is awesome!!!! It would be cool if there were some binary releases, at least for the shooter example. I'm not sure if there's anything huge blocking that though?
Also I'm admittedly not rust-proficient yet but would the cargo run command be cross-platform dependent, or is this a windows-only thing right now?
I doubt projects like this would help. For big developers, 99.99% of the time they are already riding on existing codebases (even when they call it by different names for marketing reasons) - the last two AAA games i worked at have codebases more than a decade old, one actually two decades old. While technically they could add rust as an extra language, in practice this wont happen both because the vast majority of game developers are conservative in terms of languages but also because it creates extra barriers (most people who write C++ code in games barely know C++ - the wizkids that everyone has in mind when hearing about high octane game engines are a tiny minority compared to everyone else who touches a game's codebase) which make it harder to hire new people (unlike other disciplines in gamedev, decent programmers aren't as easy to find). Also everyone hates how slow C++ is to compile and last time i checked rust is even worse.
For smaller developers projects like this still wont help drive adoption since smaller developers have the freedom to decide on their own what language they'd use (assuming they aren't already using an existing codebase, some of the stuff above also apply to smaller developers) and they'd already be using rust if they thought it'd help. In general i believe that developers who have enough knowledge to make their own engine in other languages and be able to make their engine in rust, would be able to tell if rust is a good choice or not.
Or to put it in another way, i doubt projects like this will help drive adoption for rust among game developers because the developers have either already decided what language to use (be it rust or something else) or are not in a position to decide what language to use.
(yeah sure, there might be an exception or two out there, but there are hundreds -if not thousands- of engines... after all Remedy, a AAA studio, used D in their engine yet you do not see much of an uptake of D among game developers even though technically D would be easier to grok by C++ programmers, integrate with existing engines with its C++ interop and even provides features like compile time code evaluation and generation for features that i've seen C++ projects use overcompilated macros and external build time generators that rely on brittle code comments to work)
You are seeing this from the wrong perspective, and yes although I do like Rust very much, C++ is my native tool alongside the managed languages I regularly use (reasons for other time).
Since the Assembly days it has been like this, some high level language keeps being disdained until it gets enough momentum for adoption by game developers.
Back when I started coding graphics, Basic, Pascal, Modula-2 and C were seen as the Unity for home computers, good enough for simple games, but professionals were only using Assembly.
Professionals with deep pockets would eventually manage to buy an UNIX or VMS based computer, make use of C or BLISS and cross-compile to arcade machines and 8 home computers.
While on 16 bit home computers, C, Pascal with lots of inline assembly started gaining adoption, but no one in perfect mind would make use of either C++ or Object Pascal (even with MPW most Apple games were coded in Assembly).
With Windows, OS/2, BeOS, Watcom C++ with DOS/4GW, Pentium/Abrash books, Sony Playstation C++ SDK, C++ finally started to get enough industry support to be taken seriously .
Same with Java and C# adoption, while not at the same level as C++, they have found their way as programming languages to write engine tools, or be the scripting language on top of the performance critical C++ code. Also here it was a long path to adoption driven by J2ME ecosystem, Sun's JavaGamming failed efforts, Java3D, Android, Visualization industry (JViews, VTK), while C# had initially indies writing their own C++/CLI bindings to DirectX, followed by Managed DirectX, XNA (specially it being a must have on WindowsPhone 7), MonoGame, Unity, UWP/HoloLens.
So Rust is still at the begining of this long road, if enough engines like this start poping up, eventually some well known studios or platform owners will pay attention and give it a place at the table. Microsoft is already prototyping with Rust/WinRT, who knows what plans they have for it.
As for D, the community is great, but they don't push a proper roadmap for the language and all the cool features that D might have offered 10 years ago, have slowly been added to .NET, Java and C++, additionally Swift, Rust, Go, Kotlin/Native, Nim, Zig also arrived to the party of AOT compiled languages with low level capabilities.
When one wants to go everywhere, and discusses where to go next at each crossing, it is impossible to reach the momentum we are discussing here.
Rust is placing itself as the replacement of C and C++, not as a scripting language or something at a higher level, so it makes sense to see it from the perspective of someone who would write their engine in C or C++.
And note that my comment wasn't dismissive of Rust, it was dismissive of the idea that projects like rg3d can cause gamedevs to turn towards rust. The reasoning is really at the second to last paragraph of my comment ("developers have either already decided what language to use (be it rust or something else) or are not in a position to decide what language to use").
Anyone who has enough knowledge to build a game engine like rg3d also has enough knowledge to be able to judge if Rust is capable of building an engine like rg3d even if they haven't built an engine in Rust themselves.
If after reading abour Rust a programmer cannot figure out if Rust can be used to make a game engine then that programmer is incapable of making a game engine in the first place so in the grand scheme of things this chances nothing.
Rust build times are definitly slower than C++ ones, specially when compared against Windows compilers.
However I do conceed that some of it comes down to workflow and out of the box experience (no customizations).
In C++ the only code I compile from source is my own, all third party dependencies are available as binaries.
Then not only do I do incremental compilation, Visual C++ also does incremental linking, and I do take the effort of using external templates for common types.
And modules are just aroud the corner.
C++ Builder also is quite fast, due to its Delphi like extensions, it offers a fast compilation mode for debugging workflows.
So while the compilation time for my Gtk-rs toy app has improved quite a lot during the last 3 years, the Gtkmm version of it still builds in a fraction of the time.
I think this comment is slightly disingenuous, I think it's more obvious that the aesthetics of any game (let alone engine) will primarily depend on the quality of the Assets. If you loaded up these quake 3-era meshes and textures into Unreal Engine 4 or something else you'd call 'modern', I guarantee you they'd look the same or similar.
The lighting isn't even that bad sans indirect illumination, which unreal only just got recently and Unity is losing due to Enlighten being shut down.
This reminds me of people comparing open source software with proprietary software on account of aesthetics - it's not the licensing model, or the game engine, it's the presence or absence of artists that makes the difference.
It seems like you're criticising the examples for being less than elaborate and mistaking that for a shortcoming of the engine. It's not some "easy game studio 2020"-type thing that should spit out pretty games with 10 lines of custom code, it's a basic engine that can be built upon.
I question how much of "modern" graphics (IE things you can get a PHD for) is a manifestation of the engine, and how much is a result of the underlying libraries being used, and the fancy shaders being written. I don't think it's unreasonable to believe an engine like this could catch up.
To be honest I'm not trying to implement "bleeding edge" renderer, it would just take enormous amount of time which can be put into other more important parts (there are plenty of them).
It's a single person project. I haven't seen a more advanced rust engine. Adding better rendering isn't too bad once you have some engine architecture.
You’re the one comparing it to Unity, Unreal and Godot. Everyone else is talking about game engines on Rust and how cool it is that this person built it.
You need to look at this as result/time. Godot has been around for six years, the others for much longer. This has been around for a year and again, it's a one person project. What do you expect?
Well, I'm talking from the point of view of a user. Why would I choose this engine over Godot, Unity, Unreal? Just because it's a single-person project?
Who asked you to choose this engine over Godot, Unity or Unreal? And why would others make a choice for you? Such a choice would only be up to you based on your own requirements, nobody else can make that choice.
Also this post is really about showing off an engine made in Rust, a "hack" so to speak. You are in Hacker News where people post (usually technical) things that others might find interesting - but not necessarily useful. Consider we get posts about people writing software for retro computers, just for the fun of it.
That example code is quite readable though. Are there any languages that make math more readable? Even purpose build code like matlab is about the same.
well matlab can probably abstract much of the math away. You still have to know what high level functions to use but I think I was looking for a demonstration of the use of the libraries, e.g. how is collision detection done? How do I draw primitives. How do i move the lighting, etc?
The code is quite clean and it also provide scene editor with dedicated UI widgets.
https://github.com/mrDIMAS/rusty-editor/
https://github.com/mrDIMAS/rg3d-ui
Truly impressive.