bevyengine / bevy

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

bevy cli #436

Open vultix opened 4 years ago

vultix commented 4 years ago

It would be great if we could have an official bevy cli. Here's some ideas off the top of my head for how it might look:

A lot of this functionality could be replaced or improved by an editor, and there's much we'd want to change from this, but I believe it could be incredibly useful!

cart commented 4 years ago

Yeah I think eventually we'll need a bevy cli tool. But I do want to focus on using existing ecosystem tools where we can. And I also don't want a bevy cli to be a required part of bevy setup or a part of our "getting started" guide. People should be able to get up and running with a common set of tools (namely git and cargo).

bevy new --template {shooter,2D,etc...}

git clone https://github.com/bevyengine/shooter-template

bevy build {platform} --release - builds the project and generates an artifact for the given platform

cargo build --target=SOME_TARGET. However cross platform builds often require extra configuration and/or only work on certain platforms (ex: android and ios), so automation here will be needed. I think i would prefer it if we made non-bevy tools better at this though as this isn't a bevy-specific problem. Ex: https://github.com/rust-embedded/cross

bevy prepare {platform} - prepares the platform to be built. Generates xcode project / android studio project, etc.

we might actually need a custom tool for this. once we have working android / ios builds we should definitely discuss what automation is needed here.

bevy doctor - checks your environment for any known gotchas.

yeah i like this :smile:

Could verify that you have fast compiling setup correctly, including verifying lld or zld are installed

yupyup good call

Could check for missing ANDROID_SDK_ROOT environment variables, outdated xcode version, etc...

yeah these things are easy to mess up and would benefit from some validation. im hoping we can make the "cross" project (or something like it) work for us so we can have a standardized way of building things without too much custom setup. but i guess setting up docker presents its own set of problems.

bevy upgrade --version {version} - upgrades the bevy version, performing auto-migrations for breaking changes

yeah as bevy starts to stabilize and people start building serious projects in it, migrations are a good idea.

bevy lint - possibly checks the project for best practices?

definitely an interesting idea. are clippy extensions a thing? it would be really cool to have some bevy clippy lints. the editor would likely do this at some point, so exposing that via cli is probably a good idea

So yeah, in general i think this tool will become necessary eventually, but I don't want to build custom bevy tools when we can invest our development energy into ecosystem tools / use whats already out there.

jondot commented 4 years ago

For templating you can use Hygen (I'm the author), get a feel for bevy+templates, and get a good idea of how a CLI can function in terms of developer experience for bevy. On the event that we'll never get to build that CLI, then you're left with a fully functioning app generator:

http://www.hygen.io/

It started as a toolchain for any project, grabbed a focus in the frontend community, but I do use it for everything (using the binary, no need for node.js)

CleanCut commented 4 years ago

bevy_template currently supports a tiny bit of this functionality (mainly configuring fast-compile stuff and installing external linkers). I have a discussion topic open on it: https://github.com/bevyengine/bevy/discussions/557

huhlig commented 3 years ago

A Cargo extension would be preferable to requiring yet another executable. https://doc.rust-lang.org/book/ch14-05-extending-cargo.html

alice-i-cecile commented 3 years ago

The cargo-task crate looks like it might give us extended functionality, as it doesn't appear that an official version exists.

TimJentzsch commented 2 years ago

I created a prototype, cargo-bavy: https://github.com/TimJentzsch/cargo-bavy

Notably, your CLI crate will have to be named cargo-bevy to work properly. This is why I chose bavy to avoid naming conflicts.

I also created this tool before I found this issue, so I didn't include any of the thoughts here. The implementation is quite rushed to release this before the jam, so the code quality is questionable right now :')

TimJentzsch commented 2 years ago

Some thoughts from my experience with developing cargo-bavy:

Project templates

This is an important feature, currently there is a lot of boilerplate setup needed when you want the "full" Bevy experience, such as the fast compile configuration. When you're starting out (but also when you are experienced) you don't want to set that all up. You want to start with the interesting stuff immediately.

Current state in cargo-bavy

It provides a cargo bavy new <PROJECT_NAME> command, which will create a project template for you. It will first ask you which features you want in three categories: Bevy features (e.g. hot asset reloading), compile features (e.g. LLD linking, WASM support) and project features (e.g. MIT/Apache dual license, CI workflows). Depending on your choices, it will combine them and initialize a project with them.

