Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Bevy: A game engine built in Rust (github.com/bevyengine)
173 points by yagizdegirmenci on Feb 14, 2021 | hide | past | favorite | 117 comments


There are other attempts to build a game engine in Rust. In my opinion, what sets Bevy apart is the pace at which they’re developing. Look at the release notes for Bevy 0.4 (https://bevyengine.org/news/bevy-0-4/), released 6 weeks after Bevy 0.3 (https://bevyengine.org/news/bevy-0-3/). They have momentum, plenty of contributors (50+), improving the ergonomics of existing APIs, improving the performance of pieces already performing well.

If I was making a game today, I’d probably pick Unity. A year from now? I’d take a good look at where Bevy is then. Good luck to cart and the other contributors.


Bevy has a full time developer working on it and has benefited from a whole lot of lessons learned from past attempts at building an engine in Rust.


I really like Bevy but I think that's a bit optimistic and based on the size of the studio.

Godot is in a much better spot at being the next Unity and it took a long time. It's still not there because of assets availability: you can find assets for anything for cheap on Unity.

For an indie developer with little budget and time to build complex features, it's a life saver.

For a mid-size studio (Embark?), happy to build their own technology, Bevy could be a great starting point, but the feature set is still not there.

As a solo developer trying to build a game, I tried going Bevy / Godot / tons of others and ended up back to Unity: I don't like it and it's a complete disorganised and buggy mess but it gets stuff done incredibly quick.

I didn't pick Unreal Engine because of the 5% cut over 3k. It's a marginally nicer environment to work in but I don't think it's worth the price tag over Unity (free under 100k revenue).


Fwiw, this: "I didn't pick Unreal Engine because of the 5% cut over 3k"

Is out of date by almost a year now, Unreal is now royalty free until 1 million dollars of revenue, at which point they take a 5% cut

They even backdated the change to start of the year so that developers who were charged under the 3k arrangement got refunds


From all the game engines I've seen in the last years, Bevy looks the most promising.

The API looks very clean and the development speed is outstanding for an open-source product.

After reading that Rust now plays in the C/C++ league I'm really excited about Bevy.


Rust while nice still has to catch up with 30 years ecosystem of tooling.

Many game studios won't bother using it if it doesn't come on the console vendors devkit, just like it happened with C, C++, or middleware like Unreal and Unity.


True.

But it also doesn't have to put up with 30 years of legacy cruft.


Don't you want Rust to still be around 30 years from now?


Sure, but with the cruft of the next 30 years, and not the cruft of the last 30 years


Thing is, where some see cruft, others see infrastructure ready to use today.


What does it mean that "Rust now plays in the C/C++ league"? Is this referring to the Rust Foundation announcement or some other recent news?


I believe they're talking about Rust's performance vs C/C++, but I could be wrong


Is that only a recent phenomenon, though? Hasn't it always been competitive?


What they likely mean is that C++ gamedev libraries have been heavily optimized over the course of many years, so while there is no theoretical limitation on Rust's equivalents, polishing them to the same degree is nontrivial and takes time. Bevy is the closest and that is a recent development (last couple of months).


Yes, sorry.

I was talking about performance.


I certainly have nothing against this, but even at the pace they are going it will take a long time before this is anything but just another unnecessary "rewrite it in Rust" project to me. I think Godot engine is a lot more promising for general purpose use.


A visual product like this really needs some screenshots in its readme.


As well as a gallery of examples created with the Bevy game engine ;)

https://github.com/bevyengine/awesome-bevy#games


Half of the example repos don't even have screenshots in their own readmes. It's so frustrating when I come across stuff like this - screenshots are such an important hook to really reel me in.


Agreed. It’s a common pitfall of open source projects. Sometimes I just want to see what I can do with the thing, not the details of how I can do it.


Hey we're back on HN. I'm Bevy's creator / lead developer. Feel free to ask me anything!


