bevyengine / bevy

A refreshingly simple data-driven game engine built in Rust
https://bevyengine.org
Apache License 2.0
35.49k stars 3.51k forks source link

Bevy Editor #85

Open cart opened 4 years ago

cart commented 4 years ago

Bevy should have an extensible visual editor capable of the following:

preland commented 1 year ago

Exactly; the way I see it, the best way to do this would be to make a Rust app (not necessary a Bevy-made app in fact, but it will at least need the backend for displaying the scene accurately) which reads the .rs file, adds the elements with their respective properties into the viewport (kinda makes a temporary clone/mirror of the scene), and can modify the main source file whenever the editor sends a command (ie edit an entity, add an entity, link a system etc.).

Then, when the game needs to be test ran, THEN the main source file is compiled.

This has the BIG pro of still allowing the main source file to be edited outside the bounds of the editor. There is a mild con, however, of the readability of said file (since it will be modified with a layer of abstraction, the code may not be as intuitive as it would otherwise).

To be honest, all we need is a barebones implementation. Like rly rly barebones

Even if it can only parse a few generic objects and lights and has a static viewport at first, that will be enough to lay the groundwork for everything else.

Aceeri commented 1 year ago

I don't think generating rs source files is a good idea for an editor to be doing. Ideally the editor just sits ontop of your game and you can create ron scene files. I prefer the simplicity of having components essentially define the behavior of things rather than having a shittier programming language inside of a config file.

thraidh commented 1 year ago

Parsing and modifying source files of any language (except maybe Scheme or Lisp) is usually a terrible idea, because parsing a language is way more complicated than any data-only file format.

Reading and parsing the file at runtime may be slower than instantiating things directly from code, but that is usually done only during startup.

If that performance is absolutely needed, you can convert the data to Rust code just before building the product for production, in a step is usually called baking

radlotus commented 1 year ago

Godot uses a custom format for scenes called TSCN.

minecrawler commented 1 year ago

Exactly; the way I see it, the best way to do this would be to make a Rust app (not necessary a Bevy-made app in fact, but it will at least need the backend for displaying the scene accurately) which reads the .rs file

No. I meant the opposite. Don't read .rs files. Put things into data-only files and have the editor generate the necessary code to execute them.

I don't think generating rs source files is a good idea for an editor to be doing.

Depends on the degree of generation you want from your editor. I'd love to have an editor from which I can do most things without writing a single line of code. Writing boilerplate is tedious, which is why I'd prefer the editor to handle all of that. I want to focus on the game (logic) and click a button to make things move. Maybe you don't want that, so you can write your own code and load the data files yourself. I just hope that the editor will also make it possible to have things be generated or available for people who don't want/need to roll their own logic :)

However, in my case, the editor will provide everything, while in your case, you'll need to know exactly, which things you'll need to implement in order to run a scene (file) correctly.

Also think of this use case: When I create a game, I want to start/stop/debug/inspect it quickly from the editor. I want to click a button, change things, write logic and then have my changes be hot-reloaded into the game so I have instant feedback. Bevy and its editor can and should provide such a way of software development. It's also not a novelty! At the end of the day, productivity matters so a game can be developed and pushed out to players.

Reading and parsing the file at runtime may be slower than instantiating things directly from code, but that is usually done only during startup.

I don't think reading data files will take that long. I expect asset loading (e.g. models, textures, etc.) to take way longer, so it doesn't matter if you load a scene file or use imperative programming to create your scene....

Godot uses a custom format for scenes called TSCN.

AFAIK Bevy will also have its own scene files which are used to describe asset relations and layouts

bjorn3 commented 1 year ago

We already have scene files written in the ron format. Only if you are adding components that are not part of bevy itself do you need to compile the editor with those components added. I don't think this is avoidable. How would an editor know that the MyFancyTree component should result in a tree being rendered according to my own algorithm for generating trees if it doesn't have access to this algorithm?

thraidh commented 1 year ago

You could load all user code dynamically if it is compiled to a dynamic library or even WASM. Then those libs would register MyFancyTree and the editor would know what to do. That would also allow you to modify code while the editor is running and hot-reload it. The editor could even compile it for you, so you just change your code, the editor detects the changed source file, recompiles that crate/file/code fragment to the required thing (dylib/WASM/...) and reloads it automatically.

When a final productive build is made, all that code could be compiled natively into one big binary.