Lessons learned

One advantage of this approach is that it is highly configurable. Not everyone wants to target WASM or use the LLD linker, so they can freely combine the options that they like. However, from a development perspective, this approach might be hard to scale. If the features are mostly in independent files, this is no problem. But especially with Bevy features it's important how you combine them in the code and that can quickly become hard to reason about.

Integrating the Bevy features will be the hardest task. I briefly experimented with using TokenStreams and the quote! macro to define the Rust snippets, this would provide syntax highlighting and make it easier to spot any errors. Unfortunately, the formatting got lost when converting it back to a string, even when running cargo fmt afterwards it didn't look right and wasn't really usable. Now I'm using strings as templates, but that's a lot harder to maintain.

I think the best approach would be to somehow combine this configurable approach with GitHub project templates. With more complex templates like "adventure game" or "shooter", a lot of code and assets might need to be provided, so this makes more sense to put in a dedicated repository. Then we also allow third parties to define new templates, which will be important to make this scalable. Those "fixed" templates however have the problem that they need to be opinionated about the compile and project configuration. So, ideally, the user would still be asked about the compile features they want after cloning the template project so that this flexibility is still provided for them. The challenge here is that the project initialization doesn't have a known state as basis anymore, so this needs to be a lot more robust or we need to enforce standards for the project templates. Otherwise, it might get hard to determine if a feature is already enabled or how to enable it if a file already exists.

Cargo helpers

Some cargo commands require specific configuration with Bevy, here it's nice to provide wrappers that make certain things easier for the user.

Current state in cargo-bavy

It provides several commands: cargo check, cargo build and cargo run.

For the most part, they work like their cargo counterparts. However, they will automatically pass the bevy/dynamic feature flag when it makes sense to increase the compile times and provide a new --wasm flag which handles all the boilerplate around releasing for the web.

For example, cargo bavy run --wasm will do the following:

  1. Check if all necessary tools are installed (the wasm32-unknown-unknown compile target and the wasm-bindgen-cli tool).
  2. Check if a wasm folder has been created already and initialize it with a .gitignore and index.html file if not.
  3. Copy over the assets folder into the wasm folder.
  4. Compile the app for the wasm32-unknown-unknown target.
  5. Use wasm-bindgen-cli to bundle it for the web.
  6. Launch a local webserver that serves the app to localhost.

Lessons learned

I think this has a lot of potential and I'd like to see it in an official solution as well.

During the jam, I have seen a ton of problems or questions that could be solved by this: Mainly (1) errors that result from having the bevy/dynamic feature configured in Cargo.toml and forgetting to disable it for WASM or release builds and (2) asking how to build for the web and multiple errors related to that.

Making these things easy provides a lot of value, e.g. users are more likely to test for the web early so they can develop with this target in mind.

One challenge here is related to bevy/dynamic. Setting this automatically works great, however when this is not configured in Cargo.toml, rust analyzer won't use this feature. This essentially creates "competing compiles": First you will run your app with the dynamic feature, then RA will check without it so bevy needs to be recompiled. This essentially negates all the fast compile gains. This is fixable by configuring the flag in rust analyzer via a .vscode/settings.json file (which is now an option in cargo bavy new), but this can be a big footgun for users so I'm not sure how to properly handle that.

jondot commented 2 years ago

Jumping in the discussion, between my first comment and now, I've built Backpack. You might like it or parts of it (a few parts were extracted and packaged as library).

JonahPlusPlus commented 2 years ago

I wasn't aware of the discussion here, but I made another discussion #6026 for a CLI/GUI tool that can incorporate some of these features.

nigrodev commented 9 months ago

I recently published bevyinit. Made it to be an easy and practical way to create a project using bevy with some templates and useful options

if you want to take a look: https://github.com/nigrodev/bevyinit

making a doctor command that checks the environment isn't a bad idea, I'll look into it later

alice-i-cecile commented 2 months ago

I've written up some initial work scoping for this at https://hackmd.io/@bevy/rk2Qnf5i0/edit :) We're chatting about it on Discord, but I expect to see a proper working group soon.

alice-i-cecile commented 2 months ago

There's now a working group devoted to this. We're fleshing out the core architecture and are aiming to officially adopt it (and close this issue) once the core architecture is settled and at least one polished useful feature is in place.