Skip to content

Release 0.15.0

Compare
Choose a tag to compare
@cBournhonesque cBournhonesque released this 15 May 15:56
· 391 commits to main since this release

Release 0.15.0

Added

Refactored the Replicate component

Replicate used to be a Component describing all facets of how an entity should be replicated to a remote peer.
It is now a bundle composed of multiple smaller components:

  • Server to Client:
    • ReplicationTarget: which clients should receive the entity
    • SyncTarget: which clients should predict/interpolate the entity
    • VisibilityMode: do we use interest management or not
    • ControlledBy: which clients are the 'owners' of the entity?
  • Client to Server:
    • ReplicateToServer: marker component to initiate the replication to the server
  • Shared
    • Replicating: marker component indicating that the entity should be actively replicated. If this component is removed, the replication is paused.
    • ReplicateHierarchy: whether we replicate the children of this entity or not
    • ReplicationGroup: how do we group multiple entities into a single message

On the receiver side, all replicated entities will have the Replicated component.
For client->server replication, you can use Replicated::client_id() to identify the client that replicated this entity.

You can also customize the replication of a specific component via the components:

  • DisabledComponent<C>: the component is not replicated at all
  • ReplicateOnce<C>: the component's insertion/removal are replicated, but no the updates
  • OverrideTargetComponent<C>: override the replication target (the list of receiving clients) for this component

Entity ownership

It can be useful for the server to be aware of which client is 'owning' an entity.
For example, so that you can despawn all of a client's entities when the client disconnects.

You can add the ControlledBy component on an entity in the server World to specify which clients 'own' the entity.
When this entity gets replicated, the owning clients will have the Controlled marker component added.
This can be useful for the client to identify the entities it should apply client-side prediction on. (usually client-prediction is used only on the entities owned by the client)

When a client disconnects, lightyear automatically despawns the entities owned by that client. (this will be more configurable in the future).

How can you access this per-client metadata on the server? We now spawn one entity per client on the server, which can be used to hold metadata about that client. The entity can be accessed via ConnectionManager::client_entity(client_id).
For now, the only metadata has ControlledEntities component which holds a list of all the entities controlled by a client; feel free to add more if you need!

Replication logic can be updated at runtime

Before, you could only add the Replicate component once; it was not allowed to update the Replicate component after the entity was first replicated.
Now you can freely update the replication components to make changes to the replication logic:

  • modify the ReplicationTarget component to spawn an entity on new clients, or despawn the entity on some clients
  • update the VisibilityMode component to enable interest management
  • update ReplicateHierarchy to start replicating the children of an entity
  • etc.

Client and server plugins are now plugin groups

The ClientPlugin and ServerPlugin plugins have been replaced with the ClientPlugins and ServerPlugins plugin groups.
This means that you can freely override or disable any of the internal plugins that compose the plugin groups.

All internal plugins are enabled by default, but feel free to disable any that you don't need. For example you could disable the VisibilityPlugin on the server if you don't need interest management, the ClientDiagnosticsPlugin if you don't need to compute statistics on the connection, or ClientReplicationSendPlugin if you don't need to replicate entities from the client to the server.

Immediate mode visibility

lightyear used "rooms" to perform interest management. Clients and entities could join rooms, and an entity would only be replicated to a client if they shared a room.
This semi-static method is convenient in most cases, but sometimes you need a more immediate API to handle visibility.
You can now use the VisibilityManager to directly specify the visibility of a (client, entity) pair:

  • VisibilityManager::gain_visibility
  • VisibilityManager::lose_visibility

Miscellaneous

  • You can now override the function that checks if a rollback is necessary for a given component. It defaults to PartialEq::ne (rollback if the values are different) but you can override it with add_should_rollback_fn(custom_fn)
  • Added an example to showcase how to securely send a ConnectToken to a client so that it can initiate a connection.
  • Added the [zstd] feature to run zstd-compression on all packets.

Fixed

  • ChangeDetection is not triggered anymore if a component gets replicated to an entity but is equal to the existing value of the component on that entity.
  • The NetworkingState is now correctly updated when the io gets disconnected (for example via a timeout). The io tasks now get disconnected if the NetworkingState is set to disconnected (for example if the client requests disconnection).
  • Support bevy_xpbd with f64 precision
  • Improved parallelization of prediction and interpolation systems
  • Improved protocol ergonomics: you don't need to specify the component on every function anymore
app.register_component::<PlayerId>(ChannelDirection::ServerToClient)
     .add_prediction(ComponentSyncMode::Once)
     .add_interpolation(ComponentSyncMode::Once);

Breaking changes

  • Changes mentioned above for Replicate, ClientPlugin, ServerPlugin
  • Components in the ComponentRegistry must now implement PartialEq
  • Updated RoomId to be a u64