Replies: 15 comments 92 replies
-
I'm so happy that we're seeing a sort of a pre-RFC for an editor! 😁
Does that mean that Bevy
If we don't have an example where live editing would be impractical or bad, “is not” should be changed to “may not”. In the other case we should state the example as a why response.
What is the lifecycle of the asset pipeline? When does the asset baking happen: when importing the asset into the project, or when the application is deployed?
Ok, it looks like baking happens later. But I still think it should be mentioned earlier.
Link not working (even the one at the ToC) Editor-Game runtime interactionI'm quite concerned about using flaky hot-reloading for interaction between the Editor and the Game. I've just had an idea that is different from the others I thought about in previous times, and I would like to know how it could be received by the community, because I have no idea of what downsides this approach would have. Basically, the Game and the Editor are two independent processes by nature. However, they can communicate (by exchanging their own data types through reflection and serialization) using a server/client protocol. The Game is the server. It can achieve this role by having the The Editor is the client. It can get Game data mainly in two ways.
The Editor can send data to the Game to introduce a change (e.g. loading a particular state, useful for example to directly load an advanced level instead of hacking the game code or playing through the whole game to get to that point). I think that this protocol can naturally be implemented using HTTP or WebSockets. You can even run the game and the editor in two different machines: sounds silly at first, but then I realized that game consoles exist. Other notes
|
Beta Was this translation helpful? Give feedback.
-
Thanks for your contribution and taking the time to read my doc @Nilirad :)
I don't know what you mean by "Scene asset".
For example Unity allows you to move/rotate/scale all
Baking refers to the build pipeline action of transforming editing assets into runtime assets. Very often, the Editor is incapable of using runtime assets as is, either because the data format is compressed (textures, animations, etc.) and it makes it prohibitively expensive to edit compressed data (think about editing text files inside a ZIP without decompressing it), or there's simply no way to load that runtime format (think about some platform-specific texture formats which have no library to be read on the host machine where the Editor runs, which may be a different architecture than the target platform). The baking step is traditionally done when the Author press a "Build" button, which bakes assets, compiles code, and packages everything into a shippable Game. As a UX optimization to reduce iteration time, the build pipeline can run continuously in the background and re-bake an editing asset each time it's changed, but it's optional (Unity and UE4/5 do that for lightmaps and other lighting-related data, although this can be disabled). Asset importing is a different step, unrelated to the build pipeline. Asset importing runs when a new asset is added to the list of assets the Editor currently edits (I'm carefully avoiding talking about a "project" here to avoid that discussion). When an asset is imported, it's converted from a data format the Editor cannot readily edit (for example,
I think there is a confusion between:
Hot-reloading is only related to 2. as I see it, while what you describe is a very sound solution for 1. and is also what I was thinking about (see Embedded rendering for example).
Networking. This is what you mention as HTTP or WebSocket, I just use a more generic term to avoid fixing on an actual solution here. I think the Editor should be designed to separate the serialization (convert objects to byte streams) from the transport (send and receive byte streams). The Transport is only used to communicate with another process, possibly remote, and so is only used for Live Edit and for multi-user editing.
I avoided the subject on purpose for now. This is a slightly higher level concept, that needs discussion too but is implemented on top of the core I describe here and want to nail down the design of first. There are alternative solutions, like the "document editing" model where the Editor is just a collection of document editors, and the "project" is just another type of document like an animation or a mesh are, and you can edit any asset without having to explicitly open a "project". But this is a different level of discussion that should have no influence on the design of the Editor foundation. |
Beta Was this translation helpful? Give feedback.
-
All links work in VSCode; none of them work here. It seems GitHub doesn't support section links in Markdown, or I did something wrong? |
Beta Was this translation helpful? Give feedback.
-
Thinking about how the ideas contained in this document could be furtherly developed and broken into a bunch of tightly scoped RFCs:
|
Beta Was this translation helpful? Give feedback.
-
Disclamer: While I am following the development of Bevy, I am a beginner at Rust and I have not gotten a chance to try Bevy yet
&
I like the idea of building the editor with Bevy UI for the reasons you mention yourself, and have thought about it before too, at the same time, I am not convinced that is the approach that can lead to the best outcome. I am currently building a mobile app with Unity and, for the first time ever, I used ReactNative to build the UI and embedded the unity player into it. This approach definitely has problems, however, I was able to achieve high quality UI in a short time frame, something that I could only wish for using native Unity UI, even the new UI builder package. Now, as I say in the disclaimer, I do not actually know how good Bevy UI is but it is hard to believe the community has enough capacity to develop a UI library1, as well as a game engine and an editor for it. Has it ever been considered to drop Bevy UI in favor of user-provided industry-standard solutions like Flutter or "demoting" Bevy UI to a built-in placeholder library for people that are not comfortable with industry-scale solutions yet? On top of reducing the stress on the Bevy community, embracing an industry-standard solution(e.g Flutter) has other benefits:
Footnotes
|
Beta Was this translation helpful? Give feedback.
-
Another Rust newbie here. Would it be possible to embed a bevy instance into a GUI library like iced. I have dabbed my toes into it and just by GitHub stars it seems to be one of the more popular Rust GUI libraries. Skimming through it's & Bevy's repository, it seems like both are using winit and wgpu at it's core. So I assume an overlap could be possible somewhere? |
Beta Was this translation helpful? Give feedback.
-
I feel like this discussion is missing the most important thing the editor needs to do. That is, simply instantiating entities with a specified set of components (in a given, or default, scene), in a specific location. I also want to reinforce non-goal #1, being a text editor. From my experience with Unity and Godot, the game engine itself is not a very good place to do most of the work. Programming is better done in a program specified for that. Art is better done in a program specified for that. What the game editor really excels at is the assembling of all of the different parts, code/meshes/textures/sound/etc. One idea that I would like to see in the Bevy engine would be a similar idea to Godot's exports: https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/gdscript_exports.html where you can write in code a variable that can be overwritten by the editor, and how it appears to the editor. For example: # Allow integer values from 0 to 20.
export(int, 20) var i
# Allow integer values from -10 to 20.
export(int, -10, 20) var j
# Allow floats from -10 to 20 and snap the value to multiples of 0.2.
export(float, -10, 20, 0.2) var k
# Allow values 'y = exp(x)' where 'y' varies between 100 and 1000
# while snapping to steps of 20. The editor will present a
# slider for easily editing the value.
export(float, EXP, 100, 1000, 20) var l I imagine we could do something similar in Rust (with a little more safety). For example: #[derive(EditorDisplay)]
struct MyComponent {
#[editor_display(DisplayType::Exponential, 100.0, 1000.0, 20.0)]
val: f32,
// .. stuff goes here
} |
Beta Was this translation helpful? Give feedback.
-
This is more meta, but has there been any discussion for having a "Bevy Hub" (yeah, I'm stealing it from Unity Hub) application for managing editor versions, extensions and providing anonymous analytics (crash reports, performance metrics, etc.)? I know it's not a priority right now, but it might be good to start thinking about what functionality the Editor might need to support a Hub in the future.
Would that mean that extensions would have to be approved and merged into the editor, and if people want to use their own extensions they would have to fork the editor? Couldn't more flexible solution could be done using DLLs with a standardized API that loads them at runtime? By using DLLs, a Hub could be used to add/remove functionality to the Editor by downloading DLLs from some sort of repository. |
Beta Was this translation helpful? Give feedback.
-
I would like to add something into the discussion, based on my previous experience with Unity, Godot and Unread Engine. All those engines have in common an Editor, but besides the name, they also injects the "bootstrap" of the game, so users doesn't needs to do it (in bevy it would be the It's important to understand that in those cases the Editor "generates" the game, so it acts like a compiler, optimizing assets, codes and some platform-specific code, and not like a ordinary editor where edit assets, code and so on. This is relevant to the discussion IMO because let's say I have an existing Bevy code and I would like to use it on the Editor, how editor will detect the entry-point, the "main" scene and so on? It may not be possible, unless some cleaver importing is done, since the entry-point generated by the editor may have lots of things to do. So what I wanna state here is usually a game engine editor isn't just an editor, but actually the building block of the game itself, with tons of toolings which will be disabled when exporting or generating the final build. |
Beta Was this translation helpful? Give feedback.
-
I found the issue #3877 related to this discussion somehow. It didn't ended in a PR, but I think it has some relevant ideas if anyone is interested in reading it (long discussion) |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
Editor CLIIt might be nice if the editor could expose a command line interface (CLI) for certain tasks. Assuming the editor is a workspace member called "editor", it could be recommended for users to create a Commands are functions with the signature Extensions can also add their own commands. For instance, a multiplayer server extension (think like the AWS GameLift plugin for Unity) could register a I also imagine that users would like to run many commands at once. For instance, to build all assets in a project. There are a few ways this can be implemented:
I believe 4 and 5 to be the best choices, and both could be implemented together. However, I feel 4 has a major limitation that could translate poorly to the GUI. Commands should be able to be used from both the CLI and GUI. On the GUI side, a command could be as simple as a context menu option or button, but could also have a drop-down for sub-commands or a window for setting parameters. In order for 4 to work, it would need a format that allows for passing sub-commands and parameters, like Focusing on option 5 for now, I think the best way to create commands would be like option 3c. The Another alternative is making commands part of App itself, allowing for extensions to just call As for how commands are used, when Anyways, this is just a few ideas on how it could look. It would require some work to integrate. |
Beta Was this translation helpful? Give feedback.
-
We don't need an "Editor"The previous post about the editor CLI (for some reason) made some things click in my head that I've not been able to propely think through for a while. If you've seen my "Bext" idea this is pretty much an iteration of it but I am going to take it even farther. A lot of you might disagree with what I propose here but my goal is not to convince you but to expand our view of alternative solutions and confirm that there is indeed nothing that is better than what other engines are doing. Warning: Below I describe the problem first and then propose a solution that is actually an editor but "backwards" so the title is kind of deceiving. Warning 2: My solution goes directly against one of the non-goals described originally. ProblemA standalone editor requires some limitations to be put in place which goes against the Bevy's modularity design goal "Use only what you need. Replace what you don't like". While built-in editor tools (e.g. a move tool or a "create new" tool) are helpful in many game development tasks they are framework or bootstrap specific (e.g. a move tool implies that there is also a transform component). On top of that, while helpful with some things, built-in tools are often not enough for gameplay-specific cases (e.g. a pedestrian system or a source-engine-like level designer) and at the same time manage to cause bloat and perceived lack of features. Solution: The In-Game Editor FrameworkThe solution I propose is to forget about a universal editor and help developers build their own, game-specific editors instead. Thanks to the ECS architecture it is very easy to add an in-game editor to Bevy games and simply exclude it from the production build (UX being similar to Dreams), however, that is a ton of boilerplate code. I suggest that we address that boilerplate and create a framework for and a library of in-game editor tools (e.g. a move tool, a level-block-out tool or a terrain tool) and leave it up to the developer to choose what editing functionality they want to give their non-developers as well as enable the devs to build their own editors in a conventional boilerplate-free way. This approach has the following advantages over an editor binary:
This approach also has disadvantages:
however, these disadvantages already exist, except they are less obvious:
ConclusionI believe that a standalone editor is not the most optimal solution because games often require case-sepcific editor tools and while the original "extensions" idea enables to solve that, having the editor built directly into the game is easier to implement, opens up new gameplay possibilities, and gives the developers an easier way to manage the non-developer workflow. On top of that, unlike the design described originally, the In-Game Editor Framework has quick prototype potential which indicates better simplicity and I think should be tried out and considered as an alternative. |
Beta Was this translation helpful? Give feedback.
-
Editor Vision CompromiseIt seems to me that there are two general visions of what the editor could be: a DIY framework library vs a traditional managed binary. Both have their strengths and weaknesses: DIY Framework LibraryPros
Cons
Traditional Managed BinaryPros
Cons
What I propose is a compromise between the two by first creating a general framework, then creating a code generation tool that depends on it. DIY FrameworkThis is @bjorn3's suggestion: the bevy editor is basically another Bevy app that is just another binary target (or workspace member). The editor is just: use bevy::prelude::*; // "editor" feature enabled that exports `EditorPlugins` (I used to call it `DefaultExtensions`, but I guess extensions refers more to the crates than the type)
fn main() {
App::new()
.add_plugins(EditorPlugins)
.run();
} Additional extensions can be added via their respective plugins. CodeGen ToolOnce the essentials of the DIY framework have been established, work can start on creating a codegen tool. I believe this can take the form as part of a "bevy" tool. It would be installed via It would have some commands like:
Essentially, this codegen tool abstracts the process of creating your own editor with the framework. The benefit of using it is that it makes using a single editor for many projects simple: just call [editor]
version = "0.9"
theme = "Dark" # just a thought, it could be used for managing many settings in the editor
font_size = "12" # they don't necessarily have to be used at build time, like extensions do
[extensions]
bevy_nothing = "0.3"
bevy_something = {
version = "0.2",
config = { # config can be used to pass parameters to extension install scripts
key = "Hello, World!"
}
} So, with "Bevy.toml", we have a way to specify extensions and configure them, but how does the "bevy" tool actually use them? Extension Install ScriptsAt first, I was thinking about having extensions specifying a public function or struct that impls a trait, but that seems messy. Rather, I'm now thinking that extension crates could have a binary dedicated for codegen that could be specified in "Cargo.toml" metadate, like so: [package.metadata.bevy]
script = "install" # here, install is the name of the binary target for the "bevy" tool to use The codegen would run the process and communicate via stdin/stdout/stderr (stdin for passing config, stdout for generated code, and stderr for any errors for failing). It would be good to provide helper functions to handle parsing/encoding input/output. A codegen program could look like: use bevy_editor::{Config, output};
fn main() {
let config = Config::new();
let key = config.get("key").unwrap(); //Assuming unwrap will print to stderr, maybe a special method is needed?
output!("
app.insert_plugin(SomethingPlugin({key}));
");
}
Little detour: output! {
app.insert_plugin(SomethingPlugin(#key));
} That seems nice. Anyways, the codegen tool will then take that output and put it into a file that can be {
app.insert_plugin(SomethingPlugin("my_key"));
} And then the editor source code: use bevy::prelude::*;
fn main() {
let mut app = App::new();
app.add_plugins(EditorPlugins);
include!("extensions");
app.run();
} So effectively becomes: use bevy::prelude::*;
fn main() {
let mut app = App::new();
app.add_plugins(EditorPlugins);
{
app.insert_plugin(SomethingPlugin("my_key"));
}
app.run();
} The anonymous scope allows for extensions to hygienically use variables (and not use a variable unintended for that extension). Editors with the same build settings (like extensions but ignores things like theme and whatnot) will then be cached together, so you can have two projects with the same editor but a different global editor. OverviewPros
Cons
I hope this is a good compromise between both sides. I feel the desire of a traditional editor comes out a good desire for convenience, that I believe this can provide. |
Beta Was this translation helpful? Give feedback.
-
Hybrid Editors + Project CodeGenThis expands upon my previous idea of a codegen tool from just editor management to general project management. I think @StarLederer might like this. I thought more upon the divided experience between "manual" (writing your own editor) and "automatic" (using the codegen tool) and came upon a hybrid solution. If the "bevy" tool can be used to manage generated automatic editors, then it's not too far-fetched to say it can be used to manage user-created manual editors. It would be useful if manual editors can be used for multiple projects, just like automatic editors could be using the tool. However, this means a departure from the previously described way of using "Bevy.toml" files, as there isn't much overlap between automatic and manual configs. Also, they have the major flaw of being redundant: using configuration settings to describe the same editor was a pretty silly idea. Instead, they are moved elsewhere, replaced with [editor]
profile = "node_workspace" Now, editors are identified by names, not hashes of their settings, and are stored in folders named after them inside .bevy
├── config.toml
└── editors
└── default
├── Bevy.toml
├── Cargo.toml
└── src
└── main.rs The tool comes with a default editor (replacing the idea of a global editor), specified in This means, that users can edit the source code of their editor here, allowing them to use it in a hybrid fashion: either including extensions manually with "Cargo.toml" or automatically with "Bevy.toml". However, writing this led me to an epiphany: it could be used with regular Bevy projects as well! Since extensions are just plugins, regular plugins could have installer scripts and then be included in your code with a macro. use bevy::prelude::*;
fn main() {
let mut app = App::new();
app.add_plugins(DefaultPlugins); // an editor can use `EditorPlugins`
include_plugins!(app); // adds code generated from "Bevy.toml"
app.add_plugin(bevy_custom::CustomPlugin); // something more complicated? add it manually!
app.run();
} This extends the benefit of generated code not just to editors, but all Bevy projects. The "Bevy.toml" file now looks like: [plugins] # now generic, not focused on just extensions
bevy_atmosphere = "0.5" # get a sky without writing any code! Also, with these changes, the commands available to the bevy tool also change:
The I'm starting to get excited for this, since it is starting to look less half-baked, and more like an actual solution! |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Bevy Editor
This document describes a Bevy Editor vision, in an attempt to drive and focus discussions, and collate ideas and already-discussed topics for future reference. This is not an official document, but a community-driven one.
Table of Content
Terminology
bevy
crate. This can be a game in the proper sense, or can be any multimedia / interactive application, including CAD, architecture, etc. In this document we use the term "game" as a shortcut for any such application.Plugin
trait of Bevy, even though in practice Extensions likely define one or more plugins that the Editor will make use of.Capabilities
Scene creation
Create and edit Scene objects, save them to storage, and load them back.
The Editor allows creating new scenes, editing them, saving them to file in an Editor-specific format, and re-loading them to continue working on them later.
Interactive editing
Allow interactive previews of editing actions.
The Editor favors interactive editing. Wherever possible, actions from the Author must be reflected in real-time (or as near as possible). In particular, the Editor provides a way to dynamically place entities in a 3D space and move them with the mouse cursor.
Live editing
Enable live game editing.
The Editor can connect to an instance of the Game (separate process), and supports some limited editing operations. The full range of Editor features is not available in this mode, due to the complexity it would incur.
This capability is likely complex to implement efficiently, and might be a stretch goal / not available in a first version.
Asset baking
Enable asset baking into platform-specific format(s) optimized for runtime.
The Editor integrates with an asset pipeline to allow transforming ("baking") the Game Assets into a format optimized for a target platform. This baking operation is a one-way process; baked assets cannot be un-baked back into their editing format.
The Distill crate from Amethyst appears to be a very serious candidate for this task, given its large number of available features covering most (all?) the Editor needs and more.
Non-goals
Text editor
Although the Editor must allow the Author to create new components beyond the built-in Bevy ones, and instantiate those components in a Scene, the Editor does not aim at being an all-purpose text editor. Powerful text editors exist and are commonly used, with a large number of features and customizations that would be impossible to replicate inside the Editor.
In-game editor
The Editor does not aim at being an in-game editor, a game-specific editor allowing the users of the game (the players) limited editing capabilities to build or edit game levels. Such an in-game editor can be built by the Author, but the Editor audience is exclusively game Authors, not players (the end users of the Game).
Architecture
Vision
This section describes the ideal Editor vision, and includes elements which might be forward looking and unrealistic for a first version given their complexity or the amount of work needed. They are described anyway for the sake of given an overall description of the goal.
Bevy is built as a minimal core and a collection of crates providing specific features (renderer, UI, etc.). From a design perspective, there is no real distinction between a built-in crate and a third-party one. This approach allows efficient collaboration, enabling all users to augment the engine with their own feature(s), optionally contributing them back to the community first as third-party crates, and eventually as built-in ones. The "third-party" vs. "built-in" distinction here is mainly a crate governance one, with a minimal (while Bevy is not stable) added "seal-of-approval" kind of assurance provided by the "built-in" status.
The Editor embraces this design by providing a Core around which features are built. Features are provided by Extensions, pieces of code communicating with the Core to exchange data. The main responsibility of the Core is to be a hub for this data flow, providing a centralized source of truth for all Extensions. This design is very similar to The Truth from the "Our Machinery" game engine. To achieve this function, the Core defines a data model and an API to manipulate it.
The Editor itself is also a Bevy application; it depends on the
bevy
crate and builds upon the Bevy engine. This allows dogfooding Bevy to make sure features are relevant and the engine is usable and stable. The Editor however is not a typical Game, therefore might not use a typical Bevy Game architecture. In particular, it is expected that it leans more heavily onasync
and futures, where a typical Game has minimal to no use of these.To provide the best possible editing experience and shortest iteration time, the Editor must allow running the Game in the simplest and fastest possible way. The Unity3D game engine provides this functionality, but runs a slightly different version of the Game using a custom Mono runtime embedded in the Editor, as opposed to various UnityPlayer implementations depending on platforms, some of them transpiling the C# into C++ via IL2CPP and therefore running a somewhat different code. In contrast, the goal of the Editor is to run the actual Game itself. There are various possible technical solutions to this, like running a separate process whose window is embedded into the Editor's window, or running an in-process copy of the game. These options need to be explored to find a right match.
To successfully write a Game, Developers need to make available to the Editor their own custom components and systems which enable the specific behaviors of their Game. This requires the Editor to be able to load their code, register the components and other types present in the Developer code, and instantiate such components in a Scene or any other editing context. The Editor consumes custom Developer code written in Rust, and allows the Developer to load their code without having to rebuilt the Editor from sources. This requires the Editor to deal with dynamic libraries. In the simplest variant of this feature, dynamic libraries provided by the Developer are loaded when the Editor starts, and the Developer needs to restart the Editor after each change to their code (cold reload).
Like for other Authors, enabling fast iteration for Developers is critical. To that end, the Editor must be able to hot-reload code, the process by which the Editor can unload a old version of the Developer code and reload a newly-built version containing changes without the Editor process itself being terminated. Due to the dynamic nature of the process, this feature is extremely challenging to implement efficiently and robustly, but must be considered upfront to design systems capable of handling such dynamism.
Core
Data model
TODO: describe the data types available and the custom in-memory data model format, and the use of diffs to carry modifications to objects. the data format uses properties specified by string paths (
GetPath
). also describe how new types are dynamically added and removed (hot reloading).Undo and redo
TODO: describe the undo/redo system, at the center of the Core architecture, making it available to all Extensions transparently, and explain the link with diffs (see Reflection-based diffs)
Transport
TODO: describe the serialization/deserialization via Serde into the custom in-memory data model format, with backing to disk (RON-like), and the transport abstraction which allows working with local shared memory (solo editing, performant) or with real networking (multi-user editing, remote editing).
Storage
TODO: describe the on-disk format (RON-like) for all assets saved by the Editor (the editing version, not the baked version) and the
Serializer
/Deserializer
implementation for Serde compatibility. talk aboutgit
and version control, and making the format nice to it (think about how git does merges etc. and try to reduce likelihood of merge conflicts and mismerges?)Extensions
TODO: talk about the need to try to have each Extension deal with a specific set of components, and possibly avoid overlaps as much as possible for the sake of 1) performance (parallelism) and 2) correctness (makes the job of the Core easier if less concurrent accesses).
Asset import
TODO: describe the asset importing Extension(s?) allowing to import into the Editor various formats like
.png
,.obj
,.wav
, etc.Hierarchy editor
(or Scene Editor ?)
TODO: describe the Extension which allows editing a scene by instantiating entities and components, arranging them into a hierarchy of transforms, and possibly other hierarchies. here there's a lot of room for innovation, as traditionally game engines only have a single canonical transform-based spatial hierarchy so we have an opportunity to provide something much more powerful and practical.
Inspector
TODO: describe the UI Extension allowing to edit the data of a selected or set of selected object(s), similar to the Unity Inspector window.
Build pipeline
TODO: describe the Extension integrating Distill to provide asset baking, and the (same or separate) Extension that builds/bakes/packages an Editor scene into a runtime game.
Technical choices and challenges
Type serialization
TODO: talk about the type registry, type IDs, the difficulty of unicity across processes with potentially different Rust versions
Reflection-based diffs
TODO: talk about the necessary changes and additions to
bevy_reflect
to enable allReflect
-ed types to be diffable and therefore editable by the Editor. explain the performance challenges of efficient diff create (d = b - a) and apply (a + d = b).TODO: see also ezEngine and its graph data model and diff handling.
Hot reloading
This is a stretch feature, likely not available in a first Editor version.
TODO: explain hot-reloading of code and its challenges around DLL unloading, like TypeId mismatch. talk about
dylib
vs.cdylib
, the limitations ofdylib
with respect to compiler toolchain version and unstable ABI, and the limitations ofcdylib
with respect to the C interface and lack of support for all Rust features.See how Unreal Editor itself discourages the use of hot reloading due to bugs and asset corruptions:
and
Binary distribution
The Editor is first and foremost distributed as a prebuilt binary application. Building from source is supported, but shall not be the main consumption path, to avoid a high barrier to entry for Authors unfamiliar with Rust and Cargo.
The release process shall be automated via a CI pipeline on GitHub, which builds the Editor and packs it with any additional dependent file (images, icons, etc.) into an archive (ZIP), or possibly even an installer (
.msi
,.deb
, etc.). This allows frequent releases, possiby nightly, and reduces the overhead of each release by limiting the number of manual steps, while ensuring consistency and allowing gating from automated testing to ensure quality.User interface
There is a strong desire to build the user interface (UI) of the Editor with the Bevy UI itself. Currently the UI provided by the
bevy_ui
crate is too cumbersome and limited to be able to stand up a full-featured user interface for the Editor. In particular, the constructs are too low-level and verbose to be readily usable.bevy_ui
also focuses heavily on the rendering part of the UI, and lacks much in other areas like consistent user input and interaction, or localization.Various alternatives have been proposed, like
egui
, but their integration with Bevy might cause more friction than it helps, and prevents the Editor from dogfooding the Bevy UI, provide valuable feedback on it, and drive its development. Therefore a solution based on Bevy itself, either by improvingbevy_ui
or by writing a new crate focusing on widget-intensive Editor-like applications.Looking at the Rust UI ecosystem, one valuable contribution has been the Druid UI framework. Although its design and data model do not necessarily fit well with Bevy to enable directly consuming the crate, an important learning is its ability to empower developers with a 2D graphics library and UI framework allowing them to build a polished and themed custom widget in a matter of minutes without the need to bother with GPU contructs (meshes, textures, etc.). Instead
druid
provides a set of 2D drawing commands via aRenderContext
trait, and aWidget
trait with various user interaction methods to implement, which together make the process straightforward. To that respect, the experience is similar to (but the implementation much different, more efficient) the immediate-mode GUI of Unity3D, which helped popularize the game engine and is one of its leading selling points for Editor customizing. Due to the wide variety of widgets required for the Editor, a similar solution should be investigated, for example by providing a backend based on the Bevy renderer for Piet, the 2D library used by Druid (see this blog post by Raph Levien describing Piet).Async integration
Being a "Desktop application" rather than a Game, it is expected the Engine will more heavily lean toward the use of asynchronous operations and futures. This will likely require better support for those features than already available today in Bevy. At the minute, the async integration in Bevy appears almost anecdotical; with the Editor, it could and should become a valid and robust design alternative.
Embedded rendering
Embedding the rendering of the Game process into the UI of the Editor is made possible by leveraging the platform's compositor API. This feature is available on most platforms.
This technique has some major advantages. First, it is robust to game crashes, avoiding loss of data as long as the Editor itself remains stable. It also naturally lends itself to networking, allowing video streaming of a Game running e.g. on a DevKit (console) or any other remote hardware. Data-wise, this hints at an Editor design where the build pipeline runs in the background and processes asset changes on the fly, to minimize the delay between the time the Author presses the Play button and the time the Game actually runs. A possible alternative is to use editing assets (non-baked assets) by providing the Game with a plugin which allows loading such assets during development; however this diverges the "development Game" from the "shipped Game", which is generally preferable to minimize as much as possible. For networked play, this also means either creating a networked asset fileserver so the remote Game host can access the editing assets from the local Editor host, or creating a deploy step to copy those assets (which can be slow, especially when working remotely).
Generally however embedding rendering is a challenging feature to achieve, to make it work smoothly and integrate it with the Editor UI without quirks. This requires the UI to be designed to allow embedding native child windows, something existing established UI frameworks (Qt, GTK, ...) support to various extents ranging from no support at all to complete seemless integration with their own widgets. This feature will likely require some prototyping in Rust, and some changes and improvements to the Bevy UI.
Beta Was this translation helpful? Give feedback.
All reactions