Skip to content
This repository has been archived by the owner on Nov 10, 2024. It is now read-only.

Commit

Permalink
renaming and tidying
Browse files Browse the repository at this point in the history
  • Loading branch information
RJ committed Oct 20, 2023
1 parent 2a2c0e4 commit 95f9fdd
Show file tree
Hide file tree
Showing 10 changed files with 59 additions and 100 deletions.
8 changes: 4 additions & 4 deletions NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,9 @@ New custom events are written to the bevy event queue, to be consumed by my game
<td>During rollback, we check if we should exit rollback, having resimulated everything in the requested rollback range.</td>
</tr>
<tr>
<td>CheckIfRollbackNeeded</td>
<td>NotInRollback</td>
<td>not in rb</td>
<td>Check if a newly added ServerSnapshot or ABAF/ICAF means we should rollback</td>
<td>Check if a newly added ServerSnapshot or ABAF/ICAF means we request a rollback</td>
</tr>
<tr>
<td>StartRollback</td>
Expand Down Expand Up @@ -258,7 +258,7 @@ record component births.
</td>
</tr>
<tr>
<td>DuringRollback</td>
<td>InRollback</td>
<td>in rb</td>
<td>
wipe removed component queue, remove components which shouldn't exist at this frame
Expand Down Expand Up @@ -287,7 +287,7 @@ wipe removed component queue, remove components which shouldn't exist at this fr
## How rollbacks happen

Systems that initiate rollbacks write a `RollbackRequest` to an event queue, specifying the frame they
wish to start resimulating from. These are in the `CheckIfRollbackNeeded` set.
wish to start resimulating from. These are in the `NotInRollback` set.

All rollback requests are consolidated, and a `Rollback` resource is written. The `RollbackConsolidationStrategy` from `TimewarpConfig`
determines if the oldest or newest frame from the list of requests is used.
Expand Down
24 changes: 13 additions & 11 deletions src/components.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use crate::{prelude::TimewarpError, FrameBuffer, FrameNumber, TimewarpComponent};
use bevy::prelude::*;

/// entities with NotRollbackable are ignored, even if they have components which
/// entities with NoRollback are ignored, even if they have components which
/// have been registered for rollback.
#[derive(Component)]
pub struct NotRollbackable;
pub struct NoRollback;

/// Added to every entity, for tracking which frame they were last synced to a snapshot
/// Deduct `last_snapshot_frame` from the current frame to determine how many frames this
Expand Down Expand Up @@ -32,6 +32,9 @@ impl TimewarpStatus {

/// Used when you want to insert a component T, but for an older frame.
/// insert this to an entity for an older frame will trigger a rollback.
///
/// Note: this is for timewarp-registered components.
///
/// eg:
/// ```rust,ignore
/// commands.entity(e).insert(InsertComponentAtFrame::<Shield>(shield_comp, past_frame))
Expand All @@ -47,13 +50,18 @@ impl<T: TimewarpComponent> InsertComponentAtFrame<T> {
}
}

