9 releases (breaking)
0.7.0 | Sep 4, 2024 |
---|---|
0.6.0 | Jul 4, 2024 |
0.5.0 | May 26, 2024 |
0.4.0 | May 11, 2024 |
0.0.2 | Nov 14, 2023 |
#687 in Game dev
12KB
91 lines
bevy_bundlication
Network replication for bevy based on a bundle pattern. Replication group rules for bevy_replicon using a bundle-like API.
Goals
- Simplify the definition of replication groups
- Simplify bandwidth optimization
Getting started
bevy_bundlication works with a pattern similar to a Bundle from bevy. Anything matching the bundle gets networked.
Each field needs to implement NetworkedComponent
, this can be done manually or trough a blanket impl on types that have Component
, Serialze
and Deserialize
.
For types where the blanket impl causes conflicts, the #[bundlication(as = Wrapper)]
attribute can be used where Wrapper
is a type that impletements NetworkedWrapper<YourType>
.
Bundles can be registered to bevy_replicon using replicate_group::<Bundle>()
.
use bevy::prelude::*;
use bevy_replicon::prelude::*;
#[derive(NetworkedBundle)]
pub struct PlayerPositionBundle {
// The content of this field doesn't get sent, and it will be received as the default value,
// it therefor requires neither Serialize/Deserialize nor NetworkedComponent
#[bundlication(no_send)]
pub player: Player,
// This component is sent and spawned as is
pub speed: Speed,
// We replicate Transform, but it is serialized/deserialized using the logic of JustTranslation
#[bundlication(as = JustTranslation)]
pub translation: Transform,
// If we also use this as a bundle and have fields we don't want replicon to consider, we can
// add the skip attribute
#[bundlication(skip)]
pub skipped: GlobalTransform,
}
pub struct MovementPlugin;
impl Plugin for MovementPlugin {
fn build(&self, app: &mut App) {
// To replicate the bundle, we register our bundle to bevy_replicon
app.replicate_group::<PlayerPositionBundle>();
}
}
use bevy_bundlication::prelude::*;
use serde::{Serialize, Deserialize};
// We need Default on Player because we use the no_send attribute
#[derive(Component, Default)]
pub struct Player(u128);
// Speed derives all required traits for the NetworkedBundle blanket impl
#[derive(Component, Serialize, Deserialize)]
pub struct Speed(f32);
// We define a type to network a type we don't own in a different way than its default behavior.
// This can also be used to network components without Serialize/Deserialize
// In this case we only network the translation part of Transform
#[derive(Serialize, Deserialize)]
pub struct JustTranslation(Vec3);
impl NetworkedWrapper<Transform> for JustTranslation {
fn write_data(from: &Transform, w: impl std::io::Write, _: &SerializeCtx) -> BincodeResult<()> {
serialize(w, &from.translation)?;
Ok(())
}
fn read_new(r: impl std::io::Read, _: &mut DeserializeCtx) -> BincodeResult<Transform> {
let translation: Vec3 = deserialize(r)?;
Ok(Transform::from_translation(translation))
}
}
License
All code in this repository is dual-licensed under either:
- MIT License (LICENSE-MIT or http://opensource.org/licenses/MIT)
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
at your option.
Dependencies
~42–79MB
~1.5M SLoC