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

Redesign layers and valence_server schedule. #533

Draft
wants to merge 18 commits into
base: main
Choose a base branch
from
Draft
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
8 changes: 5 additions & 3 deletions benches/idle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,19 @@ fn setup(
biomes: Res<BiomeRegistry>,
server: Res<Server>,
) {
let mut layer = LayerBundle::new(ident!("overworld"), &dimensions, &biomes, &server);
let mut layer = CombinedLayerBundle::new(Default::default(), &dimensions, &biomes, &server);

for z in -5..5 {
for x in -5..5 {
layer.chunk.insert_chunk([x, z], UnloadedChunk::new());
layer.chunk_index.insert([x, z], Chunk::new());
}
}

for z in -50..50 {
for x in -50..50 {
layer.chunk.set_block([x, 64, z], BlockState::GRASS_BLOCK);
layer
.chunk_index
.set_block([x, 64, z], BlockState::GRASS_BLOCK);
}
}

Expand Down
8 changes: 3 additions & 5 deletions benches/many_players.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use criterion::Criterion;
use rand::Rng;
use valence::entity::Position;
use valence::keepalive::KeepaliveSettings;
use valence::layer::chunk::UnloadedChunk;
use valence::layer::LayerBundle;
use valence::layer_old::chunk::Chunk;
use valence::layer_old::LayerBundle;
use valence::math::DVec3;
use valence::network::NetworkPlugin;
use valence::protocol::packets::play::{FullC2s, HandSwingC2s};
Expand Down Expand Up @@ -51,9 +51,7 @@ fn run_many_players(

for z in -world_size..world_size {
for x in -world_size..world_size {
layer
.chunk
.insert_chunk(ChunkPos::new(x, z), UnloadedChunk::new());
layer.chunk_index.insert(ChunkPos::new(x, z), Chunk::new());
}
}

Expand Down
21 changes: 7 additions & 14 deletions crates/valence_advancement/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use std::time::{SystemTime, UNIX_EPOCH};

use bevy_app::prelude::*;
use bevy_ecs::prelude::*;
use bevy_ecs::schedule::SystemSet;
use bevy_ecs::system::SystemParam;
pub use bevy_hierarchy;
use bevy_hierarchy::{Children, HierarchyPlugin, Parent};
Expand All @@ -27,21 +28,12 @@ use valence_server::{Ident, ItemStack, Text};
pub struct AdvancementPlugin;

#[derive(SystemSet, Clone, Copy, Eq, PartialEq, Hash, Debug)]
pub struct WriteAdvancementPacketToClientsSet;

#[derive(SystemSet, Clone, Copy, Eq, PartialEq, Hash, Debug)]
pub struct WriteAdvancementToCacheSet;
pub struct AdvancementSet;

impl Plugin for AdvancementPlugin {
fn build(&self, app: &mut bevy_app::App) {
app.add_plugins(HierarchyPlugin)
.configure_sets(
PostUpdate,
(
WriteAdvancementPacketToClientsSet.before(FlushPacketsSet),
WriteAdvancementToCacheSet.before(WriteAdvancementPacketToClientsSet),
),
)
.configure_set(PostUpdate, AdvancementSet.before(FlushPacketsSet))
.add_event::<AdvancementTabChangeEvent>()
.add_systems(
PreUpdate,
Expand All @@ -53,9 +45,10 @@ impl Plugin for AdvancementPlugin {
.add_systems(
PostUpdate,
(
update_advancement_cached_bytes.in_set(WriteAdvancementToCacheSet),
send_advancement_update_packet.in_set(WriteAdvancementPacketToClientsSet),
),
update_advancement_cached_bytes.before(send_advancement_update_packet),
send_advancement_update_packet,
)
.in_set(AdvancementSet),
);
}
}
Expand Down
8 changes: 4 additions & 4 deletions crates/valence_anvil/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,20 @@ use std::num::NonZeroUsize;
use std::path::{Path, PathBuf};
use std::time::{SystemTime, UNIX_EPOCH};

#[cfg(feature = "bevy_plugin")]
pub use bevy::*;
use bitfield_struct::bitfield;
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use flate2::bufread::{GzDecoder, ZlibDecoder};
use flate2::write::{GzEncoder, ZlibEncoder};
use lru::LruCache;
#[cfg(feature = "bevy_plugin")]
pub use plugin::*;
use thiserror::Error;
use valence_nbt::Compound;

#[cfg(feature = "bevy_plugin")]
mod bevy;
#[cfg(feature = "parsing")]
pub mod parsing;
#[cfg(feature = "bevy_plugin")]
mod plugin;

const LRU_CACHE_SIZE: NonZeroUsize = match NonZeroUsize::new(256) {
Some(n) => n,
Expand Down
13 changes: 6 additions & 7 deletions crates/valence_anvil/src/parsing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ use std::path::PathBuf;
use num_integer::div_ceil;
use thiserror::Error;
use valence_server::block::{PropName, PropValue};
use valence_server::layer::chunk::{Chunk, UnloadedChunk};
use valence_server::dimension_layer::chunk::ChunkOps;
use valence_server::nbt::{Compound, List, Value};
use valence_server::protocol::BlockKind;
use valence_server::registry::biome::BiomeId;
use valence_server::registry::BiomeRegistry;
use valence_server::{ChunkPos, Ident};
use valence_server::{Chunk, ChunkPos, Ident};

use crate::{RegionError, RegionFolder};

Expand Down Expand Up @@ -55,7 +55,7 @@ impl DimensionFolder {

/// A chunk parsed to show block information, biome information etc.
pub struct ParsedChunk {
pub chunk: UnloadedChunk,
pub chunk: Chunk,
pub timestamp: u32,
}

Expand Down Expand Up @@ -119,17 +119,16 @@ pub enum ParseChunkError {
fn parse_chunk(
mut nbt: Compound,
biome_map: &BTreeMap<Ident<String>, BiomeId>, // TODO: replace with biome registry arg.
) -> Result<UnloadedChunk, ParseChunkError> {
) -> Result<Chunk, ParseChunkError> {
let Some(Value::List(List::Compound(sections))) = nbt.remove("sections") else {
return Err(ParseChunkError::MissingSections);
};

if sections.is_empty() {
return Ok(UnloadedChunk::new());
return Ok(Chunk::new());
}

let mut chunk =
UnloadedChunk::with_height((sections.len() * 16).try_into().unwrap_or(u32::MAX));
let mut chunk = Chunk::with_height((sections.len() * 16).try_into().unwrap_or(i32::MAX));

let min_sect_y = sections
.iter()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ use bevy_app::prelude::*;
use bevy_ecs::prelude::*;
use flume::{Receiver, Sender};
use valence_server::client::{Client, OldView, View};
use valence_server::entity::{EntityLayerId, OldEntityLayerId};
use valence_server::layer::UpdateLayersPreClientSet;
use valence_server::dimension_layer::{
ChunkIndex, DimensionInfo, DimensionLayerQuery, UpdateDimensionLayerSet,
};
use valence_server::protocol::anyhow;
use valence_server::registry::BiomeRegistry;
use valence_server::{ChunkLayer, ChunkPos};
use valence_server::{ChunkPos, LayerId, OldLayerId};

use crate::parsing::{DimensionFolder, ParsedChunk};

Expand Down Expand Up @@ -92,21 +93,25 @@ struct ChunkWorkerState {

pub struct AnvilPlugin;

#[derive(SystemSet, Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub struct AnvilSet;

impl Plugin for AnvilPlugin {
fn build(&self, app: &mut App) {
app.add_event::<ChunkLoadEvent>()
.add_event::<ChunkUnloadEvent>()
.add_systems(PreUpdate, remove_unviewed_chunks)
.configure_set(PostUpdate, AnvilSet.before(UpdateDimensionLayerSet))
.add_systems(
PostUpdate,
(init_anvil, update_client_views, send_recv_chunks)
.chain()
.before(UpdateLayersPreClientSet),
.in_set(AnvilSet),
);
}
}

fn init_anvil(mut query: Query<&mut AnvilLevel, (Added<AnvilLevel>, With<ChunkLayer>)>) {
fn init_anvil(mut query: Query<&mut AnvilLevel, (Added<AnvilLevel>, With<DimensionInfo>)>) {
for mut level in &mut query {
if let Some(state) = level.worker_state.take() {
thread::spawn(move || anvil_worker(state));
Expand All @@ -119,12 +124,12 @@ fn init_anvil(mut query: Query<&mut AnvilLevel, (Added<AnvilLevel>, With<ChunkLa
/// This needs to run in `PreUpdate` where the chunk viewer counts have been
/// updated from the previous tick.
fn remove_unviewed_chunks(
mut chunk_layers: Query<(Entity, &mut ChunkLayer, &AnvilLevel)>,
mut chunk_layers: Query<(Entity, DimensionLayerQuery, &AnvilLevel)>,
mut unload_events: EventWriter<ChunkUnloadEvent>,
) {
for (entity, mut layer, anvil) in &mut chunk_layers {
layer.retain_chunks(|pos, chunk| {
if chunk.viewer_count_mut() > 0 || anvil.ignored_chunks.contains(&pos) {
if chunk.viewer_count() > 0 || anvil.ignored_chunks.contains(&pos) {
true
} else {
unload_events.send(ChunkUnloadEvent {
Expand All @@ -138,20 +143,20 @@ fn remove_unviewed_chunks(
}

fn update_client_views(
clients: Query<(&EntityLayerId, Ref<OldEntityLayerId>, View, OldView), With<Client>>,
mut chunk_layers: Query<(&ChunkLayer, &mut AnvilLevel)>,
clients: Query<(&LayerId, Ref<OldLayerId>, View, OldView), With<Client>>,
mut chunk_layers: Query<(&ChunkIndex, &mut AnvilLevel)>,
) {
for (loc, old_loc, view, old_view) in &clients {
let view = view.get();
let old_view = old_view.get();

if loc != &*old_loc || view != old_view || old_loc.is_added() {
let Ok((layer, mut anvil)) = chunk_layers.get_mut(loc.0) else {
let Ok((chunk_index, mut anvil)) = chunk_layers.get_mut(loc.0) else {
continue;
};

let queue_pos = |pos| {
if !anvil.ignored_chunks.contains(&pos) && layer.chunk(pos).is_none() {
if !anvil.ignored_chunks.contains(&pos) && chunk_index.get(pos).is_none() {
// Chunks closer to clients are prioritized.
match anvil.pending.entry(pos) {
Entry::Occupied(mut oe) => {
Expand Down Expand Up @@ -179,7 +184,7 @@ fn update_client_views(
}

fn send_recv_chunks(
mut layers: Query<(Entity, &mut ChunkLayer, &mut AnvilLevel)>,
mut layers: Query<(Entity, DimensionLayerQuery, &mut AnvilLevel)>,
mut to_send: Local<Vec<(Priority, ChunkPos)>>,
mut load_events: EventWriter<ChunkLoadEvent>,
) {
Expand Down
65 changes: 0 additions & 65 deletions crates/valence_boss_bar/src/components.rs

This file was deleted.

Loading