Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Blinker POC. Possible framework for constantly-updating entities. #406

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions client/src/graphics/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,11 @@ impl Window {
sim.toggle_no_clip();
}
}
KeyCode::KeyB if state == ElementState::Pressed => {
if let Some(sim) = self.sim.as_mut() {
sim.debug_spawn_blinker();
}
}
KeyCode::F1 if state == ElementState::Pressed => {
self.gui_state.toggle_gui();
}
Expand Down
1 change: 1 addition & 0 deletions client/src/prediction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ mod tests {
movement: na::Vector3::x(),
jump: false,
no_clip: true,
debug_spawn_blinker: false,
block_update: None,
};

Expand Down
32 changes: 31 additions & 1 deletion client/src/sim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use common::{
graph_ray_casting,
node::{populate_fresh_nodes, ChunkId, VoxelData},
proto::{
self, BlockUpdate, Character, CharacterInput, CharacterState, Command, Component,
self, Blinker, BlockUpdate, Character, CharacterInput, CharacterState, Command, Component,
Inventory, Position,
},
sanitize_motion_input,
Expand Down Expand Up @@ -64,6 +64,7 @@ pub struct Sim {
no_clip: bool,
/// Whether no_clip will be toggled next step
toggle_no_clip: bool,
debug_spawn_blinker: bool,
/// Whether the current step starts with a jump
is_jumping: bool,
/// Whether the jump button has been pressed since the last step
Expand Down Expand Up @@ -101,6 +102,7 @@ impl Sim {
average_movement_input: na::zero(),
no_clip: true,
toggle_no_clip: false,
debug_spawn_blinker: false,
is_jumping: false,
jump_pressed: false,
jump_held: false,
Expand Down Expand Up @@ -145,6 +147,11 @@ impl Sim {
self.toggle_no_clip = true;
}

pub fn debug_spawn_blinker(&mut self) {
// Note: the blinker currently does nothing but update internal state
self.debug_spawn_blinker = true;
}

pub fn set_jump_held(&mut self, jump_held: bool) {
self.jump_held = jump_held;
self.jump_pressed = jump_held || self.jump_pressed;
Expand Down Expand Up @@ -287,6 +294,9 @@ impl Sim {
for &(id, ref new_state) in &msg.character_states {
self.update_character_state(id, new_state);
}
for &(id, ref new_blinker) in &msg.blinker_states {
self.update_blinker_state(id, new_blinker);
}
self.reconcile_prediction(msg.latest_input);
}
}
Expand Down Expand Up @@ -322,6 +332,20 @@ impl Sim {
}
}

fn update_blinker_state(&mut self, id: EntityId, new_blinker: &Blinker) {
match self.entity_ids.get(&id) {
None => debug!(%id, "blinker state update for unknown entity"),
Some(&entity) => match self.world.get::<&mut Blinker>(entity) {
Ok(mut blinker) => {
*blinker = new_blinker.clone();
}
Err(e) => {
error!(%id, "blinker state update error: {}", e)
}
},
}
}

fn reconcile_prediction(&mut self, latest_input: u16) {
let id = self.local_character_id;
let Some(&entity) = self.entity_ids.get(&id) else {
Expand Down Expand Up @@ -424,6 +448,9 @@ impl Sim {
node = Some(x.node);
builder.add(x);
}
Blinker(x) => {
builder.add(x);
}
Inventory(x) => {
builder.add(x);
}
Expand Down Expand Up @@ -455,6 +482,7 @@ impl Sim {
movement: sanitize_motion_input(orientation * self.average_movement_input),
jump: self.is_jumping,
no_clip: self.no_clip,
debug_spawn_blinker: self.debug_spawn_blinker,
block_update: self.get_local_character_block_update(),
};
let generation = self
Expand All @@ -467,6 +495,7 @@ impl Sim {
character_input,
orientation: self.local_character_controller.orientation(),
});
self.debug_spawn_blinker = false;
}

fn update_view_position(&mut self) {
Expand All @@ -488,6 +517,7 @@ impl Sim {
/ (self.since_input_sent.as_secs_f32() / self.cfg.step_interval.as_secs_f32()),
jump: self.is_jumping,
no_clip: self.no_clip,
debug_spawn_blinker: self.debug_spawn_blinker,
block_update: None,
};
character_controller::run_character_step(
Expand Down
8 changes: 8 additions & 0 deletions common/src/proto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ pub struct StateDelta {
pub latest_input: u16,
pub positions: Vec<(EntityId, Position)>,
pub character_states: Vec<(EntityId, CharacterState)>,
pub blinker_states: Vec<(EntityId, Blinker)>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
Expand Down Expand Up @@ -72,6 +73,7 @@ pub struct CharacterInput {
pub movement: na::Vector3<f32>,
pub jump: bool,
pub no_clip: bool,
pub debug_spawn_blinker: bool,
pub block_update: Option<BlockUpdate>,
}

Expand All @@ -93,6 +95,7 @@ pub struct SerializedVoxelData {
pub enum Component {
Character(Character),
Position(Position),
Blinker(Blinker),
Material(Material),
Inventory(Inventory),
}
Expand All @@ -110,6 +113,11 @@ pub struct Character {
pub state: CharacterState,
}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Blinker {
pub on: bool,
}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Inventory {
pub contents: Vec<EntityId>,
Expand Down
33 changes: 31 additions & 2 deletions server/src/sim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ use common::{
math,
node::{populate_fresh_nodes, Chunk},
proto::{
Character, CharacterInput, CharacterState, ClientHello, Command, Component, FreshNode,
Position, Spawns, StateDelta,
Blinker, Character, CharacterInput, CharacterState, ClientHello, Command, Component,
FreshNode, Position, Spawns, StateDelta,
},
traversal::{ensure_nearby, nearby_nodes},
worldgen::ChunkParams,
Expand Down Expand Up @@ -203,6 +203,7 @@ impl Sim {
movement: na::Vector3::zeros(),
jump: false,
no_clip: true,
debug_spawn_blinker: false,
block_update: None,
};
self.spawn((position, character, inventory, initial_input))
Expand Down Expand Up @@ -289,6 +290,16 @@ impl Sim {
let span = error_span!("step", step = self.step);
let _guard = span.enter();

for (_entity, blinker) in self.world.query::<&mut Blinker>().iter() {
blinker.on = !blinker.on;

if blinker.on {
tracing::info!("Blinked ON");
} else {
tracing::info!("Blinked OFF");
}
}

// Extend graph structure
for (_, (position, _)) in self.world.query::<(&mut Position, &mut Character)>().iter() {
ensure_nearby(&mut self.graph, position, self.cfg.view_distance);
Expand Down Expand Up @@ -341,6 +352,7 @@ impl Sim {
}
}

let mut pending_blinker_spawns: Vec<(Position, Blinker)> = Vec::new();
let mut pending_block_updates: Vec<(Entity, BlockUpdate)> = vec![];

// Simulate
Expand All @@ -350,6 +362,10 @@ impl Sim {
.iter()
{
let prev_node = position.node;
if input.debug_spawn_blinker {
let blinker: Blinker = Blinker { on: false };
pending_blinker_spawns.push((*position, blinker));
}
character_controller::run_character_step(
&self.cfg,
&self.graph,
Expand All @@ -370,6 +386,10 @@ impl Sim {
self.dirty_nodes.insert(position.node);
}

for (position, blinker) in pending_blinker_spawns {
blockmath marked this conversation as resolved.
Show resolved Hide resolved
self.spawn((position, blinker));
}

for (entity, block_update) in pending_block_updates {
let id = *self.world.get::<&EntityId>(entity).unwrap();
self.attempt_block_update(id, block_update);
Expand Down Expand Up @@ -397,6 +417,12 @@ impl Sim {
.iter()
.map(|(_, (&id, ch))| (id, ch.state.clone()))
.collect(),
blinker_states: self
.world
.query::<(&EntityId, &Blinker)>()
.iter()
.map(|(_, (&id, blinker))| (id, blinker.clone()))
.collect(),
};

self.step += 1;
Expand Down Expand Up @@ -495,6 +521,9 @@ fn dump_entity(world: &hecs::World, entity: Entity) -> Vec<Component> {
if let Ok(x) = world.get::<&Character>(entity) {
components.push(Component::Character((*x).clone()));
}
if let Ok(x) = world.get::<&Blinker>(entity) {
components.push(Component::Blinker((*x).clone()));
}
if let Ok(x) = world.get::<&Inventory>(entity) {
components.push(Component::Inventory((*x).clone()));
}
Expand Down
Loading