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

Visibility Layers #424

Merged
merged 53 commits into from
Aug 2, 2023
Merged
Show file tree
Hide file tree
Changes from 45 commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
7823825
message buffer
rj00a Jul 3, 2023
505cc95
new `valence_instance`, reorganize `valence_client`
rj00a Jul 4, 2023
3e7fc00
chunk BVH
rj00a Jul 6, 2023
1266a6b
replace `valence_instance` with `valence_layer`
rj00a Jul 8, 2023
b82b43b
`valence_client` changes
rj00a Jul 8, 2023
34cf30a
get `bench_players` working at least
rj00a Jul 9, 2023
aa6e3e4
remove `ChunkState`
rj00a Jul 13, 2023
89c61f0
despawn entities in despawned entity layers
rj00a Jul 13, 2023
5c04cbd
layer bundle
rj00a Jul 13, 2023
0b98e7b
better entity layer despawn
rj00a Jul 16, 2023
e74330b
fix most examples
rj00a Jul 16, 2023
44dff7e
Merge branch 'main' into layers
rj00a Jul 16, 2023
99ada62
better layer interface
rj00a Jul 16, 2023
3166b87
get tests to compile
rj00a Jul 17, 2023
aaa9c58
fix packet_inspector
rj00a Jul 17, 2023
885c3a3
compile benches
rj00a Jul 17, 2023
85379f1
update old visible layers correctly
rj00a Jul 17, 2023
6ebc004
update playground
rj00a Jul 17, 2023
550f111
send_*_infallible, fix chunk load bugs
rj00a Jul 17, 2023
a298329
Merge branch 'main' into layers
rj00a Jul 23, 2023
6facf74
tweak idle_update
rj00a Jul 23, 2023
f474fab
Merge branch 'main' into layers
rj00a Jul 24, 2023
17ea6f3
Merge branch 'main' into layers
rj00a Jul 25, 2023
379fc4b
Fix mysterious excessive memory usage
rj00a Jul 25, 2023
a5e8dc8
tweak many_players bench
rj00a Jul 25, 2023
d56a975
tweak comment in `valence_layer`
rj00a Jul 25, 2023
85eeeb1
simplify schedule
rj00a Jul 25, 2023
b305165
Adjust view dist in many_players
rj00a Jul 25, 2023
43a181d
More packet writers for layers
rj00a Jul 26, 2023
a043c0f
More doc strings
rj00a Jul 27, 2023
cfc0ec1
Fix some clippy issues
rj00a Jul 29, 2023
8aaddee
Remove uuid -> entity map for now
rj00a Jul 29, 2023
51b381b
Despawn entities before spawning
rj00a Jul 29, 2023
61dee49
merge with main
rj00a Jul 29, 2023
3df8edd
Merge branch 'main' into layers
rj00a Jul 29, 2023
37ea3c8
update weather
rj00a Jul 30, 2023
c228fbf
redesign valence_world_border
rj00a Jul 31, 2023
c9d5f33
remove dead code from example
rj00a Jul 31, 2023
ad7d2b2
Update `valence_anvil`
rj00a Aug 1, 2023
e356656
Add layer switching and chunk view count tests
rj00a Aug 1, 2023
7065023
fix clippy
rj00a Aug 1, 2023
0b0306e
Fix chunk view bounding box bug
rj00a Aug 1, 2023
e551fa6
Fix docs
rj00a Aug 1, 2023
dd7ef6e
Merge branch 'main' into layers
rj00a Aug 1, 2023
3eaff91
Capture the Flag Example Using Entity Layers (#426)
dyc3 Aug 1, 2023
e2aa2ae
ctf: fix lints
dyc3 Aug 1, 2023
b9d5a1f
Update crates/valence_layer/src/chunk/loaded.rs
rj00a Aug 2, 2023
d8e9ed0
Document `Messages`
rj00a Aug 2, 2023
cc90a49
valence_layer: fix README.md
rj00a Aug 2, 2023
46f691c
More docs for `valence_world_border`
rj00a Aug 2, 2023
7de204b
`cargo fmt` for ctf example
rj00a Aug 2, 2023
5d87ca9
Fix excessive memory usage in `many_players_spread_out` bench
rj00a Aug 2, 2023
faf042b
Fix test
rj00a Aug 2, 2023
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
10 changes: 7 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ default = [
"network",
"player_list",
"world_border",
"weather",
]
advancement = ["dep:valence_advancement"]
anvil = ["dep:valence_anvil"]
Expand All @@ -29,6 +30,7 @@ log = ["dep:bevy_log"]
network = ["dep:valence_network"]
player_list = ["dep:valence_player_list"]
world_border = ["dep:valence_world_border"]
weather = ["dep:valence_weather"]

[dependencies]
anyhow.workspace = true
Expand All @@ -48,13 +50,14 @@ valence_client.workspace = true
valence_core.workspace = true
valence_dimension.workspace = true
valence_entity.workspace = true
valence_instance.workspace = true
valence_layer.workspace = true
valence_inventory = { workspace = true, optional = true }
valence_nbt.workspace = true
valence_network = { workspace = true, optional = true }
valence_player_list = { workspace = true, optional = true }
valence_registry.workspace = true
valence_world_border = { workspace = true, optional = true }
valence_weather = { workspace = true, optional = true }

[dev-dependencies]
anyhow.workspace = true
Expand Down Expand Up @@ -103,7 +106,7 @@ bevy_app = { version = "0.11", default-features = false }
bevy_ecs = { version = "0.11", default-features = false }
bevy_hierarchy = { version = "0.11", default-features = false }
bevy_log = { version = "0.11" }
bevy_mod_debugdump = { version = "0.8.0", default-features = false }
bevy_mod_debugdump = { version = "0.8.0", default-features = false }
bevy_utils = { version = "0.11" }
bitfield-struct = "0.3.1"
byteorder = "1.4.3"
Expand Down Expand Up @@ -170,13 +173,14 @@ valence_core_macros.path = "crates/valence_core_macros"
valence_core.path = "crates/valence_core"
valence_dimension.path = "crates/valence_dimension"
valence_entity.path = "crates/valence_entity"
valence_instance.path = "crates/valence_instance"
valence_layer.path = "crates/valence_layer"
valence_inventory.path = "crates/valence_inventory"
valence_nbt = { path = "crates/valence_nbt", features = ["uuid"] }
valence_network.path = "crates/valence_network"
valence_player_list.path = "crates/valence_player_list"
valence_registry.path = "crates/valence_registry"
valence_world_border.path = "crates/valence_world_border"
valence_boss_bar.path = "crates/valence_boss_bar"
valence_weather.path = "crates/valence_weather"
valence.path = "."
zip = "0.6.3"
8 changes: 4 additions & 4 deletions benches/idle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,19 @@ fn setup(
biomes: Res<BiomeRegistry>,
server: Res<Server>,
) {
let mut instance = Instance::new(ident!("overworld"), &dimensions, &biomes, &server);
let mut layer = LayerBundle::new(ident!("overworld"), &dimensions, &biomes, &server);

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

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

commands.spawn(instance);
commands.spawn(layer);
}
47 changes: 29 additions & 18 deletions benches/many_players.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,22 @@ use valence_core::chunk_pos::ChunkPos;
use valence_core::{ident, CoreSettings, Server};
use valence_dimension::DimensionTypeRegistry;
use valence_entity::Position;
use valence_instance::chunk::UnloadedChunk;
use valence_instance::Instance;
use valence_layer::chunk::UnloadedChunk;
use valence_layer::LayerBundle;
use valence_network::NetworkPlugin;

const CLIENT_COUNT: usize = 3000;
const VIEW_DIST: u8 = 20;
const INST_SIZE: i32 = 16;

pub fn many_players(c: &mut Criterion) {
run_many_players(c, "many_players", 3000, 16, 16);
run_many_players(c, "many_players_spread_out", 3000, 8, 200);
}

fn run_many_players(
c: &mut Criterion,
func_name: &str,
client_count: usize,
view_dist: u8,
world_size: i32,
) {
let mut app = App::new();

app.insert_resource(CoreSettings {
Expand All @@ -38,33 +45,37 @@ pub fn many_players(c: &mut Criterion) {

app.update(); // Initialize plugins.

let mut inst = Instance::new(
let mut layer = LayerBundle::new(
ident!("overworld"),
app.world.resource::<DimensionTypeRegistry>(),
app.world.resource::<BiomeRegistry>(),
app.world.resource::<Server>(),
);

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

let inst_ent = app.world.spawn(inst).id();
let layer = app.world.spawn(layer).id();

let mut clients = vec![];

// Spawn a bunch of clients in at random initial positions in the instance.
for i in 0..CLIENT_COUNT {
for i in 0..client_count {
let (mut bundle, helper) = create_mock_client(format!("client_{i}"));

bundle.player.location.0 = inst_ent;
bundle.view_distance.set(VIEW_DIST);
bundle.visible_chunk_layer.0 = layer;
bundle.visible_entity_layers.0.insert(layer);
bundle.player.layer.0 = layer;
bundle.view_distance.set(view_dist);

let mut rng = rand::thread_rng();
let x = rng.gen_range(-INST_SIZE as f64 * 16.0..=INST_SIZE as f64 * 16.0);
let z = rng.gen_range(-INST_SIZE as f64 * 16.0..=INST_SIZE as f64 * 16.0);
let x = rng.gen_range(-world_size as f64 * 16.0..=world_size as f64 * 16.0);
let z = rng.gen_range(-world_size as f64 * 16.0..=world_size as f64 * 16.0);

bundle.player.position.set(DVec3::new(x, 64.0, z));

Expand All @@ -83,7 +94,7 @@ pub fn many_players(c: &mut Criterion) {

app.update();

c.bench_function("many_players", |b| {
c.bench_function(func_name, |b| {
b.iter(|| {
let mut rng = rand::thread_rng();

Expand All @@ -92,7 +103,7 @@ pub fn many_players(c: &mut Criterion) {
for (id, helper) in &mut clients {
let pos = query.get(&app.world, *id).unwrap().get();

let offset = DVec3::new(rng.gen_range(-2.0..=2.0), 0.0, rng.gen_range(-2.0..=2.0));
let offset = DVec3::new(rng.gen_range(-1.0..=1.0), 0.0, rng.gen_range(-1.0..=1.0));

helper.send(&FullC2s {
position: pos + offset,
Expand Down
2 changes: 1 addition & 1 deletion benches/packet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use valence::protocol::var_int::VarInt;
use valence::text::IntoText;
use valence_core::protocol::encode::{PacketWriter, WritePacket};
use valence_entity::packet::EntitySpawnS2c;
use valence_instance::packet::ChunkDataS2c;
use valence_layer::packet::ChunkDataS2c;
use valence_player_list::packet::PlayerListHeaderS2c;

pub fn packet(c: &mut Criterion) {
Expand Down
1 change: 1 addition & 0 deletions crates/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ graph TD
advancement --> client
world_border --> client
boss_bar --> client
weather --> client
```
2 changes: 1 addition & 1 deletion crates/valence_anvil/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,5 @@ valence_block.workspace = true
valence_client.workspace = true
valence_core.workspace = true
valence_entity.workspace = true
valence_instance.workspace = true
valence_layer.workspace = true
valence_nbt.workspace = true
56 changes: 28 additions & 28 deletions crates/valence_anvil/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@ use flume::{Receiver, Sender};
use lru::LruCache;
use tracing::warn;
use valence_biome::{BiomeId, BiomeRegistry};
use valence_client::{Client, OldView, UpdateClientsSet, View};
use valence_client::{Client, OldView, View};
use valence_core::chunk_pos::ChunkPos;
use valence_core::ident::Ident;
use valence_entity::{Location, OldLocation};
use valence_instance::chunk::UnloadedChunk;
use valence_instance::Instance;
use valence_entity::{EntityLayerId, OldEntityLayerId};
use valence_layer::chunk::UnloadedChunk;
use valence_layer::{ChunkLayer, UpdateLayersPreClientSet};
use valence_nbt::Compound;

mod parse_chunk;
Expand Down Expand Up @@ -280,12 +280,12 @@ impl Plugin for AnvilPlugin {
PostUpdate,
(init_anvil, update_client_views, send_recv_chunks)
.chain()
.before(UpdateClientsSet),
.before(UpdateLayersPreClientSet),
);
}
}

fn init_anvil(mut query: Query<&mut AnvilLevel, (Added<AnvilLevel>, With<Instance>)>) {
fn init_anvil(mut query: Query<&mut AnvilLevel, (Added<AnvilLevel>, With<ChunkLayer>)>) {
for mut level in &mut query {
if let Some(state) = level.worker_state.take() {
thread::spawn(move || anvil_worker(state));
Expand All @@ -298,16 +298,16 @@ fn init_anvil(mut query: Query<&mut AnvilLevel, (Added<AnvilLevel>, With<Instanc
/// This needs to run in `PreUpdate` where the chunk viewer counts have been
/// updated from the previous tick.
fn remove_unviewed_chunks(
mut instances: Query<(Entity, &mut Instance, &AnvilLevel)>,
mut chunk_layers: Query<(Entity, &mut ChunkLayer, &AnvilLevel)>,
mut unload_events: EventWriter<ChunkUnloadEvent>,
) {
for (entity, mut inst, anvil) in &mut instances {
inst.retain_chunks(|pos, chunk| {
if chunk.is_viewed_mut() || anvil.ignored_chunks.contains(&pos) {
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) {
true
} else {
unload_events.send(ChunkUnloadEvent {
instance: entity,
chunk_layer: entity,
pos,
});
false
Expand All @@ -317,20 +317,20 @@ fn remove_unviewed_chunks(
}

fn update_client_views(
clients: Query<(&Location, Ref<OldLocation>, View, OldView), With<Client>>,
mut instances: Query<(&Instance, &mut AnvilLevel)>,
clients: Query<(&EntityLayerId, Ref<OldEntityLayerId>, View, OldView), With<Client>>,
mut chunk_layers: Query<(&ChunkLayer, &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((inst, mut anvil)) = instances.get_mut(loc.0) else {
let Ok((layer, mut anvil)) = chunk_layers.get_mut(loc.0) else {
continue;
};

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

fn send_recv_chunks(
mut instances: Query<(Entity, &mut Instance, &mut AnvilLevel)>,
mut layers: Query<(Entity, &mut ChunkLayer, &mut AnvilLevel)>,
mut to_send: Local<Vec<(Priority, ChunkPos)>>,
mut load_events: EventWriter<ChunkLoadEvent>,
) {
for (entity, mut inst, anvil) in &mut instances {
for (entity, mut layer, anvil) in &mut layers {
let anvil = anvil.into_inner();

// Insert the chunks that are finished loading into the instance and send load
// events.
// Insert the chunks that are finished loading into the chunk layer and send
// load events.
for (pos, res) in anvil.receiver.drain() {
anvil.pending.remove(&pos);

let status = match res {
Ok(Some((chunk, timestamp))) => {
inst.insert_chunk(pos, chunk);
layer.insert_chunk(pos, chunk);
ChunkLoadStatus::Success { timestamp }
}
Ok(None) => ChunkLoadStatus::Empty,
Err(e) => ChunkLoadStatus::Failed(e),
};

load_events.send(ChunkLoadEvent {
instance: entity,
chunk_layer: entity,
pos,
status,
});
Expand Down Expand Up @@ -424,16 +424,16 @@ fn anvil_worker(mut state: ChunkWorkerState) {
/// An event sent by `valence_anvil` after an attempt to load a chunk is made.
#[derive(Event, Debug)]
pub struct ChunkLoadEvent {
/// The [`Instance`] where the chunk is located.
pub instance: Entity,
/// The position of the chunk in the instance.
/// The [`ChunkLayer`] where the chunk is located.
pub chunk_layer: Entity,
/// The position of the chunk in the layer.
pub pos: ChunkPos,
pub status: ChunkLoadStatus,
}

#[derive(Debug)]
pub enum ChunkLoadStatus {
/// A new chunk was successfully loaded and inserted into the instance.
/// A new chunk was successfully loaded and inserted into the layer.
Success {
/// The time this chunk was last modified, measured in seconds since the
/// epoch.
Expand All @@ -446,11 +446,11 @@ pub enum ChunkLoadStatus {
Failed(anyhow::Error),
}

/// An event sent by `valence_anvil` when a chunk is unloaded from an instance.
/// An event sent by `valence_anvil` when a chunk is unloaded from an layer.
#[derive(Event, Debug)]
pub struct ChunkUnloadEvent {
/// The [`Instance`] where the chunk was unloaded.
pub instance: Entity,
/// The [`ChunkLayer`] where the chunk was unloaded.
pub chunk_layer: Entity,
/// The position of the chunk that was unloaded.
pub pos: ChunkPos,
}
2 changes: 1 addition & 1 deletion crates/valence_anvil/src/parse_chunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use thiserror::Error;
use valence_biome::BiomeId;
use valence_block::{BlockKind, PropName, PropValue};
use valence_core::ident::Ident;
use valence_instance::chunk::{Chunk, UnloadedChunk};
use valence_layer::chunk::{Chunk, UnloadedChunk};
use valence_nbt::{Compound, List, Value};

#[derive(Clone, Debug, Error)]
Expand Down
Loading
Loading