Skip to content

Commit

Permalink
Allow the server to send updated chunks to new clients
Browse files Browse the repository at this point in the history
  • Loading branch information
patowen committed Oct 17, 2023
1 parent 839f840 commit 6acc0b9
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 2 deletions.
23 changes: 22 additions & 1 deletion client/src/sim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use common::{
collision_math::Ray,
graph::{Graph, NodeId},
graph_ray_casting,
node::{populate_fresh_nodes, ChunkId, ChunkLayout, DualGraph},
node::{populate_fresh_nodes, Chunk, ChunkId, ChunkLayout, DualGraph, VoxelData},
proto::{
self, BlockUpdate, Character, CharacterInput, CharacterState, Command, Component,
GlobalChunkId, Position,
Expand Down Expand Up @@ -285,6 +285,27 @@ impl Sim {
block_update.new_material,
)
}
for (global_chunk_id, voxel_data) in msg.modified_chunks {
let Some(voxel_data) = VoxelData::from_serializable(
&voxel_data,
self.params.as_ref().unwrap().cfg.chunk_size,
) else {
tracing::error!("Voxel data received from server is invalid");
continue;
};
if let Some(node_id) = self.graph.from_hash(global_chunk_id.node_hash) {
*self
.graph
.get_chunk_mut(ChunkId::new(node_id, global_chunk_id.vertex))
.unwrap() = Chunk::Populated {
voxels: voxel_data,
surface: None,
old_surface: None,
};
} else {
tracing::error!("Voxel data received from server for unloaded chunk");
}
}
}

fn spawn(
Expand Down
39 changes: 39 additions & 0 deletions common/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::collision_math::Ray;
use crate::dodeca::Vertex;
use crate::graph::{Graph, NodeId};
use crate::lru_slab::SlotId;
use crate::proto::SerializableVoxelData;
use crate::world::Material;
use crate::worldgen::NodeState;
use crate::Chunks;
Expand Down Expand Up @@ -248,6 +249,44 @@ impl VoxelData {
VoxelData::Solid(_) => true,
}
}

pub fn from_serializable(serializable: &SerializableVoxelData, dimension: u8) -> Option<Self> {
if serializable.voxels.len() != usize::from(dimension).pow(3) {
return None;
}

let mut data = vec![Material::Void; (usize::from(dimension) + 2).pow(3)];
let mut input_index = 0;
for x in 0..dimension {
for y in 0..dimension {
for z in 0..dimension {
data[Coords([x, y, z]).to_index(dimension)] = serializable.voxels[input_index];
input_index += 1;
}
}
}
Some(VoxelData::Dense(data.into_boxed_slice()))
}

pub fn to_serializable(&self, dimension: u8) -> SerializableVoxelData {
let VoxelData::Dense(data) = self else {
panic!("Only dense chunks can be serialized.");
};

let mut serializable: Vec<Material> = Vec::with_capacity(usize::from(dimension).pow(3));
let mut output_index = 0;
for x in 0..dimension {
for y in 0..dimension {
for z in 0..dimension {
serializable[output_index] = data[Coords([x, y, z]).to_index(dimension)];
output_index += 1;
}
}
}
SerializableVoxelData {
voxels: serializable,
}
}
}

/// Contains the context needed to know the locations of individual cubes within a chunk in the chunk's coordinate
Expand Down
6 changes: 6 additions & 0 deletions common/src/proto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ pub struct Spawns {
pub despawns: Vec<EntityId>,
pub nodes: Vec<FreshNode>,
pub block_updates: Vec<BlockUpdate>,
pub modified_chunks: Vec<(GlobalChunkId, SerializableVoxelData)>,
}

#[derive(Debug, Serialize, Deserialize)]
Expand Down Expand Up @@ -86,6 +87,11 @@ pub struct BlockUpdate {
pub new_material: Material,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct SerializableVoxelData {
pub voxels: Vec<Material>,
}

#[derive(Debug, Serialize, Deserialize)]
pub enum Component {
Character(Character),
Expand Down
1 change: 1 addition & 0 deletions server/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ impl Server {
|| !spawns.despawns.is_empty()
|| !spawns.nodes.is_empty()
|| !spawns.block_updates.is_empty()
|| !spawns.modified_chunks.is_empty()
{
handles.ordered.try_send(spawns.clone())
} else {
Expand Down
32 changes: 31 additions & 1 deletion server/src/sim.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::sync::Arc;

use common::proto::BlockUpdate;
use common::dodeca::Vertex;
use common::proto::{BlockUpdate, GlobalChunkId};
use common::{node::ChunkId, GraphEntities};
use fxhash::{FxHashMap, FxHashSet};
use hecs::Entity;
Expand Down Expand Up @@ -35,6 +36,7 @@ pub struct Sim {
despawns: Vec<EntityId>,
graph_entities: GraphEntities,
dirty_nodes: FxHashSet<NodeId>,
modified_chunks: FxHashMap<u128, FxHashSet<Vertex>>,
}

impl Sim {
Expand All @@ -50,6 +52,7 @@ impl Sim {
despawns: Vec::new(),
graph_entities: GraphEntities::new(),
dirty_nodes: FxHashSet::default(),
modified_chunks: FxHashMap::default(),
};

ensure_nearby(
Expand Down Expand Up @@ -184,10 +187,32 @@ impl Sim {
.map(|(side, parent)| FreshNode { side, parent })
.collect(),
block_updates: Vec::new(),
modified_chunks: Vec::new(),
};
for (entity, &id) in &mut self.world.query::<&EntityId>() {
spawns.spawns.push((id, dump_entity(&self.world, entity)));
}
for global_chunk_id in self.modified_chunks.iter().flat_map(|pair| {
pair.1.iter().map(move |vert| GlobalChunkId {
node_hash: *pair.0,
vertex: *vert,
})
}) {
let voxels = match self
.graph
.get(self.graph.from_hash(global_chunk_id.node_hash).unwrap())
.as_ref()
.unwrap()
.chunks[global_chunk_id.vertex]
{
Chunk::Populated { ref voxels, .. } => voxels,
_ => panic!("modified chunk not available anywhere"),
};

spawns
.modified_chunks
.push((global_chunk_id, voxels.to_serializable(self.cfg.chunk_size)));
}
spawns
}

Expand Down Expand Up @@ -235,6 +260,10 @@ impl Sim {
block_update.coords,
block_update.new_material,
);
self.modified_chunks
.entry(block_update.chunk_id.node_hash)
.or_default()
.insert(block_update.chunk_id.vertex);
accepted_block_updates.push(block_update);
}

Expand Down Expand Up @@ -264,6 +293,7 @@ impl Sim {
})
.collect(),
block_updates: accepted_block_updates,
modified_chunks: vec![],
};
populate_fresh_nodes(&mut self.graph);

Expand Down

0 comments on commit 6acc0b9

Please sign in to comment.