Split up iteration of rtsim entities each tick

This commit is contained in:
ubruntu 2021-08-23 21:49:32 +00:00 committed by Marcel
parent 9200eb80ff
commit 20e33f5575
3 changed files with 36 additions and 21 deletions

View File

@ -19,7 +19,7 @@ pub struct Entity {
pub is_loaded: bool, pub is_loaded: bool,
pub pos: Vec3<f32>, pub pos: Vec3<f32>,
pub seed: u32, pub seed: u32,
pub last_tick: u64, pub last_time_ticked: f64,
pub controller: RtSimController, pub controller: RtSimController,
pub brain: Brain, pub brain: Brain,

View File

@ -110,6 +110,8 @@ pub fn init(state: &mut State, #[cfg(feature = "worldgen")] world: &world::World
#[cfg(not(feature = "worldgen"))] #[cfg(not(feature = "worldgen"))]
let mut rtsim = RtSim::new(Vec2::new(40, 40)); let mut rtsim = RtSim::new(Vec2::new(40, 40));
// TODO: Determine number of rtsim entities based on things like initial site
// populations rather than world size
#[cfg(feature = "worldgen")] #[cfg(feature = "worldgen")]
for _ in 0..world.sim().get_size().product() / 400 { for _ in 0..world.sim().get_size().product() / 400 {
let pos = rtsim let pos = rtsim
@ -124,7 +126,7 @@ pub fn init(state: &mut State, #[cfg(feature = "worldgen")] world: &world::World
pos: Vec3::from(pos.map(|e| e as f32)), pos: Vec3::from(pos.map(|e| e as f32)),
seed: thread_rng().gen(), seed: thread_rng().gen(),
controller: RtSimController::default(), controller: RtSimController::default(),
last_tick: 0, last_time_ticked: 0.0,
brain: Default::default(), brain: Default::default(),
}); });
} }

View File

@ -11,8 +11,6 @@ use common_ecs::{Job, Origin, Phase, System};
use specs::{Join, Read, ReadExpect, ReadStorage, WriteExpect, WriteStorage}; use specs::{Join, Read, ReadExpect, ReadStorage, WriteExpect, WriteStorage};
use std::sync::Arc; use std::sync::Arc;
const ENTITY_TICK_PERIOD: u64 = 30;
#[derive(Default)] #[derive(Default)]
pub struct Sys; pub struct Sys;
impl<'a> System<'a> for Sys { impl<'a> System<'a> for Sys {
@ -38,7 +36,7 @@ impl<'a> System<'a> for Sys {
_job: &mut Job<Self>, _job: &mut Job<Self>,
( (
time, time,
dt, _dt,
server_event_bus, server_event_bus,
mut rtsim, mut rtsim,
terrain, terrain,
@ -52,13 +50,23 @@ impl<'a> System<'a> for Sys {
let rtsim = &mut *rtsim; let rtsim = &mut *rtsim;
rtsim.tick += 1; rtsim.tick += 1;
// Update rtsim entities // Update unloaded rtsim entities, in groups at a time
// TODO: don't update all of them each tick const TICK_STAGGER: usize = 30;
let entities_per_iteration = rtsim.entities.len() / TICK_STAGGER;
let mut to_reify = Vec::new(); let mut to_reify = Vec::new();
for (id, entity) in rtsim.entities.iter_mut() { for (id, entity) in rtsim
if entity.is_loaded { .entities
// Nothing here yet .iter_mut()
} else if rtsim .skip((rtsim.tick as usize % TICK_STAGGER) * entities_per_iteration)
.take(entities_per_iteration)
.filter(|(_, e)| !e.is_loaded)
{
// Calculating dt ourselves because the dt provided to this fn was since the
// last frame, not since the last iteration that these entities acted
let dt = (time.0 - entity.last_time_ticked) as f32;
entity.last_time_ticked = time.0;
if rtsim
.chunks .chunks
.chunk_at(entity.pos.xy()) .chunk_at(entity.pos.xy())
.map(|c| c.is_loaded) .map(|c| c.is_loaded)
@ -75,7 +83,7 @@ impl<'a> System<'a> for Sys {
.unwrap_or_else(Vec2::zero) .unwrap_or_else(Vec2::zero)
* entity.get_body().max_speed_approx() * entity.get_body().max_speed_approx()
* entity.controller.speed_factor, * entity.controller.speed_factor,
) * dt.0; ) * dt;
} }
if let Some(alt) = world if let Some(alt) = world
@ -85,12 +93,13 @@ impl<'a> System<'a> for Sys {
entity.pos.z = alt; entity.pos.z = alt;
} }
} }
entity.tick(&time, &terrain, &world, &index.as_index_ref());
}
// Tick entity AI // Tick entity AI each time if it's loaded
if entity.last_tick + ENTITY_TICK_PERIOD <= rtsim.tick { for (_, entity) in rtsim.entities.iter_mut().filter(|(_, e)| e.is_loaded) {
entity.tick(&time, &terrain, &world, &index.as_index_ref()); entity.last_time_ticked = time.0;
entity.last_tick = rtsim.tick; entity.tick(&time, &terrain, &world, &index.as_index_ref());
}
} }
let mut server_emitter = server_event_bus.emitter(); let mut server_emitter = server_event_bus.emitter();
@ -160,10 +169,14 @@ impl<'a> System<'a> for Sys {
// Update rtsim with real entity data // Update rtsim with real entity data
for (pos, rtsim_entity, agent) in (&positions, &rtsim_entities, &mut agents).join() { for (pos, rtsim_entity, agent) in (&positions, &rtsim_entities, &mut agents).join() {
rtsim.entities.get_mut(rtsim_entity.0).map(|entity| { rtsim
entity.pos = pos.0; .entities
agent.rtsim_controller = entity.controller.clone(); .get_mut(rtsim_entity.0)
}); .filter(|e| e.is_loaded)
.map(|entity| {
entity.pos = pos.0;
agent.rtsim_controller = entity.controller.clone();
});
} }
} }
} }