bjorn3 commented 1 year ago

Dynamic linking only works if you are compiling with the exact same rustc version against the exact same libbevy_dylib.so as the editor. Doing this reliably is only possible by compiling the editor yourself too. As for wasm, that would be possible but not all code will work under wasm and you did have to define a plugin interface to allow passing data between the wasm world and the native world. It is possible but for now compiling the editor as part of the game itself rather than separately will be much easier.

Pauan commented 1 year ago

As for wasm, that would be possible but not all code will work under wasm and you did have to define a plugin interface to allow passing data between the wasm world and the native world. It is possible but for now compiling the editor as part of the game itself rather than separately will be much easier.

That is all possible, Bevy already compiles to Wasm, and Wasmtime exists, and Wasmer exists, and Tauri exists.

The Wasm ecosystem is fairly mature (especially with Rust, since Rust was one of the first languages to compile to Wasm, and Rust is used extensively in Wasm blockchains).

bjorn3 commented 1 year ago

I'm not talking about compiling and running wasm at all. I know rust is in a good position for that. What I'm talking about is that wasm can't directly call bevy api's exported by the native half (in this case the editor itself), nor directly access the memory of the native half. You need to define an abi between the wasm plugin and the native host and then translate at the boundary between the wasm half and native half. Doing this is a lot of work as you need to do this for every single function. In addition you need to somehow define a way for bevy components to be serialized and deserialized when passing the boundary. And finally there are some components like many of the render components that contain things that can't be serialized like wgpu buffers. You will need to find a way to keep those components at the native half and only reference them by a handle.

Pauan commented 1 year ago

What I'm talking about is that wasm can't directly call bevy api's exported by the native half (in this case the editor itself), nor directly access the memory of the native half. You need to define an abi between the wasm plugin and the native host and then translate at the boundary between the wasm half and native half. Doing this is a lot of work as you need to do this for every single function. In addition you need to somehow define a way for bevy components to be serialized and deserialized when passing the boundary.