I just recently started learning bracket-lib (fka rltk), and it's tutorials recommend Legion ECS, but I'm finding the macros and magic of Legion to be less ergonomic than what I've seen from bevy. Is it possible/advisable to use Bevy as a standalone ECS, that doesn't require owning the "main loop"?


Yeah Bevy ECS is built as a standalone ECS. Using it that way is perfectly advisable:

https://crates.io/crates/bevy_ecs


Awesome, thanks for confirming! I came across that package, it wasn't clear from the docs if it was intended to be imported on its own -- i'll give it a go!


Any current or planned VR features? Cheers


Nothing usable yet, but people are currently experimenting with integrating VR apis into our core graphics library (wgpu)


Gamelisp is also a super cool rust game development project. You expose gamelisp runtimes in different parts of your program, then compile and run it with gamelisp programs going into the various runtimes. Now you can iterate on your gamelisp parts without recompiling.

The documentation is very good(!) and the approach is very interesting imo, iteration times disappear but you can keep all your performance (by moving the logic into rust as you settle on a design).


Can anyone speak to their experience using Bevy on the web with WASM (related [1])? Are there other non-JavaScript game engines you’d recommend?

[1] https://github.com/bevyengine/bevy/issues/88


Bevy currently works on the web with a separate WebGL 2 based renderer. WebGPU is the long term target so that the wgpu based renderer will work cross platform. I’m not sure of the status of single-threaded WebGPU rendering but Bevy will not fully support web likely until this issue [1] is addressed. It is unfortunately not a high priority for the Chrome/Firefox teams so will take some time. You need to be able to render WebGPU to a canvas from a worker before you can achieve multi-threading.

[1] https://bugs.chromium.org/p/chromium/issues/detail?id=116971...


Also note webgl 2.0 is not enabled by default on safari (includes any iOS browser). There is an option to enable buried in the settings, but it’s not recommended to leave it on.

So it’s not really an option if you’re targeting ios.


Rust seems like an odd choice for game development: Given adequate runtime performance and expressiveness, perhaps the most valued quality in a language used for the purpose is minimal turnaround time in the edit-build-test cycle.

Here, Rust is, AFAIK, far behind other languages. C lacks expressiveness, but C++ and C# seem popular for the purpose, and their build time is good. Incremental compilation is sometimes available, potentially avoiding a slow, non-parallelizable link step.

Rust is promoted for security, but I have not heard of that as a criterion for game work, and it seems like the first criterion to be jettisoned vs. any other.

What makes Rust's slow build times tolerable for this use? Has it had more progress in incremental building than I know about?


Bevy has very fast iteration cycles and it has been a core "required" feature since the beginning. With our "fast compiles" config, compiling iterative changes to most of the examples takes less than a second. Changes to the "3d_scene" example compile in ~0.5 seconds on my machine.

Check out our most recent efforts in our last blog post, where we added easy dynamic linking for a massive compile speed boost: https://bevyengine.org/news/bevy-0-4/

I also discuss the perception that "Rust is slow to compile " in the original Bevy announcement post: https://bevyengine.org/news/introducing-bevy/

In short: fast compile times in Rust are possible. As long as your core libraries do the "right things" when it comes to design, writing user code can be extremely productive. The compiler has also gotten a lot faster over the last couple of years.


Security is relevant on server code and copy protection mechanisms, however modern game development is composed by multiple skillets, that join efforts across middleware like Unreal.

So I am with you that Rust has a very uphill battle for adoption in any game console devkit.


why does it feel like i'm seeing more rust game engines than actual games? (outside of toy 2048 clones)


To make an engine it's ok just to gather a bunch of programmers.

To make a game (even a tiny one) you need artists, sound designer, designers and so on and that's what makes it significantly harder


The Forth community takes this one step further: it's more common to see someone discussing their implementation of the Forth language, than to see someone discussing what they developed in Forth.