/// For assembling a blueprint in the past - testing.
/// When you want to rollback to insert a non-timewarp component at a specific frame, insert this.
///
/// Note: this is for non-timewarp registered components. (ones without ComponentHistory)
///
/// I use this for blueprints. The blueprint assembly function runs during rollback and
/// adds the various timewarp-registered (and other) components to the entity during rollback.
#[derive(Component, Debug)]
pub struct AssembleBlueprintAtFrame<T: TimewarpComponent> {
pub struct AssembleBlueprintAtFrame<T: Component> {
pub component: T,
pub frame: FrameNumber,
}
impl<T: TimewarpComponent> AssembleBlueprintAtFrame<T> {
impl<T: Component> AssembleBlueprintAtFrame<T> {
pub fn new(frame: FrameNumber, component: T) -> Self {
Self { component, frame }
}
Expand All @@ -62,12 +70,6 @@ impl<T: TimewarpComponent> AssembleBlueprintAtFrame<T> {
}
}

/// presence on an entity during rollback means there will be no older values available,
/// since the entity is being assembled from blueprint this frame.
/// so we load in component values matching the origin frame (not one frame prior, like usual)
#[derive(Component, Debug, Clone)]
pub struct OriginFrame(pub FrameNumber);

/// entities with components that were registered with error correction logging will receive
/// one of these components, updated with before/after values when a simulation correction
/// resulting from a rollback and resimulate causes a snap.
Expand Down
45 changes: 11 additions & 34 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,47 +205,25 @@ pub mod prelude {
use bevy::prelude::*;
use prelude::*;

/// bevy_timewarp's pre-game systems run in these sets, which get configured to run
/// before the main game logic (the set for which is provided in the plugin setup)
#[derive(SystemSet, Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum TimewarpPrefixSet {
First,

InRollback,

/// Doesn't run in rollback
///
/// Contains:
/// * detect_misuse_of_icaf<T>
/// * trigger_rollback_when_snapshot_added<T>
/// * trigger_rollback_when_icaf_added<T>
/// then:
/// * consolidate_rollback_requests
/// then:
/// * apply_deferred (so the Rollback res might exist, Ch/SS added.)
CheckIfRollbackNeeded,

/// Runs only if the Rollback resource was just Added<>
///
/// * rollback_initiated
/// then:
/// * rollback_component<T>
/// * rollback_component<T>
/// ...
NotInRollback,
StartRollback,

/// Runs always, unpacks non-timewarp components at this frame.
/// Current used for blueprints.
UnwrapBlueprints,

Last,
}

/// bevy_timewarp's systems run in these three sets, which get configured to run
/// bevy_timewarp's post-game systems run in these sets, which get configured to run
/// after the main game logic (the set for which is provided in the plugin setup)
#[derive(SystemSet, Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum TimewarpPostfixSet {
First,
Components,
DuringRollback,
InRollback,
Last,
}

Expand Down Expand Up @@ -276,8 +254,7 @@ impl Plugin for TimewarpPlugin {
TimewarpPrefixSet::First,
TimewarpPrefixSet::InRollback.run_if(resource_exists::<Rollback>()),
// -- apply_deferred -- //
TimewarpPrefixSet::CheckIfRollbackNeeded
.run_if(not(resource_exists::<Rollback>())),
TimewarpPrefixSet::NotInRollback.run_if(not(resource_exists::<Rollback>())),
// -- apply_deferred -- //
TimewarpPrefixSet::StartRollback.run_if(resource_added::<Rollback>()),
TimewarpPrefixSet::UnwrapBlueprints,
Expand All @@ -293,12 +270,12 @@ impl Plugin for TimewarpPlugin {
self.config.schedule(),
apply_deferred
.after(TimewarpPrefixSet::InRollback)
.before(TimewarpPrefixSet::CheckIfRollbackNeeded),
.before(TimewarpPrefixSet::NotInRollback),
)
.add_systems(
self.config.schedule(),
apply_deferred
.after(TimewarpPrefixSet::CheckIfRollbackNeeded)
.after(TimewarpPrefixSet::NotInRollback)
.before(TimewarpPrefixSet::StartRollback),
)
//
Expand Down Expand Up @@ -358,11 +335,11 @@ impl Plugin for TimewarpPlugin {
.add_systems(
self.config.schedule(),
(
systems::prefix_check_if_rollback_needed::consolidate_rollback_requests,
systems::prefix_not_in_rollback::consolidate_rollback_requests,
apply_deferred,
)
.chain()
.in_set(TimewarpPrefixSet::CheckIfRollbackNeeded),
.in_set(TimewarpPrefixSet::NotInRollback),
)
.add_systems(
self.config.schedule(),
Expand All @@ -381,7 +358,7 @@ impl Plugin for TimewarpPlugin {
(
TimewarpPostfixSet::First,
TimewarpPostfixSet::Components,
TimewarpPostfixSet::DuringRollback.run_if(resource_exists::<Rollback>()),
TimewarpPostfixSet::InRollback.run_if(resource_exists::<Rollback>()),
TimewarpPostfixSet::Last,
)
.chain(),
Expand Down
4 changes: 2 additions & 2 deletions src/systems.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ use crate::prelude::*;
use bevy::prelude::*;

pub(crate) mod postfix_components;
pub(crate) mod postfix_during_rollback;
pub(crate) mod postfix_in_rollback;
pub(crate) mod postfix_last;

pub(crate) mod prefix_blueprints;
pub(crate) mod prefix_check_if_rollback_needed;
pub(crate) mod prefix_first;
pub(crate) mod prefix_in_rollback;
pub(crate) mod prefix_not_in_rollback;
pub(crate) mod prefix_start_rollback;

/// footgun protection - in case your clock ticking fn isn't running properly, this avoids
Expand Down
28 changes: 12 additions & 16 deletions src/systems/postfix_components.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ fn debug_type<T: TimewarpComponent>() -> bool {
pub(crate) fn remove_components_from_despawning_entities<T: TimewarpComponent>(
mut q: Query<
(Entity, &mut ComponentHistory<T>, &DespawnMarker),
(Added<DespawnMarker>, With<T>),
(Added<DespawnMarker>, With<T>, Without<NoRollback>),
>,
mut commands: Commands,
game_clock: Res<GameClock>,
Expand All @@ -36,12 +36,15 @@ pub(crate) fn remove_components_from_despawning_entities<T: TimewarpComponent>(

/// Write current value of component to the ComponentHistory buffer for this frame
pub(crate) fn record_component_history<T: TimewarpComponent>(
mut q: Query<(
Entity,
&T,
&mut ComponentHistory<T>,
Option<&mut TimewarpCorrection<T>>,
)>,
mut q: Query<
(
Entity,
&T,
&mut ComponentHistory<T>,
Option<&mut TimewarpCorrection<T>>,
),
Without<NoRollback>,
>,
game_clock: Res<GameClock>,
mut commands: Commands,
opt_rb: Option<Res<Rollback>>,
Expand Down Expand Up @@ -96,14 +99,7 @@ pub(crate) fn record_component_history<T: TimewarpComponent>(
/// add the ComponentHistory<T> and ServerSnapshot<T> whenever an entity gets the T component.
/// NB: you must have called `app.register_rollback::<T>()` for this to work.
pub(crate) fn add_timewarp_components<T: TimewarpComponent, const CORRECTION_LOGGING: bool>(
q: Query<
(Entity, &T),
(
Added<T>,
Without<NotRollbackable>,
Without<ComponentHistory<T>>,
),
>,
q: Query<(Entity, &T), (Added<T>, Without<NoRollback>, Without<ComponentHistory<T>>)>,
mut commands: Commands,
game_clock: Res<GameClock>,
timewarp_config: Res<TimewarpConfig>,
Expand Down Expand Up @@ -142,7 +138,7 @@ pub(crate) fn add_timewarp_components<T: TimewarpComponent, const CORRECTION_LOG
/// only for comp removed ... then readded birth
/// TODO not sure if we need this birth tracking at all?
pub(crate) fn record_component_birth<T: TimewarpComponent>(
mut q: Query<(Entity, &mut ComponentHistory<T>), (Added<T>, Without<NotRollbackable>)>,
mut q: Query<(Entity, &mut ComponentHistory<T>), (Added<T>, Without<NoRollback>)>,
game_clock: Res<GameClock>,
rb: Option<Res<Rollback>>,
) {
Expand Down
File renamed without changes.
3 changes: 2 additions & 1 deletion src/systems/prefix_first.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use crate::prelude::*;
use bevy::prelude::*;

/// for when we add the ComponentHistory via a trait on EntityMut which doesn't know the error reporting setting
pub(crate) fn enable_error_correction_for_new_component_histories<T: TimewarpComponent>(
mut q: Query<&mut ComponentHistory<T>, Added<ServerSnapshot<T>>>,
) {
Expand All @@ -19,7 +20,7 @@ pub(crate) fn enable_error_correction_for_new_component_histories<T: TimewarpCom
/// when components are removed, we log the death frame
pub(crate) fn record_component_death<T: TimewarpComponent>(
mut removed: RemovedComponents<T>,
mut q: Query<&mut ComponentHistory<T>>,
mut q: Query<&mut ComponentHistory<T>, Without<NoRollback>>,
game_clock: Res<GameClock>,
) {
for entity in &mut removed {
Expand Down
19 changes: 3 additions & 16 deletions src/systems/prefix_start_rollback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,25 +77,12 @@ enum Provenance {
pub(crate) fn rollback_component<T: TimewarpComponent>(
rb: Res<Rollback>,
// T is None in case where component removed but ComponentHistory persists
mut q: Query<
(
Entity,
Option<&mut T>,
&ComponentHistory<T>,
Option<&OriginFrame>,
),
Without<NotRollbackable>,
>,
mut q: Query<(Entity, Option<&mut T>, &ComponentHistory<T>), Without<NoRollback>>,
mut commands: Commands,
game_clock: Res<GameClock>,
) {
for (entity, opt_comp, comp_hist, opt_originframe) in q.iter_mut() {
let rollback_frame = if let Some(OriginFrame(of)) = opt_originframe {
game_clock.frame().max(*of)
} else {
**game_clock
};

for (entity, opt_comp, comp_hist) in q.iter_mut() {
let rollback_frame = **game_clock;
let end_frame = rb.range.end;

let prefix = if rollback_frame != **game_clock {
Expand Down
28 changes: 12 additions & 16 deletions src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ impl TimewarpTraits for App {
);
self.add_systems(
schedule.clone(),
prefix_check_if_rollback_needed::request_rollback_for_blueprints::<T>
.before(prefix_check_if_rollback_needed::consolidate_rollback_requests)
.in_set(TimewarpPrefixSet::CheckIfRollbackNeeded),
prefix_not_in_rollback::request_rollback_for_blueprints::<T>
.before(prefix_not_in_rollback::consolidate_rollback_requests)
.in_set(TimewarpPrefixSet::NotInRollback),
)
}
fn register_rollback_with_options<T: TimewarpComponent, const CORRECTION_LOGGING: bool>(
Expand All @@ -84,8 +84,7 @@ impl TimewarpTraits for App {
}
self.add_systems(
schedule.clone(), // TODO RJRJR move to _first file?
prefix_check_if_rollback_needed::detect_misuse_of_icaf::<T>
.in_set(TimewarpPrefixSet::First),
prefix_not_in_rollback::detect_misuse_of_icaf::<T>.in_set(TimewarpPrefixSet::First),
);
self.add_systems(
schedule.clone(), // TODO RJRJ MOVE FILE
Expand All @@ -102,15 +101,12 @@ impl TimewarpTraits for App {
self.add_systems(
schedule.clone(),
(
prefix_check_if_rollback_needed::detect_misuse_of_icaf::<T>,
prefix_check_if_rollback_needed::unpack_icafs_and_maybe_rollback::<
T,
CORRECTION_LOGGING,
>,
prefix_check_if_rollback_needed::apply_snapshots_and_maybe_rollback::<T>,
prefix_not_in_rollback::detect_misuse_of_icaf::<T>,
prefix_not_in_rollback::unpack_icafs_and_maybe_rollback::<T, CORRECTION_LOGGING>,
prefix_not_in_rollback::apply_snapshots_and_maybe_rollback::<T>,
)
.before(prefix_check_if_rollback_needed::consolidate_rollback_requests)
.in_set(TimewarpPrefixSet::CheckIfRollbackNeeded),
.before(prefix_not_in_rollback::consolidate_rollback_requests)
.in_set(TimewarpPrefixSet::NotInRollback),
);
self.add_systems(
schedule.clone(),
Expand All @@ -135,10 +131,10 @@ impl TimewarpTraits for App {
self.add_systems(
schedule.clone(),
(
postfix_during_rollback::rekill_components_during_rollback::<T>,
postfix_during_rollback::clear_removed_components_queue::<T>,
postfix_in_rollback::rekill_components_during_rollback::<T>,
postfix_in_rollback::clear_removed_components_queue::<T>,
)
.in_set(TimewarpPostfixSet::DuringRollback),
.in_set(TimewarpPostfixSet::InRollback),
)
}
}
Expand Down

0 comments on commit 95f9fdd

Please sign in to comment.