Skip to content

Commit

Permalink
add unit tests for map-entities related to PreSpawned and Prediction
Browse files Browse the repository at this point in the history
  • Loading branch information
cBournhonesque committed Sep 8, 2024
1 parent e9622df commit 12db2f1
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 2 deletions.
2 changes: 1 addition & 1 deletion examples/common/src/shared.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::time::Duration;

pub const FIXED_TIMESTEP_HZ: f64 = 64.0;

pub const REPLICATION_INTERVAL: Duration = Duration::from_millis(100);
pub const REPLICATION_INTERVAL: Duration = Duration::from_millis(1000);

/// The [`SharedConfig`] must be shared between the `ClientConfig` and `ServerConfig`
pub fn shared_config(mode: Mode) -> SharedConfig {
Expand Down
39 changes: 38 additions & 1 deletion lightyear/src/client/prediction/predicted_history.rs
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ mod tests {
/// 2. Add the history for ComponentSyncMode::Full that was added to the predicted entity
/// 3. Don't add the history for ComponentSyncMode::Simple
/// 4. Don't add the history for ComponentSyncMode::Once
// TODO: check map entities
/// 5. For components that have MapEntities, the component gets mapped from Confirmed to Predicted
#[test]
fn test_add_component_history() {
let mut stepper = BevyStepper::default();
Expand All @@ -416,6 +416,7 @@ mod tests {
confirmed_entity: Some(confirmed),
})
.id();

stepper
.client_app
.world_mut()
Expand Down Expand Up @@ -537,6 +538,42 @@ mod tests {
&ComponentSyncModeOnce(1.0),
"Expected component to be added to predicted entity"
);

// 5. Component with MapEntities get mapped from Confirmed to Predicted
let tick = stepper.client_tick();
stepper
.client_app
.world_mut()
.resource_mut::<PredictionManager>()
.predicted_entity_map
.get_mut()
.confirmed_to_predicted
.insert(confirmed, predicted);
stepper
.client_app
.world_mut()
.entity_mut(confirmed)
.insert(ComponentMapEntities(confirmed));
stepper.frame_step();
assert!(
stepper
.client_app
.world()
.entity(predicted)
.get::<PredictionHistory<ComponentMapEntities>>()
.is_none(),
"Expected component value to not be added to prediction history for ComponentSyncMode::Simple"
);
assert_eq!(
stepper
.client_app
.world()
.entity(predicted)
.get::<ComponentMapEntities>()
.expect("Expected component to be added to predicted entity"),
&ComponentMapEntities(predicted),
"Expected component to be added to predicted entity with entity mapping"
);
}

/// Test that the history gets updated correctly
Expand Down
95 changes: 95 additions & 0 deletions lightyear/src/client/prediction/prespawn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,10 @@ impl PreSpawnedPlayerObject {
mod tests {
use crate::client::prediction::predicted_history::{ComponentState, PredictionHistory};
use crate::client::prediction::resource::PredictionManager;
use bevy::prelude::{default, Entity, Resource, With};

use crate::prelude::client::Confirmed;
use crate::prelude::server::{Replicate, SyncTarget};
use crate::prelude::*;
use crate::tests::protocol::*;
use crate::tests::stepper::BevyStepper;
Expand Down Expand Up @@ -514,4 +517,96 @@ mod tests {
})
);
}

#[derive(Resource)]
struct ShouldPrespawn(bool);

/// Client and server run the same system to prespawn an entity
/// The pre-spawn somehow fails on the client.
/// The server should spawn the entity, it gets spawned to the client.
/// The client spawns a Predicted version of the entity.
#[test]
fn test_prespawn_client_missing() {
let mut stepper = BevyStepper::default();

let server_entity = stepper
.server_app
.world_mut()
.spawn(Replicate {
sync: SyncTarget {
prediction: NetworkTarget::All,
..default()
},
..default()
})
.id();
stepper.frame_step();
stepper.frame_step();
let (client_confirmed, confirmed) = stepper
.client_app
.world_mut()
.query_filtered::<(Entity, &Confirmed), With<Replicated>>()
.single(stepper.client_app.world());
let client_predicted = confirmed.predicted.unwrap();

// run prespawned entity on server.
// for some reason the entity is not spawned on the client
let server_entity_2 = stepper
.server_app
.world_mut()
.spawn((
Replicate {
sync: SyncTarget {
prediction: NetworkTarget::All,
..default()
},
..default()
},
PreSpawnedPlayerObject::default(),
ComponentMapEntities(server_entity),
))
.id();
stepper.frame_step();
stepper.frame_step();

// We couldn't match the entity based on hash
// So we should have just spawned a predicted entity
let client_confirmed_2 = stepper
.client_app
.world()
.resource::<client::ConnectionManager>()
.replication_receiver
.remote_entity_map
.get_local(server_entity_2)
.expect("entity was not replicated to client");
// it should have a predicted entity
let client_predicted_2 = stepper
.client_app
.world()
.get::<Confirmed>(client_confirmed_2)
.unwrap()
.predicted
.unwrap();

// the MapEntities component should have been mapped to confirmed
assert_eq!(
stepper
.client_app
.world()
.get::<ComponentMapEntities>(client_confirmed_2)
.unwrap()
.0,
client_confirmed
);
// the MapEntities component on the predicted entity should have been mapped to predicted
assert_eq!(
stepper
.client_app
.world()
.get::<ComponentMapEntities>(client_predicted_2)
.unwrap()
.0,
client_predicted
);
}
}

0 comments on commit 12db2f1

Please sign in to comment.