I'd bet that most new Forth implementations are done for CPU:s that already have vastly more powerful languages available. So if someone want to get stuff done they would probably rather use a more productive language for that. But if they want to tinker around I'd imagine a Forth implementation would be a pretty fun learning experience. I'm myself implementing a Lisp (MAL) just because it's fun. I'm not really planning on using the implementation for anything though.


Competent Forth developers consistently seem to consider Forth a far more productive language than C. Not something I can comment on personally though, I know C far better than I know Forth.


So they say. But every architecture known to man already has a Forth implementation. So why bother make another when you can get busy doing useful stuff? I would say it's just for the fun of programming a Forth.


Common lisp too


This is a pretty common joke about all game development, not just Rust.


If you re interested in Rust game dev, check out the rg3d engine https://github.com/mrDIMAS/rg3d. Join the rg3d discord channel https://discord.gg/xENF5Uh

Here’s a sample game made with it https://github.com/mrDIMAS/StationIapetus


I'm about to build a stack on top of Unreal, but I don't really need the "game" parts, just the "real time rendering" ones.

I consider building on Unreal to be an (acceptable) risk, but I'd prefer to build on something not owned by another company.

I'm really hoping some of these Rust projects start to focus on rendering, not just the game pieces.


Have you considered Godot engine? Godot is free software, so legally you have the right to do basically anything with it that Godot engine's owners do. It's years ahead of the engine in the OP in terms of features+polish, and seems likely to continue being developed for a long time. I'd definitely suggest using Godot unless you really need a specific feature of Unreal engine.


If GP is interested in real time rendering features, they may end up butting against the same wall I do every time I try to use godot for a quick 3d experiment: a lot of features you may want when it comes to rendering have been combined with the swap to vulkan, coming in Godot 4.0, which has been a long time coming, with an alpha this year hopefully, but one of the devs has already joked that it will be delayed until next year.



How much of rendering you need? Are you providing the shaders yourself?

If you only need multi-platform rendering (including Emscripten, and a shader abstraction), have you looked into BGFX, or even Sokol GFX? They provide the bits you need to render. Unity is even using BGFX in its "Tiny" version. Sokol GFX is new but very easy to use.

I believe both have Rust bindings if this is important to you.


I'm not sure using Unreal is a risk. It's used commercially by a lot of companies for much more than gaming. It's also open source. Obviously not written in Rust though, if that's important.



Have you considered Godot? You can use wrappers.


Build fails with 6 month old rust.


It's not surprising that a project that's really early in development chooses to keep up with the latest rust as a min. reqirement.

Once it gets to a 1.0, that adoption of new features may slow down.


And?


Wasn't this a big deal when Rust hit version 1.0 [1]? There's a lot of reasons for not being able to use a bleeding edge compiler version.

[1] https://blog.rust-lang.org/2014/10/30/Stability.html


> Wasn't this a big deal when Rust hit version 1.0 [1]?

No. The big deal of Rust 1.0 is that a 6 months old Bevy can compile on the latest version of the compiler. Since new features regularly get added, codebases which use the new features will naturally not work with compiler version predating those features.

It is a concern (as seen with the recent cryptography hubhub), but it's a project-specific concern: projects have to decide on their compiler compatibility range.

Though you could say that it's an ecosystem problem, outside of specific projects I don't think there any sort of badge or way to assert compatibility with specific compiler versions. Since distros are starting to ship rustc (and are unlikely to track the standard mainline), I expect awareness of this issue will grow over time.


They promised improvements in keeping backwards compatibility, i.e. building old code on new rust. No one promised forward compatibility, building new code on old rust.


Yeah ok, makes sense of course. It's still a somewhat strange decision on the project's part. It's basically similar to using C++20 features only six months after the first C++ compilers support C++20. If that's a one-time thing during development of the framework it's probably fine. But if in 5 years the project still reqiures a less than 6-months old compiler version, I'd be worried ;)


