Hacker News new | past | comments | ask | show | jobs | submit login
Bevy 0.4: data oriented game engine built in Rust (bevyengine.org)
113 points by _cart on Dec 19, 2020 | hide | past | favorite | 23 comments




I've tried to make games in my spare time before. Working in Bevy is the first time I've made actual progress on my projects.

There's something about the way the ECS framework is designed that just works. In particular the way the "systems" part of the ECS is automagically generated from regular old rust functions is just brilliant to me.

Aside from the ECS stuff, the WASM support is something else I'm pretty happy with (shout out to mrk-its for their help here). I can compile my game for native when I'm working on it locally, then when I want to show it off I can just `aws s3 cp` it up to a bucket and have people try it out in their browsers. The performance is still great there.


Same. I've been using Bevy to experiment with some accessible game mechanics for the past few months now. The speed from which I can go from "I really want map exploration to report this and that detail on an entity, based on this and that characteristic," to code that just works and does what I want, is astounding. The degree to which I can then optimize that code, to only run it when this or that component changes value for instance, is also amazing. And when some Bevy subsystem or other isn't up to my standards, I can plug in some other library, add a few components in my game, and more or less forget about the details of the lower-level integration. It's an amazingly productive engine. If it'd launched a year earlier, I'd probably have built my just released game in Bevy rather than Godot.


The way that you can turn normal Rust functions into systems, grabbing the relevant components through their type signature is wonderful sugar, and feels magic to use.


That's the level of Rust I wish there were more learning materials about.


I tried to make sense of the tutorial with various degrees of success :) Does this mean the components get automatically iterated over in no particular order (for instance the Persons in the example)?


That's correct.


Have you ever used an ECS system? This isn’t unique.


I don't know if it's unique, but it is the first ECS I've used where the level of sugar matches my mental model of what's going on behind the scenes.

I've primarily used specs & Unity's ECS before this.


The ergonomics are certainly top notch. The only other ECS I've used is the in-progress Unity one, and boy is that _painful_ by comparison.


Leveraging the type system with a good focus on generics as a means to achieve an ergonomic API may not be unique but well executed.


Lead Bevy developer/project lead here. Let me know if you have any questions!


Wow! Another very impressive release so soon!

I know that Bevy has no builtin physics solution at the moment and read the issue [1]. My understanding is that the plugins for Rapier are the main way to go for now. How "useful" is that situation currently and what are the general long term plans in that area beyond the current experimentation?

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


Thanks!

The official Bevy Rapier plugin (built by the Rapier team) is definitely your best bet right now. People have been using it with success: https://twitter.com/swainrob/status/1317573306271305733, https://github.com/indiv0/colonize/

The PhysX rust crate also works with Bevy if you want a more "time tested" physics implementation: https://twitter.com/swainrob/status/1317574431666032646. But it doesn't have direct integration like the bevy_rapier plugin.

Eventually we might implement a built in "high level" physics api, but I'd rather let the 3rd party Bevy physics ecosystem develop for a bit so we know what works and what doesn't. Theres so many other things to do right now that I don't feel much pressure to build the perfect official physics api when other people are already working on great 3rd party solutions for us :)


What do you think of Unity's ECS approach, and how are you approaching it differently with Bevy?


First: I won't pretend to be a Unity DOTS expert, but I have worked with it briefly. There are many similarities:

1. The general data model: entities, components, systems

2. Running systems in parallel

3. Archetypal ECS: a specific ECS storage strategy that groups entities of the same "data layout" together to increase cache friendliness during iteration.

Bevy has a lot of query/filtering/change detection features that I haven't seen implemented the same way elsewhere. But I can't comment on whether or not Unity DOTS has those features because I don't have enough experience with it.

I think we differ the most in UX. Wild (hard to verify) claim: I think Bevy has the most ergonomic ECS in existence. If you compare a Unity example (https://github.com/Unity-Technologies/EntityComponentSystemS...) to a Bevy example (https://github.com/bevyengine/bevy/blob/master/examples/2d/s...), I think its clear which one is easier to read/write (especially when you factor in the fact that the Bevy example is fully self contained). But its also worth pointing out that Unity is still one of the _more_ ergonomic ECS-es out there. Its still pretty good.


From the getting started tutorial,[1] I notice that (certain) functions appear to have the method "system" added to them. For example:

> Note the hello_world.system() function call. This is a "trait extension method" that converts the hello_world function into the System type. ...

Later follows an example where a function previously defined as add_people appears to have a method called "system", allowing expressions like this:

    add_people.system()
I don't see any macros on the function definitions, so where does this come from. Also, what's the purpose of adding the system method to functions?

[1] https://bevyengine.org/learn/book/getting-started/ecs/


The .system() method converts the function pointer to an actual System trait implementation.

This is accomplished by implementing traits for functions that match a specific signature. Ex: Fn(SystemParam), Fn(SystemParam, SystemParam), etc.

The .system() method uses the SystemParam type information to determine what resources are being accessed, which gets converted to logic that can pass the resource data in. It also uses the extracted type information to inform the system executor how to safely run each system in parallel.


the system() method is part of the IntoSystem trait that converts the function into a System object:

https://github.com/bevyengine/bevy/blob/master/crates/bevy_e...

There are macros below that implement that for Func types.


You can define a trait and add an blanket implementation of that trait for `Fn()`

Somewhat like this: https://play.rust-lang.org/?version=stable&mode=debug&editio...

Edit: updated playground link


Just out of curiosity, how this compares to Amethyst?



A question I was going to ask as well.

I love both Erlend's take and your response. You both had the opportunity to be small-minded and snippish about this, and you both took the high road and approached things from a collaborative and supportive point of view. Thank you for the demonstration of what open source is supposed to be about, and I'm not talking about the (spiritual?) fork here.




Join us for AI Startup School this June 16-17 in San Francisco!

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

Search: