aboutsummaryrefslogtreecommitdiff
path: root/azalea/src/pathfinder
diff options
context:
space:
mode:
authormat <27899617+mat-1@users.noreply.github.com>2026-01-13 10:51:30 -0600
committerGitHub <noreply@github.com>2026-01-13 10:51:30 -0600
commitd5fa5e32b37754b3b5c136e58821e48cd3b7c2ff (patch)
treeea04702f96ad170fb1d90e5ed2dc875ae8166495 /azalea/src/pathfinder
parentefb36d5fc0fe56a98f5795c53dfa109887cd5aae (diff)
downloadazalea-drasl-d5fa5e32b37754b3b5c136e58821e48cd3b7c2ff.tar.xz
Rename Instance to World (#304)
Diffstat (limited to 'azalea/src/pathfinder')
-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
6 files changed, 85 insertions, 97 deletions
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