Skip to content

Commit bc04295

Browse files
committed
made chunks cache its chunk data packet.
1 parent 8333eb3 commit bc04295

File tree

3 files changed

+61
-50
lines changed

3 files changed

+61
-50
lines changed

server/src/player/player.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ impl<E : PlayerExtension> Player<E> {
191191
return;
192192
};
193193
if diff == ChunkDiff::New {
194-
self.write_packet(&chunk.get_chunk_data(x, z, true));
194+
chunk.write_chunk_data(x, z, true, &mut self.packet_buffer);
195195
for entity_id in chunk.entities.iter_mut() {
196196
if let Some(index) = world.entity_map.get(entity_id) {
197197
let entity = &mut world.entities[*index];
@@ -210,8 +210,7 @@ impl<E : PlayerExtension> Player<E> {
210210
}
211211
}
212212
}
213-
let chunk_data = chunk_grid.empty_chunk.get_chunk_data(x, z, true);
214-
self.write_packet(&chunk_data);
213+
chunk_grid.empty_chunk.write_chunk_data(x, z, true, &mut self.packet_buffer);
215214
}
216215
)
217216
}

server/src/world/chunk/chunk.rs

Lines changed: 58 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,18 @@ pub struct ChunkSection {
99
solid_block_amount: u16,
1010
data: [u16; 4096],
1111
}
12-
13-
// could make the data a packet buffer? like store the chunk just as the packet
14-
// so instead of serializing the chunk for packet you just copy chunk packet buffer
15-
1612
pub struct Chunk {
1713
pub chunk_sections: [Option<ChunkSection>; 16],
1814
pub packet_buffer: PacketBuffer,
1915
pub players: Vec<ClientId>,
20-
pub entities: Vec<EntityId>
16+
pub entities: Vec<EntityId>,
17+
18+
// contains the chunk data packet,
19+
// and is updated when a player tries to access it and is dirty,
20+
// ideally we would somehow store blocks in the packet buffer,
21+
// however it'd be annoying
22+
cached_chunk_data: PacketBuffer,
23+
dirty: bool,
2124
}
2225

2326
impl Chunk {
@@ -28,6 +31,9 @@ impl Chunk {
2831
packet_buffer: PacketBuffer::new(),
2932
players: Vec::new(),
3033
entities: Vec::new(),
34+
35+
cached_chunk_data: PacketBuffer::new(),
36+
dirty: false,
3137
}
3238
}
3339

@@ -58,60 +64,66 @@ impl Chunk {
5864
section.solid_block_amount += 1;
5965
}
6066
section.data[index as usize] = block_state_id;
67+
self.dirty = true;
6168
}
6269
}
6370

64-
pub fn get_chunk_data(&self, x: i32, z: i32, new: bool) -> ChunkData {
65-
let mut bitmask = 0u16;
66-
67-
for index in 0..16 {
68-
if let Some(section) = &self.chunk_sections[index] {
69-
if section.solid_block_amount != 0 {
70-
bitmask |= 1 << index;
71+
pub fn write_chunk_data(&mut self, x: i32, z: i32, new: bool, into: &mut PacketBuffer) {
72+
if self.dirty {
73+
let mut bitmask = 0u16;
74+
75+
for index in 0..16 {
76+
if let Some(section) = &self.chunk_sections[index] {
77+
if section.solid_block_amount != 0 {
78+
bitmask |= 1 << index;
79+
}
7180
}
7281
}
73-
}
7482

75-
let section_count = bitmask.count_ones() as usize;
76-
let data_size: usize = section_count * 12288 + if new { 256 } else { 0 };
83+
let section_count = bitmask.count_ones() as usize;
84+
let data_size: usize = section_count * 12288 + if new { 256 } else { 0 };
7785

78-
let mut data = vec![0u8; data_size];
79-
let mut offset = 0;
86+
let mut data = vec![0u8; data_size];
87+
let mut offset = 0;
8088

81-
for section in self.chunk_sections.iter().flatten() {
82-
if section.solid_block_amount == 0 {
83-
continue
84-
}
85-
for block in section.data {
86-
data[offset] = (block & 0xFF) as u8;
87-
data[offset + 1] = ((block >> 8) & 0xFF) as u8;
88-
offset += 2;
89-
}
90-
};
89+
for section in self.chunk_sections.iter().flatten() {
90+
if section.solid_block_amount == 0 {
91+
continue
92+
}
93+
for block in section.data {
94+
data[offset] = (block & 0xFF) as u8;
95+
data[offset + 1] = ((block >> 8) & 0xFF) as u8;
96+
offset += 2;
97+
}
98+
};
9199

92-
// currently all blocks have max skylight and regular light,
93-
// however ive come across issues, where it seems clients recalculate light (due to it being invalid?)
94-
// causing massive fps drops
100+
// currently all blocks have max skylight and regular light,
101+
// however ive come across issues, where it seems clients recalculate light (due to it being invalid?)
102+
// causing massive fps drops
95103

96-
if section_count != 0 {
97-
for _ in 0..4096 {
98-
data[offset] = 255;
99-
offset += 1;
104+
if section_count != 0 {
105+
for _ in 0..4096 {
106+
data[offset] = 255;
107+
offset += 1;
108+
}
100109
}
101-
}
102-
if new {
103-
for _ in 0..256 {
104-
data[offset] = 1;
105-
offset += 1;
110+
if new {
111+
for _ in 0..256 {
112+
data[offset] = 1;
113+
offset += 1;
114+
}
106115
}
116+
self.cached_chunk_data.clear();
117+
self.cached_chunk_data.write_packet(&ChunkData {
118+
chunk_x: x,
119+
chunk_z: z,
120+
is_new_chunk: new,
121+
bitmask,
122+
data,
123+
});
124+
self.dirty = false;
107125
}
108-
ChunkData {
109-
chunk_x: x,
110-
chunk_z: z,
111-
is_new_chunk: new,
112-
bitmask,
113-
data,
114-
}
126+
into.copy_from(&self.cached_chunk_data);
115127
}
116128

117129
// maybe use hashset instead for these methods?

server/src/world/world.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ impl<E : WorldExtension> World<E> {
113113
chunk_z,
114114
VIEW_DISTANCE + 1,
115115
|chunk, x, z| {
116-
player.write_packet(&chunk.get_chunk_data(x, z, true));
116+
chunk.write_chunk_data(x, z, true, &mut player.packet_buffer);
117117
}
118118
);
119119

0 commit comments

Comments
 (0)