Releases: cBournhonesque/lightyear
Release 0.18.0
Release 0.18.0
- Upgrades lightyear to be compatible with the latest versions of bevy, leafwing-input-manager, and edgegap
- Provide support to rollback Resources thanks to @nick-e!
- Various bug fixes
- Paves the way to a deeper integration with @RJ 's bevygap, which is a framework to easily deploy Bevy apps on Edgegap, a multiplayer game server hosting service. In particular @RJ is hosting some of the lightyear examples on https://rj.github.io/lightyear!
What's Changed
- Make the RemoteEntityMap public by @cBournhonesque in #601
- Spaceships example: fix Visual Interpolation bits by @RJ in #599
- Order lightyear plugins w.r.t avian plugins by @cBournhonesque in #602
- Send events as server::events::InputEvent instead of client::events:InputEvent in send_input_directly_to_client_events when using HostServer by @nazgul72 in #606
- Remove unneeded import by @FastestMolasses in #607
- Fix listen-server commands in examples by @qtfkwk in #609
- Fix certificate generate commands in examples by @qtfkwk in #608
- Use the parent's ReplicationGroup when propagating it to the children by @cBournhonesque in #612
- Fix panic when sending too many messages in one packet by @cBournhonesque in #615
- Create server-authoritative 3D physics example by @nick-e in #617
- Support rolling back resources by @nick-e in #622
- Spaceships example: change Without to With in Visual Interp setup by @RJ in #624
- Rollback time resource during rollback by @nick-e in #623
- Add book section describing component prediction criteria by @nick-e in #626
- add unit tests for map-entities related to PreSpawned and Prediction by @cBournhonesque in #632
- Add missing
reflect(Component)
s by @philpax in #636 - Slight adjustments to lobby example. Removing redundancies. First pr by @Sirmadeira in #634
- Separate
Replicated
fromInitialReplicated
by @cBournhonesque in #638 - docs: update resource replication example by @philpax in #640
- docs: basic book contribution info by @philpax in #641
- Update xwt-web-sys requirement from 0.12 to 0.13 by @dependabot in #646
- Update egui_extras requirement from 0.28 to 0.29 by @dependabot in #652
- Simplify wrapping_diff code by @ambiso in #653
- Expose and document
SerializeFns
by @philpax in #654 - Fix 639 by @cBournhonesque in #642
- Update bevy-inspector-egui requirement from 0.25 to 0.26 by @dependabot in #650
- fix: expose ReplicateToServer by @philpax in #657
- Support LWIM 15.1 triple axis input by @msvbg in #661
- Require UserAction bound for InputPlugin by @Aceeri in #665
- Avoid panic when getting EntityCommands in hierarchy by @msvbg in #666
- Disable default leafwing features by @vladbat00 in #670
- Fix compiling in wasm by @vladbat00 in #671
- Fixes #644 by @cBournhonesque in #656
- Update metrics requirement from 0.23 to 0.24 by @dependabot in #675
- Update metrics-tracing-context requirement from 0.15 to 0.17 by @dependabot in #674
- Update governor requirement from 0.6.0 to 0.7.0 by @dependabot in #682
- Adjusting simple box to have map by @Sirmadeira in #678
- Bump codecov/codecov-action from 4 to 5 by @dependabot in #696
- Ignore leafwing test by @nick-e in #695
- Fix tarpaulin compile error by @nick-e in #694
- Fix clippy lint error by @nick-e in #693
- Fixed example floor not being rendered by @sQu1rr in #689
- Update pprof requirement from 0.13.0 to 0.14.0 by @dependabot in #688
- fix: Remove
ring
to fix wasm32 web builds by @cdata in #687 - Update bevy-inspector-egui requirement from 0.26 to 0.27 by @dependabot in #680
- Update metrics-util requirement from 0.15 to 0.18 by @dependabot in #672
- Map entities when rollbacking predicted component by @nick-e in #647
- fix logspam when client disconnects by @cBournhonesque in #698
- Fix pre-prediction example by @cBournhonesque in #703
- fix client replication example by @cBournhonesque in #705
- Update thiserror requirement from 1.0.50 to 2.0.3 by @dependabot in #709
- Update hashbrown requirement from 0.14 to 0.15 by @dependabot in #708
- Update wtransport requirement from =0.1.14 to =0.5.0 by @dependabot in #706
- Compilation fixes by @RJ in #711
- Use a hook on PreSpawnedPlayerObject component to compute missing hashes by @RJ in #710
- Fix pre predicted replication by @cBournhonesque in #713
- package update by @cBournhonesque in #714
- Handle host-server disconnects correctly by @cBournhonesque in #722
- Fix duplicate despawn by @cBournhonesque in #724
- Make states enum reflective for pretty eguis by @Sirmadeira in #723
- upgrade dependencies by @cBournhonesque in #726
- Cargo refactor & examples work by @RJ in #732
- Upgrade to bevy 0.15 by @cBournhonesque in #700
New Contributors
- @FastestMolasses made their first contribution in #607
- @qtfkwk made their first contribution in #609
- @nick-e made their first contribution in #617
- @philpax made their first contribution in #636
- @Sirmadeira made their first contribution in #634
- @ambiso made their first contribution in #653
- @Aceeri made their first contribution in #665
- @vladbat00 made their first contribution in #670
- @sQu1rr made their first contribution in #689
- @cdata made their first contribution in #687
Full Changelog: 0.17.0...0.18.0
Release 0.17.0
Release 0.17.0
Upgrade to leafwing 0.15
Leafwing's newest version brings some improvements to the API, but also fixes an important bug where you couldn't use JustPressed
and JustReleased
in the FixedUpdate
schedule. That was problematic since networking usually requires inputs to be handled in the FixedUpdate
schedule. With this fix it is now much easier to use leafwing-inputs with lightyear.
Added rollback for non-networked components
Previously, only components that were registered in the ComponentRegistry
(meaning that they can be networked) could be affected by rollback. However there's plenty of cases where you might want to rollback non-networked client components: for example rolling back animations or sounds. You can now call app.add_rollback::<C>()
to enable rollback for a non-networked component.
Seamless entity mapping
Previously, entity-mapping was only done on the receiver. (i.e. server spawns E1, sends it to the client who spawns E2 and maintains a mapping from E1 to E2). The mapping wasn't applied when sending messages/updates, which meant that the client had to map the entity manually from E2 to E1 if they wanted to send a message about E2. Entity mapping is now correctly applied in all directions.
Introducing authority transfer
Lightyear
now has the concept of Authority
: which peer (client or server) is simulating the entity and sending replication updates for it? Only one peer can have authority over an entity at any given time.
The server can freely transfer authority over an entity to other peers with the EntityCommands::transfer_authority(new_owner)
command.
The Replicate
bundles automatically provide you with authority over the entity; make sure to remember to update them if you're just adding Replicate
on the server to re-broadcast a client-authoritative entity to other clients.
You can find an example with authority transfer here.
Important fixes
- Guarantee that inputs get synced correctly even in low bandwidth situations. PR
What's Changed
- set the channel priority to INF for ping/pong/inputs by @cBournhonesque in #566
- add MTU config for QUIC by @cBournhonesque in #567
- make InputBuffer::pop public by @RJ in #570
- Update book visual interp page with fixed physics example by @RJ in #571
- Add avian3d utilities by @cBournhonesque in #572
- Upgrade to leafwing 0.15 by @cBournhonesque in #575
- Use
Commands
instead ofWorld
to apply replication updates by @cBournhonesque in #581 - Fixed Local client not sending Connect event in HostServer Mode + Added Test by @zwazel in #578
- Add rollback for non-networked components by @cBournhonesque in #583
- add unit test server send message in host-server mode by @cBournhonesque in #588
- Dependency upgrade (wtransport, xwt, mock_instant) by @cBournhonesque in #589
- Allow seamless entity mapping by @cBournhonesque in #591
- Fix resource replication in host-server mode by @cBournhonesque in #592
- Add authority handling natively by @cBournhonesque in #594
- Excessive iteration over query in simple_box example by @nazgul72 in #596
- Add an example for authority transfer by @cBournhonesque in #597
- Fix Pre-Prediction by @cBournhonesque in #598
- Release 0.17 by @cBournhonesque in #600
New Contributors
Full Changelog: 0.16.4...0.17.0
0.16.4
What's Changed
- Add HostServer test harness by @cBournhonesque in #537
- Let the local-client in host-server mode send a message to the Server by @cBournhonesque in #538
- In host-server mode, send messages from server to the local client by @cBournhonesque in #542
- Emit ConnectEvent correctly on the server in HostServer mode by @cBournhonesque in #543
- Extend prelude with aliases for conflicting items by @cBournhonesque in #544
- propagate replicate for children after the entity is spawned by @cBournhonesque in #548
- fix observer panicking with resource missing by @cBournhonesque in #549
- Add helper functions to map from local world to remote world by @cBournhonesque in #554
- Add linear interpolation for Quat by @cBournhonesque in #555
- Cb/add quat lerp by @cBournhonesque in #556
- Make Lifetime pub by @cBournhonesque in #557
- add option to trigger change detection in visual interpolation by @cBournhonesque in #558
- VisualInterpolation: add option to trigger change detection by @cBournhonesque in #559
- fixes for bevy 0.14.1 by @cBournhonesque in #561
Full Changelog: 0.16.3...0.16.4
Release 0.16.0
Release 0.16.0
Added
Support for Steam P2P
Thanks to a PR from @msvbg , it is now possible to connect to a client acting as host-server by using Steam P2P sockets
The network_send_interval
is now configurable with more precision
Previously you only had access to 2 settings:
- client_send_interval
- server_send_interval
which would control how often the client or the server sent packets to the remote.
Now the send_interval
is configurable:
- per ReplicationGroup (if you want to update an entity less frequently)
- per Channel
This gives you more flexibility to control how often you want to send messages/packets.
For example, you can send replication updates every 100ms, but send client inputs every frame if available. (this setup is particularly useful if you want to predict other player's inputs, a la RocketLeague)
@RJ added an example with remote player prediction
Added better support for handling remote player inputs. Now inputs from other players can easily be forwarded to a given player so that they can run client-prediction on all entities (the local player entity and the remote player entities)
@RJ created an awesome example spaceships
showcasing how to achieve something like this.
It uses input delay, remote player prediction, physics via xpbd, etc.
Updated the InputDelay/Prediction settings [EXPERIMENTAL]
Previously you could only set a fixed amount of input delay (for example 3 ticks).
Now the input delay depends on your network conditions: the settings are identical to what is described here.
Note that this feature is still being tested and might not work if the network conditions are varying.
Miscellaneous
- Some common bevy
RunConditions
are now provided, such asis_started
,is_disconnected
,is_host_server
, etc. - The serialization logic now uses
bincode
instead ofbitcode
. You can provide your own serialization function instead of bincode. - lightyear doesn't use
anyhow
anymore, instead functions now return typed errors such asReplicationError
,SerializationError
, etc. - Extra diagnostics are provided, such as
PingDiagnostics
to track the jitter/RTT, orRollbackDiagnostics
to track the number of rollbacks
Fixed
- lightyear can now work properly when running on wasm even if the tab is put in the background! Thanks to https://github.com/Nul-led/bevy_web_keepalive/tree/main from @Nul-led
- Tons of bugfixes for replication edge cases
- Input handling has been refactored to be more robust and more independent from world replication. In particular inputs can be replicated every tick even if the world replication is less frequent
Breaking changes
- The serialization logic now uses
bincode
instead ofbitcode
- The
Controlled
component now has an extra fieldlifetime
that specified how to despawn the entity if the controlling client is disconnected Visibility
has been renamed toNetworkRelevance
to avoid a name conflict with bevy'sVisibility
- The
DisconnectEvent
now returns aDisconnectReason
explaining why the client was disconnected - The
PredictionConfig
,ReplicationConfig
,SharedConfig
now contain additional fields
What's Changed
- improve examples common by @cBournhonesque in #361
- fix examples by @cBournhonesque in #362
- despawn recursive predicted/interpolated entities by @cBournhonesque in #363
- send updates since we last sent an update, not since we last received an ACK for that entity by @cBournhonesque in #365
- add subscribe_ack to reliable sender, add subscribe_nack to all channels by @cBournhonesque in #366
- add common run conditions by @cBournhonesque in #368
- Update musli requirement from 0.0.121 to 0.0.122 by @dependabot in #367
- Add WebPlugin to keep running in background by @cBournhonesque in #371
- add simple_setup example by @cBournhonesque in #372
- fix action-state for other players by @cBournhonesque in #374
- Draw Confirmed entity outlines in xpbd_physics demo by @RJ in #375
- Rebroadcast remote players inputs to have more precise rollbacks when predicting other players by @cBournhonesque in #376
- add option to display confirmed entities by @cBournhonesque in #377
- collect rollback metrics, write to Diagnostics by @cBournhonesque in #378
- put rollback diagnostics into PredictionDiagnosticsPlugin by @cBournhonesque in #379
- Add PingDiagnosticPlugin by @cBournhonesque in #380
- Add delta compression by @cBournhonesque in #384
- add componentsync mode to Controlled by @cBournhonesque in #392
- fix replication issue with send_tick by @cBournhonesque in #399
- improve config docs by @cBournhonesque in #400
- Add user-provided hook to accept/reject connections by @cBournhonesque in #401
- switch to bevy_keepalive by @cBournhonesque in #403
- Add extra tests/docs for delta-compression by @cBournhonesque in #404
- Fix delta compression by @cBournhonesque in #406
- fix by @cBournhonesque in #409
- fix example by @cBournhonesque in #411
- make ClientConnection.client pub by @cBournhonesque in #412
- switch benchmark backend to criterion by @cBournhonesque in #413
- Support steam p2p sockets by @msvbg in #346
- fix remote inputs entity mapping by @cBournhonesque in #414
- Return DisconnectReason in the DisconnectEvent for clients by @cBournhonesque in #416
- remove None state and instead init NetworkingState without entering OnDisconnect by @cBournhonesque in #417
- update benchmarks: separate send/receive by @cBournhonesque in #420
- add trace feature with lots of trace instrumentation by @cBournhonesque in #422
- add channel bandwidth stats by @cBournhonesque in #424
- Rewrite packet builder by @cBournhonesque in #428
- Few QOL changes by @cBournhonesque in #429
- Replicate existing entities from client->server when client reconnects to a server by @cBournhonesque in #431
- add perf tracing logs by @cBournhonesque in #432
- add lz4 by @cBournhonesque in #433
- Remove anyhow, use thiserror by @cBournhonesque in #434
- Remove unused imports by @cBournhonesque in #438
- Fix docs by @cBournhonesque in #439
- cleanup unused deps by @cBournhonesque in #440
- Update criterion requirement from 0.3 to 0.5 by @dependabot in #442
- Update metrics requirement from 0.22 to 0.23 by @dependabot in #441
- Update tokio-tungstenite requirement from 0.21.0 to 0.23.0 by @dependabot in #445
- Remove unused imports leafwing by @cBournhonesque in #447
- Improve replication logic by @cBournhonesque in #446
- apply visual interpolation before transform propagate by @cBournhonesque in #451
- Removed bitcode by @cBournhonesque in #452
- Return an error message in case a message is too big to be fragmented by @cBournhonesque in #454
- Fix build packet when we cannot write the channel_id by @cBournhonesque in #458
- Re-use allocations during write by @cBournhonesque in #459
- flag to enable sending messages bigger than 300MB by @cBournhonesque in #460
- type-erased the replication systems by @cBournhonesque in #461
- add tools to profile with flamegraph by @cBournhonesque in #462
- enab...
Release 0.15.0
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 entitySyncTarget
: which clients should predict/interpolate the entityVisibilityMode
: do we use interest management or notControlledBy
: 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 notReplicationGroup
: 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 allReplicateOnce<C>
: the component's insertion/removal are replicated, but no the updatesOverrideTargetComponent<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 withadd_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 theNetworkingState
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 implementPartialEq
- Updated
RoomId
to be a u64
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()
Release 0.13.0
Release 0.13.0
Added
Added Steam transport
You can now use Steam sockets as a networking Transport layer!
Note that the server can run multiple transports in parallel, so you can have cross-play between steam and non-steam users!
Running lightyear in "Host Server" mode
In the previous release, I updated all the examples to run in "listen server" mode (the server and client are running in the same machine). This was done by starting a client bevy app and a server bevy app in different threads, and sending messages between them via channels.
This works fine but has some disadvantages:
- extra CPU overhead from running 2 bevy apps and 2 Worlds
- complexity of having 2 different timelines
- inputs would be slightly delayed (by 1-2 frames)
In this release, you can now run lightyear
in "host server" mode. In this mode, you can create a single bevy app where the server also acts as a client. There are no packets sent between client and server because the client and server plugins are running in the same bevy World
!
Updated
- Added an object pool to re-use memory allocation of ReadBuffers used to deserialize packets
Fixed
- Fixed a bug with interest management where an entity would get despawned when changing rooms
Breaking changes
- Updated
ClientId
: instead of au64
it is now anenum
that depends on the type of Transport used by the client - Removed the
GlobalMetadata
structs; the client_id is directly accessible viaconnection.id()
- Pre-Predicted entities are now spawned using the
PrePredicted
component instead ofShouldBePredicted
- Updated
ConnectEvent
andDisconnectedEvent
on the client side to also include theClientId
of the client withevent.client_id()
- Inputs are buffered on the client-side using an
InputManager
resource, not theClientConnection
anymore
Planned Future work
- Add steam p2p connections
- Enable runtime configuration of the transports: for example let a different user become the 'host' at runtime
Release 0.12.0
Release 0.12.0
Added
Server can support multiple Transports simultaneously
A lightyear
server can now listen simultaneously on different types of Transports: WebSocket, WebTransport, UDP, local channels, etc.
It requires almost no code change: instead of providing a single TransportConfig
when building the server, you can now provide a Vec<TransportConfig>
and the server will be listening on each config simultaneously!
All examples have been updated to showcase this behavior: the server listens for WebTransport connections on port 5000, UDP on port 5001 and WebSocket on port 5002!
This is very exciting for two main reasons:
- this is will allow cross-play between different connection configurations. I have plans to integrate with Steam and EOS (Epic Online Services). With this feature, players connected via Steam could also play with players connected via UDP directly to a dedicated server!
- this enables running
lightyear
in "Listen Server" mode!
Running lightyear in "Listen Server" mode
"Listen Server" means that a player acts as both the server and the client. (the server will run on a separate thread on the client's machine). This could be useful for p2p games, or for some single-player game architectures where the client talks to a local server.
With the above change, it is now easy to run lightyear
as a Listen Server! The server and client apps run on different threads and use local channels to communicate with 0 latency, and other clients can still connect to the host.
All examples have been updated to be able to run like this with the command: cargo run -- listen-server
Updated
- Updated all examples to use a separate
settings.ron
file to specify the networking configuration. (the previous cli-based approach wasn't flexibly enough when using multiple transports for a given server)
Future work
My next priority will be to add Steam
as a connection option.
Release 0.11.0
Release 0.11.0
Small release with mostly internal changes.
Fixed
Internal refactor by regrouping logic into bevy plugins
Moved some of the logic for the client and server into 3 new internal plugins:
- NetworkingPlugin: contains the main
receive
andsend
systems that receive and send raw packets - ReplicationPlugin: contains the logic to perform World replication
- EventsPlugin: write bevy
Events
whenever a networking event happens (MessageReceived, InputReceived, ConnectionReceived, etc.)
The main server and client plugins are now relatively short and just consist in importing a few other plugins.
Fixed a bug that was causing the docs to not be generated
The vendored bitcode crate could not be compiled in nightly anymore, this has been fixed.
Added
remove_replicate
command
Added an EntityCommand
called remove_replicate
that lets you stop replicating an entity, and guarantees that any event related to that entity won't be replicated, including Despawns.
For example you can call
entity_commands.remove_replicate();
entity_commands.despawn()
on the server, and the entity's despawn won't be replicated to clients. (This could be useful if you want to play a despawn animation on the client)
Breaking changes
- The
SharedConfig
struct does not have aenable_replication
field anymore. This field was previously unused, so I am removing it for clarity. In the future, I will probably provide the ability to disable replication by turning theClient
andServer
plugins intoPluginGroup
s
Release 0.10.0
Support for bevy 0.13
Lightyear is updated for bevy 0.13!
There are still a couple of issues (a leafwing-input related problem on the bullet_prespawn example, and waiting for bevy_inspector_egui
to be updated for bevy 0.13) which will be fixed in a future minor release.
Hierarchy replication
Lightyear now supports replicating bevy hierarchies (i.e. replicating the Parent
/Children
components).
You can just set replicate.replicate_hierarchy = true
on the Replicate
component of the root entity of your hierarchy; all entities in the hierarchy will be replicated in a single ReplicationGroup
(meaning that it is guaranteed that updates for all these entities will be received by the remote on the same tick).
Scheduling quality-of-life
Lightyear now makes use of the newly added FixedFirst
, FixedPreUpdate
, FixedPostUpdate
schedules, which means that you can now add all your logic in the FixedUpdate
schedule without worrying about ordering with other lightyear
systems. In particular, the FixedUpdateSet::Main
SystemSet
has been removed.
Visual interpolation
Most networked data is meant to be updated in the FixedUpdate
schedule so that they don't depend on framerate.
This can cause visual artifacts (jitter, etc.) because you could have multiple frames in a row without the FixedUpdate
schedule running, or the FixedUpdate
schedule could run multiple times in a single frame.
I've added a plugin VisualInterpolationPlugin
that smoothly interpolates the value of a component between the FixedUpdate values. This adds 1 tick (FixedUpdate timestep) of visual delay, which should be negligible in most cases.
You can read more about it in the book.
Fixed
- Interpolation is now more precise, as it uses the
Time<Fixed>::overstep_fraction
to compute the interpolation percentage
Migration
- The
FixedUpdateSet::Main
SystemSet
has been removed, you can now just add your systems to theFixedUpdate
schedule - The
MapEntities
trait has been replaced with theLightyearMapEntities
trait - The
input_buffer
systems have to be added to theFixedPreUpdate
schedule. (this limitation is only present for native inputs, not for leafwing_inputs) - The
LogConfig
setting inSharedConfig
has been removed. I will provide a customtracing::subscriber
Layer
to add additional metrics/logging