Yes, I know how Wasm works (I was a Rust Wasm Core team member, and I've helped out with the Wasm WG).

All of those issues have been solved or worked around in various ways, since Wasm<->JS has exactly those same problems, and we needed to solve those issues for Wasm<->JS, so we solved it.

All of the complicated busywork (including serialization and proxying) is automated with macros. There is no technical reason why Bevy can't use Wasm, as you said it would require some work, but everything requires work.

I don't necessarily think using Wasm is the best option, but I also don't think we should immediately dismiss it out of hand either.

thraidh commented 1 year ago

Dynamic linking only works if you are compiling with the exact same rustc version against the exact same libbevy_dylib.so as the editor. Doing this reliably is only possible by compiling the editor yourself too.

That means, dynamic linking is reliably possible if you compile the editor yourself once and then only recompile one custom game-specific code part, when that changes. The other option would be to recompile the editor plus all the custom parts, whenever one of those parts changes.

Therefore editor needs to be compiled in all cases, but dynamic linking would probably be faster and can be done without restarting the editor.

I may be working with incomplete knowledge, so it might sound good, but might not work at all. It is probably easier for editor/bevy developers to make a monolithic editor, but it would probably result in a worse user experience.

I believe, as a library/tool maker we should tackle the complicated stuff to make it easier for the users. That does not mean, that there can't be a first version that is not as good as it could be.

preland commented 1 year ago

I will try to reiterate what I was trying to say earlier, as I don’t think I explained it very well earlier.

If I were to make the editor backend myself (which at this point I’m considering even though I suck at Rust string parsing), I would have it take a rust project file as input (like the folder that gets generated by cargo new insert-project-name). From there, it would look through the main.rs file to find objects and other data via string parsing (which Rust is uniquely good at doing, since it has very powerful string syntax, as well as good memory design; case in point the numerous macros that embed other languages within Rust). From this data, it would create instances of the objects with the same properties within the editor window.

For example, if you wanted to load a scene with a cube and a light in it, the editor would take the folder, parse the main.rs for objects, and would add the objects to the editor itself.

This would mean that the editor isn’t technically directly representing the scene, which is intentional, as this would take too much time. There could be some integration with rust-analyzer to address bugs , but that would be separate from the scene representation (ie. There can be errors in the code while still having the scene render properly coded parts).

When it comes time to “run” the application (similar to how most game engines have a “run” button) the editor would then initiate a compilation and then run the created artifact. The editor could even potentially run a “debug” version of the code with automatic breakpoints and resource allocation (much later idea that someone else would handle) when you “run” the game, and then when it comes time to export the project (I intentionally don’t say build, since the “run” command already does this) it could run in “release” mode.

To address some of the concerns listed above:

  1. The editor would not prevent you from writing the project from scratch in any way. To reiterate, this implementation of the editor only modifies .rs files. No extra XML, YAML, or semi-obfuscated data files. Everything remains purely Rust at the end; turtles all the way down.
  2. The editor would, in theory, allow someone to not have to touch the underlying source code at all. Now, this wouldn’t be encouraged, as the best the editor could ever possibly standalone be would be something like Scratch, but it would be possible. The most likely way this works is you can add/remove objects, edit the positions of said objects, add components to objects, etc. Anything that requires significant logic will also require coding. The main point of the editor is to make it easier to place objects in the game, and to understand how the end product looks without having to recompile every time you move a box a few units.
  3. In the case that I do get around to making an editor in this way, it will probably be incredibly barebones, and will definitely have errors. Especially considering that my environment platform (Intel Mac with integrated graphics) is barely supported by Bevy as is, and has significant graphical bugs (at least it did- it might’ve been fixed by now). I’ll get working on it when I have time, but don’t expect it to really support displaying anything other than cubes and (only specific not-IntelMac buggy) light sources. If I’m feeling really productive, I might even make the camera movable 😂.

Either way, I just want there to be an editor for Bevy that just, works. No lag spikes and no continuous recompilation. UI design philosophy can wait for when we have something to actually apply it to.

thraidh commented 1 year ago

While that idea might fit your current use case, it has some flaws.

You want to parse main.rs for strings to locate entities and components and update those via the editor. You assume, that should be possible, because Rust is good at string parsing (when I think about a language good at string parsing I end up with Perl, because I'm that old), but you were a little light on details.

What if I don't instantiate my objects in main.rs, but in some other included source files? Will your parser follow every use directive? What if I don't instantiate my objects directly, but instead I have a function cube(x,y,z,color), which can produce a lot of cubes in different locations with different colors? If your parser would understand that and be smart enough to modify the function calls, that would be amazing. What if I want to have a 8k x 8k height field as a landscape and thousands of trees? Should that really live in main.rs as code?

All these things would not be necessary, if there was some scene file, that is just data and your main.rs just contains something like scene = load_scene_from_file("myscene.xyz"); scene.instantiate(...); where instantiate(...) would turn the scene description into actual entities and components. The editor can load and modify that same file and you wouldn't even have to recompile your main.rs.

But even this would just be for the MVP editor for very simple use cases, because you also would not want all your stuff in one big scene file.

And then there is the case of custom components and how to handle and display those in the editor, but that is a different discussion.

preland commented 1 year ago

Those are some fair points. As for only parsing main.rs, this was only as a starting point for design, and I wouldn’t be against allowing objects declared in other .rs files being parsed. However, I would prefer to have most of the editor modifications within a single file. It may not be the best idea to have them in main.rs though, so perhaps it could be in its own file, such as an editor.rs?

As for the case of rendering objects via function instantiation, I personally wouldn’t do that. It could be an experimental setting, but it wouldn’t be on by default. This is similar to how Unity and other editors handle function instanced objects. I would like to note that the reason function instantiation is so common currently is not because it’s necessary, but because the lack of an editor makes it the only option to efficiently add large batches of objects.

As for having a data file that is parsed, I personally would prefer not to do so, the reason being that the project should still be capable of development without the editor. Adding a data file muddies this quite a bit in many ways. Plus, unless this data file is human-readable, it will be difficult to understand and change by hand. And as another issue, any errors introduced into the data file will be fairly difficult to debug as opposed to using a Rust file.

Remember that, as far as the editor is concerned, the .rs file IS a data file. It just so happens to read the file and write to it as if it were valid Rust.

bjorn3 commented 1 year ago

As for having a data file that is parsed, I personally would prefer not to do so, the reason being that the project should still be capable of development without the editor. Adding a data file muddies this quite a bit in many ways. Plus, unless this data file is human-readable, it will be difficult to understand and change by hand. And as another issue, any errors introduced into the data file will be fairly difficult to debug as opposed to using a Rust file.

Bevy's scene files are in ron format, which is a text format with a similar data model to rust. It is possible to edit them by hand. See https://github.com/bevyengine/bevy/blob/main/assets/scenes/load_scene_example.scn.ron for an example. Am additional benefit of using scene files over rust source files is that it allows hot reloading. You can edit a scene file while your game is running and the changes will instantly be reflected back to the game without requiring any recompilation.

thraidh commented 1 year ago

As for the case of rendering objects via function instantiation, I personally wouldn’t do that.

If I would put instantiations into code it would be mostly for procedurally generated content, so there are good reasons to do that.

I would like to note that the reason function instantiation is so common currently is not because it’s necessary, but because the lack of an editor makes it the only option to efficiently add large batches of objects.

I read that as: to work with a large amount of objects, you either need functions or an editor.

As for having a data file that is parsed, I personally would prefer not to do so, the reason being that the project should still be capable of development without the editor.

Why do you want to modify object instantiations using a text editor instead of an editor that is made for that express purpose?

If you have just a cube and a light, that might even work, but if you run your game with 10000 trees and you want to modify one, you'd probably not even able to find it in your code and even if, you'd have to think really hard about how exactly you have to change its location, because you don't have visual feedback in your text editor.

An analogy might be to want to edit images using a text editor. That is actually possible, if you convert the image to XPM, but would you really want that? LibreOffice/OpenOffice/Microsoft Office documents are mostly just compressed XML, but you'd never want to edit that using a text editor, even if that is totally possible, just not feasible.

bjorn3 commented 1 year ago

If you have just a cube and a light, that might even work, but if you run your game with 10000 trees and you want to modify one, you'd probably not even able to find it in your code and even if, you'd have to think really hard about how exactly you have to change its location, because you don't have visual feedback in your text editor.

I believe it is intended to be able to develop without requiring any editor other than a code editor. Also if you have very large scenes, you likely can't include them in the game executable anyway as code, but need to split them into separate asset files to allow lazily loading them only as necessary. If you split a secne out as separate asset, you have to use a pure data format to describe it rather than use rust source code.

minecrawler commented 1 year ago

@preland If that solution works for you, why don't you just go ahead and implement it? The Bevy Community has always been about creating an ecosystem of tools, PoCs and proposals.

However, I think your proposal is not going to scale for other people, who want to do data-driven development in teams consisting of people of different professions, have several big scenes with hundreds of thousands of entities in each, which are not just cubes and lights, and complex logic surrounding them. Hence we'll need to come up with a solution for them as well ;)

For the discussion surrounding the editor and requirements, we already have a big discussion here. Actually, I think it would make sense to discuss hot-reloading and other interesting topics there as well!

djeedai commented 1 year ago

Let's keep the discussion courteous and assume best intent. If @preland thinks editing .rs files is an avenue to explore they're welcome to discuss and try an implementation, even if you strongly disagree. I also think this is not the right path, but who knows, we might be wrong.

Edit: typo

adam-arthur commented 1 year ago

I'm curious why an editor is considered fundamental here.

A big differentiator and part of the reason to choose Bevy is due to it being code-first, without a ton of editor abstractions that make understanding a project more difficult. Especially if there are all kinds of custom metadata files. And using a visual editor tends to be non-ergonomic for people coming from a development background.

Certainly it would be great if any editor was only an optional addition over an existing Bevy codebase, but if it becomes the only supported way to edit Bevy projects, it will lessen one of the compelling differentiating factors. People who want a visual editing experience will likely lean towards Unity or Godot... Rust tends to be too technical of a language for that crowd.

If the editor is optional/not required, then no harm no foul 😄

Pauan commented 1 year ago

@adam-arthur I'm curious why an editor is considered fundamental here.

The purpose of an editor is to compose scenes. You load your assets into the editor, and then you can drag-and-drop them into the scene. Doing that with code for thousands of entities is a massive pain, but it's effortless with an editor.

This is incredibly useful for creating landscapes or modular buildings, or for designing levels, etc.

It's much easier to do this in a dedicated editor, instead of trying to hack it in Blender / Maya / etc.

An editor can be much higher performance (Blender cannot handle large scenes), it can have a better UI, and it can have more features. And the output of the editor can be easily run directly in Bevy. And everything you see in the editor matches with the game engine (lighting, materials, etc.)

Using an editor massively speeds up your workflow, that's the point of an editor. It's just 1 button press to instantly jump from the editor into your game, this creates a very fast development loop.

The editor doesn't replace your code... it complements your code. You still need to write Rust code, even with the editor.

preland commented 1 year ago

Yes, an editor would be optional— consider it to be like the “front-end” of the project, while the “backend” is still usable on its own.

While I do agree with the ergonomic and developmental benefits of code-only creation, it is difficult to justify from an artistic perspective. For example, would you want to paint an image of a landscape using only code? While it can be done, and there are some benefits to doing it so, the lack of immediate graphical feedback is an issue for most users, whether power or not.

The way I see it, using code should be the preferred way of editing a project. The editor is just a tool, or another way of looking at the project as a whole.

(P.S. An update on my current editor progress: I’ve been messing around with the example project that loads in a scene from a file. While I must admit it holds promise, there are some…. rather annoying issues with it. The main one I’m running into is that the current systems implementation limits the parameters you can use to either the full World, or to basically all the other params. This….. is problematic for many reasons, the biggest one being that it makes hot loading/editing a scene nearly impossible without going heavily against the grain of the preexisting codebase. If anyone else wants to mess with the example code for that project, someone above has a link for it [I don’t think the example is in the default branch btw]. I know that syntax matching the main file will be a very difficult task, but I think it will likely be the best way to go forward. If there are security concerns over modifying code algorithmically, the edited file could be a temporary file, similar to how apps like Microsoft Word handle their file editing).

adam-arthur commented 1 year ago

Business application UIs are developed entirely in code all the time, primarily. Usually working off a pre generated mockup of course.

HMR and other techniques are used such that you can edit the code and see the visual impact immediately. It doesn't mean developers are using drag and drop to code the UI.

I don't see a huge advantage to drag and drop vs having a visual REPL, similar to many existing application UI workflows.

In my case the game is 99% procedurally generated, so a scene editor doesn't really provide any value. But obviously that's just one specific case.

Just saying, the primary reason I chose Bevy was that it was code first, and doesn't come with all the design cruft and ad hoc abstractions that editor workflows tend to morph the engine towards.

But if code first is still supported and remains a first class citizen then I have no concerns

djeedai commented 1 year ago

A big differentiator and part of the reason to choose Bevy is due to it being code-first, without a ton of editor abstractions that make understanding a project more difficult.

I think you're conflating having an Editor to edit some assets with having a core "runtime" that drives the app and takes away customizing from the developers. Unity has an Editor that works for custom scripts, and there's close to zero abstraction on it. You can add properties and edit them in the Editor or by code, and it's essentially the same. However Unity also takes over all the core features (audio, built-in renderer, scene management, asset loading, etc.) under a runtime they call "Player" and which is mandatory and prevents customizing a lot of things. The fact the runtime exists is not directly related to the fact there's an Editor. This issue is not a discussion about a runtime, which I think there's relative consensus will be very slim if it ever exists for the reasons you invoked (although it might be useful for beginners). That doesn't change that there's immense value to an Editor; there's plenty of areas like VFX or Animation where working with code alone is reasonably impossible.

hedgein commented 1 year ago

Hello, I am a university student who's is aspiring to be a game dev and loves rust. I've been streaming Rust (and other game engines/coding languages!) for over a year now. I don't know if my two cents are valid here, but I for one will say that I deliciously have been wanting an editor just for the reasons Pauan describes, the benefits to the overall workflow would make me NOM NOM NOM. I would gobble that stuff up hahaha.

lgsandbox commented 1 year ago

Does anyone remember which open issue is currently gathering requirements for an editor? I remember seeing it a month or so ago but forgot to bookmark it.

lgsandbox commented 1 year ago

Found what I was looking for immediately after posting. It was a discussion, if anyone else is looking for the requirements collection for the editor it is here:

https://github.com/bevyengine/bevy/discussions/7100

godotc commented 11 months ago

A game project edit and run in editor like loading a dynamic library/module/plugin, and link to the bevy core. Could be packged the core units and run in stand-alone mode.

A interactive scene to construct the world(map/level/scene-tree like other editor) and not to insert the startup system by coding.

A scripting language, debuger and universal assets format. Store the scenes, scripting and art resourcesfor high level develop (without recompile the rust source). Can split the core rs codes lib/feature and dynamic developments.

Some thoughts noted here.

TristanAppDev commented 11 months ago

Any news on this one?

Is there a way to contribute to the editor?

rrtt2323 commented 10 months ago

https://github.com/rewin123/space_editor Does this have potential?

preland commented 10 months ago

https://github.com/rewin123/space_editor Does this have potential?

I decided to look into it, and....

Yes, this is by far the best editor I've seen. It has almost everything done right, and the things it doesn't have right are either easily modifiable by the end user or just plainly unimplemented.

This one has my vote, even if it is admittedly far from production-ready.

SSebigo commented 8 months ago

Personally, the only thing holding me back from using Bevy is the lack of an editor.

I can understand the people that don't want an editor because they like doing everything, but the reality is that in the mainstream, teams are rarely just programmers, and you bet those non-programmers aren't going to learn Rust just for the fun of it.

Godot understood that pretty early into development. Very few people want to deal with code for "simple" things like UI, sounds, VFX, animation, especially with a compiled language.

I would advise just taking something like the project @rrtt2323 posted and build from there. Remove, add, modify what's needed to have the editor as fast as possible. And maybe take it from Godot, alphas, betas, RC releases are a good idea if you want feedback from the people building WITH Bevy and not building Bevy (huge difference).

HarveyUmbra commented 6 months ago

@SSebigo correct but Bevy is not Godot. Bevy's goals are not Godot's goals. Here is a comment from @cart where bevy's goals are roughly explained. comment

One goal of Bevy is that the editor is written in the same programming language as the game programmer uses. This goal brings many advantages, but it takes a long time until an engine is there. I hope that your goals haven't changed between now. Because these goals lead to a better engine in the long run.

jrmoserbaltimore commented 5 months ago

@SSebigo correct but Bevy is not Godot. Bevy's goals are not Godot's goals. Here is a comment from @cart where bevy's goals are roughly explained. comment

It looks like @cart recognized that game engines have tended to converge on the Unity/Unreal/Godot kind of thing for a reason. Bevy is quite different, being all-in on ECS, but the concept of an engine still has many similarities; I'd suggest the following on paper to figure out a rough design:

This has the advantage of immediately assuming that highly-mature game development software—what is often called a "studio" because it's presented as an all-in-one package of tools you'll need for a particular task—have refined their user experience over time and so starting there, and then throwing out or heavily modifying the parts of that user experience that don't fit perfectly with Bevy, most probably ending in something that at a glance looks superficially like other editors, kind of operates like other editors overall, but is built around a completely different conceptual framework. Parts of the workflow, like scene editing or UI design tools, might come out looking similar (yeah, probably) because that's the best way anyone can think of right now to do some particular thing or another; other parts will probably be totally different because Unity is not Bevy and the way Unity does something won't make sense for Bevy.

And maybe take it from Godot, alphas, betas, RC releases are a good idea if you want feedback from the people building WITH Bevy and not building Bevy (huge difference).

That too to get the continuous feedback, but I think something non-functional and quick to slap together is the best starting point. You're of course going to throw that directly in the trash and rewrite from scratch.

Imagine you're a software developer in 1988 and your manager describes to you this brand new never-before-done idea of "Windows." What do you do?

You spend a week writing software to draw on the screen, draw a few windows collecting groups of icons, write a file browser, a small paint program, and a text editor, all with the same shape—similar menus, buttons in the same place—and windows that can be dragged and resized. Thing is most of the icons are totally non-functional, and the ones that work don't run programs but rather bring up built-in functions of your little "Windows" program. Barely any of it works, but you can browse your C:, draw some stuff with a brush and paint bucket, type some text and save it to disk with a file open/save dialog box, and move and resize the windows for each of these things.

You show it to your manager, they show it to the people who give you money, and suddenly you have millions of dollars coming your way to hire a team of programmers to make all that stuff happen for real, with APIs and drivers and separate programs that actually work, along with decent performance and good software architecture.

When you do this with groups of specialists, it's called a focus group. Write the dirty little strip of code that pretends to be a rickety and dysfunctional editor but really is practically nothing but some garbage slapped together to kind of look like one, ask people who want to use the engine and its editor if this looks good, and take feedback on what parts feel like they're the right workflow (but broken) and what they think is missing or just a stupid way of doing something. Once you've got something that they like, toss that out and write one that looks just like it but for real.

This approach pays huge dividends. You skip all the work of writing some kind of preview alpha kind-of-buggy concept that kind of actually works until you know what you should be writing.