Added a delta time cap to avoid missing important physics events

Former-commit-id: e9f14ddda0963537ae6593c2dacc6a877f88c824
This commit is contained in:
Joshua Barretto 2019-05-01 12:28:26 +01:00
parent 342ea6aa65
commit 9ebe3c3e6f
3 changed files with 20 additions and 8 deletions

View File

@ -30,7 +30,13 @@ struct Time(f64);
/// A resource used to store the time since the last tick
#[derive(Default)]
pub struct DeltaTime(pub f64);
pub struct DeltaTime(pub f32);
/// At what point should we stop speeding up physics to compensate for lag? If we speed physics up
/// too fast, we'd skip important physics events like collisions. This constant determines what
/// the upper limit is. If delta time exceeds this value, the game's physics will begin to produce
/// time lag. Ideally, we'd avoid such a situation.
const MAX_DELTA_TIME: f32 = 0.2;
pub struct Changes {
pub new_chunks: HashSet<Vec3<i32>>,
@ -198,9 +204,11 @@ impl State {
self.ecs.write_resource::<TimeOfDay>().0 += dt.as_secs_f64() * DAY_CYCLE_FACTOR;
self.ecs.write_resource::<Time>().0 += dt.as_secs_f64();
// Run systems to update the world
self.ecs.write_resource::<DeltaTime>().0 = dt.as_secs_f64();
// Update delta time
// Above a delta time of MAX_DELTA_TIME, start lagging to avoid skipping important physics events
self.ecs.write_resource::<DeltaTime>().0 = dt.as_secs_f32().min(MAX_DELTA_TIME);
// Run systems to update the world
// Create and run dispatcher for ecs systems
let mut dispatch_builder = DispatcherBuilder::new().with_pool(self.thread_pool.clone());
sys::add_local_systems(&mut dispatch_builder);

View File

@ -23,10 +23,10 @@ impl<'a> System<'a> for Sys {
fn run(&mut self, (terrain, dt, mut positions, mut velocities): Self::SystemData) {
for (pos, vel) in (&mut positions, &mut velocities).join() {
// Gravity
vel.0.z = (vel.0.z - GRAVITY * dt.0 as f32).max(-50.0);
vel.0.z = (vel.0.z - GRAVITY * dt.0).max(-50.0);
// Movement
pos.0 += vel.0 * dt.0 as f32;
pos.0 += vel.0 * dt.0;
// Basic collision with terrain
let mut i = 0;

View File

@ -1,5 +1,5 @@
// Library
use noise::{NoiseFn, Perlin};
use noise::{NoiseFn, Perlin, Seedable};
use vek::*;
// Project
@ -32,7 +32,10 @@ impl World {
let dirt = Block::new(3, Rgb::new(128, 90, 0));
let sand = Block::new(4, Rgb::new(180, 150, 50));
let perlin_nz = Perlin::new();
let perlin_nz = Perlin::new()
.set_seed(1);
let temp_nz = Perlin::new()
.set_seed(2);
for lpos in chunk.iter_positions() {
let wpos = lpos + chunk_pos * chunk.get_size().map(|e| e as i32);
@ -46,6 +49,7 @@ impl World {
let height = perlin_nz.get(Vec2::from(wposf * freq).into_array()) * ampl
+ perlin_nz.get(Vec2::from(wposf * small_freq).into_array()) * small_ampl
+ offs;
let temp = (temp_nz.get(Vec2::from(wposf * (1.0 / 64.0)).into_array()) + 1.0) * 0.5;
chunk
.set(
@ -55,7 +59,7 @@ impl World {
} else if wposf.z < height - 1.0 {
dirt
} else if wposf.z < height {
grass
Block::new(2, Rgb::new(10 + (150.0 * temp) as u8, 150, 0))
} else {
air
},