bevy icon indicating copy to clipboard operation
bevy copied to clipboard

Implement the Bevy Remote Protocol (BRP).

Open pcwalton opened this issue 1 year ago • 21 comments

This commit implements most of the Bevy Remote Protocol proposal by @coreh in the form of an HTTP server that's activated when RemotePlugin is added to the App. Requests and responses are sent via JSON, using serde and the reflection capability as appropriate. The server is implemented using Tokio and hyper.

All of the proposal has been implemented, with the exception of the POLL request, as it's not needed for debuggers to function and I'm uncertain as to its design.

In addition to the verbs in the proposal, an additional verb has been added, LIST. It allows the client to enumerate all components attached to an entity, or, if called without an entity, all components that are registered to the App.

Two new examples have been added, server and client. The server example spawns a test scene and allows connections. The client example offers a simple command-line interface to BRP queries. I considered having client be more extensive, but it struck me as out of scope for this PR, which is already rather large.

Note that this PR is missing some documentation, so I'm leaving it as a draft for now.

Changelog

Added

  • The new Bevy Remote Protocol allows debuggers to connect to your app over HTTP and inspect and modify the ECS. To use it, add the RemotePlugin to your app.

pcwalton avatar May 29 '24 02:05 pcwalton

You added a new feature but didn't update the readme. Please run cargo run -p build-templated-pages -- update features to update it, and commit the file change.

github-actions[bot] avatar May 29 '24 03:05 github-actions[bot]

I think the smol+hyper stack is perfectly viable, maybe run the server directly on one of bevy's task pools using smol_hyper?

mintlu8 avatar May 29 '24 12:05 mintlu8

🙌 @pcwalton Thanks for carrying the torch on this, as I haven't been super available for the last couple of months due to various IRL duties/activities. I'll review this PR as soon as I have some bandwidth.

coreh avatar May 29 '24 15:05 coreh

Just out of curiosity, how viable would it be to implement Reflect for https://github.com/bevyengine/bevy/blob/main/crates/bevy_ecs/src/world/mod.rs#L77 and use them. But don't know if there is too much overlap, especially with Get and Query logically.

valaphee avatar May 29 '24 16:05 valaphee

@mintlu8 Do you have a minimal example of how that would look?

pcwalton avatar May 29 '24 18:05 pcwalton

Note that I'm treating "make request JSON convenient to write by hand" as more or less a non-goal. My hope is that this will kickstart the development of community debugging GUIs, and those will be what nearly everyone uses. This doesn't mean that the JSON should be harder to write than necessary, but it does mean that clarity wins over convenience. Conveniences like abbreviations for components, verbs, etc. belong at the level of the debugging UI.

pcwalton avatar May 29 '24 18:05 pcwalton

Compressed JSON is surprisingly competitive and is also easy to inspect and debug. I'd prefer to just stick with it. We can always add more formats later.

pcwalton avatar May 29 '24 19:05 pcwalton

Since my last two comments sound kind of contradictory, let me clarify: Easy exploration and testing of the API via curl is a goal of my implementation of the BRP, but normal day-to-day use of curl isn't. It should be easy to experiment with the API via curl or similar tools. But you should be using a dedicated client to do most of your real work in it. I suspect most users will want to use GUIs, which could be based on sickle, egui, Web, native, etc. There could also be other UIs, such as CLIs or TUIs.

The inclusion of LIST enables clients to implement abbreviation of component names. A client could start with LIST to retrieve the full names of all components registered to the app. Then it could use that information to resolve short names (e.g. Transform) when they're unambiguous and to report an error when they're ambiguous. A client is in a better position to do this than the server, because it can report errors without a round-trip and can also implement nice things like autocomplete and menu drop-down lists of components.

pcwalton avatar May 29 '24 20:05 pcwalton

I made the BRP extensible by adding a RemoteVerbs resource that you can add things to.

pcwalton avatar May 29 '24 22:05 pcwalton

@valaphee I don't know how this is applicable; commands seem completely orthogonal. Commands are for granting delayed access to a world within an otherwise-parallel system. But the BRP is already running with exclusive world access, so it has no need for commands.

pcwalton avatar May 29 '24 22:05 pcwalton

Compressed JSON is surprisingly competitive and is also easy to inspect and debug. I'd prefer to just stick with it. We can always add more formats later.

Makes sense. (Sorry if you were responding to a comment I deleted--I misunderstood that writing by hand is a non-goal, but reading commands might still be in scope.)

B-Reif avatar May 30 '24 07:05 B-Reif

@mintlu8 Do you have a minimal example of how that would look?

This one? https://github.com/smol-rs/smol/blob/master/examples/hyper-server.rs

mintlu8 avatar May 30 '24 20:05 mintlu8

smol hasn't had any commits for 2 months. Do we still want to rely on it?

pcwalton avatar May 30 '24 20:05 pcwalton

smol hasn't had any commits for 2 months. Do we still want to rely on it?

Bevy pretty much uses the entire smol stack under the hood for its async stuff, I don't see why not. async_task, async_io, futures_lite and async_channel are all smol crates.

mintlu8 avatar May 30 '24 21:05 mintlu8

Ok, this is now using smol instead of Tokio.

pcwalton avatar May 31 '24 03:05 pcwalton

I'm putting this as "needs review" because I'm waiting on @coreh to look at it before doing more.

pcwalton avatar May 31 '24 22:05 pcwalton

There actually aren't as many components as you might think -- no more than 50 IIRC. I don't think pagination is necessary. Maybe in the future.

pcwalton avatar Jun 03 '24 06:06 pcwalton

Is there any way to implement this as a protocol agnostic tower service instead? AFAIK hyper is built on tower so much of that work could be reused for an additional http example.

LegNeato avatar Jun 04 '24 21:06 LegNeato

@LegNeato Can you elaborate as to what you mean?

pcwalton avatar Jun 18 '24 00:06 pcwalton

@LegNeato Can you elaborate as to what you mean?

Looking at the patch closer, I think it would best be as a separate project. The thought was to write BRP aupport as a tower service and then wrap it in bevy on the server side and let other non-bevy tools consume the tower service directly on the client side.

LegNeato avatar Jun 20 '24 23:06 LegNeato

i haven't looked super closely at this pr. but i think it could be useful to add code gen for swagger/openapi. this could be in another pr also nice work looks amazing

n1ght-hunter avatar Jul 05 '24 03:07 n1ght-hunter

@LegNeato Can you elaborate as to what you mean?

Looking at the patch closer, I think it would best be as a separate project. The thought was to write BRP aupport as a tower service and then wrap it in bevy on the server side and let other non-bevy tools consume the tower service directly on the client side.

Another benefit of implementing as a tower service is the service can be exposed through other transport mechanisms besides TCP/QUIC such as Unix domain sockets (UDS works on Windows too!)

asasine avatar Jul 17 '24 11:07 asasine

Any idea of whether a brp server would work on the web? The server example is marked as wasm so I would assume so but I can't think of way for the server to be accessed if running on the web. https://github.com/bevyengine/bevy/blob/a56805a3b2df2248fe6ee584bd8344983bd04393/Cargo.toml#L3271-L3275

For context I'd like to use this for the 3rd example use case in the BRP proposal.

JS/HTML-based UI interacting with an embedded Bevy application running in a browser;

LiamGallagher737 avatar Jul 17 '24 21:07 LiamGallagher737

Adopted in #14880: please continue conversation there!

alice-i-cecile avatar Aug 22 '24 20:08 alice-i-cecile