Release 0.14.0
Release 0.14.0
Added
Refactored the Protocol
lightyear
used to require a Protocol
struct which contained 2 enums MessageProtocol
and ComponentProtocol
that held the list of messages that could be sent over the network.
Now you can split up a protocol into multiple pieces, each piece can be registered directly on the App
:
app.add_message::<Message1>(ChannelDirection::Bidirectional);
app.add_plugins(InputPlugin::<Inputs>::default());
app.register_component::<PlayerPosition>(ChannelDirection::ServerToClient)
.add_prediction::<PlayerPosition>(ComponentSyncMode::Full)
.add_interpolation::<PlayerPosition>(ComponentSyncMode::Full)
.add_linear_interpolation_fn::<PlayerPosition>();
app.add_channel::<Channel1>(ChannelSettings {
mode: ChannelMode::OrderedReliable(ReliableSettings::default()),
..default()
});
This approach provides more flexibility, since the Protocol can now be defined in various separate plugins; it also removes a lot of procedural macro magic that was hard to maintain.
Currently the only requirement is that the protocol registration must happen after the ClientPlugin
or the ServerPlugin
have been added.
Network configuration is modifiable at runtime
Previously, your network configuration would be set in stone after adding the ClientPlugin
and ServerPlugin
.
Now, you can freely update the configuration (by updating the ClientConfig
and ServerConfig
resources) at any time, and the configuration change will take effect on the next connection attempt.
I also introduce the NetworkingState
state to track the status of the client or server (Connecting, Connected, Disconnected).
This means that a machine can dynamically become a client or a server depending on the configuration!
Here is an example where clients can choose at runtime whether to host the game by acting as 'host-servers', or just join the game as clients.
Automatic Resource replication
You can now easily replicate resources!
There are 2 steps:
- Define the resource in your protocol:
app.register_resource::<R>(ChannelDirection::ServerToClient);
- Use commands to start/stop the replication:
commands.replicate_resource::<R>(target)
starts the replicationcommands.pause_replicate_resource::<R>()
pauses the replication (without removing the resource)
And every changes to your resource will now be replicated!
Updated
Automatic cleanup on client disconnection
When a client gets disconnected, we now automatically cleanup all entities and resources that had been spawned on the client via replication.
In the future I have plans to make this behavior more configurable (we might want some entities to remain even when disconnected), but I chose to enable this currently for simplicity.
Separating the prediction and interpolation mode
Previously, there was only one configuration shared between Prediction and Interpolation. But there are actually situations where one would want to only enable Prediction and not Interpolation, or vice-versa.
For example, you might need to turn on Prediction on a physics component like AngularVelocity
, but not turn on Interpolation since AngularVelocity
doesn't have any visual impact on the component.
You can now independently specify the prediction behavior and the interpolation behavior.
Breaking changes
- The
ClientPlugin
is now directly created from theClientConfig
, same forServerPlugin
- You now have to define a shared protocol by registering the protocol on the
App
after theClientPlugin
andServerPlugin
have been registered. - You now update the connection status via
Commands
:commands.connect_client()
commands.disconnect_client()
commands.start_server()
commands.stop_server()