aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md1
-rw-r--r--Cargo.lock1
-rw-r--r--azalea-client/src/client.rs10
-rw-r--r--azalea-client/src/local_player.rs63
-rw-r--r--azalea-client/src/plugins/block_update.rs8
-rw-r--r--azalea-client/src/plugins/chunks.rs22
-rw-r--r--azalea-client/src/plugins/disconnect.rs6
-rw-r--r--azalea-client/src/plugins/interact/mod.rs12
-rw-r--r--azalea-client/src/plugins/interact/pick.rs12
-rw-r--r--azalea-client/src/plugins/inventory/equipment_effects.rs14
-rw-r--r--azalea-client/src/plugins/inventory/mod.rs12
-rw-r--r--azalea-client/src/plugins/join.rs11
-rw-r--r--azalea-client/src/plugins/mining.rs42
-rw-r--r--azalea-client/src/plugins/movement.rs18
-rw-r--r--azalea-client/src/plugins/packet/config/mod.rs10
-rw-r--r--azalea-client/src/plugins/packet/game/events.rs17
-rw-r--r--azalea-client/src/plugins/packet/game/mod.rs217
-rw-r--r--azalea-client/src/plugins/packet/mod.rs2
-rw-r--r--azalea-client/src/plugins/tick_counter.rs8
-rw-r--r--azalea-client/src/plugins/tick_end.rs4
-rw-r--r--azalea-client/src/test_utils/simulation.rs18
-rw-r--r--azalea-client/tests/simulation/change_dimension_to_nether_and_back.rs22
-rw-r--r--azalea-client/tests/simulation/client_disconnect.rs4
-rw-r--r--azalea-client/tests/simulation/login_to_dimension_with_same_name.rs24
-rw-r--r--azalea-client/tests/simulation/receive_spawn_entity_and_start_config_packet.rs4
-rw-r--r--azalea-client/tests/simulation/receive_start_config_packet.rs4
-rw-r--r--azalea-core/src/registry_holder/mod.rs2
-rw-r--r--azalea-entity/src/plugin/components.rs10
-rw-r--r--azalea-entity/src/plugin/indexing.rs76
-rw-r--r--azalea-entity/src/plugin/mod.rs71
-rw-r--r--azalea-entity/src/plugin/relative_updates.rs6
-rw-r--r--azalea-physics/src/collision/entity_collisions.rs6
-rw-r--r--azalea-physics/src/collision/mod.rs10
-rw-r--r--azalea-physics/src/collision/world_collisions.rs12
-rw-r--r--azalea-physics/src/fluids.rs22
-rw-r--r--azalea-physics/src/lib.rs36
-rw-r--r--azalea-physics/src/travel.rs14
-rw-r--r--azalea-physics/tests/physics.rs102
-rw-r--r--azalea-protocol/Cargo.toml8
-rw-r--r--azalea-protocol/src/packets/game/c_add_entity.rs4
-rw-r--r--azalea-world/src/container.rs66
-rw-r--r--azalea-world/src/find_blocks.rs20
-rw-r--r--azalea-world/src/lib.rs9
-rw-r--r--azalea-world/src/world.rs54
-rw-r--r--azalea/examples/testbot/commands/debug.rs22
-rw-r--r--azalea/src/client_impl/entity_query.rs54
-rw-r--r--azalea/src/client_impl/mod.rs47
-rw-r--r--azalea/src/entity_ref/mod.rs4
-rw-r--r--azalea/src/entity_ref/shared_impls.rs24
-rw-r--r--azalea/src/events.rs4
-rw-r--r--azalea/src/nearest_entity.rs46
-rw-r--r--azalea/src/pathfinder/debug.rs8
-rw-r--r--azalea/src/pathfinder/extras/utils.rs4
-rw-r--r--azalea/src/pathfinder/mod.rs79
-rw-r--r--azalea/src/pathfinder/moves/mod.rs21
-rw-r--r--azalea/src/pathfinder/simulation.rs56
-rw-r--r--azalea/src/pathfinder/world.rs14
-rw-r--r--azalea/src/swarm/builder.rs6
-rw-r--r--azalea/src/swarm/chat.rs12
-rw-r--r--azalea/src/swarm/events.rs4
-rw-r--r--azalea/src/swarm/mod.rs4
61 files changed, 748 insertions, 755 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a0ac74dd..d95581e1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -18,6 +18,7 @@ is breaking anyways, semantic versioning is not followed.
### Changed
+- Rename `Instance` to `World` (and rename other related types).
- Move the `Client` struct out of `azalea-client` into `azalea`.
- `Client::ecs` is now an `RwLock` instead of a `Mutex`.
- `Client::component` and `entity_component` now return a mapped RwLock guard instead of cloning the component.
diff --git a/Cargo.lock b/Cargo.lock
index f7f86db7..10ea58df 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -536,6 +536,7 @@ dependencies = [
"azalea-inventory",
"azalea-protocol-macros",
"azalea-registry",
+ "azalea-world",
"bevy_ecs",
"flate2",
"futures",
diff --git a/azalea-client/src/client.rs b/azalea-client/src/client.rs
index b7d01d58..90b1264c 100644
--- a/azalea-client/src/client.rs
+++ b/azalea-client/src/client.rs
@@ -11,7 +11,7 @@ use azalea_entity::{
EntityUpdateSystems, PlayerAbilities, indexing::EntityIdIndex, inventory::Inventory,
};
use azalea_physics::local_player::PhysicsState;
-use azalea_world::InstanceContainer;
+use azalea_world::Worlds;
use bevy_app::{App, AppExit, Plugin, PluginsState, SubApp, Update};
use bevy_ecs::{
message::MessageCursor,
@@ -29,7 +29,7 @@ use crate::{
connection::RawConnection,
cookies::ServerCookies,
interact::BlockStatePredictionHandler,
- local_player::{Hunger, InstanceHolder, PermissionLevel, TabList},
+ local_player::{Hunger, PermissionLevel, TabList, WorldHolder},
mining,
movement::LastSentLookDirection,
player::retroactively_add_game_profile_component,
@@ -43,7 +43,7 @@ use crate::{
#[derive(Bundle)]
pub struct LocalPlayerBundle {
pub raw_connection: RawConnection,
- pub instance_holder: InstanceHolder,
+ pub world_holder: WorldHolder,
pub metadata: azalea_entity::metadata::PlayerMetadataBundle,
}
@@ -56,7 +56,7 @@ pub struct LocalPlayerBundle {
/// If you want to filter for this, use [`InGameState`].
#[derive(Bundle, Default)]
pub struct JoinedClientBundle {
- // note that InstanceHolder isn't here because it's set slightly before we fully join the world
+ // note that WorldHolder isn't here because it's set slightly before we fully join the world
pub physics_state: PhysicsState,
pub inventory: Inventory,
pub tab_list: TabList,
@@ -98,7 +98,7 @@ impl Plugin for AzaleaPlugin {
.after(crate::join::handle_start_join_server_event),
),
)
- .init_resource::<InstanceContainer>()
+ .init_resource::<Worlds>()
.init_resource::<TabList>();
}
}
diff --git a/azalea-client/src/local_player.rs b/azalea-client/src/local_player.rs
index 9e44913c..444b2fcc 100644
--- a/azalea-client/src/local_player.rs
+++ b/azalea-client/src/local_player.rs
@@ -1,7 +1,7 @@
use std::{collections::HashMap, sync::Arc};
use azalea_core::game_type::GameMode;
-use azalea_world::{Instance, PartialInstance};
+use azalea_world::{PartialWorld, World};
use bevy_ecs::{component::Component, prelude::*};
use derive_more::{Deref, DerefMut};
use parking_lot::RwLock;
@@ -9,28 +9,29 @@ use uuid::Uuid;
use crate::{ClientInformation, player::PlayerInfo};
-/// A component that keeps strong references to our [`PartialInstance`] and
-/// [`Instance`] for local players.
+/// A component that keeps strong references to our [`PartialWorld`] and
+/// [`World`] for local players.
///
-/// This can also act as a convenience for accessing the player's Instance since
-/// the alternative is to look up the player's [`InstanceName`] in the
-/// [`InstanceContainer`].
+/// This can also act as a convenient way to access the player's `World`, since
+/// the alternative is to look up the player's [`WorldName`] in the [`Worlds`]
+/// resource.
///
-/// [`InstanceContainer`]: azalea_world::InstanceContainer
-/// [`InstanceName`]: azalea_world::InstanceName
+/// [`Worlds`]: azalea_world::Worlds
+/// [`WorldName`]: azalea_world::WorldName
#[derive(Clone, Component)]
-pub struct InstanceHolder {
- /// The partial instance is the world this client currently has loaded.
+pub struct WorldHolder {
+ /// The slice of the world that this client actually has loaded, based on
+ /// its render distance.
+ pub partial: Arc<RwLock<PartialWorld>>,
+ /// The combined [`PartialWorld`]s of all clients in the same world.
///
- /// It has a limited render distance.
- pub partial_instance: Arc<RwLock<PartialInstance>>,
- /// The combined [`PartialInstance`]s of all clients in the same instance
- /// (aka world/dimension).
- ///
- /// This is only relevant if you're using a shared world (i.e. a
- /// swarm).
- pub instance: Arc<RwLock<Instance>>,
+ /// The distinction between this and `partial` is mostly only relevant if
+ /// you're using a shared world (i.e. a swarm). If in doubt, prefer to use
+ /// the shared world.
+ pub shared: Arc<RwLock<World>>,
}
+#[deprecated = "renamed to `WorldHolder`."]
+pub type InstanceHolder = WorldHolder;
/// The gamemode of a local player. For a non-local player, you can look up the
/// player in the [`TabList`].
@@ -103,18 +104,18 @@ impl Hunger {
}
}
-impl InstanceHolder {
- /// Create a new `InstanceHolder` for the given entity.
+impl WorldHolder {
+ /// Create a new `WorldHolder` for the given entity.
///
- /// The partial instance will be created for you. The render distance will
+ /// The partial world will be created for you. The render distance will
/// be set to a default value, which you can change by creating a new
- /// partial_instance.
- pub fn new(entity: Entity, instance: Arc<RwLock<Instance>>) -> Self {
+ /// partial world.
+ pub fn new(entity: Entity, shared: Arc<RwLock<World>>) -> Self {
let client_information = ClientInformation::default();
- InstanceHolder {
- instance,
- partial_instance: Arc::new(RwLock::new(PartialInstance::new(
+ WorldHolder {
+ shared,
+ partial: Arc::new(RwLock::new(PartialWorld::new(
azalea_world::chunk_storage::calculate_chunk_storage_range(
client_information.view_distance.into(),
),
@@ -123,19 +124,19 @@ impl InstanceHolder {
}
}
- /// Reset the `Instance` to a new reference to an empty instance, but with
+ /// Reset the [`World`] to be a reference to an empty world, but with
/// the same registries as the current one.
///
/// This is used by Azalea when entering the config state.
pub fn reset(&mut self) {
- let registries = self.instance.read().registries.clone();
+ let registries = self.shared.read().registries.clone();
- let new_instance = Instance {
+ let new_world = World {
registries,
..Default::default()
};
- self.instance = Arc::new(RwLock::new(new_instance));
+ self.shared = Arc::new(RwLock::new(new_world));
- self.partial_instance.write().reset();
+ self.partial.write().reset();
}
}
diff --git a/azalea-client/src/plugins/block_update.rs b/azalea-client/src/plugins/block_update.rs
index 46e6b409..51dba728 100644
--- a/azalea-client/src/plugins/block_update.rs
+++ b/azalea-client/src/plugins/block_update.rs
@@ -5,7 +5,7 @@ use bevy_ecs::prelude::*;
use crate::{
chunks::handle_receive_chunk_event, interact::BlockStatePredictionHandler,
- local_player::InstanceHolder,
+ local_player::WorldHolder,
};
pub struct BlockUpdatePlugin;
@@ -34,12 +34,12 @@ pub struct QueuedServerBlockUpdates {
pub fn handle_block_update_event(
mut query: Query<(
&mut QueuedServerBlockUpdates,
- &InstanceHolder,
+ &WorldHolder,
&mut BlockStatePredictionHandler,
)>,
) {
- for (mut queued, instance_holder, mut prediction_handler) in query.iter_mut() {
- let world = instance_holder.instance.read();
+ for (mut queued, world_holder, mut prediction_handler) in query.iter_mut() {
+ let world = world_holder.shared.read();
for (pos, block_state) in queued.list.drain(..) {
if !prediction_handler.update_known_server_state(pos, block_state) {
world.chunks.set_block_state(pos, block_state);
diff --git a/azalea-client/src/plugins/chunks.rs b/azalea-client/src/plugins/chunks.rs
index d5014516..0937c2ef 100644
--- a/azalea-client/src/plugins/chunks.rs
+++ b/azalea-client/src/plugins/chunks.rs
@@ -17,7 +17,7 @@ use bevy_ecs::prelude::*;
use tracing::{error, trace};
use crate::{
- inventory::InventorySystems, local_player::InstanceHolder, packet::game::SendGamePacketEvent,
+ inventory::InventorySystems, local_player::WorldHolder, packet::game::SendGamePacketEvent,
respawn::perform_respawn,
};
@@ -66,42 +66,40 @@ pub struct ChunkBatchFinishedEvent {
pub fn handle_receive_chunk_event(
mut events: MessageReader<ReceiveChunkEvent>,
- mut query: Query<&InstanceHolder>,
+ mut query: Query<&WorldHolder>,
) {
for event in events.read() {
let pos = ChunkPos::new(event.packet.x, event.packet.z);
let local_player = query.get_mut(event.entity).unwrap();
- let mut instance = local_player.instance.write();
- let mut partial_instance = local_player.partial_instance.write();
+ let mut world = local_player.shared.write();
+ let mut partial_world = local_player.partial.write();
// OPTIMIZATION: if we already know about the chunk from the shared world (and
// not ourselves), then we don't need to parse it again. This is only used when
// we have a shared world, since we check that the chunk isn't currently owned
// by this client.
- let shared_chunk = instance.chunks.get(&pos);
- let this_client_has_chunk = partial_instance.chunks.limited_get(&pos).is_some();
+ let shared_chunk = world.chunks.get(&pos);
+ let this_client_has_chunk = partial_world.chunks.limited_get(&pos).is_some();
if !this_client_has_chunk && let Some(shared_chunk) = shared_chunk {
trace!("Skipping parsing chunk {pos:?} because we already know about it");
- partial_instance
- .chunks
- .limited_set(&pos, Some(shared_chunk));
+ partial_world.chunks.limited_set(&pos, Some(shared_chunk));
continue;
}
let heightmaps = &event.packet.chunk_data.heightmaps;
- if let Err(e) = partial_instance.chunks.replace_with_packet_data(
+ if let Err(e) = partial_world.chunks.replace_with_packet_data(
&pos,
&mut Cursor::new(&event.packet.chunk_data.data),
heightmaps,
- &mut instance.chunks,
+ &mut world.chunks,
) {
error!(
"Couldn't set chunk data: {e}. World height: {}",
- instance.chunks.height
+ world.chunks.height
);
}
}
diff --git a/azalea-client/src/plugins/disconnect.rs b/azalea-client/src/plugins/disconnect.rs
index 081c174e..be98383b 100644
--- a/azalea-client/src/plugins/disconnect.rs
+++ b/azalea-client/src/plugins/disconnect.rs
@@ -1,10 +1,10 @@
//! Disconnect a client from the server.
use azalea_chat::FormattedText;
+use azalea_core::entity_id::MinecraftEntityId;
use azalea_entity::{
EntityBundle, HasClientLoaded, InLoadedChunk, LocalEntity, metadata::PlayerMetadataBundle,
};
-use azalea_core::entity_id::MinecraftEntityId;
use bevy_app::{App, Plugin, PostUpdate};
use bevy_ecs::prelude::*;
use derive_more::Deref;
@@ -14,7 +14,7 @@ use super::login::IsAuthenticated;
#[cfg(feature = "online-mode")]
use crate::chat_signing;
use crate::{
- client::JoinedClientBundle, connection::RawConnection, local_player::InstanceHolder,
+ client::JoinedClientBundle, connection::RawConnection, local_player::WorldHolder,
tick_counter::TicksConnected,
};
@@ -63,7 +63,7 @@ pub struct RemoveOnDisconnectBundle {
pub entity: EntityBundle,
pub minecraft_entity_id: MinecraftEntityId,
- pub instance_holder: InstanceHolder,
+ pub world_holder: WorldHolder,
pub player_metadata: PlayerMetadataBundle,
pub in_loaded_chunk: InLoadedChunk,
//// This makes it close the TCP connection.
diff --git a/azalea-client/src/plugins/interact/mod.rs b/azalea-client/src/plugins/interact/mod.rs
index d8f8b8b4..04986de7 100644
--- a/azalea-client/src/plugins/interact/mod.rs
+++ b/azalea-client/src/plugins/interact/mod.rs
@@ -30,7 +30,7 @@ use azalea_protocol::packets::game::{
s_swing::ServerboundSwing,
s_use_item_on::ServerboundUseItemOn,
};
-use azalea_world::Instance;
+use azalea_world::World;
use bevy_app::{App, Plugin, Update};
use bevy_ecs::prelude::*;
use tracing::warn;
@@ -140,7 +140,7 @@ impl BlockStatePredictionHandler {
}
}
- pub fn end_prediction_up_to(&mut self, seq: u32, world: &Instance) {
+ pub fn end_prediction_up_to(&mut self, seq: u32, world: &World) {
let mut to_remove = Vec::new();
for (pos, state) in &self.server_state {
if state.seq > seq {
@@ -377,10 +377,10 @@ pub fn handle_entity_interact(
///
/// If this is false, then we can interact with the block.
///
-/// Passing the inventory, block position, and instance is necessary for the
-/// adventure mode check.
+/// The world, block position, and inventory are used for the adventure mode
+/// check.
pub fn check_is_interaction_restricted(
- instance: &Instance,
+ world: &World,
block_pos: BlockPos,
game_mode: &GameMode,
inventory: &Inventory,
@@ -393,7 +393,7 @@ pub fn check_is_interaction_restricted(
let held_item = inventory.held_item();
match &held_item {
ItemStack::Present(item) => {
- let block = instance.chunks.get_block_state(block_pos);
+ let block = world.chunks.get_block_state(block_pos);
let Some(block) = block else {
// block isn't loaded so just say that it is restricted
return true;
diff --git a/azalea-client/src/plugins/interact/pick.rs b/azalea-client/src/plugins/interact/pick.rs
index 8ffe47e8..1fed584a 100644
--- a/azalea-client/src/plugins/interact/pick.rs
+++ b/azalea-client/src/plugins/interact/pick.rs
@@ -17,7 +17,7 @@ use azalea_physics::{
clip::{BlockShapeType, ClipContext, FluidPickType},
collision::entity_collisions::{AabbQuery, get_entities},
};
-use azalea_world::{Instance, InstanceContainer, InstanceName};
+use azalea_world::{World, WorldName, Worlds};
use bevy_ecs::prelude::*;
use derive_more::{Deref, DerefMut};
@@ -37,13 +37,13 @@ pub fn update_hit_result_component(
&Position,
&EntityDimensions,
&LookDirection,
- &InstanceName,
+ &WorldName,
&Physics,
&Attributes,
),
With<LocalEntity>,
>,
- instance_container: Res<InstanceContainer>,
+ worlds: Res<Worlds>,
aabb_query: AabbQuery,
pickable_query: MaybePickableEntityQuery,
) {
@@ -63,7 +63,7 @@ pub fn update_hit_result_component(
let eye_position = position.up(dimensions.eye_height.into());
- let Some(world_lock) = instance_container.get(world_name) else {
+ let Some(world_lock) = worlds.get(world_name) else {
continue;
};
let world = world_lock.read();
@@ -117,7 +117,7 @@ pub struct PickOpts<'world, 'state, 'a, 'b, 'c> {
look_direction: LookDirection,
eye_position: Vec3,
aabb: &'a Aabb,
- world: &'a Instance,
+ world: &'a World,
entity_pick_range: f64,
block_pick_range: f64,
aabb_query: &'a AabbQuery<'world, 'state, 'b>,
@@ -246,7 +246,7 @@ struct PickEntityOpts<'world, 'state, 'a, 'b> {
source_entity: Entity,
eye_position: Vec3,
end_position: Vec3,
- world: &'a azalea_world::Instance,
+ world: &'a azalea_world::World,
pick_range_squared: f64,
predicate: &'a dyn Fn(Entity) -> bool,
aabb: &'a Aabb,
diff --git a/azalea-client/src/plugins/inventory/equipment_effects.rs b/azalea-client/src/plugins/inventory/equipment_effects.rs
index 47220bf2..d5897f48 100644
--- a/azalea-client/src/plugins/inventory/equipment_effects.rs
+++ b/azalea-client/src/plugins/inventory/equipment_effects.rs
@@ -19,7 +19,7 @@ use bevy_ecs::{
};
use tracing::{debug, error, warn};
-use crate::local_player::InstanceHolder;
+use crate::local_player::WorldHolder;
/// A component that contains the equipment slots that we had last tick.
///
@@ -91,9 +91,9 @@ pub struct EquipmentChange {
pub fn handle_equipment_changes(
equipment_changes: On<EquipmentChangesEvent>,
- mut query: Query<(&InstanceHolder, &mut LastEquipmentItems, &mut Attributes)>,
+ mut query: Query<(&WorldHolder, &mut LastEquipmentItems, &mut Attributes)>,
) {
- let Ok((instance_holder, mut last_equipment_items, mut attributes)) =
+ let Ok((world_holder, mut last_equipment_items, mut attributes)) =
query.get_mut(equipment_changes.entity)
else {
error!(
@@ -112,7 +112,7 @@ pub fn handle_equipment_changes(
// stopLocationBasedEffects
for (attribute, modifier) in
- collect_attribute_modifiers_from_item(slot, &change.old, instance_holder)
+ collect_attribute_modifiers_from_item(slot, &change.old, world_holder)
{
if let Some(attribute) = attributes.get_mut(attribute) {
attribute.remove(&modifier.id);
@@ -126,7 +126,7 @@ pub fn handle_equipment_changes(
// see ItemStack.forEachModifier in vanilla
for (attribute, modifier) in
- collect_attribute_modifiers_from_item(slot, &change.new, instance_holder)
+ collect_attribute_modifiers_from_item(slot, &change.new, world_holder)
{
if let Some(attribute) = attributes.get_mut(attribute) {
attribute.remove(&modifier.id);
@@ -144,7 +144,7 @@ pub fn handle_equipment_changes(
fn collect_attribute_modifiers_from_item(
slot: EquipmentSlot,
item: &ItemStack,
- instance_holder: &InstanceHolder,
+ world_holder: &WorldHolder,
) -> Vec<(azalea_registry::builtin::Attribute, AttributeModifier)> {
let mut modifiers = Vec::new();
@@ -161,7 +161,7 @@ fn collect_attribute_modifiers_from_item(
.get_component::<components::Enchantments>()
.unwrap_or_default();
if !enchants.levels.is_empty() {
- let registry_holder = &instance_holder.instance.read().registries;
+ let registry_holder = &world_holder.shared.read().registries;
for (enchant, &level) in &enchants.levels {
let Some((_enchant_id, enchant_definition)) = enchant.resolve(registry_holder) else {
warn!(
diff --git a/azalea-client/src/plugins/inventory/mod.rs b/azalea-client/src/plugins/inventory/mod.rs
index 740decb1..908ebe66 100644
--- a/azalea-client/src/plugins/inventory/mod.rs
+++ b/azalea-client/src/plugins/inventory/mod.rs
@@ -11,7 +11,7 @@ use azalea_protocol::packets::game::{
s_set_carried_item::ServerboundSetCarriedItem,
};
use azalea_registry::builtin::MenuKind;
-use azalea_world::{InstanceContainer, InstanceName};
+use azalea_world::{WorldName, Worlds};
use bevy_app::{App, Plugin};
use bevy_ecs::prelude::*;
use indexmap::IndexMap;
@@ -167,10 +167,10 @@ pub struct ContainerClickEvent {
pub fn handle_container_click_event(
container_click: On<ContainerClickEvent>,
mut commands: Commands,
- mut query: Query<(Entity, &mut Inv, Option<&PlayerAbilities>, &InstanceName)>,
- instance_container: Res<InstanceContainer>,
+ mut query: Query<(Entity, &mut Inv, Option<&PlayerAbilities>, &WorldName)>,
+ worlds: Res<Worlds>,
) {
- let (entity, mut inventory, player_abilities, instance_name) =
+ let (entity, mut inventory, player_abilities, world_name) =
query.get_mut(container_click.entity).unwrap();
if inventory.id != container_click.window_id {
error!(
@@ -180,7 +180,7 @@ pub fn handle_container_click_event(
return;
}
- let Some(instance) = instance_container.get(instance_name) else {
+ let Some(world) = worlds.get(world_name) else {
return;
};
@@ -191,7 +191,7 @@ pub fn handle_container_click_event(
);
let new_slots = inventory.menu().slots();
- let registry_holder = &instance.read().registries;
+ let registry_holder = &world.read().registries;
// see which slots changed after clicking and put them in the map the server
// uses this to check if we desynced
diff --git a/azalea-client/src/plugins/join.rs b/azalea-client/src/plugins/join.rs
index c254bc26..a6c9c586 100644
--- a/azalea-client/src/plugins/join.rs
+++ b/azalea-client/src/plugins/join.rs
@@ -11,7 +11,7 @@ use azalea_protocol::{
login::{ClientboundLoginPacket, ServerboundHello, ServerboundLoginPacket},
},
};
-use azalea_world::Instance;
+use azalea_world::World;
use bevy_app::prelude::*;
use bevy_ecs::prelude::*;
use bevy_tasks::{IoTaskPool, Task, futures_lite::future};
@@ -23,6 +23,7 @@ use crate::{
LocalPlayerBundle,
account::Account,
connection::RawConnection,
+ local_player::WorldHolder,
packet::login::{InLoginState, SendLoginPacketEvent},
};
@@ -204,12 +205,12 @@ pub fn poll_create_connection_task(
let (read_conn, write_conn) = conn.into_split();
let (read_conn, write_conn) = (read_conn.raw, write_conn.raw);
- let instance = Instance::default();
- let instance_holder = crate::local_player::InstanceHolder::new(
+ let world = World::default();
+ let world_holder = WorldHolder::new(
entity,
// default to an empty world, it'll be set correctly later when we
// get the login packet
- Arc::new(RwLock::new(instance)),
+ Arc::new(RwLock::new(world)),
);
entity_mut.insert((
@@ -220,7 +221,7 @@ pub fn poll_create_connection_task(
write_conn,
ConnectionProtocol::Login,
),
- instance_holder,
+ world_holder,
metadata: azalea_entity::metadata::PlayerMetadataBundle::default(),
},
InLoginState,
diff --git a/azalea-client/src/plugins/mining.rs b/azalea-client/src/plugins/mining.rs
index e9dcbe59..35b01a6a 100644
--- a/azalea-client/src/plugins/mining.rs
+++ b/azalea-client/src/plugins/mining.rs
@@ -8,7 +8,7 @@ use azalea_inventory::ItemStack;
use azalea_physics::{PhysicsSystems, collision::BlockWithShape};
use azalea_protocol::packets::game::s_player_action::{self, ServerboundPlayerAction};
use azalea_registry::builtin::{BlockKind, ItemKind};
-use azalea_world::{InstanceContainer, InstanceName};
+use azalea_world::{Worlds, WorldName};
use bevy_app::{App, Plugin, Update};
use bevy_ecs::prelude::*;
use derive_more::{Deref, DerefMut};
@@ -20,7 +20,7 @@ use crate::{
check_is_interaction_restricted, pick::HitResultComponent,
},
inventory::InventorySystems,
- local_player::{InstanceHolder, LocalGameMode, PermissionLevel},
+ local_player::{LocalGameMode, PermissionLevel, WorldHolder},
movement::MoveEventsSystems,
packet::game::SendGamePacketEvent,
};
@@ -219,7 +219,7 @@ pub fn handle_mining_queued(
query: Query<(
Entity,
&MiningQueued,
- &InstanceHolder,
+ &WorldHolder,
&LocalGameMode,
&Inventory,
&ActiveEffects,
@@ -240,7 +240,7 @@ pub fn handle_mining_queued(
for (
entity,
mining_queued,
- instance_holder,
+ world_holder,
game_mode,
inventory,
active_effects,
@@ -261,9 +261,9 @@ pub fn handle_mining_queued(
trace!("handle_mining_queued {mining_queued:?}");
commands.entity(entity).remove::<MiningQueued>();
- let instance = instance_holder.instance.read();
+ let world = world_holder.shared.read();
if check_is_interaction_restricted(
- &instance,
+ &world,
mining_queued.position,
&game_mode.current,
inventory,
@@ -320,7 +320,7 @@ pub fn handle_mining_queued(
));
}
- let target_block_state = instance
+ let target_block_state = world
.get_block_state(mining_queued.position)
.unwrap_or_default();
@@ -472,7 +472,7 @@ pub struct FinishMiningBlockEvent {
pub fn handle_finish_mining_block_observer(
finish_mining_block: On<FinishMiningBlockEvent>,
mut query: Query<(
- &InstanceName,
+ &WorldName,
&LocalGameMode,
&Inventory,
&PlayerAbilities,
@@ -480,12 +480,12 @@ pub fn handle_finish_mining_block_observer(
&Position,
&mut BlockStatePredictionHandler,
)>,
- instances: Res<InstanceContainer>,
+ worlds: Res<Worlds>,
) {
let event = finish_mining_block.event();
let (
- instance_name,
+ world_name,
game_mode,
inventory,
abilities,
@@ -493,9 +493,9 @@ pub fn handle_finish_mining_block_observer(
player_pos,
mut prediction_handler,
) = query.get_mut(finish_mining_block.entity).unwrap();
- let instance_lock = instances.get(instance_name).unwrap();
- let instance = instance_lock.read();
- if check_is_interaction_restricted(&instance, event.position, &game_mode.current, inventory) {
+ let world_lock = worlds.get(world_name).unwrap();
+ let world = world_lock.read();
+ if check_is_interaction_restricted(&world, event.position, &game_mode.current, inventory) {
return;
}
@@ -508,7 +508,7 @@ pub fn handle_finish_mining_block_observer(
}
}
- let Some(block_state) = instance.get_block_state(event.position) else {
+ let Some(block_state) = world.get_block_state(event.position) else {
return;
};
@@ -528,7 +528,7 @@ pub fn handle_finish_mining_block_observer(
// when we break a waterlogged block we want to keep the water there
let fluid_state = FluidState::from(block_state);
let block_state_for_fluid = BlockState::from(fluid_state);
- let old_state = instance
+ let old_state = world
.set_block_state(event.position, block_state_for_fluid)
.unwrap_or_default();
prediction_handler.retain_known_server_state(event.position, old_state, **player_pos);
@@ -581,7 +581,7 @@ pub fn decrement_mine_delay(mut query: Query<&mut MineDelay>) {
pub fn continue_mining_block(
mut query: Query<(
Entity,
- &InstanceName,
+ &WorldName,
&LocalGameMode,
&Inventory,
&MineBlockPos,
@@ -598,11 +598,11 @@ pub fn continue_mining_block(
)>,
mut commands: Commands,
mut mine_block_progress_events: MessageWriter<MineBlockProgressEvent>,
- instances: Res<InstanceContainer>,
+ worlds: Res<Worlds>,
) {
for (
entity,
- instance_name,
+ world_name,
game_mode,
inventory,
current_mining_pos,
@@ -644,9 +644,9 @@ pub fn continue_mining_block(
)
{
trace!("continue mining block at {:?}", mining.pos);
- let instance_lock = instances.get(instance_name).unwrap();
- let instance = instance_lock.read();
- let target_block_state = instance.get_block_state(mining.pos).unwrap_or_default();
+ let world_lock = worlds.get(world_name).unwrap();
+ let world = world_lock.read();
+ let target_block_state = world.get_block_state(mining.pos).unwrap_or_default();
trace!("target_block_state: {target_block_state:?}");
diff --git a/azalea-client/src/plugins/movement.rs b/azalea-client/src/plugins/movement.rs
index 40cc108e..94b996a0 100644
--- a/azalea-client/src/plugins/movement.rs
+++ b/azalea-client/src/plugins/movement.rs
@@ -31,12 +31,12 @@ use azalea_protocol::{
},
};
use azalea_registry::builtin::EntityKind;
-use azalea_world::Instance;
+use azalea_world::World;
use bevy_app::{App, Plugin, Update};
use bevy_ecs::prelude::*;
use crate::{
- local_player::{Hunger, InstanceHolder, LocalGameMode},
+ local_player::{Hunger, LocalGameMode, WorldHolder},
packet::game::SendGamePacketEvent,
};
@@ -296,7 +296,7 @@ pub fn local_player_ai_step(
&PlayerAbilities,
&metadata::Swimming,
&metadata::SleepingPos,
- &InstanceHolder,
+ &WorldHolder,
&Position,
Option<&Hunger>,
Option<&LastSentInput>,
@@ -316,7 +316,7 @@ pub fn local_player_ai_step(
abilities,
swimming,
sleeping_pos,
- instance_holder,
+ world_holder,
position,
hunger,
last_sent_input,
@@ -333,7 +333,7 @@ pub fn local_player_ai_step(
let is_passenger = false;
let is_sleeping = sleeping_pos.is_some();
- let world = instance_holder.instance.read();
+ let world = world_holder.shared.read();
let ctx = CanPlayerFitCtx {
world: &world,
entity,
@@ -587,16 +587,16 @@ pub fn update_pose(
&Physics,
&PhysicsState,
&LocalGameMode,
- &InstanceHolder,
+ &WorldHolder,
&Position,
)>,
aabb_query: AabbQuery,
collidable_entity_query: CollidableEntityQuery,
) {
- for (entity, mut pose, physics, physics_state, game_mode, instance_holder, position) in
+ for (entity, mut pose, physics, physics_state, game_mode, world_holder, position) in
query.iter_mut()
{
- let world = instance_holder.instance.read();
+ let world = world_holder.shared.read();
let world = &*world;
let ctx = CanPlayerFitCtx {
world,
@@ -642,7 +642,7 @@ pub fn update_pose(
}
struct CanPlayerFitCtx<'world, 'state, 'a, 'b> {
- world: &'a Instance,
+ world: &'a World,
entity: Entity,
position: Position,
aabb_query: &'a AabbQuery<'world, 'state, 'b>,
diff --git a/azalea-client/src/plugins/packet/config/mod.rs b/azalea-client/src/plugins/packet/config/mod.rs
index 27dae837..f59b8c23 100644
--- a/azalea-client/src/plugins/packet/config/mod.rs
+++ b/azalea-client/src/plugins/packet/config/mod.rs
@@ -17,7 +17,7 @@ use crate::{
connection::RawConnection,
cookies::{RequestCookieEvent, StoreCookieEvent},
disconnect::DisconnectEvent,
- local_player::InstanceHolder,
+ local_player::WorldHolder,
packet::game::{KeepAliveEvent, ResourcePackEvent},
};
@@ -69,12 +69,12 @@ pub struct ConfigPacketHandler<'a> {
}
impl ConfigPacketHandler<'_> {
pub fn registry_data(&mut self, p: &ClientboundRegistryData) {
- as_system::<Query<&InstanceHolder>>(self.ecs, |mut query| {
- let instance_holder = query.get_mut(self.player).unwrap();
- let mut instance = instance_holder.instance.write();
+ as_system::<Query<&WorldHolder>>(self.ecs, |mut query| {
+ let world_holder = query.get_mut(self.player).unwrap();
+ let mut world = world_holder.shared.write();
// add the new registry data
- instance
+ world
.registries
.append(p.registry_id.clone(), p.entries.clone());
});
diff --git a/azalea-client/src/plugins/packet/game/events.rs b/azalea-client/src/plugins/packet/game/events.rs
index 535bd519..bc070ec8 100644
--- a/azalea-client/src/plugins/packet/game/events.rs
+++ b/azalea-client/src/plugins/packet/game/events.rs
@@ -5,8 +5,7 @@ use azalea_protocol::packets::{
Packet,
game::{ClientboundGamePacket, ClientboundPlayerCombatKill, ServerboundGamePacket},
};
-use azalea_registry::identifier::Identifier;
-use azalea_world::Instance;
+use azalea_world::{World, WorldName};
use bevy_ecs::prelude::*;
use parking_lot::RwLock;
use tracing::{error, trace};
@@ -138,16 +137,18 @@ pub struct ResourcePackEvent {
pub prompt: Option<FormattedText>,
}
-/// An instance (aka world, dimension) was loaded by a client.
+/// A world instance (aka dimension) was loaded by a client.
///
-/// Since the instance is given to you as a weak reference, it won't be able to
-/// be `upgrade`d if all local players leave it.
+/// Since the world is given to you as a weak reference, it won't be able to be
+/// `upgrade`d if all local players unload it.
#[derive(Clone, Debug, Message)]
-pub struct InstanceLoadedEvent {
+pub struct WorldLoadedEvent {
pub entity: Entity,
- pub name: Identifier,
- pub instance: Weak<RwLock<Instance>>,
+ pub name: WorldName,
+ pub world: Weak<RwLock<World>>,
}
+#[deprecated = "renamed to `WorldLoadedEvent`."]
+pub type InstanceLoadedEvent = WorldLoadedEvent;
/// A Bevy trigger that's sent when our client receives a [`ClientboundPing`]
/// packet in the game state.
diff --git a/azalea-client/src/plugins/packet/game/mod.rs b/azalea-client/src/plugins/packet/game/mod.rs
index f93a02ea..6489c899 100644
--- a/azalea-client/src/plugins/packet/game/mod.rs
+++ b/azalea-client/src/plugins/packet/game/mod.rs
@@ -19,7 +19,7 @@ use azalea_protocol::{
packets::{ConnectionProtocol, game::*},
};
use azalea_registry::builtin::EntityKind;
-use azalea_world::{InstanceContainer, InstanceName, PartialInstance};
+use azalea_world::{PartialWorld, WorldName, Worlds};
use bevy_ecs::{prelude::*, system::SystemState};
pub use events::*;
use tracing::{debug, error, trace, warn};
@@ -34,7 +34,7 @@ use crate::{
disconnect::DisconnectEvent,
interact::BlockStatePredictionHandler,
inventory::{ClientsideCloseContainerEvent, MenuOpenedEvent, SetContainerContentEvent},
- local_player::{Hunger, InstanceHolder, LocalGameMode, TabList},
+ local_player::{Hunger, LocalGameMode, TabList, WorldHolder},
movement::{KnockbackData, KnockbackEvent},
packet::{as_system, declare_packet_handlers},
player::{GameProfileComponent, PlayerInfo},
@@ -207,15 +207,15 @@ impl GamePacketHandler<'_> {
(
&GameProfileComponent,
&ClientInformation,
- Option<&mut InstanceName>,
+ Option<&mut WorldName>,
Option<&mut LoadedBy>,
&mut EntityIdIndex,
- &mut InstanceHolder,
+ &mut WorldHolder,
),
With<LocalEntity>,
>,
- MessageWriter<InstanceLoadedEvent>,
- ResMut<InstanceContainer>,
+ MessageWriter<WorldLoadedEvent>,
+ ResMut<Worlds>,
ResMut<EntityUuidIndex>,
Query<&mut LoadedBy, Without<LocalEntity>>,
)>(
@@ -223,33 +223,31 @@ impl GamePacketHandler<'_> {
|(
mut commands,
mut query,
- mut instance_loaded_events,
- mut instance_container,
+ mut world_loaded_events,
+ mut worlds,
mut entity_uuid_index,
mut loaded_by_query,
)| {
let (
game_profile,
client_information,
- instance_name,
+ world_name,
loaded_by,
mut entity_id_index,
- mut instance_holder,
+ mut world_holder,
) = query.get_mut(self.player).unwrap();
- let new_instance_name = p.common.dimension.clone();
+ let new_world_name = WorldName(p.common.dimension.clone());
- if let Some(mut instance_name) = instance_name {
- **instance_name = new_instance_name.clone();
+ if let Some(mut world_name) = world_name {
+ *world_name = new_world_name.clone();
} else {
- commands
- .entity(self.player)
- .insert(InstanceName(new_instance_name.clone()));
+ commands.entity(self.player).insert(new_world_name.clone());
}
- let weak_instance;
+ let weak_world;
{
- let client_registries = &instance_holder.instance.read().registries;
+ let client_registries = &world_holder.shared.read().registries;
let Some((_dimension_type, dimension_data)) =
p.common.dimension_type(client_registries)
@@ -257,46 +255,44 @@ impl GamePacketHandler<'_> {
return;
};
- // add this world to the instance_container (or don't if it's already
- // there)
- weak_instance = instance_container.get_or_insert(
- new_instance_name.clone(),
+ // add this world to the `worlds` (or don't, if it's already there)
+ weak_world = worlds.get_or_insert(
+ new_world_name.clone(),
dimension_data.height,
dimension_data.min_y,
client_registries,
);
- instance_loaded_events.write(InstanceLoadedEvent {
+ world_loaded_events.write(WorldLoadedEvent {
entity: self.player,
- name: new_instance_name.clone(),
- instance: Arc::downgrade(&weak_instance),
+ name: new_world_name.clone(),
+ world: Arc::downgrade(&weak_world),
});
}
- // set the partial_world to an empty world
- // (when we add chunks or entities those will be in the
- // instance_container)
+ // set the partial world to an empty world (when we add chunks or entities those
+ // will be in the `worlds`)
- *instance_holder.partial_instance.write() = PartialInstance::new(
+ *world_holder.partial.write() = PartialWorld::new(
azalea_world::chunk_storage::calculate_chunk_storage_range(
client_information.view_distance.into(),
),
- // this argument makes it so other clients don't update this player entity
- // in a shared instance
+ // this argument makes it so other clients don't update this player entity in a
+ // shared world
Some(self.player),
);
{
- let client_registries = instance_holder.instance.read().registries.clone();
- let shared_registries = &mut weak_instance.write().registries;
- // add the registries from this instance to the weak instance
+ let client_registries = world_holder.shared.read().registries.clone();
+ let shared_registries = &mut weak_world.write().registries;
+ // add the registries from this world to the weak world
shared_registries.extend(client_registries);
}
- instance_holder.instance = weak_instance;
+ world_holder.shared = weak_world;
let entity_bundle = EntityBundle::new(
game_profile.uuid,
Vec3::ZERO,
EntityKind::Player,
- new_instance_name,
+ new_world_name,
);
let entity_id = p.player_id;
// insert our components into the ecs :)
@@ -316,7 +312,7 @@ impl GamePacketHandler<'_> {
Some(game_profile.uuid),
&mut entity_id_index,
&mut entity_uuid_index,
- &mut instance_holder.instance.write(),
+ &mut world_holder.shared.write(),
);
// every entity is now unloaded by this player
@@ -532,9 +528,9 @@ impl GamePacketHandler<'_> {
pub fn set_chunk_cache_center(&mut self, p: &ClientboundSetChunkCacheCenter) {
debug!("Got chunk cache center packet {p:?}");
- as_system::<Query<&InstanceHolder>>(self.ecs, |mut query| {
- let instance_holder = query.get_mut(self.player).unwrap();
- let mut partial_world = instance_holder.partial_instance.write();
+ as_system::<Query<&WorldHolder>>(self.ecs, |mut query| {
+ let world_holder = query.get_mut(self.player).unwrap();
+ let mut partial_world = world_holder.partial.write();
partial_world
.chunks
@@ -564,10 +560,10 @@ impl GamePacketHandler<'_> {
as_system::<(
Commands,
- Query<(&mut EntityIdIndex, Option<&InstanceName>, Option<&TabList>)>,
+ Query<(&mut EntityIdIndex, Option<&WorldName>, Option<&TabList>)>,
Query<&mut LoadedBy>,
Query<Entity>,
- Res<InstanceContainer>,
+ Res<Worlds>,
ResMut<EntityUuidIndex>,
)>(
self.ecs,
@@ -576,22 +572,22 @@ impl GamePacketHandler<'_> {
mut query,
mut loaded_by_query,
entity_query,
- instance_container,
+ worlds,
mut entity_uuid_index,
)| {
- let (mut entity_id_index, instance_name, tab_list) =
+ let (mut entity_id_index, world_name, tab_list) =
query.get_mut(self.player).unwrap();
let entity_id = p.id;
- let Some(instance_name) = instance_name else {
+ let Some(world_name) = world_name else {
warn!("got add player packet but we haven't gotten a login packet yet");
return;
};
// check if the entity already exists, and if it does then only add to LoadedBy
- let instance = instance_container.get(instance_name).unwrap();
- if let Some(&ecs_entity) = instance.read().entity_by_id.get(&entity_id) {
+ let world = worlds.get(world_name).unwrap();
+ if let Some(&ecs_entity) = world.read().entity_by_id.get(&entity_id) {
// entity already exists
let Ok(mut loaded_by) = loaded_by_query.get_mut(ecs_entity) else {
// LoadedBy for this entity isn't in the ecs! figure out what went wrong
@@ -621,7 +617,7 @@ impl GamePacketHandler<'_> {
// entity doesn't exist in the global index!
- let bundle = p.as_entity_bundle((**instance_name).clone());
+ let bundle = p.as_entity_bundle(world_name.to_owned());
let mut spawned =
commands.spawn((entity_id, LoadedBy(HashSet::from([self.player])), bundle));
let ecs_entity: Entity = spawned.id();
@@ -636,7 +632,7 @@ impl GamePacketHandler<'_> {
Some(p.uuid),
&mut entity_id_index,
&mut entity_uuid_index,
- &mut instance.write(),
+ &mut world.write(),
);
// add the GameProfileComponent if the uuid is in the tab list
@@ -659,12 +655,12 @@ impl GamePacketHandler<'_> {
pub fn set_entity_data(&mut self, p: &ClientboundSetEntityData) {
as_system::<(
Commands,
- Query<(&EntityIdIndex, &InstanceHolder)>,
+ Query<(&EntityIdIndex, &WorldHolder)>,
// this is a separate query since it's applied on the entity id that's being updated
// instead of the player that received the packet
Query<&EntityKindComponent>,
)>(self.ecs, |(mut commands, query, entity_kind_query)| {
- let (entity_id_index, instance_holder) = query.get(self.player).unwrap();
+ let (entity_id_index, world_holder) = query.get(self.player).unwrap();
let entity = entity_id_index.get_by_minecraft_entity(p.id);
@@ -693,7 +689,7 @@ impl GamePacketHandler<'_> {
// we use RelativeEntityUpdate because it makes sure changes aren't made
// multiple times
commands.entity(entity).queue(RelativeEntityUpdate::new(
- instance_holder.partial_instance.clone(),
+ world_holder.partial.clone(),
move |entity| {
let entity_id = entity.id();
entity.world_scope(|world| {
@@ -720,10 +716,10 @@ impl GamePacketHandler<'_> {
// vanilla servers use this packet for knockback, but note that the Explode
// packet is also sometimes used by servers for knockback
- as_system::<(Commands, Query<(&EntityIdIndex, &InstanceHolder)>)>(
+ as_system::<(Commands, Query<(&EntityIdIndex, &WorldHolder)>)>(
self.ecs,
|(mut commands, query)| {
- let (entity_id_index, instance_holder) = query.get(self.player).unwrap();
+ let (entity_id_index, world_holder) = query.get(self.player).unwrap();
let Some(entity) = entity_id_index.get_by_minecraft_entity(p.id) else {
// note that this log (and some other ones like the one in RemoveEntities)
@@ -742,7 +738,7 @@ impl GamePacketHandler<'_> {
let data = KnockbackData::Set(p.delta.to_vec3());
commands.entity(entity).queue(RelativeEntityUpdate::new(
- instance_holder.partial_instance.clone(),
+ world_holder.partial.clone(),
move |entity_mut| {
entity_mut
.world_scope(|world| world.trigger(KnockbackEvent { entity, data }));
@@ -790,10 +786,10 @@ impl GamePacketHandler<'_> {
pub fn teleport_entity(&mut self, p: &ClientboundTeleportEntity) {
debug!("Got teleport entity packet {p:?}");
- as_system::<(Commands, Query<(&EntityIdIndex, &InstanceHolder)>)>(
+ as_system::<(Commands, Query<(&EntityIdIndex, &WorldHolder)>)>(
self.ecs,
|(mut commands, mut query)| {
- let (entity_id_index, instance_holder) = query.get_mut(self.player).unwrap();
+ let (entity_id_index, world_holder) = query.get_mut(self.player).unwrap();
let Some(entity) = entity_id_index.get_by_minecraft_entity(p.id) else {
warn!("Got teleport entity packet for unknown entity id {}", p.id);
@@ -804,7 +800,7 @@ impl GamePacketHandler<'_> {
let change = p.change.clone();
commands.entity(entity).queue(RelativeEntityUpdate::new(
- instance_holder.partial_instance.clone(),
+ world_holder.partial.clone(),
move |entity| {
let entity_id = entity.id();
entity.world_scope(move |world| {
@@ -835,10 +831,10 @@ impl GamePacketHandler<'_> {
pub fn rotate_head(&mut self, _p: &ClientboundRotateHead) {}
pub fn move_entity_pos(&mut self, p: &ClientboundMoveEntityPos) {
- as_system::<(Commands, Query<(&EntityIdIndex, &InstanceHolder)>)>(
+ as_system::<(Commands, Query<(&EntityIdIndex, &WorldHolder)>)>(
self.ecs,
|(mut commands, mut query)| {
- let (entity_id_index, instance_holder) = query.get_mut(self.player).unwrap();
+ let (entity_id_index, world_holder) = query.get_mut(self.player).unwrap();
debug!("Got move entity pos packet {p:?}");
@@ -851,7 +847,7 @@ impl GamePacketHandler<'_> {
let new_delta = p.delta.clone();
let new_on_ground = p.on_ground;
commands.entity(entity).queue(RelativeEntityUpdate::new(
- instance_holder.partial_instance.clone(),
+ world_holder.partial.clone(),
move |entity_mut| {
let mut physics = entity_mut.get_mut::<Physics>().unwrap();
let new_pos = physics.vec_delta_codec.decode(&new_delta);
@@ -874,10 +870,10 @@ impl GamePacketHandler<'_> {
}
pub fn move_entity_pos_rot(&mut self, p: &ClientboundMoveEntityPosRot) {
- as_system::<(Commands, Query<(&EntityIdIndex, &InstanceHolder)>)>(
+ as_system::<(Commands, Query<(&EntityIdIndex, &WorldHolder)>)>(
self.ecs,
|(mut commands, mut query)| {
- let (entity_id_index, instance_holder) = query.get_mut(self.player).unwrap();
+ let (entity_id_index, world_holder) = query.get_mut(self.player).unwrap();
debug!("Got move entity pos rot packet {p:?}");
@@ -901,7 +897,7 @@ impl GamePacketHandler<'_> {
let new_on_ground = p.on_ground;
commands.entity(entity).queue(RelativeEntityUpdate::new(
- instance_holder.partial_instance.clone(),
+ world_holder.partial.clone(),
move |entity_mut| {
let mut physics = entity_mut.get_mut::<Physics>().unwrap();
let new_position = physics.vec_delta_codec.decode(&new_delta);
@@ -924,10 +920,10 @@ impl GamePacketHandler<'_> {
}
pub fn move_entity_rot(&mut self, p: &ClientboundMoveEntityRot) {
- as_system::<(Commands, Query<(&EntityIdIndex, &InstanceHolder)>)>(
+ as_system::<(Commands, Query<(&EntityIdIndex, &WorldHolder)>)>(
self.ecs,
|(mut commands, mut query)| {
- let (entity_id_index, instance_holder) = query.get_mut(self.player).unwrap();
+ let (entity_id_index, world_holder) = query.get_mut(self.player).unwrap();
let entity = entity_id_index.get_by_minecraft_entity(p.entity_id);
if let Some(entity) = entity {
@@ -938,7 +934,7 @@ impl GamePacketHandler<'_> {
let new_on_ground = p.on_ground;
commands.entity(entity).queue(RelativeEntityUpdate::new(
- instance_holder.partial_instance.clone(),
+ world_holder.partial.clone(),
move |entity_mut| {
let mut physics = entity_mut.get_mut::<Physics>().unwrap();
physics.set_on_ground(new_on_ground);
@@ -1113,10 +1109,10 @@ impl GamePacketHandler<'_> {
let mob_effect = p.mob_effect;
let effect_data = &p.data;
- as_system::<(Commands, Query<(&EntityIdIndex, &InstanceHolder)>)>(
+ as_system::<(Commands, Query<(&EntityIdIndex, &WorldHolder)>)>(
self.ecs,
|(mut commands, query)| {
- let (entity_id_index, instance_holder) = query.get(self.player).unwrap();
+ let (entity_id_index, world_holder) = query.get(self.player).unwrap();
let Some(entity) = entity_id_index.get_by_minecraft_entity(p.entity_id) else {
debug!(
@@ -1126,10 +1122,10 @@ impl GamePacketHandler<'_> {
return;
};
- let partial_instance = instance_holder.partial_instance.clone();
+ let partial_world = world_holder.partial.clone();
let effect_data = effect_data.clone();
commands.entity(entity).queue(RelativeEntityUpdate::new(
- partial_instance,
+ partial_world,
move |entity| {
if let Some(mut active_effects) = entity.get_mut::<ActiveEffects>() {
active_effects.insert(mob_effect, effect_data.clone());
@@ -1147,11 +1143,11 @@ impl GamePacketHandler<'_> {
pub fn award_stats(&mut self, _p: &ClientboundAwardStats) {}
pub fn block_changed_ack(&mut self, p: &ClientboundBlockChangedAck) {
- as_system::<Query<(&InstanceHolder, &mut BlockStatePredictionHandler)>>(
+ as_system::<Query<(&WorldHolder, &mut BlockStatePredictionHandler)>>(
self.ecs,
|mut query| {
let (local_player, mut prediction_handler) = query.get_mut(self.player).unwrap();
- let world = local_player.instance.read();
+ let world = local_player.shared.read();
prediction_handler.end_prediction_up_to(p.seq, &world);
},
);
@@ -1277,12 +1273,12 @@ impl GamePacketHandler<'_> {
pub fn forget_level_chunk(&mut self, p: &ClientboundForgetLevelChunk) {
debug!("Got forget level chunk packet {p:?}");
- as_system::<Query<&InstanceHolder>>(self.ecs, |mut query| {
+ as_system::<Query<&WorldHolder>>(self.ecs, |mut query| {
let local_player = query.get_mut(self.player).unwrap();
- let mut partial_instance = local_player.partial_instance.write();
+ let mut partial_world = local_player.partial.write();
- partial_instance.chunks.limited_set(&p.pos, None);
+ partial_world.chunks.limited_set(&p.pos, None);
});
}
@@ -1355,10 +1351,10 @@ impl GamePacketHandler<'_> {
let mob_effect = p.effect;
- as_system::<(Commands, Query<(&EntityIdIndex, &InstanceHolder)>)>(
+ as_system::<(Commands, Query<(&EntityIdIndex, &WorldHolder)>)>(
self.ecs,
|(mut commands, query)| {
- let (entity_id_index, instance_holder) = query.get(self.player).unwrap();
+ let (entity_id_index, world_holder) = query.get(self.player).unwrap();
let Some(entity) = entity_id_index.get_by_minecraft_entity(p.entity_id) else {
debug!(
@@ -1368,9 +1364,9 @@ impl GamePacketHandler<'_> {
return;
};
- let partial_instance = instance_holder.partial_instance.clone();
+ let partial_world = world_holder.partial.clone();
commands.entity(entity).queue(RelativeEntityUpdate::new(
- partial_instance,
+ partial_world,
move |entity| {
if let Some(mut active_effects) = entity.get_mut::<ActiveEffects>() {
active_effects.remove(mob_effect);
@@ -1405,71 +1401,67 @@ impl GamePacketHandler<'_> {
Commands,
Query<
(
- &mut InstanceHolder,
+ &mut WorldHolder,
&GameProfileComponent,
&ClientInformation,
- Option<&mut InstanceName>,
+ Option<&mut WorldName>,
),
With<LocalEntity>,
>,
MessageWriter<_>,
- ResMut<InstanceContainer>,
+ ResMut<Worlds>,
Query<&mut LoadedBy, Without<LocalEntity>>,
)>(
self.ecs,
- |(mut commands, mut query, mut events, mut instance_container, mut loaded_by_query)| {
- let Ok((mut instance_holder, game_profile, client_information, instance_name)) =
+ |(mut commands, mut query, mut events, mut worlds, mut loaded_by_query)| {
+ let Ok((mut world_holder, game_profile, client_information, world_name)) =
query.get_mut(self.player)
else {
warn!("Got respawn packet but player doesn't have the required components");
return;
};
- let new_instance_name = p.common.dimension.clone();
+ let new_world_name = WorldName(p.common.dimension.clone());
- if let Some(mut instance_name) = instance_name {
- **instance_name = new_instance_name.clone();
+ if let Some(mut world_name) = world_name {
+ *world_name = new_world_name.clone();
} else {
- commands
- .entity(self.player)
- .insert(InstanceName(new_instance_name.clone()));
+ commands.entity(self.player).insert(new_world_name.clone());
}
- let weak_instance;
+ let weak_world;
{
- let client_registries = &instance_holder.instance.read().registries;
+ let client_registries = &world_holder.shared.read().registries;
let Some((_dimension_type, dimension_data)) =
p.common.dimension_type(client_registries)
else {
return;
};
- // add this world to the instance_container (or don't if it's already
- // there)
- weak_instance = instance_container.get_or_insert(
- new_instance_name.clone(),
+ // add this world to the `worlds` (or don't if it's already there)
+ weak_world = worlds.get_or_insert(
+ new_world_name.clone(),
dimension_data.height,
dimension_data.min_y,
client_registries,
);
- events.write(InstanceLoadedEvent {
+ events.write(WorldLoadedEvent {
entity: self.player,
- name: new_instance_name.clone(),
- instance: Arc::downgrade(&weak_instance),
+ name: new_world_name.clone(),
+ world: Arc::downgrade(&weak_world),
});
}
- // set the partial_world to an empty world
- // (when we add chunks or entities those will be in the
- // instance_container)
+ // set the partial world to an empty world (when we add chunks or entities,
+ // those will be in the `worlds`)
- *instance_holder.partial_instance.write() = PartialInstance::new(
+ *world_holder.partial.write() = PartialWorld::new(
azalea_world::chunk_storage::calculate_chunk_storage_range(
client_information.view_distance.into(),
),
Some(self.player),
);
- instance_holder.instance = weak_instance;
+ world_holder.shared = weak_world;
// every entity is now unloaded by this player
for mut loaded_by in &mut loaded_by_query.iter_mut() {
@@ -1481,7 +1473,7 @@ impl GamePacketHandler<'_> {
game_profile.uuid,
Vec3::ZERO,
EntityKind::Player,
- new_instance_name,
+ new_world_name,
);
// update the local gamemode and metadata things
commands.entity(self.player).insert((
@@ -1502,11 +1494,10 @@ impl GamePacketHandler<'_> {
pub fn start_configuration(&mut self, _p: &ClientboundStartConfiguration) {
debug!("Got start configuration packet");
- as_system::<(Commands, Query<(&mut RawConnection, &mut InstanceHolder)>)>(
+ as_system::<(Commands, Query<(&mut RawConnection, &mut WorldHolder)>)>(
self.ecs,
|(mut commands, mut query)| {
- let Some((mut raw_conn, mut instance_holder)) = query.get_mut(self.player).ok()
- else {
+ let Some((mut raw_conn, mut world_holder)) = query.get_mut(self.player).ok() else {
warn!("Got start configuration packet but player doesn't have a RawConnection");
return;
};
@@ -1523,16 +1514,16 @@ impl GamePacketHandler<'_> {
.remove::<crate::JoinedClientBundle>()
.remove::<EntityBundle>();
- instance_holder.reset();
+ world_holder.reset();
},
);
}
pub fn entity_position_sync(&mut self, p: &ClientboundEntityPositionSync) {
- as_system::<(Commands, Query<(&EntityIdIndex, &InstanceHolder)>)>(
+ as_system::<(Commands, Query<(&EntityIdIndex, &WorldHolder)>)>(
self.ecs,
|(mut commands, mut query)| {
- let (entity_id_index, instance_holder) = query.get_mut(self.player).unwrap();
+ let (entity_id_index, world_holder) = query.get_mut(self.player).unwrap();
let Some(entity) = entity_id_index.get_by_minecraft_entity(p.id) else {
debug!("Got teleport entity packet for unknown entity id {}", p.id);
@@ -1544,7 +1535,7 @@ impl GamePacketHandler<'_> {
let new_look_direction = p.values.look_direction;
commands.entity(entity).queue(RelativeEntityUpdate::new(
- instance_holder.partial_instance.clone(),
+ world_holder.partial.clone(),
move |entity_mut| {
let is_local_entity = entity_mut.get::<LocalEntity>().is_some();
let mut physics = entity_mut.get_mut::<Physics>().unwrap();
diff --git a/azalea-client/src/plugins/packet/mod.rs b/azalea-client/src/plugins/packet/mod.rs
index 9d842dc6..63a94ee0 100644
--- a/azalea-client/src/plugins/packet/mod.rs
+++ b/azalea-client/src/plugins/packet/mod.rs
@@ -45,7 +45,7 @@ impl Plugin for PacketPlugin {
.add_message::<game::DeathEvent>()
.add_message::<game::KeepAliveEvent>()
.add_message::<game::ResourcePackEvent>()
- .add_message::<game::InstanceLoadedEvent>()
+ .add_message::<game::WorldLoadedEvent>()
.add_message::<login::ReceiveCustomQueryEvent>();
}
}
diff --git a/azalea-client/src/plugins/tick_counter.rs b/azalea-client/src/plugins/tick_counter.rs
index e4b5f0a4..fba8bc1c 100644
--- a/azalea-client/src/plugins/tick_counter.rs
+++ b/azalea-client/src/plugins/tick_counter.rs
@@ -1,6 +1,6 @@
use azalea_core::tick::GameTick;
use azalea_physics::PhysicsSystems;
-use azalea_world::InstanceName;
+use azalea_world::WorldName;
use bevy_app::{App, Plugin};
use bevy_ecs::prelude::*;
@@ -27,9 +27,9 @@ impl Plugin for TickCounterPlugin {
}
}
-/// Increment the [`TicksConnected`] component on every entity
-/// that lives in an instance.
-pub fn increment_counter(mut query: Query<&mut TicksConnected, With<InstanceName>>) {
+/// Increment the [`TicksConnected`] component for every entity that's in any
+/// world.
+pub fn increment_counter(mut query: Query<&mut TicksConnected, With<WorldName>>) {
for mut counter in &mut query {
counter.0 += 1;
}
diff --git a/azalea-client/src/plugins/tick_end.rs b/azalea-client/src/plugins/tick_end.rs
index 15cd2e59..6df46c78 100644
--- a/azalea-client/src/plugins/tick_end.rs
+++ b/azalea-client/src/plugins/tick_end.rs
@@ -4,7 +4,7 @@ use azalea_core::tick::GameTick;
use azalea_entity::LocalEntity;
use azalea_physics::PhysicsSystems;
use azalea_protocol::packets::game::ServerboundClientTickEnd;
-use azalea_world::InstanceName;
+use azalea_world::WorldName;
use bevy_app::{App, Plugin};
use bevy_ecs::prelude::*;
@@ -27,7 +27,7 @@ impl Plugin for TickEndPlugin {
}
pub fn game_tick_packet(
- query: Query<Entity, (With<LocalEntity>, With<InstanceName>)>,
+ query: Query<Entity, (With<LocalEntity>, With<WorldName>)>,
mut commands: Commands,
) {
for entity in query.iter() {
diff --git a/azalea-client/src/test_utils/simulation.rs b/azalea-client/src/test_utils/simulation.rs
index 0e480b92..ce4c919d 100644
--- a/azalea-client/src/test_utils/simulation.rs
+++ b/azalea-client/src/test_utils/simulation.rs
@@ -31,7 +31,7 @@ use azalea_registry::{
data::{Biome, DimensionKind},
identifier::Identifier,
};
-use azalea_world::{Chunk, Instance, Section, palette::PalettedContainer};
+use azalea_world::{Chunk, Section, World, palette::PalettedContainer};
use bevy_app::App;
use bevy_ecs::{
component::Mutable,
@@ -45,7 +45,7 @@ use uuid::Uuid;
use crate::{
InConfigState, LocalPlayerBundle, connection::RawConnection, disconnect::DisconnectEvent,
- local_player::InstanceHolder, packet::game::SendGamePacketEvent, player::GameProfileComponent,
+ local_player::WorldHolder, packet::game::SendGamePacketEvent, player::GameProfileComponent,
};
/// A way to simulate a client in a server, used for some internal tests.
@@ -175,15 +175,15 @@ impl Simulation {
}
pub fn chunk(&self, chunk_pos: ChunkPos) -> Option<Arc<RwLock<Chunk>>> {
- self.component::<InstanceHolder>()
- .instance
+ self.component::<WorldHolder>()
+ .shared
.read()
.chunks
.get(&chunk_pos)
}
pub fn get_block_state(&self, pos: BlockPos) -> Option<BlockState> {
- self.component::<InstanceHolder>()
- .instance
+ self.component::<WorldHolder>()
+ .shared
.read()
.get_block_state(pos)
}
@@ -287,12 +287,12 @@ fn create_local_player_bundle(
let raw_connection = RawConnection::new_networkless(connection_protocol);
- let instance = Instance::default();
- let instance_holder = InstanceHolder::new(entity, Arc::new(RwLock::new(instance)));
+ let world = World::default();
+ let world_holder = WorldHolder::new(entity, Arc::new(RwLock::new(world)));
let local_player_bundle = LocalPlayerBundle {
raw_connection,
- instance_holder,
+ world_holder,
metadata: PlayerMetadataBundle::default(),
};
diff --git a/azalea-client/tests/simulation/change_dimension_to_nether_and_back.rs b/azalea-client/tests/simulation/change_dimension_to_nether_and_back.rs
index 2d4fb749..c23ef843 100644
--- a/azalea-client/tests/simulation/change_dimension_to_nether_and_back.rs
+++ b/azalea-client/tests/simulation/change_dimension_to_nether_and_back.rs
@@ -6,7 +6,7 @@ use azalea_protocol::packets::{
config::{ClientboundFinishConfiguration, ClientboundRegistryData},
};
use azalea_registry::{DataRegistry, data::DimensionKind, identifier::Identifier};
-use azalea_world::InstanceName;
+use azalea_world::WorldName;
use simdnbt::owned::{NbtCompound, NbtTag};
#[test]
@@ -19,12 +19,12 @@ fn test_change_dimension_to_nether_and_back() {
fn generic_test_change_dimension_to_nether_and_back(using_respawn: bool) {
let make_basic_login_or_respawn_packet = if using_respawn {
- |dimension: DimensionKind, instance_name: Identifier| {
- make_basic_respawn_packet(dimension, instance_name).into_variant()
+ |dimension: DimensionKind, world_name: Identifier| {
+ make_basic_respawn_packet(dimension, world_name).into_variant()
}
} else {
- |dimension: DimensionKind, instance_name: Identifier| {
- make_basic_login_packet(dimension, instance_name).into_variant()
+ |dimension: DimensionKind, world_name: Identifier| {
+ make_basic_login_packet(dimension, world_name).into_variant()
}
};
@@ -81,9 +81,9 @@ fn generic_test_change_dimension_to_nether_and_back(using_respawn: bool) {
simulation.tick();
assert_eq!(
- *simulation.component::<InstanceName>(),
+ *simulation.component::<WorldName>(),
Identifier::new("azalea:a"),
- "InstanceName should be azalea:a after setting dimension to that"
+ "WorldName should be azalea:a after setting dimension to that"
);
simulation.receive_packet(make_basic_empty_chunk(ChunkPos::new(0, 0), (384 + 64) / 16));
@@ -108,9 +108,9 @@ fn generic_test_change_dimension_to_nether_and_back(using_respawn: bool) {
"chunk should not exist immediately after changing dimensions"
);
assert_eq!(
- *simulation.component::<InstanceName>(),
+ *simulation.component::<WorldName>(),
Identifier::new("azalea:b"),
- "InstanceName should be azalea:b after changing dimensions to that"
+ "WorldName should be azalea:b after changing dimensions to that"
);
simulation.receive_packet(make_basic_empty_chunk(ChunkPos::new(0, 0), 256 / 16));
@@ -136,9 +136,9 @@ fn generic_test_change_dimension_to_nether_and_back(using_respawn: bool) {
simulation.tick();
assert_eq!(
- *simulation.component::<InstanceName>(),
+ *simulation.component::<WorldName>(),
Identifier::new("azalea:a"),
- "InstanceName should be azalea:a after setting dimension back to that"
+ "WorldName should be azalea:a after setting dimension back to that"
);
assert!(
simulation.chunk(ChunkPos::new(0, 0)).is_none(),
diff --git a/azalea-client/tests/simulation/client_disconnect.rs b/azalea-client/tests/simulation/client_disconnect.rs
index 0956fbfa..60f112c2 100644
--- a/azalea-client/tests/simulation/client_disconnect.rs
+++ b/azalea-client/tests/simulation/client_disconnect.rs
@@ -1,6 +1,6 @@
use azalea_client::test_utils::prelude::*;
use azalea_protocol::packets::ConnectionProtocol;
-use azalea_world::InstanceName;
+use azalea_world::WorldName;
#[test]
fn test_client_disconnect() {
@@ -12,7 +12,7 @@ fn test_client_disconnect() {
simulation.tick();
// make sure we're disconnected
- let is_connected = simulation.has_component::<InstanceName>();
+ let is_connected = simulation.has_component::<WorldName>();
assert!(!is_connected);
// tick again to make sure nothing goes wrong
diff --git a/azalea-client/tests/simulation/login_to_dimension_with_same_name.rs b/azalea-client/tests/simulation/login_to_dimension_with_same_name.rs
index 917c50bb..ef67130f 100644
--- a/azalea-client/tests/simulation/login_to_dimension_with_same_name.rs
+++ b/azalea-client/tests/simulation/login_to_dimension_with_same_name.rs
@@ -1,5 +1,5 @@
use azalea_client::{
- InConfigState, InGameState, local_player::InstanceHolder, test_utils::prelude::*,
+ InConfigState, InGameState, local_player::WorldHolder, test_utils::prelude::*,
};
use azalea_core::position::ChunkPos;
use azalea_entity::LocalEntity;
@@ -9,7 +9,7 @@ use azalea_protocol::packets::{
game::ClientboundStartConfiguration,
};
use azalea_registry::{DataRegistry, data::DimensionKind, identifier::Identifier};
-use azalea_world::InstanceName;
+use azalea_world::WorldName;
use simdnbt::owned::{NbtCompound, NbtTag};
#[test]
@@ -22,12 +22,12 @@ fn test_login_to_dimension_with_same_name() {
fn generic_test_login_to_dimension_with_same_name(using_respawn: bool) {
let make_basic_login_or_respawn_packet = if using_respawn {
- |dimension: DimensionKind, instance_name: Identifier| {
- make_basic_respawn_packet(dimension, instance_name).into_variant()
+ |dimension: DimensionKind, world_name: Identifier| {
+ make_basic_respawn_packet(dimension, world_name).into_variant()
}
} else {
- |dimension: DimensionKind, instance_name: Identifier| {
- make_basic_login_packet(dimension, instance_name).into_variant()
+ |dimension: DimensionKind, world_name: Identifier| {
+ make_basic_login_packet(dimension, world_name).into_variant()
}
};
@@ -66,9 +66,9 @@ fn generic_test_login_to_dimension_with_same_name(using_respawn: bool) {
simulation.tick();
assert_eq!(
- *simulation.component::<InstanceName>(),
+ *simulation.component::<WorldName>(),
Identifier::new("azalea:overworld"),
- "InstanceName should be azalea:overworld after setting dimension to that"
+ "WorldName should be azalea:overworld after setting dimension to that"
);
simulation.receive_packet(make_basic_empty_chunk(ChunkPos::new(0, 0), (384 + 64) / 16));
@@ -107,14 +107,14 @@ fn generic_test_login_to_dimension_with_same_name(using_respawn: bool) {
"chunk should not exist immediately after changing dimensions"
);
assert_eq!(
- *simulation.component::<InstanceName>(),
+ *simulation.component::<WorldName>(),
Identifier::new("azalea:overworld"),
- "InstanceName should still be azalea:overworld after changing dimensions to that"
+ "WorldName should still be azalea:overworld after changing dimensions to that"
);
assert_eq!(
simulation
- .component::<InstanceHolder>()
- .instance
+ .component::<WorldHolder>()
+ .shared
.read()
.chunks
.height,
diff --git a/azalea-client/tests/simulation/receive_spawn_entity_and_start_config_packet.rs b/azalea-client/tests/simulation/receive_spawn_entity_and_start_config_packet.rs
index 13dd38fc..d6b228cb 100644
--- a/azalea-client/tests/simulation/receive_spawn_entity_and_start_config_packet.rs
+++ b/azalea-client/tests/simulation/receive_spawn_entity_and_start_config_packet.rs
@@ -5,7 +5,7 @@ use azalea_protocol::packets::{
game::{ClientboundAddEntity, ClientboundStartConfiguration},
};
use azalea_registry::builtin::EntityKind;
-use azalea_world::InstanceName;
+use azalea_world::WorldName;
use uuid::Uuid;
#[test]
@@ -15,7 +15,7 @@ fn test_receive_spawn_entity_and_start_config_packet() {
let mut simulation = Simulation::new(ConnectionProtocol::Game);
simulation.receive_packet(default_login_packet());
simulation.tick();
- assert!(simulation.has_component::<InstanceName>());
+ assert!(simulation.has_component::<WorldName>());
simulation.tick();
simulation.receive_packet(ClientboundAddEntity {
diff --git a/azalea-client/tests/simulation/receive_start_config_packet.rs b/azalea-client/tests/simulation/receive_start_config_packet.rs
index f87d65da..a54abe5b 100644
--- a/azalea-client/tests/simulation/receive_start_config_packet.rs
+++ b/azalea-client/tests/simulation/receive_start_config_packet.rs
@@ -1,6 +1,6 @@
use azalea_client::{InConfigState, test_utils::prelude::*};
use azalea_protocol::packets::{ConnectionProtocol, game::ClientboundStartConfiguration};
-use azalea_world::InstanceName;
+use azalea_world::WorldName;
#[test]
fn test_receive_start_config_packet() {
@@ -10,7 +10,7 @@ fn test_receive_start_config_packet() {
simulation.receive_packet(default_login_packet());
simulation.tick();
- assert!(simulation.has_component::<InstanceName>());
+ assert!(simulation.has_component::<WorldName>());
simulation.tick();
simulation.receive_packet(ClientboundStartConfiguration);
diff --git a/azalea-core/src/registry_holder/mod.rs b/azalea-core/src/registry_holder/mod.rs
index 90bad921..c83db40c 100644
--- a/azalea-core/src/registry_holder/mod.rs
+++ b/azalea-core/src/registry_holder/mod.rs
@@ -26,7 +26,7 @@ use tracing::error;
///
/// This is the registry that is sent to the client upon login.
///
-/// Note that `azalea-client` stores registries in `Instance` rather than
+/// Note that `azalea-client` stores registries per-world rather than
/// per-client like you might expect. This is an optimization for swarms to
/// reduce memory usage, since registries are expected to be the same for every
/// client in a world.
diff --git a/azalea-entity/src/plugin/components.rs b/azalea-entity/src/plugin/components.rs
index abeab160..4698a808 100644
--- a/azalea-entity/src/plugin/components.rs
+++ b/azalea-entity/src/plugin/components.rs
@@ -1,7 +1,7 @@
use azalea_block::fluid_state::FluidKind;
use azalea_core::position::{BlockPos, ChunkPos, Vec3};
-use azalea_registry::{builtin::EntityKind, identifier::Identifier};
-use azalea_world::InstanceName;
+use azalea_registry::builtin::EntityKind;
+use azalea_world::WorldName;
use bevy_ecs::{bundle::Bundle, component::Component};
use derive_more::{Deref, DerefMut};
use uuid::Uuid;
@@ -18,7 +18,7 @@ use crate::{
pub struct EntityBundle {
pub kind: EntityKindComponent,
pub uuid: EntityUuid,
- pub world_name: InstanceName,
+ pub world_name: WorldName,
pub position: Position,
pub last_sent_position: LastSentPosition,
@@ -36,13 +36,13 @@ pub struct EntityBundle {
}
impl EntityBundle {
- pub fn new(uuid: Uuid, pos: Vec3, kind: EntityKind, world_name: Identifier) -> Self {
+ pub fn new(uuid: Uuid, pos: Vec3, kind: EntityKind, world_name: WorldName) -> Self {
let dimensions = EntityDimensions::from(kind);
Self {
kind: EntityKindComponent(kind),
uuid: EntityUuid(uuid),
- world_name: InstanceName(world_name),
+ world_name,
position: Position(pos),
chunk_pos: EntityChunkPos(ChunkPos::from(&pos)),
last_sent_position: LastSentPosition(pos),
diff --git a/azalea-entity/src/plugin/indexing.rs b/azalea-entity/src/plugin/indexing.rs
index 3fba6b3c..9e539c23 100644
--- a/azalea-entity/src/plugin/indexing.rs
+++ b/azalea-entity/src/plugin/indexing.rs
@@ -6,7 +6,7 @@ use std::{
};
use azalea_core::{entity_id::MinecraftEntityId, position::ChunkPos};
-use azalea_world::{Instance, InstanceContainer, InstanceName};
+use azalea_world::{World, WorldName, Worlds};
use bevy_ecs::prelude::*;
use derive_more::{Deref, DerefMut};
use nohash_hasher::IntMap;
@@ -48,10 +48,10 @@ impl EntityUuidIndex {
/// An index of Minecraft entity IDs to Azalea ECS entities.
///
/// This is a `Component` so local players can keep track of entity IDs
-/// independently from the instance.
+/// independently from the world.
///
-/// If you need a per-instance instead of per-client version of this, you can
-/// use [`Instance::entity_by_id`].
+/// If you need a per-world instead of per-client version of this, you can
+/// use [`World::entity_by_id`].
#[derive(Component, Default)]
pub struct EntityIdIndex {
/// An index of entities by their MinecraftEntityId
@@ -105,7 +105,7 @@ impl EntityIdIndex {
} else {
// this is expected to happen when despawning entities if it was already
// despawned for another reason (like because the client received a
- // remove_entities packet, or if we're in a shared instance where entity ids are
+ // remove_entities packet, or if we're in a shared world where entity ids are
// different for each client)
trace!(
"Failed to remove {entity:?} from a client's EntityIdIndex (using EntityIdIndex::remove_by_ecs_entity). This may be expected behavior."
@@ -125,30 +125,30 @@ impl Debug for EntityUuidIndex {
#[derive(Component, Debug, Deref, DerefMut)]
pub struct EntityChunkPos(pub ChunkPos);
-/// Update the chunk position indexes in [`Instance::entities_by_chunk`].
+/// Update the chunk position indexes in [`World::entities_by_chunk`].
///
-/// [`Instance::entities_by_chunk`]: azalea_world::Instance::entities_by_chunk
+/// [`World::entities_by_chunk`]: azalea_world::World::entities_by_chunk
pub fn update_entity_chunk_positions(
- mut query: Query<(Entity, &Position, &InstanceName, &mut EntityChunkPos), Changed<Position>>,
- instance_container: Res<InstanceContainer>,
+ mut query: Query<(Entity, &Position, &WorldName, &mut EntityChunkPos), Changed<Position>>,
+ worlds: Res<Worlds>,
) {
- for (entity, pos, instance_name, mut entity_chunk_pos) in query.iter_mut() {
+ for (entity, pos, world_name, mut entity_chunk_pos) in query.iter_mut() {
let old_chunk = **entity_chunk_pos;
let new_chunk = ChunkPos::from(*pos);
if old_chunk != new_chunk {
**entity_chunk_pos = new_chunk;
if old_chunk != new_chunk {
- let Some(instance_lock) = instance_container.get(instance_name) else {
+ let Some(world_lock) = worlds.get(world_name) else {
continue;
};
- let mut instance = instance_lock.write();
+ let mut world = world_lock.write();
// move the entity from the old chunk to the new one
- if let Some(entities) = instance.entities_by_chunk.get_mut(&old_chunk) {
+ if let Some(entities) = world.entities_by_chunk.get_mut(&old_chunk) {
entities.remove(&entity);
}
- instance
+ world
.entities_by_chunk
.entry(new_chunk)
.or_default()
@@ -159,20 +159,20 @@ pub fn update_entity_chunk_positions(
}
}
-/// Insert new entities into [`Instance::entities_by_chunk`].
+/// Insert new entities into [`World::entities_by_chunk`].
pub fn insert_entity_chunk_position(
- query: Query<(Entity, &Position, &InstanceName), Added<EntityChunkPos>>,
- instance_container: Res<InstanceContainer>,
+ query: Query<(Entity, &Position, &WorldName), Added<EntityChunkPos>>,
+ worlds: Res<Worlds>,
) {
for (entity, pos, world_name) in query.iter() {
- let Some(instance_lock) = instance_container.get(world_name) else {
+ let Some(world_lock) = worlds.get(world_name) else {
// entity must've been despawned already
continue;
};
- let mut instance = instance_lock.write();
+ let mut world = world_lock.write();
let chunk = ChunkPos::from(*pos);
- instance
+ world
.entities_by_chunk
.entry(chunk)
.or_default()
@@ -185,26 +185,24 @@ pub fn insert_entity_chunk_position(
pub fn remove_despawned_entities_from_indexes(
mut commands: Commands,
mut entity_uuid_index: ResMut<EntityUuidIndex>,
- instance_container: Res<InstanceContainer>,
+ worlds: Res<Worlds>,
query: Query<
(
Entity,
&EntityUuid,
&MinecraftEntityId,
&Position,
- &InstanceName,
+ &WorldName,
&LoadedBy,
),
(Changed<LoadedBy>, Without<LocalEntity>),
>,
mut entity_id_index_query: Query<&mut EntityIdIndex>,
) {
- for (entity, uuid, minecraft_id, position, instance_name, loaded_by) in &query {
- let Some(instance_lock) = instance_container.get(instance_name) else {
- // the instance isn't even loaded by us, so we can safely delete the entity
- debug!(
- "Despawned entity {entity:?} because it's in an instance that isn't loaded anymore"
- );
+ for (entity, uuid, minecraft_id, position, world_name, loaded_by) in &query {
+ let Some(world_lock) = worlds.get(world_name) else {
+ // the world isn't even loaded by us, so we can safely delete the entity
+ debug!("Despawned entity {entity:?} because it's in a world that isn't loaded anymore");
if entity_uuid_index.entity_by_uuid.remove(uuid).is_none() {
warn!(
"Tried to remove entity {entity:?} from the uuid index but it was not there."
@@ -216,7 +214,7 @@ pub fn remove_despawned_entities_from_indexes(
continue;
};
- let mut instance = instance_lock.write();
+ let mut world = world_lock.write();
// if the entity is being loaded by any of our clients, don't despawn it
if !loaded_by.is_empty() {
@@ -225,17 +223,17 @@ pub fn remove_despawned_entities_from_indexes(
// remove the entity from the chunk index
let chunk = ChunkPos::from(position);
- match instance.entities_by_chunk.get_mut(&chunk) {
+ match world.entities_by_chunk.get_mut(&chunk) {
Some(entities_in_chunk) => {
if entities_in_chunk.remove(&entity) {
// remove the chunk if there's no entities in it anymore
if entities_in_chunk.is_empty() {
- instance.entities_by_chunk.remove(&chunk);
+ world.entities_by_chunk.remove(&chunk);
}
} else {
// search all the other chunks for it :(
let mut found_in_other_chunks = HashSet::new();
- for (other_chunk, entities_in_other_chunk) in &mut instance.entities_by_chunk {
+ for (other_chunk, entities_in_other_chunk) in &mut world.entities_by_chunk {
if entities_in_other_chunk.remove(&entity) {
found_in_other_chunks.insert(other_chunk);
}
@@ -253,7 +251,7 @@ pub fn remove_despawned_entities_from_indexes(
}
_ => {
let mut found_in_other_chunks = HashSet::new();
- for (other_chunk, entities_in_other_chunk) in &mut instance.entities_by_chunk {
+ for (other_chunk, entities_in_other_chunk) in &mut world.entities_by_chunk {
if entities_in_other_chunk.remove(&entity) {
found_in_other_chunks.insert(other_chunk);
}
@@ -273,9 +271,9 @@ pub fn remove_despawned_entities_from_indexes(
if entity_uuid_index.entity_by_uuid.remove(uuid).is_none() {
warn!("Tried to remove entity {entity:?} from the uuid index but it was not there.");
}
- if instance.entity_by_id.remove(minecraft_id).is_none() {
+ if world.entity_by_id.remove(minecraft_id).is_none() {
debug!(
- "Tried to remove entity {entity:?} from the per-instance entity id index but it was not there. This may be expected if you're in a shared instance."
+ "Tried to remove entity {entity:?} from the per-world entity id index but it was not there. This may be expected if you're in a shared world."
);
}
@@ -296,16 +294,16 @@ pub fn add_entity_to_indexes(
entity_uuid: Option<Uuid>,
entity_id_index: &mut EntityIdIndex,
entity_uuid_index: &mut EntityUuidIndex,
- instance: &mut Instance,
+ world: &mut World,
) {
// per-client id index
entity_id_index.insert(entity_id, ecs_entity);
- // per-instance id index
- instance.entity_by_id.insert(entity_id, ecs_entity);
+ // per-world id index
+ world.entity_by_id.insert(entity_id, ecs_entity);
if let Some(uuid) = entity_uuid {
- // per-instance uuid index
+ // per-world uuid index
entity_uuid_index.insert(uuid, ecs_entity);
}
}
diff --git a/azalea-entity/src/plugin/mod.rs b/azalea-entity/src/plugin/mod.rs
index 03dda233..e40c24f2 100644
--- a/azalea-entity/src/plugin/mod.rs
+++ b/azalea-entity/src/plugin/mod.rs
@@ -11,7 +11,7 @@ use azalea_core::{
tick::GameTick,
};
use azalea_registry::{builtin::BlockKind, tags};
-use azalea_world::{ChunkStorage, InstanceContainer, InstanceName};
+use azalea_world::{ChunkStorage, WorldName, Worlds};
use bevy_app::{App, Plugin, PostUpdate, Update};
use bevy_ecs::prelude::*;
pub use components::*;
@@ -97,22 +97,17 @@ pub fn add_dead(mut commands: Commands, query: Query<(Entity, &Health), Changed<
}
pub fn update_fluid_on_eyes(
- mut query: Query<(
- &mut FluidOnEyes,
- &Position,
- &EntityDimensions,
- &InstanceName,
- )>,
- instance_container: Res<InstanceContainer>,
+ mut query: Query<(&mut FluidOnEyes, &Position, &EntityDimensions, &WorldName)>,
+ worlds: Res<Worlds>,
) {
- for (mut fluid_on_eyes, position, dimensions, instance_name) in query.iter_mut() {
- let Some(instance) = instance_container.get(instance_name) else {
+ for (mut fluid_on_eyes, position, dimensions, world_name) in query.iter_mut() {
+ let Some(world) = worlds.get(world_name) else {
continue;
};
let adjusted_eye_y = position.y + (dimensions.eye_height as f64) - 0.1111111119389534;
let eye_block_pos = BlockPos::from(position.with_y(adjusted_eye_y));
- let fluid_at_eye = instance
+ let fluid_at_eye = world
.read()
.get_fluid_state(eye_block_pos)
.unwrap_or_default();
@@ -126,10 +121,10 @@ pub fn update_fluid_on_eyes(
}
pub fn update_on_climbable(
- mut query: Query<(&mut OnClimbable, &Position, &InstanceName), With<LocalEntity>>,
- instance_container: Res<InstanceContainer>,
+ mut query: Query<(&mut OnClimbable, &Position, &WorldName), With<LocalEntity>>,
+ worlds: Res<Worlds>,
) {
- for (mut on_climbable, position, instance_name) in query.iter_mut() {
+ for (mut on_climbable, position, world_name) in query.iter_mut() {
// TODO: there's currently no gamemode component that can be accessed from here,
// maybe LocalGameMode should be replaced with two components, maybe called
// EntityGameMode and PreviousGameMode?
@@ -138,27 +133,27 @@ pub fn update_on_climbable(
// continue;
// }
- let Some(instance) = instance_container.get(instance_name) else {
+ let Some(world) = worlds.get(world_name) else {
continue;
};
- let instance = instance.read();
+ let world = world.read();
let block_pos = BlockPos::from(position);
- let block_state_at_feet = instance.get_block_state(block_pos).unwrap_or_default();
+ let block_state_at_feet = world.get_block_state(block_pos).unwrap_or_default();
let block_at_feet = Box::<dyn BlockTrait>::from(block_state_at_feet);
let registry_block_at_feet = block_at_feet.as_registry_block();
**on_climbable = tags::blocks::CLIMBABLE.contains(&registry_block_at_feet)
|| (tags::blocks::TRAPDOORS.contains(&registry_block_at_feet)
- && is_trapdoor_useable_as_ladder(block_state_at_feet, block_pos, &instance));
+ && is_trapdoor_usable_as_ladder(block_state_at_feet, block_pos, &world));
}
}
-fn is_trapdoor_useable_as_ladder(
+fn is_trapdoor_usable_as_ladder(
block_state: BlockState,
block_pos: BlockPos,
- instance: &azalea_world::Instance,
+ world: &azalea_world::World,
) -> bool {
// trapdoor must be open
if !block_state
@@ -169,9 +164,7 @@ fn is_trapdoor_useable_as_ladder(
}
// block below must be a ladder
- let block_below = instance
- .get_block_state(block_pos.down(1))
- .unwrap_or_default();
+ let block_below = world.get_block_state(block_pos.down(1)).unwrap_or_default();
let registry_block_below = Box::<dyn BlockTrait>::from(block_below).as_registry_block();
if registry_block_below != BlockKind::Ladder {
return false;
@@ -257,17 +250,17 @@ pub struct InLoadedChunk;
/// Update the [`InLoadedChunk`] component for all entities in the world.
pub fn update_in_loaded_chunk(
mut commands: bevy_ecs::system::Commands,
- query: Query<(Entity, &InstanceName, &Position)>,
- instance_container: Res<InstanceContainer>,
+ query: Query<(Entity, &WorldName, &Position)>,
+ worlds: Res<Worlds>,
) {
- for (entity, instance_name, position) in &query {
+ for (entity, world_name, position) in &query {
let player_chunk_pos = ChunkPos::from(position);
- let Some(instance_lock) = instance_container.get(instance_name) else {
+ let Some(world_lock) = worlds.get(world_name) else {
commands.entity(entity).remove::<InLoadedChunk>();
continue;
};
- let in_loaded_chunk = instance_lock.read().chunks.get(&player_chunk_pos).is_some();
+ let in_loaded_chunk = world_lock.read().chunks.get(&player_chunk_pos).is_some();
if in_loaded_chunk {
commands.entity(entity).insert(InLoadedChunk);
} else {
@@ -326,20 +319,20 @@ mod tests {
};
use azalea_core::position::{BlockPos, ChunkPos};
use azalea_registry::builtin::BlockKind;
- use azalea_world::{Chunk, ChunkStorage, Instance, PartialInstance};
+ use azalea_world::{Chunk, ChunkStorage, PartialWorld, World};
- use super::is_trapdoor_useable_as_ladder;
+ use super::is_trapdoor_usable_as_ladder;
#[test]
fn test_is_trapdoor_useable_as_ladder() {
- let mut partial_instance = PartialInstance::default();
+ let mut partial_world = PartialWorld::default();
let mut chunks = ChunkStorage::default();
- partial_instance.chunks.set(
+ partial_world.chunks.set(
&ChunkPos { x: 0, z: 0 },
Some(Chunk::default()),
&mut chunks,
);
- partial_instance.chunks.set_block_state(
+ partial_world.chunks.set_block_state(
BlockPos::new(0, 0, 0),
BlockKind::Stone.into(),
&chunks,
@@ -349,7 +342,7 @@ mod tests {
facing: FacingCardinal::East,
waterlogged: false,
};
- partial_instance
+ partial_world
.chunks
.set_block_state(BlockPos::new(0, 0, 0), ladder.into(), &chunks);
@@ -360,17 +353,17 @@ mod tests {
powered: false,
waterlogged: false,
};
- partial_instance
+ partial_world
.chunks
.set_block_state(BlockPos::new(0, 1, 0), trapdoor.into(), &chunks);
- let instance = Instance::from(chunks);
- let trapdoor_matches_ladder = is_trapdoor_useable_as_ladder(
- instance
+ let world = World::from(chunks);
+ let trapdoor_matches_ladder = is_trapdoor_usable_as_ladder(
+ world
.get_block_state(BlockPos::new(0, 1, 0))
.unwrap_or_default(),
BlockPos::new(0, 1, 0),
- &instance,
+ &world,
);
assert!(trapdoor_matches_ladder);
diff --git a/azalea-entity/src/plugin/relative_updates.rs b/azalea-entity/src/plugin/relative_updates.rs
index f80ccddc..53eb4c95 100644
--- a/azalea-entity/src/plugin/relative_updates.rs
+++ b/azalea-entity/src/plugin/relative_updates.rs
@@ -18,7 +18,7 @@
use std::sync::Arc;
use azalea_core::entity_id::MinecraftEntityId;
-use azalea_world::PartialInstance;
+use azalea_world::PartialWorld;
use bevy_ecs::prelude::*;
use derive_more::{Deref, DerefMut};
use parking_lot::RwLock;
@@ -38,13 +38,13 @@ use crate::LocalEntity;
/// other clients within render distance will get too. You usually don't need
/// this when the change isn't relative either.
pub struct RelativeEntityUpdate {
- pub partial_world: Arc<RwLock<PartialInstance>>,
+ pub partial_world: Arc<RwLock<PartialWorld>>,
// a function that takes the entity and updates it
pub update: Box<dyn FnOnce(&mut EntityWorldMut) + Send + Sync>,
}
impl RelativeEntityUpdate {
pub fn new(
- partial_world: Arc<RwLock<PartialInstance>>,
+ partial_world: Arc<RwLock<PartialWorld>>,
update: impl FnOnce(&mut EntityWorldMut) + Send + Sync + 'static,
) -> Self {
Self {
diff --git a/azalea-physics/src/collision/entity_collisions.rs b/azalea-physics/src/collision/entity_collisions.rs
index de70b2b9..5933f2d3 100644
--- a/azalea-physics/src/collision/entity_collisions.rs
+++ b/azalea-physics/src/collision/entity_collisions.rs
@@ -3,7 +3,7 @@ use azalea_entity::{
Physics,
metadata::{AbstractBoat, Shulker},
};
-use azalea_world::Instance;
+use azalea_world::World;
use bevy_ecs::{
component::Component,
entity::Entity,
@@ -51,7 +51,7 @@ pub fn update_last_bounding_box(
}
pub fn get_entity_collisions(
- world: &Instance,
+ world: &World,
aabb: &Aabb,
source_entity: Option<Entity>,
aabb_query: &AabbQuery,
@@ -83,7 +83,7 @@ pub fn get_entity_collisions(
/// `source_entity` is the entity that the bounding box belongs to, and won't be
/// one of the returned entities.
pub fn get_entities(
- world: &Instance,
+ world: &World,
source_entity: Option<Entity>,
aabb: &Aabb,
predicate: &dyn Fn(Entity) -> bool,
diff --git a/azalea-physics/src/collision/mod.rs b/azalea-physics/src/collision/mod.rs
index f720fdba..430b91ad 100644
--- a/azalea-physics/src/collision/mod.rs
+++ b/azalea-physics/src/collision/mod.rs
@@ -19,7 +19,7 @@ use azalea_entity::{
metadata::Sprinting,
};
use azalea_registry::builtin::BlockKind;
-use azalea_world::{ChunkStorage, Instance};
+use azalea_world::{ChunkStorage, World};
use bevy_ecs::{entity::Entity, world::Mut};
pub use blocks::BlockWithShape;
pub use discrete_voxel_shape::*;
@@ -110,7 +110,7 @@ fn collide(ctx: &MoveCtx, movement: Vec3) -> Vec3 {
pub struct MoveCtx<'world, 'state, 'a, 'b> {
pub mover_type: MoverType,
- pub world: &'a Instance,
+ pub world: &'a World,
pub position: Mut<'a, Position>,
pub physics: &'a mut Physics,
pub source_entity: Entity,
@@ -338,7 +338,7 @@ fn is_above_ground(ctx: &CanFallAtLeastCtx, max_up_step: f32) -> bool {
pub struct CanFallAtLeastCtx<'world, 'state, 'a, 'b> {
physics: &'a Physics,
- world: &'a Instance,
+ world: &'a World,
source_entity: Entity,
aabb_query: &'a AabbQuery<'world, 'state, 'b>,
collidable_entity_query: &'a CollidableEntityQuery<'world, 'state>,
@@ -377,7 +377,7 @@ fn can_fall_at_least(
fn collide_bounding_box(
movement: Vec3,
entity_bounding_box: &Aabb,
- world: &Instance,
+ world: &World,
entity_collisions: &[VoxelShape],
) -> Vec3 {
let mut collision_boxes: Vec<VoxelShape> = Vec::with_capacity(entity_collisions.len() + 1);
@@ -437,7 +437,7 @@ fn collide_with_shapes(
/// Get the [`VoxelShape`] for the given fluid state.
///
-/// The instance and position are required so it can check if the block above is
+/// The world and position are required so it can check if the block above is
/// also the same fluid type.
pub fn fluid_shape(fluid: &FluidState, world: &ChunkStorage, pos: BlockPos) -> &'static VoxelShape {
if fluid.amount == 9 {
diff --git a/azalea-physics/src/collision/world_collisions.rs b/azalea-physics/src/collision/world_collisions.rs
index cd883649..36a085de 100644
--- a/azalea-physics/src/collision/world_collisions.rs
+++ b/azalea-physics/src/collision/world_collisions.rs
@@ -7,14 +7,14 @@ use azalea_core::{
position::{BlockPos, ChunkBlockPos, ChunkPos, ChunkSectionBlockPos, ChunkSectionPos, Vec3},
};
use azalea_inventory::ItemStack;
-use azalea_world::{Chunk, Instance};
+use azalea_world::{Chunk, World};
use bevy_ecs::entity::Entity;
use parking_lot::RwLock;
use super::{BLOCK_SHAPE, Shapes};
use crate::collision::{Aabb, BlockWithShape, VoxelShape};
-pub fn get_block_collisions(world: &Instance, aabb: &Aabb) -> Vec<VoxelShape> {
+pub fn get_block_collisions(world: &World, aabb: &Aabb) -> Vec<VoxelShape> {
let mut state = BlockCollisionsState::new(world, aabb, EntityCollisionContext::of(None));
let mut block_collisions = Vec::new();
@@ -34,7 +34,7 @@ pub fn get_block_collisions(world: &Instance, aabb: &Aabb) -> Vec<VoxelShape> {
block_collisions
}
-pub fn get_block_and_liquid_collisions(world: &Instance, aabb: &Aabb) -> Vec<VoxelShape> {
+pub fn get_block_and_liquid_collisions(world: &World, aabb: &Aabb) -> Vec<VoxelShape> {
let mut state = BlockCollisionsState::new(
world,
aabb,
@@ -59,7 +59,7 @@ pub fn get_block_and_liquid_collisions(world: &Instance, aabb: &Aabb) -> Vec<Vox
}
pub struct BlockCollisionsState<'a> {
- pub world: &'a Instance,
+ pub world: &'a World,
pub aabb: &'a Aabb,
pub entity_shape: VoxelShape,
pub cursor: Cursor3d,
@@ -126,7 +126,7 @@ impl<'a> BlockCollisionsState<'a> {
block_collisions.push(block_shape);
}
- pub fn new(world: &'a Instance, aabb: &'a Aabb, context: EntityCollisionContext) -> Self {
+ pub fn new(world: &'a World, aabb: &'a Aabb, context: EntityCollisionContext) -> Self {
let origin = BlockPos {
x: (aabb.min.x - EPSILON).floor() as i32 - 1,
y: (aabb.min.y - EPSILON).floor() as i32 - 1,
@@ -283,7 +283,7 @@ impl CanStandOnFluidPredicate {
/// a performance loss for Azalea. If this ever turns out to be a bottleneck,
/// then maybe you should try having it do that instead.
pub fn for_entities_in_chunks_colliding_with(
- world: &Instance,
+ world: &World,
aabb: &Aabb,
mut consumer: impl FnMut(ChunkPos, &HashSet<Entity>),
) {
diff --git a/azalea-physics/src/fluids.rs b/azalea-physics/src/fluids.rs
index fa6a1586..73ee7ddb 100644
--- a/azalea-physics/src/fluids.rs
+++ b/azalea-physics/src/fluids.rs
@@ -8,7 +8,7 @@ use azalea_core::{
};
use azalea_entity::{HasClientLoaded, LocalEntity, Physics, Position};
use azalea_registry::builtin::BlockKind;
-use azalea_world::{Instance, InstanceContainer, InstanceName};
+use azalea_world::{World, WorldName, Worlds};
use bevy_ecs::prelude::*;
use crate::collision::legacy_blocks_motion;
@@ -16,13 +16,13 @@ use crate::collision::legacy_blocks_motion;
#[allow(clippy::type_complexity)]
pub fn update_in_water_state_and_do_fluid_pushing(
mut query: Query<
- (&mut Physics, &Position, &InstanceName),
+ (&mut Physics, &Position, &WorldName),
(With<LocalEntity>, With<HasClientLoaded>),
>,
- instance_container: Res<InstanceContainer>,
+ worlds: Res<Worlds>,
) {
- for (mut physics, position, instance_name) in &mut query {
- let Some(world_lock) = instance_container.get(instance_name) else {
+ for (mut physics, position, world_name) in &mut query {
+ let Some(world_lock) = worlds.get(world_name) else {
continue;
};
let world = world_lock.read();
@@ -41,7 +41,7 @@ pub fn update_in_water_state_and_do_fluid_pushing(
.registries
.dimension_type
.map
- .get(&**instance_name)
+ .get(&**world_name)
.and_then(|i| i.ultrawarm)
.unwrap_or_default();
let lava_push_factor = if is_ultrawarm {
@@ -60,7 +60,7 @@ pub fn update_in_water_state_and_do_fluid_pushing(
}
fn update_in_water_state_and_do_water_current_pushing(
physics: &mut Physics,
- world: &Instance,
+ world: &World,
_position: Position,
) {
// TODO: implement vehicles and boats
@@ -86,7 +86,7 @@ fn update_in_water_state_and_do_water_current_pushing(
fn update_fluid_height_and_do_fluid_pushing(
physics: &mut Physics,
- world: &Instance,
+ world: &World,
checking_fluid: FluidKind,
fluid_push_factor: f64,
) -> bool {
@@ -180,7 +180,7 @@ pub fn update_swimming() {
}
// FlowingFluid.getFlow
-pub fn get_fluid_flow(fluid: &FluidState, world: &Instance, pos: BlockPos) -> Vec3 {
+pub fn get_fluid_flow(fluid: &FluidState, world: &World, pos: BlockPos) -> Vec3 {
let mut z_flow: f64 = 0.;
let mut x_flow: f64 = 0.;
@@ -244,7 +244,7 @@ pub fn get_fluid_flow(fluid: &FluidState, world: &Instance, pos: BlockPos) -> Ve
// i don't really get what this is for
fn is_solid_face(
fluid: &FluidState,
- world: &Instance,
+ world: &World,
adjacent_pos: BlockPos,
direction: Direction,
) -> bool {
@@ -269,7 +269,7 @@ fn is_solid_face(
fn is_face_sturdy(
_block_state: BlockState,
- _world: &Instance,
+ _world: &World,
_pos: BlockPos,
_direction: Direction,
) -> bool {
diff --git a/azalea-physics/src/lib.rs b/azalea-physics/src/lib.rs
index 90c89b16..491bda0e 100644
--- a/azalea-physics/src/lib.rs
+++ b/azalea-physics/src/lib.rs
@@ -21,7 +21,7 @@ use azalea_entity::{
metadata::Sprinting, move_relative,
};
use azalea_registry::builtin::{BlockKind, EntityKind, MobEffect};
-use azalea_world::{Instance, InstanceContainer, InstanceName};
+use azalea_world::{World, WorldName, Worlds};
use bevy_app::{App, Plugin, Update};
use bevy_ecs::prelude::*;
use clip::box_traverse_blocks;
@@ -71,12 +71,12 @@ pub fn ai_step(
&LookDirection,
&Sprinting,
&ActiveEffects,
- &InstanceName,
+ &WorldName,
&EntityKindComponent,
),
(With<LocalEntity>, With<HasClientLoaded>),
>,
- instance_container: Res<InstanceContainer>,
+ worlds: Res<Worlds>,
) {
for (
mut physics,
@@ -85,7 +85,7 @@ pub fn ai_step(
look_direction,
sprinting,
active_effects,
- instance_name,
+ world_name,
entity_kind,
) in &mut query
{
@@ -147,8 +147,8 @@ pub fn ai_step(
*position,
*look_direction,
*sprinting,
- instance_name,
- &instance_container,
+ world_name,
+ &worlds,
active_effects,
);
physics.no_jump_delay = 10;
@@ -176,13 +176,13 @@ fn jump_in_liquid(physics: &mut Physics) {
#[allow(clippy::type_complexity)]
pub fn apply_effects_from_blocks(
mut query: Query<
- (&mut Physics, &Position, &EntityDimensions, &InstanceName),
+ (&mut Physics, &Position, &EntityDimensions, &WorldName),
(With<LocalEntity>, With<HasClientLoaded>),
>,
- instance_container: Res<InstanceContainer>,
+ worlds: Res<Worlds>,
) {
for (mut physics, position, dimensions, world_name) in &mut query {
- let Some(world_lock) = instance_container.get(world_name) else {
+ let Some(world_lock) = worlds.get(world_name) else {
continue;
};
let world = world_lock.read();
@@ -211,7 +211,7 @@ pub fn apply_effects_from_blocks(
fn check_inside_blocks(
physics: &mut Physics,
dimensions: &EntityDimensions,
- world: &Instance,
+ world: &World,
movements: &[EntityMovement],
) -> Vec<BlockState> {
let mut blocks_inside = Vec::new();
@@ -291,7 +291,7 @@ fn collided_with_shape_moving_from(
// BlockBehavior.entityInside
fn handle_entity_inside_block(
- world: &Instance,
+ world: &World,
block: BlockState,
block_pos: BlockPos,
physics: &mut Physics,
@@ -339,12 +339,12 @@ pub fn jump_from_ground(
position: Position,
look_direction: LookDirection,
sprinting: Sprinting,
- instance_name: &InstanceName,
- instance_container: &InstanceContainer,
+ world_name: &WorldName,
+ worlds: &Worlds,
active_effects: &ActiveEffects,
) {
- let world_lock = instance_container
- .get(instance_name)
+ let world_lock = worlds
+ .get(world_name)
.expect("All entities should be in a valid world");
let world = world_lock.read();
@@ -436,7 +436,7 @@ fn handle_on_climbable(
velocity: Vec3,
on_climbable: OnClimbable,
position: Position,
- world: &Instance,
+ world: &World,
pose: Option<Pose>,
) -> Vec3 {
if !*on_climbable {
@@ -488,7 +488,7 @@ fn get_friction_influenced_speed(
/// Returns the what the entity's jump should be multiplied by based on the
/// block they're standing on.
-fn block_jump_factor(world: &Instance, position: Position) -> f32 {
+fn block_jump_factor(world: &World, position: Position) -> f32 {
let block_at_pos = world.chunks.get_block_state(position.into());
let block_below = world
.chunks
@@ -516,7 +516,7 @@ fn block_jump_factor(world: &Instance, position: Position) -> f32 {
// public double getJumpBoostPower() {
// return this.hasEffect(MobEffects.JUMP) ? (double)(0.1F *
// (float)(this.getEffect(MobEffects.JUMP).getAmplifier() + 1)) : 0.0D; }
-fn jump_power(world: &Instance, position: Position) -> f32 {
+fn jump_power(world: &World, position: Position) -> f32 {
0.42 * block_jump_factor(world, position)
}
diff --git a/azalea-physics/src/travel.rs b/azalea-physics/src/travel.rs
index 0b980d5a..257e2924 100644
--- a/azalea-physics/src/travel.rs
+++ b/azalea-physics/src/travel.rs
@@ -7,7 +7,7 @@ use azalea_entity::{
Attributes, HasClientLoaded, Jumping, LocalEntity, LookDirection, OnClimbable, Physics,
PlayerAbilities, Pose, Position, metadata::Sprinting, move_relative,
};
-use azalea_world::{Instance, InstanceContainer, InstanceName};
+use azalea_world::{World, WorldName, Worlds};
use bevy_ecs::prelude::*;
use crate::{
@@ -29,7 +29,7 @@ pub fn travel(
(
Entity,
&Attributes,
- &InstanceName,
+ &WorldName,
&OnClimbable,
&Jumping,
Option<&PhysicsState>,
@@ -42,7 +42,7 @@ pub fn travel(
),
(With<LocalEntity>, With<HasClientLoaded>),
>,
- instance_container: Res<InstanceContainer>,
+ worlds: Res<Worlds>,
aabb_query: AabbQuery,
collidable_entity_query: CollidableEntityQuery,
) {
@@ -61,7 +61,7 @@ pub fn travel(
position,
) in &mut query
{
- let Some(world_lock) = instance_container.get(world_name) else {
+ let Some(world_lock) = worlds.get(world_name) else {
continue;
};
let world = world_lock.read();
@@ -252,7 +252,7 @@ fn get_fluid_falling_adjusted_movement(
}
fn is_free(
- world: &Instance,
+ world: &World,
source_entity: Entity,
aabb_query: &AabbQuery,
collidable_entity_query: &CollidableEntityQuery,
@@ -274,7 +274,7 @@ fn is_free(
}
pub fn no_collision(
- world: &Instance,
+ world: &World,
source_entity: Option<Entity>,
aabb_query: &AabbQuery,
collidable_entity_query: &CollidableEntityQuery,
@@ -323,7 +323,7 @@ fn border_collision(_entity_physics: &Physics, _aabb: &Aabb) -> Option<Aabb> {
None
}
-fn contains_any_liquid(world: &Instance, bounding_box: Aabb) -> bool {
+fn contains_any_liquid(world: &World, bounding_box: Aabb) -> bool {
let min = bounding_box.min.to_block_pos_floor();
let max = bounding_box.max.to_block_pos_ceil();
diff --git a/azalea-physics/tests/physics.rs b/azalea-physics/tests/physics.rs
index 42dcf809..8359e05e 100644
--- a/azalea-physics/tests/physics.rs
+++ b/azalea-physics/tests/physics.rs
@@ -12,11 +12,8 @@ use azalea_core::{
};
use azalea_entity::{EntityBundle, EntityPlugin, HasClientLoaded, LocalEntity, Physics, Position};
use azalea_physics::PhysicsPlugin;
-use azalea_registry::{
- builtin::{BlockKind, EntityKind},
- identifier::Identifier,
-};
-use azalea_world::{Chunk, Instance, InstanceContainer, PartialInstance};
+use azalea_registry::builtin::{BlockKind, EntityKind};
+use azalea_world::{Chunk, PartialWorld, World, WorldName, Worlds};
use bevy_app::App;
use parking_lot::RwLock;
use uuid::Uuid;
@@ -25,26 +22,24 @@ use uuid::Uuid;
fn make_test_app() -> App {
let mut app = App::new();
app.add_plugins((PhysicsPlugin, EntityPlugin))
- .init_resource::<InstanceContainer>();
+ .init_resource::<Worlds>();
app
}
-pub fn insert_overworld(app: &mut App) -> Arc<RwLock<Instance>> {
- app.world_mut()
- .resource_mut::<InstanceContainer>()
- .get_or_insert(
- Identifier::new("minecraft:overworld"),
- 384,
- -64,
- &RegistryHolder::default(),
- )
+pub fn insert_overworld(app: &mut App) -> Arc<RwLock<World>> {
+ app.world_mut().resource_mut::<Worlds>().get_or_insert(
+ WorldName::new("minecraft:overworld"),
+ 384,
+ -64,
+ &RegistryHolder::default(),
+ )
}
#[test]
fn test_gravity() {
let mut app = make_test_app();
let world_lock = insert_overworld(&mut app);
- let mut partial_world = PartialInstance::default();
+ let mut partial_world = PartialWorld::default();
// the entity has to be in a loaded chunk for physics to work
partial_world.chunks.set(
&ChunkPos { x: 0, z: 0 },
@@ -63,7 +58,7 @@ fn test_gravity() {
z: 0.,
},
EntityKind::Zombie,
- Identifier::new("minecraft:overworld"),
+ WorldName::new("minecraft:overworld"),
),
MinecraftEntityId(0),
LocalEntity,
@@ -101,7 +96,7 @@ fn test_gravity() {
fn test_collision() {
let mut app = make_test_app();
let world_lock = insert_overworld(&mut app);
- let mut partial_world = PartialInstance::default();
+ let mut partial_world = PartialWorld::default();
partial_world.chunks.set(
&ChunkPos { x: 0, z: 0 },
@@ -119,7 +114,7 @@ fn test_collision() {
z: 0.5,
},
EntityKind::Player,
- Identifier::new("minecraft:overworld"),
+ WorldName::new("minecraft:overworld"),
),
MinecraftEntityId(0),
LocalEntity,
@@ -158,7 +153,7 @@ fn test_collision() {
fn test_slab_collision() {
let mut app = make_test_app();
let world_lock = insert_overworld(&mut app);
- let mut partial_world = PartialInstance::default();
+ let mut partial_world = PartialWorld::default();
partial_world.chunks.set(
&ChunkPos { x: 0, z: 0 },
@@ -176,7 +171,7 @@ fn test_slab_collision() {
z: 0.5,
},
EntityKind::Player,
- Identifier::new("minecraft:overworld"),
+ WorldName::new("minecraft:overworld"),
),
MinecraftEntityId(0),
LocalEntity,
@@ -209,7 +204,7 @@ fn test_slab_collision() {
fn test_top_slab_collision() {
let mut app = make_test_app();
let world_lock = insert_overworld(&mut app);
- let mut partial_world = PartialInstance::default();
+ let mut partial_world = PartialWorld::default();
partial_world.chunks.set(
&ChunkPos { x: 0, z: 0 },
@@ -227,7 +222,7 @@ fn test_top_slab_collision() {
z: 0.5,
},
EntityKind::Player,
- Identifier::new("minecraft:overworld"),
+ WorldName::new("minecraft:overworld"),
),
MinecraftEntityId(0),
LocalEntity,
@@ -258,16 +253,13 @@ fn test_top_slab_collision() {
#[test]
fn test_weird_wall_collision() {
let mut app = make_test_app();
- let world_lock = app
- .world_mut()
- .resource_mut::<InstanceContainer>()
- .get_or_insert(
- Identifier::new("minecraft:overworld"),
- 384,
- -64,
- &RegistryHolder::default(),
- );
- let mut partial_world = PartialInstance::default();
+ let world_lock = app.world_mut().resource_mut::<Worlds>().get_or_insert(
+ WorldName::new("minecraft:overworld"),
+ 384,
+ -64,
+ &RegistryHolder::default(),
+ );
+ let mut partial_world = PartialWorld::default();
partial_world.chunks.set(
&ChunkPos { x: 0, z: 0 },
@@ -285,7 +277,7 @@ fn test_weird_wall_collision() {
z: 0.5,
},
EntityKind::Player,
- Identifier::new("minecraft:overworld"),
+ WorldName::new("minecraft:overworld"),
),
MinecraftEntityId(0),
LocalEntity,
@@ -321,16 +313,13 @@ fn test_weird_wall_collision() {
#[test]
fn test_negative_coordinates_weird_wall_collision() {
let mut app = make_test_app();
- let world_lock = app
- .world_mut()
- .resource_mut::<InstanceContainer>()
- .get_or_insert(
- Identifier::new("minecraft:overworld"),
- 384,
- -64,
- &RegistryHolder::default(),
- );
- let mut partial_world = PartialInstance::default();
+ let world_lock = app.world_mut().resource_mut::<Worlds>().get_or_insert(
+ WorldName::new("minecraft:overworld"),
+ 384,
+ -64,
+ &RegistryHolder::default(),
+ );
+ let mut partial_world = PartialWorld::default();
partial_world.chunks.set(
&ChunkPos { x: -1, z: -1 },
@@ -348,7 +337,7 @@ fn test_negative_coordinates_weird_wall_collision() {
z: -7.5,
},
EntityKind::Player,
- Identifier::new("minecraft:overworld"),
+ WorldName::new("minecraft:overworld"),
),
MinecraftEntityId(0),
LocalEntity,
@@ -388,16 +377,13 @@ fn test_negative_coordinates_weird_wall_collision() {
#[test]
fn spawn_and_unload_world() {
let mut app = make_test_app();
- let world_lock = app
- .world_mut()
- .resource_mut::<InstanceContainer>()
- .get_or_insert(
- Identifier::new("minecraft:overworld"),
- 384,
- -64,
- &RegistryHolder::default(),
- );
- let mut partial_world = PartialInstance::default();
+ let world_lock = app.world_mut().resource_mut::<Worlds>().get_or_insert(
+ WorldName::new("minecraft:overworld"),
+ 384,
+ -64,
+ &RegistryHolder::default(),
+ );
+ let mut partial_world = PartialWorld::default();
partial_world.chunks.set(
&ChunkPos { x: -1, z: -1 },
@@ -415,7 +401,7 @@ fn spawn_and_unload_world() {
z: -7.5,
},
EntityKind::Player,
- Identifier::new("minecraft:overworld"),
+ WorldName::new("minecraft:overworld"),
),
MinecraftEntityId(0),
LocalEntity,
@@ -440,7 +426,7 @@ fn spawn_and_unload_world() {
fn test_afk_pool() {
let mut app = make_test_app();
let world_lock = insert_overworld(&mut app);
- let mut partial_world = PartialInstance::default();
+ let mut partial_world = PartialWorld::default();
partial_world.chunks.set(
&ChunkPos { x: 0, z: 0 },
@@ -531,7 +517,7 @@ fn test_afk_pool() {
z: 1.5,
},
EntityKind::Player,
- Identifier::new("minecraft:overworld"),
+ WorldName::new("minecraft:overworld"),
),
MinecraftEntityId(0),
LocalEntity,
diff --git a/azalea-protocol/Cargo.toml b/azalea-protocol/Cargo.toml
index c7b0fd57..193e153e 100644
--- a/azalea-protocol/Cargo.toml
+++ b/azalea-protocol/Cargo.toml
@@ -23,6 +23,7 @@ azalea-entity = { workspace = true }
azalea-inventory.workspace = true
azalea-protocol-macros.workspace = true
azalea-registry.workspace = true
+azalea-world = { workspace = true, optional = true }
bevy_ecs = { workspace = true, optional = true }
# byteorder.workspace = true
flate2.workspace = true
@@ -46,7 +47,12 @@ reqwest = { workspace = true, optional = true, features = ["socks"] }
default = ["online-mode", "connecting"]
connecting = []
online-mode = ["azalea-auth/online-mode", "dep:reqwest"]
-bevy_ecs = ["dep:bevy_ecs", "azalea-entity/bevy_ecs", "azalea-core/bevy_ecs"]
+bevy_ecs = [
+ "dep:bevy_ecs",
+ "dep:azalea-world",
+ "azalea-entity/bevy_ecs",
+ "azalea-core/bevy_ecs",
+]
[lints]
workspace = true
diff --git a/azalea-protocol/src/packets/game/c_add_entity.rs b/azalea-protocol/src/packets/game/c_add_entity.rs
index 19f229ee..1b94baef 100644
--- a/azalea-protocol/src/packets/game/c_add_entity.rs
+++ b/azalea-protocol/src/packets/game/c_add_entity.rs
@@ -3,7 +3,7 @@ use azalea_core::{delta::LpVec3, entity_id::MinecraftEntityId, position::Vec3};
use azalea_protocol_macros::ClientboundGamePacket;
use azalea_registry::builtin::EntityKind;
#[cfg(feature = "bevy_ecs")]
-use azalea_registry::identifier::Identifier;
+use azalea_world::WorldName;
use uuid::Uuid;
#[derive(AzBuf, ClientboundGamePacket, Clone, Debug, PartialEq)]
@@ -36,7 +36,7 @@ impl ClientboundAddEntity {
/// You must apply the metadata after inserting the bundle with
/// [`Self::apply_metadata`].
#[cfg(feature = "bevy_ecs")]
- pub fn as_entity_bundle(&self, world_name: Identifier) -> azalea_entity::EntityBundle {
+ pub fn as_entity_bundle(&self, world_name: WorldName) -> azalea_entity::EntityBundle {
azalea_entity::EntityBundle::new(self.uuid, self.position, self.entity_type, world_name)
}
diff --git a/azalea-world/src/container.rs b/azalea-world/src/container.rs
index 97bc2a1f..af344dc0 100644
--- a/azalea-world/src/container.rs
+++ b/azalea-world/src/container.rs
@@ -1,5 +1,6 @@
use std::{
collections::HashMap,
+ fmt::{self, Display},
sync::{Arc, Weak},
};
@@ -12,14 +13,14 @@ use parking_lot::RwLock;
use rustc_hash::FxHashMap;
use tracing::{debug, error};
-use crate::{ChunkStorage, Instance};
+use crate::{ChunkStorage, World};
-/// A container of [`Instance`]s (aka worlds).
+/// A container of [`World`] instances.
///
-/// Instances are stored as a Weak pointer here, so if no clients are using an
-/// instance it will be forgotten.
+/// Worlds are stored as a `Weak` pointer here, so if no clients are using a
+/// world then it will be forgotten.
#[derive(Default, Resource)]
-pub struct InstanceContainer {
+pub struct Worlds {
// We just refer to the chunks here and don't include entities because there's not that many
// cases where we'd want to get every entity in the world (just getting the entities in chunks
// should work fine).
@@ -29,22 +30,21 @@ pub struct InstanceContainer {
// If it looks like we're relying on the server giving us unique world names, that's because we
// are. An evil server could give us two worlds with the same name and then we'd have no way of
- // telling them apart. We hope most servers are nice and don't do that though. It's only an
- // issue when there's multiple clients with the same WorldContainer in different worlds
- // anyways.
- pub instances: FxHashMap<Identifier, Weak<RwLock<Instance>>>,
+ // telling them apart. We hope most servers are nice and don't do that. Perhaps this should be
+ // changed in the future to be configurable.
+ pub map: FxHashMap<WorldName, Weak<RwLock<World>>>,
}
-impl InstanceContainer {
+impl Worlds {
pub fn new() -> Self {
- InstanceContainer::default()
+ Worlds::default()
}
- /// Get an instance (aka world) from the container.
+ /// Get a world instance from the container.
///
- /// Returns `None` if none of the clients are in this instance.
- pub fn get(&self, name: &InstanceName) -> Option<Arc<RwLock<Instance>>> {
- self.instances.get(name).and_then(|world| world.upgrade())
+ /// Returns `None` if none of the clients are in the requested world.
+ pub fn get(&self, name: &WorldName) -> Option<Arc<RwLock<World>>> {
+ self.map.get(name).and_then(|world| world.upgrade())
}
/// Add an empty world to the container (unless it already exists) and
@@ -52,12 +52,12 @@ impl InstanceContainer {
#[must_use = "the world will be immediately forgotten if unused"]
pub fn get_or_insert(
&mut self,
- name: Identifier,
+ name: WorldName,
height: u32,
min_y: i32,
default_registries: &RegistryHolder,
- ) -> Arc<RwLock<Instance>> {
- match self.instances.get(&name).and_then(|world| world.upgrade()) {
+ ) -> Arc<RwLock<World>> {
+ match self.map.get(&name).and_then(|world| world.upgrade()) {
Some(existing_lock) => {
let existing = existing_lock.read();
if existing.chunks.height != height {
@@ -75,24 +75,40 @@ impl InstanceContainer {
existing_lock.clone()
}
_ => {
- let world = Arc::new(RwLock::new(Instance {
+ let world = Arc::new(RwLock::new(World {
chunks: ChunkStorage::new(height, min_y),
entities_by_chunk: HashMap::new(),
entity_by_id: IntMap::default(),
registries: default_registries.clone(),
}));
- debug!("Added new instance {name}");
- self.instances.insert(name, Arc::downgrade(&world));
+ debug!("Added new world {name:?}");
+ self.map.insert(name, Arc::downgrade(&world));
world
}
}
}
}
-/// The name of the [`Instance`] (aka world/dimension) that the entity is in.
+/// The name of the [`World`] (aka dimension) that an entity is in.
///
-/// If two entities share the same instance name, we assume they're in the
-/// same instance.
+/// If two entities share the same world name, then Azalea assumes that they're
+/// in the same world.
#[derive(Clone, Component, Debug, Deref, DerefMut, Eq, Hash, PartialEq)]
#[doc(alias("worldname", "world name", "dimension"))]
-pub struct InstanceName(pub Identifier);
+pub struct WorldName(pub Identifier);
+impl WorldName {
+ /// Create a new `WorldName` with the given name.
+ pub fn new(name: &str) -> Self {
+ Self(Identifier::new(name))
+ }
+}
+impl Display for WorldName {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ self.0.fmt(f)
+ }
+}
+impl From<Identifier> for WorldName {
+ fn from(ident: Identifier) -> Self {
+ Self(ident)
+ }
+}
diff --git a/azalea-world/src/find_blocks.rs b/azalea-world/src/find_blocks.rs
index bd4ec09a..f8f1fd91 100644
--- a/azalea-world/src/find_blocks.rs
+++ b/azalea-world/src/find_blocks.rs
@@ -1,9 +1,9 @@
use azalea_block::{BlockState, BlockStates};
use azalea_core::position::{BlockPos, ChunkPos};
-use crate::{Chunk, ChunkStorage, Instance, iterators::ChunkIterator, palette::Palette};
+use crate::{Chunk, ChunkStorage, World, iterators::ChunkIterator, palette::Palette};
-impl Instance {
+impl World {
/// Find the coordinates of a block in the world.
///
/// Note that this is sorted by `x+y+z` and not `x^2+y^2+z^2` for
@@ -206,8 +206,8 @@ impl Iterator for FindBlocks<'_> {
/// An optimized function for finding the block positions in a chunk that match
/// the given block states.
///
-/// This is used internally by [`Instance::find_block`] and
-/// [`Instance::find_blocks`].
+/// This is used internally by [`World::find_block`] and
+/// [`World::find_blocks`].
pub fn find_blocks_in_chunk(
block_states: &BlockStates,
chunk_pos: ChunkPos,
@@ -257,9 +257,9 @@ mod tests {
#[test]
fn find_block() {
- let mut instance = Instance::default();
+ let mut world = World::default();
- let chunk_storage = &mut instance.chunks;
+ let chunk_storage = &mut world.chunks;
let mut partial_chunk_storage = PartialChunkStorage::default();
// block at (17, 0, 0) and (0, 18, 0)
@@ -278,15 +278,15 @@ mod tests {
chunk_storage.set_block_state(BlockPos { x: 17, y: 0, z: 0 }, BlockKind::Stone.into());
chunk_storage.set_block_state(BlockPos { x: 0, y: 18, z: 0 }, BlockKind::Stone.into());
- let pos = instance.find_block(BlockPos { x: 0, y: 0, z: 0 }, &BlockKind::Stone.into());
+ let pos = world.find_block(BlockPos { x: 0, y: 0, z: 0 }, &BlockKind::Stone.into());
assert_eq!(pos, Some(BlockPos { x: 17, y: 0, z: 0 }));
}
#[test]
fn find_block_next_to_chunk_border() {
- let mut instance = Instance::default();
+ let mut world = World::default();
- let chunk_storage = &mut instance.chunks;
+ let chunk_storage = &mut world.chunks;
let mut partial_chunk_storage = PartialChunkStorage::default();
// block at (-1, 0, 0) and (15, 0, 0)
@@ -305,7 +305,7 @@ mod tests {
chunk_storage.set_block_state(BlockPos { x: -1, y: 0, z: 0 }, BlockKind::Stone.into());
chunk_storage.set_block_state(BlockPos { x: 15, y: 0, z: 0 }, BlockKind::Stone.into());
- let pos = instance.find_block(BlockPos { x: 0, y: 0, z: 0 }, &BlockKind::Stone.into());
+ let pos = world.find_block(BlockPos { x: 0, y: 0, z: 0 }, &BlockKind::Stone.into());
assert_eq!(pos, Some(BlockPos { x: -1, y: 0, z: 0 }));
}
}
diff --git a/azalea-world/src/lib.rs b/azalea-world/src/lib.rs
index 7212c519..325d3b43 100644
--- a/azalea-world/src/lib.rs
+++ b/azalea-world/src/lib.rs
@@ -12,5 +12,12 @@ mod world;
pub use bit_storage::BitStorage;
pub use chunk_storage::{Chunk, ChunkStorage, PartialChunkStorage, Section};
-pub use container::{InstanceContainer, InstanceName};
+pub use container::{Worlds, WorldName};
pub use world::*;
+
+#[deprecated = "renamed to `WorldName`."]
+pub type InstanceName = WorldName;
+#[deprecated = "renamed to `WorldContainer`."]
+pub type InstanceContainer = Worlds;
+#[deprecated = "renamed to `PartialWorld`."]
+pub type PartialInstance = PartialWorld;
diff --git a/azalea-world/src/world.rs b/azalea-world/src/world.rs
index a6ee1a63..74390ee4 100644
--- a/azalea-world/src/world.rs
+++ b/azalea-world/src/world.rs
@@ -14,30 +14,30 @@ use nohash_hasher::IntMap;
use crate::{ChunkStorage, PartialChunkStorage};
-/// PartialInstances are usually owned by clients, and hold strong references to
-/// chunks and entities in [`Instance`]s.
+/// A reference to a slice of the world, as seen by an individual client.
///
-/// Basically, they hold the chunks and entities that are within render
-/// distance but can still access chunks and entities owned by other
-/// `PartialInstance`s that have the same `Instance`.
+/// A `PartialWorld` will typically be owned by a client, and it holds strong
+/// references to chunks and entities in a [`World`]s.
///
-/// This is primarily useful for having multiple clients in the same Instance.
-pub struct PartialInstance {
+/// In other words, this type holds the chunks and entities that are within
+/// render distance for a client. The same chunk/entity may be referenced by
+/// more than one `PartialWorld`.
+pub struct PartialWorld {
pub chunks: PartialChunkStorage,
/// Some metadata about entities, like what entities are in certain chunks.
/// This does not contain the entity data itself, that's in the ECS.
pub entity_infos: PartialEntityInfos,
}
-impl PartialInstance {
+impl PartialWorld {
pub fn new(chunk_radius: u32, owner_entity: Option<Entity>) -> Self {
- PartialInstance {
+ PartialWorld {
chunks: PartialChunkStorage::new(chunk_radius),
entity_infos: PartialEntityInfos::new(owner_entity),
}
}
- /// Clears the internal references to chunks in the PartialInstance and
+ /// Clears the internal references to chunks in the [`PartialWorld`] and
/// resets the view center.
pub fn reset(&mut self) {
self.chunks = PartialChunkStorage::new(self.chunks.chunk_radius);
@@ -75,16 +75,21 @@ impl PartialEntityInfos {
}
}
-/// A world where the chunks are stored as weak pointers. This is used for
-/// shared worlds.
+/// A Minecraft world, sometimes referred to as a dimension.
///
-/// Also see [`PartialInstance`].
+/// This is the most commonly used type to interact with the world that a client
+/// is in. In here, all chunks are stored as weak pointers, which means that
+/// clients in different areas of the same world can share the same `World`
+/// instance.
///
-/// This is sometimes interchangeably called a "world". However, this type is
-/// called `Instance` to avoid colliding with the `World` type from Bevy ECS.
+/// Also see [`PartialWorld`].
+///
+/// Note that this is distinct from Bevy's `World` type, which contains all of
+/// the data for every client. When referring to the Bevy `World` within Azalea,
+/// the term "ECS" is generally used instead.
#[derive(Debug, Default)]
-#[doc(alias("world", "dimension"))]
-pub struct Instance {
+#[doc(alias("instance", "dimension", "level"))]
+pub struct World {
pub chunks: ChunkStorage,
/// An index of all the entities we know are in the chunks of the world
@@ -101,7 +106,10 @@ pub struct Instance {
pub registries: RegistryHolder,
}
-impl Instance {
+#[deprecated = "renamed to `World`."]
+pub type Instance = World;
+
+impl World {
/// Get the block at the given position, or `None` if it's outside of the
/// world that we have loaded.
pub fn get_block_state(&self, pos: BlockPos) -> Option<BlockState> {
@@ -131,17 +139,17 @@ impl Instance {
}
}
-impl Debug for PartialInstance {
+impl Debug for PartialWorld {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("PartialInstance")
+ f.debug_struct("PartialWorld")
.field("chunks", &self.chunks)
.field("entity_infos", &self.entity_infos)
.finish()
}
}
-impl Default for PartialInstance {
- /// Creates a completely self-contained `PartialInstance`. This is only for
+impl Default for PartialWorld {
+ /// Creates a completely self-contained [`PartialWorld`]. This is only for
/// testing and shouldn't be used in actual code!
fn default() -> Self {
let chunk_storage = PartialChunkStorage::default();
@@ -153,7 +161,7 @@ impl Default for PartialInstance {
}
}
-impl From<ChunkStorage> for Instance {
+impl From<ChunkStorage> for World {
/// Make an empty world from this `ChunkStorage`. This is meant to be a
/// convenience function for tests.
fn from(chunks: ChunkStorage) -> Self {
diff --git a/azalea/examples/testbot/commands/debug.rs b/azalea/examples/testbot/commands/debug.rs
index 1f9d5e5d..57d9ff1f 100644
--- a/azalea/examples/testbot/commands/debug.rs
+++ b/azalea/examples/testbot/commands/debug.rs
@@ -15,7 +15,7 @@ use azalea::{
use azalea_core::hit_result::HitResult;
use azalea_entity::{EntityKindComponent, metadata};
use azalea_inventory::components::MaxStackSize;
-use azalea_world::InstanceContainer;
+use azalea_world::Worlds;
use bevy_app::AppExit;
use bevy_ecs::{message::Messages, query::With, world::EntityRef};
use parking_lot::Mutex;
@@ -331,16 +331,16 @@ pub fn register(commands: &mut CommandDispatcher<Mutex<CommandSource>>) {
// info.layout().size()).unwrap();
match name.as_ref() {
- "azalea_world::container::InstanceContainer" => {
- let instance_container = ecs.resource::<InstanceContainer>();
+ "azalea_world::container::Worlds" => {
+ let worlds = ecs.resource::<Worlds>();
- for (instance_name, instance) in &instance_container.instances {
- writeln!(report, "- Name: {instance_name}").unwrap();
- writeln!(report, "- Reference count: {}", instance.strong_count())
+ for (world_name, world) in &worlds.map {
+ writeln!(report, "- Name: {world_name}").unwrap();
+ writeln!(report, "- Reference count: {}", world.strong_count())
.unwrap();
- if let Some(instance) = instance.upgrade() {
- let instance = instance.read();
- let strong_chunks = instance
+ if let Some(world) = world.upgrade() {
+ let world = world.read();
+ let strong_chunks = world
.chunks
.map
.iter()
@@ -350,13 +350,13 @@ pub fn register(commands: &mut CommandDispatcher<Mutex<CommandSource>>) {
report,
"- Chunks: {} strongly referenced, {} in map",
strong_chunks,
- instance.chunks.map.len()
+ world.chunks.map.len()
)
.unwrap();
writeln!(
report,
"- Entities: {}",
- instance.entities_by_chunk.len()
+ world.entities_by_chunk.len()
)
.unwrap();
}
diff --git a/azalea/src/client_impl/entity_query.rs b/azalea/src/client_impl/entity_query.rs
index 44fbe9e8..27c3aa9a 100644
--- a/azalea/src/client_impl/entity_query.rs
+++ b/azalea/src/client_impl/entity_query.rs
@@ -2,7 +2,7 @@ use std::{any, sync::Arc};
use azalea_core::position::Vec3;
use azalea_entity::Position;
-use azalea_world::InstanceName;
+use azalea_world::WorldName;
use bevy_ecs::{
component::Component,
entity::Entity,
@@ -44,9 +44,9 @@ impl Client {
/// # Examples
///
/// ```
- /// # use azalea_world::InstanceName;
+ /// # use azalea_world::WorldName;
/// # fn example(client: &azalea::Client) {
- /// let world_name = client.component::<InstanceName>();
+ /// let world_name = client.component::<WorldName>();
/// # }
pub fn component<T: Component>(&self) -> MappedRwLockReadGuard<'_, T> {
self.get_component::<T>().unwrap_or_else(|| {
@@ -150,9 +150,9 @@ impl Client {
/// Quickly returns an [`EntityRef`] for an arbitrary entity that
/// matches the given predicate function that is in the same
- /// [`Instance`] as the client.
+ /// [`World`] as the client.
///
- /// [`Instance`]: azalea_world::Instance
+ /// [`World`]: azalea_world::World
pub fn any_entity_by<Q: QueryData, F: QueryFilter>(
&self,
predicate: impl EntityPredicate<Q, F>,
@@ -162,7 +162,7 @@ impl Client {
}
/// Quickly returns a lightweight [`Entity`] for an arbitrary entity that
/// matches the given predicate function that is in the same
- /// [`Instance`] as the client.
+ /// [`World`] as the client.
///
/// To get an [`EntityRef`], consider using [`Self::any_entity_by`]
/// instead.
@@ -184,13 +184,13 @@ impl Client {
/// # }
/// ```
///
- /// [`Instance`]: azalea_world::Instance
+ /// [`World`]: azalea_world::World
pub fn any_entity_id_by<Q: QueryData, F: QueryFilter>(
&self,
predicate: impl EntityPredicate<Q, F>,
) -> Option<Entity> {
- let instance_name = self.get_component::<InstanceName>()?.clone();
- predicate.find_any(self.ecs.clone(), &instance_name)
+ let world_name = self.get_component::<WorldName>()?.clone();
+ predicate.find_any(self.ecs.clone(), &world_name)
}
/// Return an [`EntityRef`] for the nearest entity that matches the
@@ -225,7 +225,7 @@ impl Client {
self.nearest_entity_ids_by(predicate).first().copied()
}
- /// Returns an array of all [`EntityRef`]s in the instance that match the
+ /// Returns an array of all [`EntityRef`]s in the world that match the
/// predicate, sorted by nearest first.
///
/// To only get the nearest entity, consider using
@@ -240,7 +240,7 @@ impl Client {
.map(|e| self.entity_ref_for(e))
.collect()
}
- /// Returns an array of all [`Entity`]s in the instance that match the
+ /// Returns an array of all [`Entity`]s in the world that match the
/// predicate, sorted by nearest first.
///
/// To only get the nearest entity, consider using
@@ -259,18 +259,18 @@ impl Client {
&self,
predicate: impl EntityPredicate<Q, F>,
) -> Box<[Entity]> {
- let (instance_name, position) = {
- let Some(instance_name) = self.get_component::<InstanceName>() else {
+ let (world_name, position) = {
+ let Some(world_name) = self.get_component::<WorldName>() else {
return Box::new([]);
};
let Some(position) = self.get_component::<Position>() else {
return Box::new([]);
};
- (instance_name.clone(), **position)
+ (world_name.clone(), **position)
};
- predicate.find_all_sorted(self.ecs.clone(), &instance_name, position)
+ predicate.find_all_sorted(self.ecs.clone(), &world_name, position)
}
/// Get a component from an entity.
@@ -316,15 +316,11 @@ impl Client {
}
pub trait EntityPredicate<Q: QueryData, Filter: QueryFilter> {
- fn find_any(
- &self,
- ecs_lock: Arc<RwLock<World>>,
- instance_name: &InstanceName,
- ) -> Option<Entity>;
+ fn find_any(&self, ecs_lock: Arc<RwLock<World>>, world_name: &WorldName) -> Option<Entity>;
fn find_all_sorted(
&self,
ecs_lock: Arc<RwLock<World>>,
- instance_name: &InstanceName,
+ world_name: &WorldName,
nearest_to: Vec3,
) -> Box<[Entity]>;
}
@@ -333,30 +329,26 @@ where
F: Fn(ROQueryItem<Q>) -> bool,
for<'w, 's> <<Q as QueryData>::ReadOnly as QueryData>::Item<'w, 's>: Copy,
{
- fn find_any(
- &self,
- ecs_lock: Arc<RwLock<World>>,
- instance_name: &InstanceName,
- ) -> Option<Entity> {
+ fn find_any(&self, ecs_lock: Arc<RwLock<World>>, world_name: &WorldName) -> Option<Entity> {
let mut ecs = ecs_lock.write();
- let mut query = ecs.query_filtered::<(Entity, &InstanceName, Q), Filter>();
+ let mut query = ecs.query_filtered::<(Entity, &WorldName, Q), Filter>();
query
.iter(&ecs)
- .find(|(_, e_instance_name, q)| *e_instance_name == instance_name && (self)(*q))
+ .find(|(_, e_world_name, q)| *e_world_name == world_name && (self)(*q))
.map(|(e, _, _)| e)
}
fn find_all_sorted(
&self,
ecs_lock: Arc<RwLock<World>>,
- instance_name: &InstanceName,
+ world_name: &WorldName,
nearest_to: Vec3,
) -> Box<[Entity]> {
let mut ecs = ecs_lock.write();
- let mut query = ecs.query_filtered::<(Entity, &InstanceName, &Position, Q), Filter>();
+ let mut query = ecs.query_filtered::<(Entity, &WorldName, &Position, Q), Filter>();
let mut entities = query
.iter(&ecs)
- .filter(|(_, e_instance_name, _, q)| *e_instance_name == instance_name && (self)(*q))
+ .filter(|(_, e_world_name, _, q)| *e_world_name == world_name && (self)(*q))
.map(|(e, _, position, _)| (e, Vec3::from(position)))
.collect::<Vec<(Entity, Vec3)>>();
diff --git a/azalea/src/client_impl/mod.rs b/azalea/src/client_impl/mod.rs
index f884898f..d55e5a38 100644
--- a/azalea/src/client_impl/mod.rs
+++ b/azalea/src/client_impl/mod.rs
@@ -7,7 +7,7 @@ use azalea_client::{
connection::RawConnection,
disconnect::DisconnectEvent,
join::{ConnectOpts, StartJoinServerEvent},
- local_player::{Hunger, InstanceHolder, TabList},
+ local_player::{Hunger, TabList, WorldHolder},
packet::game::SendGamePacketEvent,
player::{GameProfileComponent, PlayerInfo},
start_ecs_runner,
@@ -25,13 +25,9 @@ use azalea_protocol::{
resolve::ResolveError,
};
use azalea_registry::{DataRegistryKeyRef, identifier::Identifier};
-use azalea_world::{Instance, InstanceName, PartialInstance};
+use azalea_world::{PartialWorld, World, WorldName};
use bevy_app::App;
-use bevy_ecs::{
- entity::Entity,
- resource::Resource,
- world::{Mut, World},
-};
+use bevy_ecs::{entity::Entity, resource::Resource, world::Mut};
use parking_lot::RwLock;
use tokio::sync::mpsc;
use uuid::Uuid;
@@ -67,17 +63,17 @@ pub struct Client {
/// A mutually exclusive reference to the entity component system (ECS).
///
/// You probably don't need to access this directly. Note that if you're
- /// using a shared world (i.e. a swarm), the ECS will contain all entities
- /// in all instances/dimensions.
+ /// using a shared world (i.e. a swarm), the ECS will also contain all
+ /// entities in all worlds.
///
/// You can nearly always use [`Self::component`], [`Self::query_self`],
/// [`Self::query_entity`], or another one of those related functions to
/// access the ECS instead.
- pub ecs: Arc<RwLock<World>>,
+ pub ecs: Arc<RwLock<bevy_ecs::world::World>>,
}
pub struct StartClientOpts {
- pub ecs_lock: Arc<RwLock<World>>,
+ pub ecs_lock: Arc<RwLock<bevy_ecs::world::World>>,
pub account: Account,
pub connect_opts: ConnectOpts,
pub event_sender: Option<mpsc::UnboundedSender<Event>>,
@@ -144,7 +140,7 @@ impl Client {
/// World, and schedule runner function.
/// You should only use this if you want to change these fields from the
/// defaults, otherwise use [`Client::join`].
- pub fn new(entity: Entity, ecs: Arc<RwLock<World>>) -> Self {
+ pub fn new(entity: Entity, ecs: Arc<RwLock<bevy_ecs::world::World>>) -> Self {
Self {
// default our id to 0, it'll be set later
entity,
@@ -278,15 +274,16 @@ impl Client {
f(value)
}
- /// Get an `RwLock` with a reference to our (potentially shared) world.
+ /// Get an `RwLock` with a reference to our (potentially shared) Minecraft
+ /// world.
///
- /// This gets the [`Instance`] from the client's [`InstanceHolder`]
+ /// This gets the [`World`] from the client's [`WorldHolder`]
/// component. If it's a normal client, then it'll be the same as the
/// world the client has loaded. If the client is using a shared world,
/// then the shared world will be a superset of the client's world.
- pub fn world(&self) -> Arc<RwLock<Instance>> {
- let instance_holder = self.component::<InstanceHolder>();
- instance_holder.instance.clone()
+ pub fn world(&self) -> Arc<RwLock<World>> {
+ let world_holder = self.component::<WorldHolder>();
+ world_holder.shared.clone()
}
/// Get an `RwLock` with a reference to the world that this client has
@@ -298,15 +295,15 @@ impl Client {
/// let world = client.partial_world();
/// let is_0_0_loaded = world.read().chunks.limited_get(&ChunkPos::new(0, 0)).is_some();
/// # }
- pub fn partial_world(&self) -> Arc<RwLock<PartialInstance>> {
- let instance_holder = self.component::<InstanceHolder>();
- instance_holder.partial_instance.clone()
+ pub fn partial_world(&self) -> Arc<RwLock<PartialWorld>> {
+ let world_holder = self.component::<WorldHolder>();
+ world_holder.partial.clone()
}
/// Returns whether we have a received the login packet yet.
pub fn logged_in(&self) -> bool {
// the login packet tells us the world name
- self.query_self::<Option<&InstanceName>, _>(|ins| ins.is_some())
+ self.query_self::<Option<&WorldName>, _>(|ins| ins.is_some())
}
/// Returns the client as an [`EntityRef`], allowing you to treat it as any
@@ -409,8 +406,8 @@ impl Client {
/// Call the given function with the client's [`RegistryHolder`].
///
- /// The player's instance (aka world) will be locked during this time, which
- /// may result in a deadlock if you try to access the instance again while
+ /// Note that the player's world will be locked during this time, which may
+ /// result in a deadlock if you try to access the world again while
/// in the function.
///
/// [`RegistryHolder`]: azalea_core::registry_holder::RegistryHolder
@@ -418,8 +415,8 @@ impl Client {
&self,
f: impl FnOnce(&azalea_core::registry_holder::RegistryHolder) -> R,
) -> R {
- let instance = self.world();
- let registries = &instance.read().registries;
+ let world = self.world();
+ let registries = &world.read().registries;
f(registries)
}
diff --git a/azalea/src/entity_ref/mod.rs b/azalea/src/entity_ref/mod.rs
index d604fe00..e09852c1 100644
--- a/azalea/src/entity_ref/mod.rs
+++ b/azalea/src/entity_ref/mod.rs
@@ -57,9 +57,9 @@ impl EntityRef {
/// # Examples
///
/// ```
- /// # use azalea_world::InstanceName;
+ /// # use azalea_world::WorldName;
/// # fn example(client: &azalea::Client) {
- /// let world_name = client.component::<InstanceName>();
+ /// let world_name = client.component::<WorldName>();
/// # }
pub fn component<T: Component>(&self) -> MappedRwLockReadGuard<'_, T> {
self.client.entity_component(self.entity)
diff --git a/azalea/src/entity_ref/shared_impls.rs b/azalea/src/entity_ref/shared_impls.rs
index f6aa332e..79396f56 100644
--- a/azalea/src/entity_ref/shared_impls.rs
+++ b/azalea/src/entity_ref/shared_impls.rs
@@ -2,7 +2,7 @@ use azalea_core::{entity_id::MinecraftEntityId, position::Vec3};
use azalea_entity::{
Attributes, Dead, EntityUuid, Physics, Position, dimensions::EntityDimensions, metadata::Health,
};
-use azalea_world::InstanceName;
+use azalea_world::WorldName;
use uuid::Uuid;
use super::EntityRef;
@@ -141,21 +141,29 @@ impl_entity_functions! {
}
Client:
- /// Get the name of the instance (world) that the bot is in.
+ #[deprecated = "renamed to `world_name`."]
+ EntityRef:
+ #[deprecated = "renamed to `world_name`."]
+ pub fn instance_name(&self) -> WorldName {
+ self.world_name()
+ }
+
+ Client:
+ /// Get the name of the world that the bot is in.
///
/// This can be used to check if the client is in the same world as another
/// entity.
- #[doc(alias("world_name", "dimension_name"))]
+ #[doc(alias("dimension_name"))]
EntityRef:
- /// Get the name of the instance (world) that the entity is in.
+ /// Get the name of the world that the entity is in.
///
/// This can be used to check if the entity is in the same world as another
/// entity.
///
- /// Also see [`Client::instance_name`],
- #[doc(alias("world_name", "dimension_name"))]
- pub fn instance_name(&self) -> InstanceName {
- (*self.component::<InstanceName>()).clone()
+ /// Also see [`Client::world_name`],
+ #[doc(alias("dimension_name"))]
+ pub fn world_name(&self) -> WorldName {
+ (*self.component::<WorldName>()).clone()
}
Client:
diff --git a/azalea/src/events.rs b/azalea/src/events.rs
index 18d24773..b0bc8cd1 100644
--- a/azalea/src/events.rs
+++ b/azalea/src/events.rs
@@ -7,7 +7,7 @@ use azalea_chat::FormattedText;
use azalea_core::{entity_id::MinecraftEntityId, position::ChunkPos, tick::GameTick};
use azalea_entity::{Dead, InLoadedChunk};
use azalea_protocol::packets::game::c_player_combat_kill::ClientboundPlayerCombatKill;
-use azalea_world::InstanceName;
+use azalea_world::WorldName;
use bevy_app::{App, Plugin, PreUpdate, Update};
use bevy_ecs::prelude::*;
use derive_more::{Deref, DerefMut};
@@ -211,7 +211,7 @@ pub fn chat_listener(
}
// only tick if we're in a world
-pub fn tick_listener(query: Query<&LocalPlayerEvents, With<InstanceName>>) {
+pub fn tick_listener(query: Query<&LocalPlayerEvents, With<WorldName>>) {
for local_player_events in &query {
let _ = local_player_events.send(Event::Tick);
}
diff --git a/azalea/src/nearest_entity.rs b/azalea/src/nearest_entity.rs
index bf3f2fdb..3dc32adc 100644
--- a/azalea/src/nearest_entity.rs
+++ b/azalea/src/nearest_entity.rs
@@ -1,6 +1,6 @@
use azalea_core::entity_id::MinecraftEntityId;
use azalea_entity::Position;
-use azalea_world::InstanceName;
+use azalea_world::WorldName;
use bevy_ecs::{
prelude::Entity,
query::{QueryFilter, With},
@@ -11,8 +11,8 @@ use bevy_ecs::{
/// entity, (or several) close to a given position.
///
/// This system parameter allows for additional filtering of entities based off
-/// of ECS marker components, such as `With<>`, `Without<>`, or `Added<>`, etc.
-/// All functions used by this system parameter instance will respect the
+/// of ECS marker components, such as `With<T>`, `Without<T>`, or `Added<T>`,
+/// etc. All functions used by this system parameter instance will respect the
/// applied filter.
///
/// ```
@@ -50,13 +50,12 @@ pub struct EntityFinder<'w, 's, F = ()>
where
F: QueryFilter + 'static,
{
- all_entities:
- Query<'w, 's, (&'static Position, &'static InstanceName), With<MinecraftEntityId>>,
+ all_entities: Query<'w, 's, (&'static Position, &'static WorldName), With<MinecraftEntityId>>,
filtered_entities: Query<
'w,
's,
- (Entity, &'static InstanceName, &'static Position),
+ (Entity, &'static WorldName, &'static Position),
(With<MinecraftEntityId>, F),
>,
}
@@ -65,21 +64,22 @@ impl<'a, F> EntityFinder<'_, '_, F>
where
F: QueryFilter + 'static,
{
- /// Gets the nearest entity to the given position and world instance name.
+ /// Gets the nearest entity to the given position and with the given world
+ /// name.
///
/// This method will return `None` if there are no entities within range. If
/// multiple entities are within range, only the closest one is returned.
pub fn nearest_to_position(
&'a self,
position: Position,
- instance_name: &InstanceName,
+ world_name: &WorldName,
max_distance: f64,
) -> Option<Entity> {
let mut nearest_entity = None;
let mut min_distance = max_distance;
- for (target_entity, e_instance, e_pos) in self.filtered_entities.iter() {
- if e_instance != instance_name {
+ for (target_entity, e_world, e_pos) in self.filtered_entities.iter() {
+ if e_world != world_name {
continue;
}
@@ -99,19 +99,19 @@ where
/// multiple entities are within range, only the closest one is
/// returned.
pub fn nearest_to_entity(&'a self, entity: Entity, max_distance: f64) -> Option<Entity> {
- let Ok((position, instance_name)) = self.all_entities.get(entity) else {
+ let Ok((position, world_name)) = self.all_entities.get(entity) else {
return None;
};
let mut nearest_entity = None;
let mut min_distance = max_distance;
- for (target_entity, e_instance, e_pos) in self.filtered_entities.iter() {
+ for (target_entity, e_world, e_pos) in self.filtered_entities.iter() {
if entity == target_entity {
continue;
};
- if e_instance != instance_name {
+ if e_world != world_name {
continue;
}
@@ -135,13 +135,13 @@ where
pub fn nearby_entities_to_position(
&'a self,
position: &'a Position,
- instance_name: &'a InstanceName,
+ world_name: &'a WorldName,
max_distance: f64,
) -> impl Iterator<Item = (Entity, f64)> + 'a {
self.filtered_entities
.iter()
- .filter_map(move |(target_entity, e_instance, e_pos)| {
- if e_instance != instance_name {
+ .filter_map(move |(target_entity, e_world, e_pos)| {
+ if e_world != world_name {
return None;
}
@@ -167,23 +167,23 @@ where
max_distance: f64,
) -> impl Iterator<Item = (Entity, f64)> + 'a {
let position;
- let instance_name;
- if let Ok((pos, instance)) = self.all_entities.get(entity) {
- position = *pos;
- instance_name = Some(instance);
+ let world_name;
+ if let Ok((p, w)) = self.all_entities.get(entity) {
+ position = *p;
+ world_name = Some(w);
} else {
position = Position::default();
- instance_name = None;
+ world_name = None;
};
self.filtered_entities
.iter()
- .filter_map(move |(target_entity, e_instance, e_pos)| {
+ .filter_map(move |(target_entity, e_world, e_pos)| {
if entity == target_entity {
return None;
}
- if Some(e_instance) != instance_name {
+ if Some(e_world) != world_name {
return None;
}
diff --git a/azalea/src/pathfinder/debug.rs b/azalea/src/pathfinder/debug.rs
index 25f82946..7fe44919 100644
--- a/azalea/src/pathfinder/debug.rs
+++ b/azalea/src/pathfinder/debug.rs
@@ -1,4 +1,4 @@
-use azalea_client::{chat::SendChatEvent, local_player::InstanceHolder};
+use azalea_client::{chat::SendChatEvent, local_player::WorldHolder};
use azalea_core::position::Vec3;
use bevy_ecs::prelude::*;
@@ -35,7 +35,7 @@ use super::ExecutingPath;
pub struct PathfinderDebugParticles;
pub fn debug_render_path_with_particles(
- mut query: Query<(Entity, &ExecutingPath, &InstanceHolder), With<PathfinderDebugParticles>>,
+ mut query: Query<(Entity, &ExecutingPath, &WorldHolder), With<PathfinderDebugParticles>>,
// chat_events is Option because the tests don't have SendChatEvent
// and we have to use ResMut<Messages> because bevy doesn't support Option<MessageWriter>
chat_events: Option<ResMut<Messages<SendChatEvent>>>,
@@ -50,12 +50,12 @@ pub fn debug_render_path_with_particles(
*tick_count += 1;
return;
}
- for (entity, executing_path, instance_holder) in &mut query {
+ for (entity, executing_path, world_holder) in &mut query {
if executing_path.path.is_empty() {
continue;
}
- let chunks = &instance_holder.instance.read().chunks;
+ let chunks = &world_holder.shared.read().chunks;
let mut start = executing_path.last_reached_node;
for (i, edge) in executing_path.path.iter().enumerate() {
diff --git a/azalea/src/pathfinder/extras/utils.rs b/azalea/src/pathfinder/extras/utils.rs
index 3ae0b457..53345139 100644
--- a/azalea/src/pathfinder/extras/utils.rs
+++ b/azalea/src/pathfinder/extras/utils.rs
@@ -115,13 +115,13 @@ pub fn get_hit_result_while_looking_at_with_eye_position(
#[cfg(test)]
mod tests {
use azalea_core::position::ChunkPos;
- use azalea_world::{Chunk, PartialInstance};
+ use azalea_world::{Chunk, PartialWorld};
use super::*;
#[test]
fn test_cannot_reach_block_through_wall_when_y_is_negative() {
- let mut partial_world = PartialInstance::default();
+ let mut partial_world = PartialWorld::default();
let mut world = ChunkStorage::default();
partial_world
.chunks
diff --git a/azalea/src/pathfinder/mod.rs b/azalea/src/pathfinder/mod.rs
index fe94e42d..96de98da 100644
--- a/azalea/src/pathfinder/mod.rs
+++ b/azalea/src/pathfinder/mod.rs
@@ -36,7 +36,7 @@ use azalea_block::{BlockState, BlockTrait};
use azalea_client::{
StartSprintEvent, StartWalkEvent,
inventory::InventorySystems,
- local_player::InstanceHolder,
+ local_player::WorldHolder,
mining::{Mining, MiningSystems, StartMiningBlockEvent},
movement::MoveEventsSystems,
};
@@ -46,7 +46,7 @@ use azalea_core::{
};
use azalea_entity::{LocalEntity, Physics, Position, inventory::Inventory, metadata::Player};
use azalea_physics::{PhysicsSystems, get_block_pos_below_that_affects_movement};
-use azalea_world::{InstanceContainer, InstanceName};
+use azalea_world::{WorldName, Worlds};
use bevy_app::{PreUpdate, Update};
use bevy_ecs::prelude::*;
use bevy_tasks::{AsyncComputeTaskPool, Task};
@@ -109,7 +109,7 @@ impl Plugin for PathfinderPlugin {
(
goto_listener,
handle_tasks,
- stop_pathfinding_on_instance_change,
+ stop_pathfinding_on_world_change,
path_found_listener,
handle_stop_pathfinding_event,
)
@@ -307,16 +307,16 @@ pub fn goto_listener(
&mut Pathfinder,
Option<&mut ExecutingPath>,
&Position,
- &InstanceName,
+ &WorldName,
&Inventory,
Option<&CustomPathfinderState>,
)>,
- instance_container: Res<InstanceContainer>,
+ worlds: Res<Worlds>,
) {
let thread_pool = AsyncComputeTaskPool::get();
for event in events.read() {
- let Ok((mut pathfinder, executing_path, position, instance_name, inventory, custom_state)) =
+ let Ok((mut pathfinder, executing_path, position, world_name, inventory, custom_state)) =
query.get_mut(event.entity)
else {
warn!("got goto event for an entity that can't pathfind");
@@ -367,8 +367,8 @@ pub fn goto_listener(
);
}
- let world_lock = instance_container
- .get(instance_name)
+ let world_lock = worlds
+ .get(world_name)
.expect("Entity tried to pathfind but the entity isn't in a valid world");
let goal = event.goal.clone();
@@ -417,7 +417,7 @@ pub struct CalculatePathCtx {
pub entity: Entity,
pub start: BlockPos,
pub goal: Arc<dyn Goal>,
- pub world_lock: Arc<RwLock<azalea_world::Instance>>,
+ pub world_lock: Arc<RwLock<azalea_world::World>>,
pub goto_id_atomic: Arc<AtomicUsize>,
pub mining_cache: MiningCache,
pub custom_state: CustomPathfinderState,
@@ -559,15 +559,15 @@ pub fn path_found_listener(
mut query: Query<(
&mut Pathfinder,
Option<&mut ExecutingPath>,
- &InstanceName,
+ &WorldName,
&Inventory,
Option<&CustomPathfinderState>,
)>,
- instance_container: Res<InstanceContainer>,
+ worlds: Res<Worlds>,
mut commands: Commands,
) {
for event in events.read() {
- let Ok((mut pathfinder, executing_path, instance_name, inventory, custom_state)) =
+ let Ok((mut pathfinder, executing_path, world_name, inventory, custom_state)) =
query.get_mut(event.entity)
else {
debug!("got path found event for an entity that can't pathfind");
@@ -580,8 +580,8 @@ pub fn path_found_listener(
// combine the old and new paths if the first node of the new path is a
// successor of the last node of the old path
if let Some(last_node_of_current_path) = executing_path.path.back() {
- let world_lock = instance_container
- .get(instance_name)
+ let world_lock = worlds
+ .get(world_name)
.expect("Entity tried to pathfind but the entity isn't in a valid world");
let origin = event.start;
let successors_fn: moves::SuccessorsFn = event.successors_fn;
@@ -676,11 +676,11 @@ pub fn timeout_movement(
&mut ExecutingPath,
&Position,
Option<&Mining>,
- &InstanceName,
+ &WorldName,
&Inventory,
Option<&CustomPathfinderState>,
)>,
- instance_container: Res<InstanceContainer>,
+ worlds: Res<Worlds>,
) {
for (
entity,
@@ -688,7 +688,7 @@ pub fn timeout_movement(
mut executing_path,
position,
mining,
- instance_name,
+ world_name,
inventory,
custom_state,
) in &mut query
@@ -713,8 +713,8 @@ pub fn timeout_movement(
let cur_pos = player_pos_to_block_pos(**position);
executing_path.last_reached_node = cur_pos;
- let world_lock = instance_container
- .get(instance_name)
+ let world_lock = worlds
+ .get(world_name)
.expect("Entity tried to pathfind but the entity isn't in a valid world");
let Some(opts) = pathfinder.opts.clone() else {
warn!(
@@ -751,15 +751,14 @@ pub fn check_node_reached(
&mut ExecutingPath,
&Position,
&Physics,
- &InstanceName,
+ &WorldName,
)>,
mut walk_events: MessageWriter<StartWalkEvent>,
mut commands: Commands,
- instance_container: Res<InstanceContainer>,
+ worlds: Res<Worlds>,
) {
- for (entity, mut pathfinder, mut executing_path, position, physics, instance_name) in &mut query
- {
- let Some(instance) = instance_container.get(instance_name) else {
+ for (entity, mut pathfinder, mut executing_path, position, physics, world_name) in &mut query {
+ let Some(world) = worlds.get(world_name) else {
warn!("entity is pathfinding but not in a valid world");
continue;
};
@@ -794,8 +793,8 @@ pub fn check_node_reached(
let block_pos_below = get_block_pos_below_that_affects_movement(*position);
let block_state_below = {
- let instance = instance.read();
- instance
+ let world = world.read();
+ world
.chunks
.get_block_state(block_pos_below)
.unwrap_or(BlockState::AIR)
@@ -879,21 +878,21 @@ pub fn check_for_path_obstruction(
Entity,
&mut Pathfinder,
&mut ExecutingPath,
- &InstanceName,
+ &WorldName,
&Inventory,
Option<&CustomPathfinderState>,
)>,
- instance_container: Res<InstanceContainer>,
+ worlds: Res<Worlds>,
) {
- for (entity, mut pathfinder, mut executing_path, instance_name, inventory, custom_state) in
+ for (entity, mut pathfinder, mut executing_path, world_name, inventory, custom_state) in
&mut query
{
let Some(opts) = pathfinder.opts.clone() else {
continue;
};
- let world_lock = instance_container
- .get(instance_name)
+ let world_lock = worlds
+ .get(world_name)
.expect("Entity tried to pathfind but the entity isn't in a valid world");
// obstruction check (the path we're executing isn't possible anymore)
@@ -948,8 +947,8 @@ pub fn check_for_path_obstruction(
continue;
};
- let world_lock = instance_container
- .get(instance_name)
+ let world_lock = worlds
+ .get(world_name)
.expect("Entity tried to pathfind but the entity isn't in a valid world");
// patch up to 20 nodes
@@ -980,7 +979,7 @@ fn patch_path(
pathfinder: &mut Pathfinder,
inventory: &Inventory,
entity: Entity,
- world_lock: Arc<RwLock<azalea_world::Instance>>,
+ world_lock: Arc<RwLock<azalea_world::World>>,
custom_state: CustomPathfinderState,
opts: PathfinderOpts,
) {
@@ -1145,7 +1144,7 @@ pub fn tick_execute_path(
&Position,
&Physics,
Option<&Mining>,
- &InstanceHolder,
+ &WorldHolder,
&Inventory,
)>,
mut look_at_events: MessageWriter<LookAtEvent>,
@@ -1154,7 +1153,7 @@ pub fn tick_execute_path(
mut jump_events: MessageWriter<JumpEvent>,
mut start_mining_events: MessageWriter<StartMiningBlockEvent>,
) {
- for (entity, executing_path, position, physics, mining, instance_holder, inventory_component) in
+ for (entity, executing_path, position, physics, mining, world_holder, inventory_component) in
&mut query
{
if let Some(edge) = executing_path.path.front() {
@@ -1165,7 +1164,7 @@ pub fn tick_execute_path(
start: executing_path.last_reached_node,
physics,
is_currently_mining: mining.is_some(),
- instance: instance_holder.instance.clone(),
+ world: world_holder.shared.clone(),
menu: inventory_component.inventory_menu.clone(),
commands: &mut commands,
@@ -1246,13 +1245,13 @@ pub fn handle_stop_pathfinding_event(
}
}
-pub fn stop_pathfinding_on_instance_change(
- mut query: Query<(Entity, &mut ExecutingPath), Changed<InstanceName>>,
+pub fn stop_pathfinding_on_world_change(
+ mut query: Query<(Entity, &mut ExecutingPath), Changed<WorldName>>,
mut stop_pathfinding_events: MessageWriter<StopPathfindingEvent>,
) {
for (entity, mut executing_path) in &mut query {
if !executing_path.path.is_empty() {
- debug!("instance changed, clearing path");
+ debug!("world changed, clearing path");
executing_path.path.clear();
stop_pathfinding_events.write(StopPathfindingEvent {
entity,
diff --git a/azalea/src/pathfinder/moves/mod.rs b/azalea/src/pathfinder/moves/mod.rs
index 33c34c3b..d575c01a 100644
--- a/azalea/src/pathfinder/moves/mod.rs
+++ b/azalea/src/pathfinder/moves/mod.rs
@@ -13,7 +13,7 @@ use azalea_client::{
};
use azalea_core::position::{BlockPos, Vec3};
use azalea_inventory::Menu;
-use azalea_world::Instance;
+use azalea_world::World;
use bevy_ecs::{entity::Entity, message::MessageWriter, system::Commands};
use parking_lot::RwLock;
use tracing::debug;
@@ -65,7 +65,7 @@ pub struct ExecuteCtx<'s, 'w1, 'w2, 'w3, 'w4, 'w5, 'w6, 'a> {
pub position: Vec3,
pub physics: &'a azalea_entity::Physics,
pub is_currently_mining: bool,
- pub instance: Arc<RwLock<Instance>>,
+ pub world: Arc<RwLock<World>>,
pub menu: Menu,
pub commands: &'a mut Commands<'w1, 's>,
@@ -124,11 +124,7 @@ impl ExecuteCtx<'_, '_, '_, '_, '_, '_, '_, '_> {
/// Returns whether this block could be mined.
pub fn should_mine(&mut self, block: BlockPos) -> bool {
- let block_state = self
- .instance
- .read()
- .get_block_state(block)
- .unwrap_or_default();
+ let block_state = self.world.read().get_block_state(block).unwrap_or_default();
if is_block_state_passable(block_state) {
// block is already passable, no need to mine it
return false;
@@ -141,11 +137,7 @@ impl ExecuteCtx<'_, '_, '_, '_, '_, '_, '_, '_> {
///
/// Returns whether the block is being mined.
pub fn mine(&mut self, block: BlockPos) -> bool {
- let block_state = self
- .instance
- .read()
- .get_block_state(block)
- .unwrap_or_default();
+ let block_state = self.world.read().get_block_state(block).unwrap_or_default();
if is_block_state_passable(block_state) {
// block is already passable, no need to mine it
return false;
@@ -196,10 +188,7 @@ impl ExecuteCtx<'_, '_, '_, '_, '_, '_, '_, '_> {
}
pub fn get_block_state(&self, block: BlockPos) -> BlockState {
- self.instance
- .read()
- .get_block_state(block)
- .unwrap_or_default()
+ self.world.read().get_block_state(block).unwrap_or_default()
}
}
diff --git a/azalea/src/pathfinder/simulation.rs b/azalea/src/pathfinder/simulation.rs
index ca5e4f36..94837f9e 100644
--- a/azalea/src/pathfinder/simulation.rs
+++ b/azalea/src/pathfinder/simulation.rs
@@ -13,8 +13,8 @@ use azalea_entity::{
Attributes, LookDirection, Physics, Position, dimensions::EntityDimensions,
inventory::Inventory,
};
-use azalea_registry::{builtin::EntityKind, identifier::Identifier};
-use azalea_world::{ChunkStorage, Instance, InstanceContainer, PartialInstance};
+use azalea_registry::builtin::EntityKind;
+use azalea_world::{ChunkStorage, PartialWorld, World, WorldName, Worlds};
use bevy_app::App;
use bevy_ecs::prelude::*;
use parking_lot::RwLock;
@@ -45,14 +45,14 @@ impl SimulatedPlayerBundle {
}
}
-fn simulation_instance_name() -> Identifier {
- Identifier::new("azalea:simulation")
+fn simulation_world_name() -> WorldName {
+ WorldName::new("azalea:simulation")
}
-fn create_simulation_instance(chunks: ChunkStorage) -> (App, Arc<RwLock<Instance>>) {
- let instance_name = simulation_instance_name();
+fn create_simulation_world(chunks: ChunkStorage) -> (App, Arc<RwLock<World>>) {
+ let world_name = simulation_world_name();
- let instance = Arc::new(RwLock::new(Instance {
+ let world = Arc::new(RwLock::new(World {
chunks,
..Default::default()
}));
@@ -72,8 +72,8 @@ fn create_simulation_instance(chunks: ChunkStorage) -> (App, Arc<RwLock<Instance
azalea_client::interact::InteractPlugin,
azalea_client::loading::PlayerLoadedPlugin,
))
- .insert_resource(InstanceContainer {
- instances: [(instance_name.clone(), Arc::downgrade(&instance.clone()))]
+ .insert_resource(Worlds {
+ map: [(world_name.clone(), Arc::downgrade(&world.clone()))]
.iter()
.cloned()
.collect(),
@@ -83,14 +83,14 @@ fn create_simulation_instance(chunks: ChunkStorage) -> (App, Arc<RwLock<Instance
schedule.set_executor_kind(bevy_ecs::schedule::ExecutorKind::SingleThreaded);
});
- (app, instance)
+ (app, world)
}
fn create_simulation_player_complete_bundle(
- instance: Arc<RwLock<Instance>>,
+ world: Arc<RwLock<World>>,
player: &SimulatedPlayerBundle,
) -> impl Bundle {
- let instance_name = simulation_instance_name();
+ let world_name = simulation_world_name();
(
MinecraftEntityId(0),
@@ -100,12 +100,12 @@ fn create_simulation_player_complete_bundle(
Uuid::nil(),
*player.position,
EntityKind::Player,
- instance_name,
+ world_name,
),
- azalea_client::local_player::InstanceHolder {
- // partial_instance is never actually used by the pathfinder so
- partial_instance: Arc::new(RwLock::new(PartialInstance::default())),
- instance: instance.clone(),
+ azalea_client::local_player::WorldHolder {
+ // the partial world is never actually used by the pathfinder, so we can leave it empty
+ partial: Arc::new(RwLock::new(PartialWorld::default())),
+ shared: world.clone(),
},
Inventory::default(),
LocalGameMode::from(GameMode::Survival),
@@ -117,11 +117,11 @@ fn create_simulation_player_complete_bundle(
}
fn create_simulation_player(
- ecs: &mut World,
- instance: Arc<RwLock<Instance>>,
+ ecs: &mut bevy_ecs::world::World,
+ world: Arc<RwLock<World>>,
player: SimulatedPlayerBundle,
) -> Entity {
- let mut entity = ecs.spawn(create_simulation_player_complete_bundle(instance, &player));
+ let mut entity = ecs.spawn(create_simulation_player_complete_bundle(world, &player));
entity.insert(player);
entity.id()
}
@@ -130,17 +130,17 @@ fn create_simulation_player(
pub struct Simulation {
pub app: App,
pub entity: Entity,
- _instance: Arc<RwLock<Instance>>,
+ _world: Arc<RwLock<World>>,
}
impl Simulation {
pub fn new(chunks: ChunkStorage, player: SimulatedPlayerBundle) -> Self {
- let (mut app, instance) = create_simulation_instance(chunks);
- let entity = create_simulation_player(app.world_mut(), instance.clone(), player);
+ let (mut app, world) = create_simulation_world(chunks);
+ let entity = create_simulation_player(app.world_mut(), world.clone(), player);
Self {
app,
entity,
- _instance: instance,
+ _world: world,
}
}
@@ -168,12 +168,12 @@ impl Simulation {
/// A set of simulations, useful for efficiently doing multiple simulations.
pub struct SimulationSet {
pub app: App,
- instance: Arc<RwLock<Instance>>,
+ world: Arc<RwLock<World>>,
}
impl SimulationSet {
pub fn new(chunks: ChunkStorage) -> Self {
- let (app, instance) = create_simulation_instance(chunks);
- Self { app, instance }
+ let (app, world) = create_simulation_world(chunks);
+ Self { app, world }
}
pub fn tick(&mut self) {
self.app.update();
@@ -181,7 +181,7 @@ impl SimulationSet {
}
pub fn spawn(&mut self, player: SimulatedPlayerBundle) -> Entity {
- create_simulation_player(self.app.world_mut(), self.instance.clone(), player)
+ create_simulation_player(self.app.world_mut(), self.world.clone(), player)
}
pub fn despawn(&mut self, entity: Entity) {
self.app.world_mut().despawn(entity);
diff --git a/azalea/src/pathfinder/world.rs b/azalea/src/pathfinder/world.rs
index 13d60162..fdeb0b2f 100644
--- a/azalea/src/pathfinder/world.rs
+++ b/azalea/src/pathfinder/world.rs
@@ -11,7 +11,7 @@ use azalea_core::{
};
use azalea_physics::collision::BlockWithShape;
use azalea_registry::{builtin::BlockKind, tags};
-use azalea_world::{Instance, palette::PalettedContainer};
+use azalea_world::{World, palette::PalettedContainer};
use parking_lot::RwLock;
use super::{mining::MiningCache, rel_block_pos::RelBlockPos};
@@ -25,7 +25,7 @@ pub struct CachedWorld {
origin: BlockPos,
min_y: i32,
- world_lock: Arc<RwLock<Instance>>,
+ world_lock: Arc<RwLock<World>>,
// we store `PalettedContainer`s instead of `Chunk`s or `Section`s because it doesn't contain
// any unnecessary data like heightmaps or biomes.
@@ -99,7 +99,7 @@ pub struct CachedSection {
}
impl CachedWorld {
- pub fn new(world_lock: Arc<RwLock<Instance>>, origin: BlockPos) -> Self {
+ pub fn new(world_lock: Arc<RwLock<World>>, origin: BlockPos) -> Self {
let min_y = world_lock.read().chunks.min_y;
Self {
origin,
@@ -675,13 +675,13 @@ pub fn is_block_state_water(block_state: BlockState) -> bool {
#[cfg(test)]
mod tests {
- use azalea_world::{Chunk, ChunkStorage, PartialInstance};
+ use azalea_world::{Chunk, ChunkStorage, PartialWorld};
use super::*;
#[test]
fn test_is_passable() {
- let mut partial_world = PartialInstance::default();
+ let mut partial_world = PartialWorld::default();
let mut world = ChunkStorage::default();
partial_world
@@ -703,7 +703,7 @@ mod tests {
#[test]
fn test_is_solid() {
- let mut partial_world = PartialInstance::default();
+ let mut partial_world = PartialWorld::default();
let mut world = ChunkStorage::default();
partial_world
.chunks
@@ -724,7 +724,7 @@ mod tests {
#[test]
fn test_is_standable() {
- let mut partial_world = PartialInstance::default();
+ let mut partial_world = PartialWorld::default();
let mut world = ChunkStorage::default();
partial_world
.chunks
diff --git a/azalea/src/swarm/builder.rs b/azalea/src/swarm/builder.rs
index 14c9c290..560be3d8 100644
--- a/azalea/src/swarm/builder.rs
+++ b/azalea/src/swarm/builder.rs
@@ -10,7 +10,7 @@ use std::{
use azalea_client::{DefaultPlugins, account::Account, start_ecs_runner};
use azalea_protocol::address::{ResolvableAddr, ResolvedAddr};
-use azalea_world::InstanceContainer;
+use azalea_world::Worlds;
use bevy_app::{App, AppExit, Plugins, SubApp};
use bevy_ecs::{component::Component, resource::Resource};
use futures::future::join_all;
@@ -431,7 +431,7 @@ where
addr
};
- let instance_container = Arc::new(RwLock::new(InstanceContainer::default()));
+ let worlds = Arc::new(RwLock::new(Worlds::default()));
// we can't modify the swarm plugins after this
let (bots_tx, mut bots_rx) = mpsc::unbounded_channel();
@@ -451,7 +451,7 @@ where
ecs: ecs_lock.clone(),
address: Arc::new(RwLock::new(address)),
- instance_container,
+ worlds,
bots_tx,
diff --git a/azalea/src/swarm/chat.rs b/azalea/src/swarm/chat.rs
index 0bad69c1..c5e3eba3 100644
--- a/azalea/src/swarm/chat.rs
+++ b/azalea/src/swarm/chat.rs
@@ -2,12 +2,12 @@
// How the chat event works (to avoid firing the event multiple times):
// ---
-// There's a shared queue of all the chat messages
-// Each bot contains an index of the farthest message we've seen
-// When a bot receives a chat messages, it looks into the queue to find the
-// earliest instance of the message content that's after the bot's chat index.
-// If it finds it, then its personal index is simply updated. Otherwise, fire
-// the event and add to the queue.
+// There's a shared queue of all the chat messages. Each bot contains an index
+// of the farthest message that it has seen. When a bot receives a chat
+// message, it looks into the shared queue to find the earliest instance of the
+// message content, that's after the bot's current chat index. If it finds it,
+// then its personal index is simply updated. Otherwise, it fires the event and
+// adds to the shared queue.
//
// To make sure the queue doesn't grow too large, we keep a `chat_min_index`
// in Swarm that's set to the smallest index of all the bots, and we remove all
diff --git a/azalea/src/swarm/events.rs b/azalea/src/swarm/events.rs
index ee5859ca..83817c86 100644
--- a/azalea/src/swarm/events.rs
+++ b/azalea/src/swarm/events.rs
@@ -1,4 +1,4 @@
-use azalea_client::local_player::InstanceHolder;
+use azalea_client::local_player::WorldHolder;
use azalea_core::entity_id::MinecraftEntityId;
use bevy_app::{App, Plugin, Update};
use bevy_ecs::prelude::*;
@@ -21,7 +21,7 @@ pub struct SwarmReadyEvent;
struct IsSwarmReady(bool);
fn check_ready(
- query: Query<Option<&MinecraftEntityId>, With<InstanceHolder>>,
+ query: Query<Option<&MinecraftEntityId>, With<WorldHolder>>,
mut is_swarm_ready: ResMut<IsSwarmReady>,
mut ready_events: MessageWriter<SwarmReadyEvent>,
) {
diff --git a/azalea/src/swarm/mod.rs b/azalea/src/swarm/mod.rs
index b1061346..4ecb0726 100644
--- a/azalea/src/swarm/mod.rs
+++ b/azalea/src/swarm/mod.rs
@@ -15,7 +15,7 @@ use std::sync::{
use azalea_client::{account::Account, chat::ChatPacket, join::ConnectOpts};
use azalea_entity::LocalEntity;
use azalea_protocol::address::ResolvedAddr;
-use azalea_world::InstanceContainer;
+use azalea_world::Worlds;
use bevy_app::{PluginGroup, PluginGroupBuilder};
use bevy_ecs::prelude::*;
pub use builder::SwarmBuilder;
@@ -47,7 +47,7 @@ pub struct Swarm {
// the address is public and mutable so plugins can change it
pub address: Arc<RwLock<ResolvedAddr>>,
- pub instance_container: Arc<RwLock<InstanceContainer>>,
+ pub worlds: Arc<RwLock<Worlds>>,
/// This is used internally to make the client handler function work.
pub(crate) bots_tx: mpsc::UnboundedSender<(Option<crate::Event>, Client)>,