2 releases
new 0.15.0-rc.2 | Oct 27, 2024 |
---|---|
0.15.0-rc.1 | Oct 22, 2024 |
#2205 in Game dev
517 downloads per month
4MB
66K
SLoC
An implementation of the Bevy Remote Protocol, to allow for remote control of a Bevy app.
Adding the RemotePlugin
to your [App
] will setup everything needed without
starting any transports. To start accepting remote connections you will need to
add a second plugin like the RemoteHttpPlugin
to enable communication
over HTTP. These remote clients can inspect and alter the state of the
entity-component system.
The Bevy Remote Protocol is based on the JSON-RPC 2.0 protocol.
Request objects
A typical client request might look like this:
{
"method": "bevy/get",
"id": 0,
"params": {
"entity": 4294967298,
"components": [
"bevy_transform::components::transform::Transform"
]
}
}
The id
and method
fields are required. The params
field may be omitted
for certain methods:
-
id
is arbitrary JSON data. The server completely ignores its contents, and the client may use it for any purpose. It will be copied via serialization and deserialization (so object property order, etc. can't be relied upon to be identical) and sent back to the client as part of the response. -
method
is a string that specifies one of the possibleBrpRequest
variants:bevy/query
,bevy/get
,bevy/insert
, etc. It's case-sensitive. -
params
is parameter data specific to the request.
For more information, see the documentation for BrpRequest
.
BrpRequest
is serialized to JSON via serde
, so the serde
documentation may be useful to clarify the correspondence between the Rust
structure and the JSON format.
Response objects
A response from the server to the client might look like this:
{
"jsonrpc": "2.0",
"id": 0,
"result": {
"bevy_transform::components::transform::Transform": {
"rotation": { "x": 0.0, "y": 0.0, "z": 0.0, "w": 1.0 },
"scale": { "x": 1.0, "y": 1.0, "z": 1.0 },
"translation": { "x": 0.0, "y": 0.5, "z": 0.0 }
}
}
}
The id
field will always be present. The result
field will be present if the
request was successful. Otherwise, an error
field will replace it.
-
id
is the arbitrary JSON data that was sent as part of the request. It will be identical to theid
data sent during the request, modulo serialization and deserialization. If there's an error reading theid
field, it will benull
. -
result
will be present if the request succeeded and will contain the response specific to the request. -
error
will be present if the request failed and will contain an error object with more information about the cause of failure.
Error objects
An error object might look like this:
{
"code": -32602,
"message": "Missing \"entity\" field"
}
The code
and message
fields will always be present. There may also be a data
field.
-
code
is an integer representing the kind of an error that happened. Error codes documented in theerror_codes
module. -
message
is a short, one-sentence human-readable description of the error. -
data
is an optional field of arbitrary type containing additional information about the error.
Built-in methods
The Bevy Remote Protocol includes a number of built-in methods for accessing and modifying data
in the ECS. Each of these methods uses the bevy/
prefix, which is a namespace reserved for
BRP built-in methods.
bevy/get
Retrieve the values of one or more components from an entity.
params
:
entity
: The ID of the entity whose components will be fetched.components
: An array of fully-qualified type names of components to fetch.strict
(optional): A flag to enable strict mode which will fail if any one of the components is not present or can not be reflected. Defaults to false.
If strict
is false:
result
:
components
: A map associating each type name to its value on the requested entity.errors
: A map associating each type name with an error if it was not on the entity or could not be reflected.
If strict
is true:
result
: A map associating each type name to its value on the requested entity.
bevy/query
Perform a query over components in the ECS, returning all matching entities and their associated component values.
All of the arrays that comprise this request are optional, and when they are not provided, they will be treated as if they were empty.
params
:
data
:components
(optional): An array of fully-qualified type names of components to fetch.option
(optional): An array of fully-qualified type names of components to fetch optionally.has
(optional): An array of fully-qualified type names of components whose presence will be reported as boolean values.
filter
(optional):with
(optional): An array of fully-qualified type names of components that must be present on entities in order for them to be included in results.without
(optional): An array of fully-qualified type names of components that must not be present on entities in order for them to be included in results.
result
: An array, each of which is an object containing:
entity
: The ID of a query-matching entity.components
: A map associating each type name fromcomponents
/option
to its value on the matching entity if the component is present.has
: A map associating each type name fromhas
to a boolean value indicating whether or not the entity has that component. Ifhas
was empty or omitted, this key will be omitted in the response.
bevy/spawn
Create a new entity with the provided components and return the resulting entity ID.
params
:
components
: A map associating each component's fully-qualified type name with its value.
result
:
entity
: The ID of the newly spawned entity.
bevy/destroy
Despawn the entity with the given ID.
params
:
entity
: The ID of the entity to be despawned.
result
: null.
bevy/remove
Delete one or more components from an entity.
params
:
entity
: The ID of the entity whose components should be removed.components
: An array of fully-qualified type names of components to be removed.
result
: null.
bevy/insert
Insert one or more components into an entity.
params
:
entity
: The ID of the entity to insert components into.components
: A map associating each component's fully-qualified type name with its value.
result
: null.
bevy/reparent
Assign a new parent to one or more entities.
params
:
entities
: An array of entity IDs of entities that will be made children of theparent
.parent
(optional): The entity ID of the parent to which the child entities will be assigned. If excluded, the given entities will be removed from their parents.
result
: null.
bevy/list
List all registered components or all components present on an entity.
When params
is not provided, this lists all registered components. If params
is provided,
this lists only those components present on the provided entity.
params
(optional):
entity
: The ID of the entity whose components will be listed.
result
: An array of fully-qualified type names of components.
bevy/get+watch
Watch the values of one or more components from an entity.
params
:
entity
: The ID of the entity whose components will be fetched.components
: An array of fully-qualified type names of components to fetch.strict
(optional): A flag to enable strict mode which will fail if any one of the components is not present or can not be reflected. Defaults to false.
If strict
is false:
result
:
components
: A map of components added or changed in the last tick associating each type name to its value on the requested entity.removed
: An array of fully-qualified type names of components removed from the entity in the last tick.errors
: A map associating each type name with an error if it was not on the entity or could not be reflected.
If strict
is true:
result
:
components
: A map of components added or changed in the last tick associating each type name to its value on the requested entity.removed
: An array of fully-qualified type names of components removed from the entity in the last tick.
bevy/list+watch
Watch all components present on an entity.
When params
is not provided, this lists all registered components. If params
is provided,
this lists only those components present on the provided entity.
params
:
entity
: The ID of the entity whose components will be listed.
result
:
added
: An array of fully-qualified type names of components added to the entity in the last tick.removed
: An array of fully-qualified type names of components removed from the entity in the last tick.
Custom methods
In addition to the provided methods, the Bevy Remote Protocol can be extended to include custom
methods. This is primarily done during the initialization of RemotePlugin
, although the
methods may also be extended at runtime using the RemoteMethods
resource.
Example
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(
// `default` adds all of the built-in methods, while `with_method` extends them
RemotePlugin::default()
.with_method("super_user/cool_method", path::to::my::cool::handler)
// ... more methods can be added by chaining `with_method`
)
.add_systems(
// ... standard application setup
)
.run();
}
The handler is expected to be a system-convertible function which takes optional JSON parameters
as input and returns a BrpResult
. This means that it should have a type signature which looks
something like this:
fn handler(In(params): In<Option<Value>>, world: &mut World) -> BrpResult {
todo!()
}
Arbitrary system parameters can be used in conjunction with the optional Value
input. The
handler system will always run with exclusive World
access.
Dependencies
~10–23MB
~340K SLoC