Why? The advantage of having a single Rust compiler is that there is almost never any reason to use an old one. There are some cases where I can see that using a pinned compiler version would be important: if you are doing mission-critical embedded or financial programming and need a verified compiler. But none of those apply to game development.


I see having a single compiler instead of multiple competing compilers more as a bug than a feature, at least in the long run. It's fine as long as the language is in "exploration phase", but hopefully we'll see more independent Rust compilers in the future (e.g. https://github.com/Rust-GCC/gccrs)


Whether it’s a bug or a feature is immaterial to the present discussion of what you should do when there’s one implementation. The reasonable thing to do is to upgrade the compiler when a new one comes out. Each upgrade is generally pain free because the team goes to great lengths to ensure backwards compatibility. They compile every single open source code base with the latest release before putting it out.

In that context, I don’t see the issue with Rust codebases depending on the latest compiler. I understand that it’s done differently with C/C++ and that’s fine. I don’t see why both models can’t work.


One significant reason to use an old compiler is if you want to avoid having multiple package managers on your system (i.e. rustup _and_ apt).

The normal philosophy on typical Linux systems is in fact _not_ to require bleeding-edge compiler versions; there’s no “gccup” program. It’s the rust project that is proposing a new and different model.


IMO you shouldn't really ever be using system provided versions of compilers or programming languages. Linux distros are significantly constrained in terms of which language versions they package because they need to use those versions to package packages which rely on those languages. That, along with the fact that most distros only release every 6 months to 2 years means that you generally have quite out of date versions.

It seems that rustup itself is not currently packaged by debian or other linux distros which seems to be a bigger issue. If you could `apt install rustup && rustup install stable` then that seems preferably in pretty much every way to `apt install rust` and getting an old version.


Src based distros tend to be a little better with this.


I would add that having multiple package managers on the same system can be a hazard.

For example, NEVER install a Python package globally with pip on a Debian System, it WILL conflict with Debian packages (and you'll be very unhappy and confused on the next apt remove or pip uninstall).


Rust/Cargo definitely learned what not to do from pip...


You don't need to have it installed in /usr. It can be (and is by default) completely contained within your home folder.

Anyone not doing it this way is just making life needlessly hard for himself and his problems should be ignored entirely.


For devs, there's no reason to have to use an old version of Rust, especially given Rust's strong backwards compatibility guarantees. It's not like Rust takes advantage of dynamic linking by having all libraries being compiled with the same compiler.


Except when using compiler based distributions, then again this is about game development and 1% userbase is irrelevant.


Most C/C++ projects do compile if you use a 6 month old compiler.


Part of the reason Rust is still fun is that it hasn’t hit the point yet where everything has to worry about backwards compatibility. Let’s keep it that way as long as possible.


This kind of comment is worrying, I would never choose a library / framework if I had to upgrade the runtime every 3 month.


You don’t have to. If you want to depend on other people’s code, they may use new features, which may require a newer compiler. But you are in full control there; you are not forced to upgrade.

(Note also it is the compiler, not a runtime. Big difference when it comes to things like deployments, IMHO.)


Rust doesn't have a runtime so you're good


Rust does have a runtime, but it's statically linked.

https://doc.rust-lang.org/reference/runtime.html


"runtime" is a term that has conflicting colloquial and precise definitions.

In a precise sense, any non-assembly language, including C, has a runtime. In practice, this makes the term "runtime" not super useful to many folks, so they mean "virtual machine" or "large, featureful runtime that's required to support critical language features" when they say "runtime."

Rust is the same as C in this regard. It technically has a runtime, but not in the way that many people mean.


So what?


If you think the whole world of IT works on bleeding edge tech, you're mistaken.

Most distributions have an LTS that is supported for 5 to 10 years. You won't get the newest, hottest compiler on those platforms.

> So what?

Rust is a great language, but y'all need to calm down with the hype. "Not Rust" != evil.


For as long as Rust has existed, no-one who is writing rust actually wants to use a compiler version that's any older than the newest. The language keeps adding good stuff in every version. I thought it would calm down a bit after NLL, but now everyone is salivating for const generics, which will land in 1.41... and in a whole lot of versions after that, as they split up the feature into smaller, easier to implement and study chunks. The language simply hasn't reached the level of maturity of C++ where people yawn at the new features that are going to be added.

> Most distributions have an LTS that is supported for 5 to 10 years. You won't get the newest, hottest compiler on those platforms.

Yes, you do, because you won't be using the distribution-supplied compiler because like the entire rest of the rust developer community you are using rustup.


There is a huge community wide discussion about this. Characterizing it as “no-one” completely ignores that some of the most prolific and vocal community members have advocated for expressly supporting older Rusts.

One of the core issues here, imo, is that it is unclear which Rust is the oldest one to be supported. That requires a clarity in understanding the pros and cons of each one, and simply due to there being more releases of rustc, it’s a little less clear which version gets you the most bang for your buck here.

I agree that some of this is a function of the new-ness of the language. I think once (if) we start an LTS program, that will help, and is partially why I desire such a thing. https://rust-lang.github.io/rfcs/2495-min-rust-version.html is an example of a feature we’re adding to help people do this kind of thing. It’s small but it’s a start.


What if you're in a constrained environment, there is no rustup installed, and you don't have the permissions to install it?

This issue certainly occurred with a lot of C/C++ projects over the past 30 years, why would Rust be exempt of that issue in the future?


If someone is working in an insane environment then that is his problem and also highly unlikely to be using Rust anyway. Why should library developers care about keeping compatibility with old Rust compiler versions for some arbitrary amount of time?


That's easy to answer. Because users want that. Of course developers are free to ignore such users, and such users will choose a different library.


rustup is installed within the user's home directory. If you can't write to your own home, then what can you do on this device that involves compiling code?


> rustup is installed within the user's home directory. If you can't write to your own home, then what can you do on this device that involves compiling code?

there are plenty of companies when you don't have the right to import any new executable code (coming from "outside") in office computers.


Small example in one of my previous job:

Application was built using Java/SpringBoot, and the CI/CD was based on Jenkins.

We had no control over the version of maven/jdk installed within the Jenkins, and the network policies did not authorize outgoing traffic (so no curling rustup). Only one company repository (based on Nexus) was available.

Basically, we were users of a company provided/constrained platform to build our applications using a curated list of tools that has been audited by another team.

If we wanted to add a dependency not present in the provided repository, it would require time for the audit and integration. Time we did not necessarily had.

Now, with Rust/rustup/Cargo, the company would have provided a specific set of Rust versions and a private crate repository. I doubt that the auditing team would have time to add a new Rust version every week.

If a crate present on the private repository is updated upstream and requires a more recent Rust version, the crate update will be delayed until the Rust version is audited/validated/integrated.

IMHO, this is a very common use case, since companies like to split concerns in different specialized teams.


Easy, using system compilers and home mounted as noexec, quite common in corporate UNIX deployments with IT managed development servers that the devs connect from their workstations.


> If you think the whole world of IT works on bleeding edge tech, you're mistaken.

Unfortunately HN attracts the very vocal minority...


Anyone developing games with this project is likely to be on Windows, Linux or Mac, on x64 or aarch64. Such developers would likely install Rust with rustup, not with the distro provided one. So yes, any developer that fits this description can rely on the newest, hottest compiler.


And that's perfectly fine. But game developers are a small fractions of Rust developers.


Right, but it's this specific project that requires the latest Rust compiler, not Rust libraries in general.


I think most devs use rustup, not the distro supplied one.


Is rustc even in the repos? Should it (and cargo) be? Or should they just have rustup? I lean towards the latter


Some distros ship programs compiled with rust, and they do so using the version of rustc in the repo.


rustc is in pretty much every distro's repos at this point. They often have Cargo too. They sometimes, but not always, have rustup.


Why would you use 6 month old rust?


Some OS-arch combinations might not have the latest one available. This is an issue for OSes that aren’t Windows, Mac or Linux and architectures that aren’t x64 or aarch64.


Any developer relying on OS provided rust installation is just making life needlessly complicated for himself.


I agree, but if a developer is developing on a tier 2 or tier 3 platform, they can’t necessarily rely on rustup either.


but how many of these folks are compiling bevy on these tier 2 platforms?


I agree it should be avoided if possible, but sometimes it can't be avoided.


Distribution does integration. It's better to use a bit older version, but properly integrated with other parts of the system.


That is completely pointless for a rust compiler. What are they going to integrate.


GDB, llvm, gcc, IDE, devel packages, etc. My distribution (Fedora) contains latest or prior version of rust, cargo, RLS, and clippy, which are updated as usual.


It's competitor, Amethyst, fails to build on Linux with current Rust.

I think it's something to do with outdated dependencies of winit running into namespacing issues with macros that were added to the standard library


I was under the impression that Amethyst was not a competitor.

There was a post stating Amethyst was basically in need of a re-architecture that could never be resourced and because Bevy was already based on that “new” architecture it was easier to switch all development effort over.

But maybe this thread is out of date.

https://community.amethyst.rs/t/bevy-engine-addressing-the-e...


Certainly that rewrite was huge, and it is currently "mostly complete", but Bevy launching when it did helped stifle a lot of the momentum. However, it was picked back up again in November and is now mostly complete: https://github.com/amethyst/amethyst/issues/2517

From outside at this point, the rewrite looks like a mistake , given the lost momentum and the current state of the project, but maybe when they finally get it out it'll turn out differently in 6 months.


This may come off as snarky, but as long as I've been following Rust and Amethyst the latter seems to always be in some kind of "not quite there yet but it will be after the next rewrite/rearchitecture". Same goes for Conrod, its GUI library.

It seemed like an inevitability that some other library would come along that would move forward a bit quicker.


Does anybody know if bevy supports networking or multiplayer?


There are a couple networking plugins in the works. They are focused on providing cross-platform UDP networking. But it’s still mostly roll your own.


Can't wait to use `player!.0.<>->move^([]->^t, Box<&loc, g*>)` to move player characters!


We've heavily invested in legibility and ergonomics in Bevy. I'd argue that our ECS is top tier in ergonomics and legibility across all engines / languages. Here is a gist of a fully self-contained Bevy App for player movement. Feel free to compare that to _any_ other engine / framework:

https://gist.github.com/cart/96b1d39cd04274da566dbf28bf87c2a...


Bevy's syntax does look tame, it was more of a jab at Rust syntax.

I swear, people behind Rust would replace every single textual keyword with a symbol if they could.


I'm a Rust newbie, could you explain how a function got a method "system"? Is there some macro at work here?


Functions are "types" just like everything else in rust. And you can implement traits (which can add methods) on any type. So its just "normal" rust code to add a function call to a function of a certain type.

This enables us to (statically) extract information from the type signature of the function and use it to populate the relevant values using the ECS. We also use this type information to automatically (and safely) parallelize system execution based on what ECS resources are accessed (and if they are mutated).

We do (internally) use macros to implement our IntoSystem trait for all relevant function types, but there are no macros in user-facing code.


I see, that's interesting and it seems powerful.

But I would never use such a feature, it increases the code mental load (what you should know before being able to read the code).

From one codebase to another, I can't even keep the same assumptions.


Yeah implementing traits for functions is rarely advisable. However in this one very specific case (what amounts to dependency injection) it gives us very nice clarity and ergonomics. I'll take that over the macros everyone else is using in this context, or the expensive "runtime reflection" other languages might use to do the same thing. At least its still "normal" static rust code.


One can do that with extension traits, which offer some kind of extension functions. I guess here a Bevy trait is implemented on `fn (commands: Commands)`




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: