aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormat <git@matdoes.dev>2026-01-17 11:58:37 -1030
committermat <git@matdoes.dev>2026-01-17 11:58:37 -1030
commit74ef7d19b2bc4453f5368cc39c838582f2f3bafd (patch)
treecd133a77934f461b52db614eb10a99eb620f53e6
parenta49c8d0b53fed223bab127704c604291ee77f921 (diff)
downloadazalea-drasl-74ef7d19b2bc4453f5368cc39c838582f2f3bafd.tar.xz
use more compact chunk section positions in pathfinder
-rw-r--r--azalea-core/src/position.rs4
-rw-r--r--azalea/benches/pathfinder.rs2
-rw-r--r--azalea/examples/testbot/commands/debug.rs2
-rw-r--r--azalea/src/pathfinder/mod.rs4
-rw-r--r--azalea/src/pathfinder/moves/basic.rs2
-rw-r--r--azalea/src/pathfinder/moves/mod.rs2
-rw-r--r--azalea/src/pathfinder/moves/parkour.rs2
-rw-r--r--azalea/src/pathfinder/moves/uncommon.rs2
-rw-r--r--azalea/src/pathfinder/positions.rs (renamed from azalea/src/pathfinder/rel_block_pos.rs)39
-rw-r--r--azalea/src/pathfinder/world.rs34
10 files changed, 69 insertions, 24 deletions
diff --git a/azalea-core/src/position.rs b/azalea-core/src/position.rs
index 3f2a724f..f664957f 100644
--- a/azalea-core/src/position.rs
+++ b/azalea-core/src/position.rs
@@ -787,7 +787,7 @@ impl From<BlockPos> for ChunkPos {
impl From<BlockPos> for ChunkSectionPos {
#[inline]
fn from(pos: BlockPos) -> Self {
- ChunkSectionPos {
+ Self {
x: pos.x >> 4,
y: pos.y >> 4,
z: pos.z >> 4,
@@ -797,7 +797,7 @@ impl From<BlockPos> for ChunkSectionPos {
impl From<&BlockPos> for ChunkSectionPos {
#[inline]
fn from(pos: &BlockPos) -> Self {
- ChunkSectionPos {
+ Self {
x: pos.x >> 4,
y: pos.y >> 4,
z: pos.z >> 4,
diff --git a/azalea/benches/pathfinder.rs b/azalea/benches/pathfinder.rs
index 5c06474b..bdb4b3c4 100644
--- a/azalea/benches/pathfinder.rs
+++ b/azalea/benches/pathfinder.rs
@@ -7,7 +7,7 @@ use azalea::{
custom_state::CustomPathfinderStateRef,
goals::{BlockPosGoal, Goal},
mining::MiningCache,
- rel_block_pos::RelBlockPos,
+ positions::RelBlockPos,
world::CachedWorld,
},
};
diff --git a/azalea/examples/testbot/commands/debug.rs b/azalea/examples/testbot/commands/debug.rs
index 3c72c85f..ac1f31e9 100644
--- a/azalea/examples/testbot/commands/debug.rs
+++ b/azalea/examples/testbot/commands/debug.rs
@@ -10,7 +10,7 @@ use azalea::{
packet::game,
pathfinder::{
ExecutingPath, Pathfinder, custom_state::CustomPathfinderStateRef, mining::MiningCache,
- moves::PathfinderCtx, rel_block_pos::RelBlockPos, world::CachedWorld,
+ moves::PathfinderCtx, positions::RelBlockPos, world::CachedWorld,
},
};
use azalea_core::hit_result::HitResult;
diff --git a/azalea/src/pathfinder/mod.rs b/azalea/src/pathfinder/mod.rs
index cab30f7a..9a75f868 100644
--- a/azalea/src/pathfinder/mod.rs
+++ b/azalea/src/pathfinder/mod.rs
@@ -13,7 +13,7 @@ pub mod goals;
mod goto_event;
pub mod mining;
pub mod moves;
-pub mod rel_block_pos;
+pub mod positions;
pub mod simulation;
#[cfg(test)]
mod tests;
@@ -55,7 +55,7 @@ use futures_lite::future;
use goals::BlockPosGoal;
pub use goto_event::{GotoEvent, PathfinderOpts};
use parking_lot::RwLock;
-use rel_block_pos::RelBlockPos;
+use positions::RelBlockPos;
use tokio::sync::broadcast::error::RecvError;
use tracing::{debug, error, info, trace, warn};
diff --git a/azalea/src/pathfinder/moves/basic.rs b/azalea/src/pathfinder/moves/basic.rs
index 69c949d7..1e8b7c64 100644
--- a/azalea/src/pathfinder/moves/basic.rs
+++ b/azalea/src/pathfinder/moves/basic.rs
@@ -9,7 +9,7 @@ use azalea_core::{
use super::{Edge, ExecuteCtx, IsReachedCtx, MoveData, PathfinderCtx, default_is_reached};
use crate::pathfinder::{
- astar, costs::*, moves::BARITONE_COMPAT, player_pos_to_block_pos, rel_block_pos::RelBlockPos,
+ astar, costs::*, moves::BARITONE_COMPAT, player_pos_to_block_pos, positions::RelBlockPos,
};
pub fn basic_move(ctx: &mut PathfinderCtx, node: RelBlockPos) {
diff --git a/azalea/src/pathfinder/moves/mod.rs b/azalea/src/pathfinder/moves/mod.rs
index e62ae516..95d3ae35 100644
--- a/azalea/src/pathfinder/moves/mod.rs
+++ b/azalea/src/pathfinder/moves/mod.rs
@@ -23,7 +23,7 @@ use super::{
astar,
custom_state::CustomPathfinderStateRef,
mining::MiningCache,
- rel_block_pos::RelBlockPos,
+ positions::RelBlockPos,
world::{CachedWorld, is_block_state_passable},
};
use crate::{
diff --git a/azalea/src/pathfinder/moves/parkour.rs b/azalea/src/pathfinder/moves/parkour.rs
index 09f4078a..b6b97465 100644
--- a/azalea/src/pathfinder/moves/parkour.rs
+++ b/azalea/src/pathfinder/moves/parkour.rs
@@ -3,7 +3,7 @@ use azalea_core::{direction::CardinalDirection, position::BlockPos};
use tracing::trace;
use super::{Edge, ExecuteCtx, IsReachedCtx, MoveData, PathfinderCtx};
-use crate::pathfinder::{astar, costs::*, player_pos_to_block_pos, rel_block_pos::RelBlockPos};
+use crate::pathfinder::{astar, costs::*, player_pos_to_block_pos, positions::RelBlockPos};
pub fn parkour_move(ctx: &mut PathfinderCtx, node: RelBlockPos) {
if !ctx.world.is_block_solid(node.down(1)) {
diff --git a/azalea/src/pathfinder/moves/uncommon.rs b/azalea/src/pathfinder/moves/uncommon.rs
index 43df3334..bc85333e 100644
--- a/azalea/src/pathfinder/moves/uncommon.rs
+++ b/azalea/src/pathfinder/moves/uncommon.rs
@@ -9,7 +9,7 @@ use crate::pathfinder::{
BARITONE_COMPAT, MoveData, PathfinderCtx,
basic::{descend_is_reached, execute_descend_move},
},
- rel_block_pos::RelBlockPos,
+ positions::RelBlockPos,
};
pub fn uncommon_move(ctx: &mut PathfinderCtx, node: RelBlockPos) {
diff --git a/azalea/src/pathfinder/rel_block_pos.rs b/azalea/src/pathfinder/positions.rs
index 0900ac91..ca2768b2 100644
--- a/azalea/src/pathfinder/rel_block_pos.rs
+++ b/azalea/src/pathfinder/positions.rs
@@ -1,6 +1,7 @@
use std::{
+ cmp,
hash::{Hash, Hasher},
- mem::transmute,
+ mem::{self, transmute},
ops::{Add, Mul},
};
@@ -131,3 +132,39 @@ impl Hash for RelBlockPos {
self.as_u64().hash(state);
}
}
+
+/// Similar to [`ChunkSectionPos`] but fits in 64 bits.
+///
+/// [`ChunkSectionPos`]: azalea_core::position::ChunkSectionPos
+#[derive(Clone, Copy, PartialEq, Eq)]
+#[repr(C)]
+pub struct SmallChunkSectionPos {
+ pub y: i32,
+ pub x: i16,
+ pub z: i16,
+}
+impl SmallChunkSectionPos {
+ pub fn as_u64(self) -> u64 {
+ unsafe { mem::transmute::<_, u64>(self) }
+ }
+}
+impl From<BlockPos> for SmallChunkSectionPos {
+ #[inline]
+ fn from(pos: BlockPos) -> Self {
+ Self {
+ x: (pos.x >> 4) as i16,
+ y: pos.y >> 4,
+ z: (pos.z >> 4) as i16,
+ }
+ }
+}
+impl PartialOrd for SmallChunkSectionPos {
+ fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
+ self.as_u64().partial_cmp(&other.as_u64())
+ }
+}
+impl Ord for SmallChunkSectionPos {
+ fn cmp(&self, other: &Self) -> cmp::Ordering {
+ self.as_u64().cmp(&other.as_u64())
+ }
+}
diff --git a/azalea/src/pathfinder/world.rs b/azalea/src/pathfinder/world.rs
index 9970de8d..ec8aa259 100644
--- a/azalea/src/pathfinder/world.rs
+++ b/azalea/src/pathfinder/world.rs
@@ -1,6 +1,7 @@
use core::f32;
use std::{
cell::{RefCell, UnsafeCell},
+ cmp, mem,
sync::Arc,
};
@@ -14,7 +15,8 @@ use azalea_registry::{builtin::BlockKind, tags};
use azalea_world::{World, palette::PalettedContainer};
use parking_lot::RwLock;
-use super::{mining::MiningCache, rel_block_pos::RelBlockPos};
+use super::{mining::MiningCache, positions::RelBlockPos};
+use crate::pathfinder::positions::SmallChunkSectionPos;
/// An efficient representation of the world used for the pathfinder.
pub struct CachedWorld {
@@ -46,7 +48,7 @@ pub struct CachedSections {
impl CachedSections {
#[inline]
- pub fn get_mut(&mut self, pos: ChunkSectionPos) -> Option<&mut CachedSection> {
+ pub fn get_mut(&mut self, pos: SmallChunkSectionPos) -> Option<&mut CachedSection> {
if let Some(last_item) = self.sections.get(self.last_index) {
if last_item.pos == pos {
return Some(&mut self.sections[self.last_index]);
@@ -83,7 +85,7 @@ impl CachedSections {
}
pub struct CachedSection {
- pub pos: ChunkSectionPos,
+ pub pos: SmallChunkSectionPos,
pub bitsets: Box<SectionBitsets>,
}
#[derive(Default)]
@@ -130,7 +132,7 @@ impl CachedWorld {
fn with_section<T>(
&self,
- section_pos: ChunkSectionPos,
+ section_pos: SmallChunkSectionPos,
f: impl FnOnce(&azalea_world::palette::PalettedContainer<BlockState>) -> T,
) -> Option<T> {
if section_pos.y * 16 < self.min_y {
@@ -138,7 +140,7 @@ impl CachedWorld {
return None;
}
- let chunk_pos = ChunkPos::from(section_pos);
+ let chunk_pos = ChunkPos::new(section_pos.x as i32, section_pos.z as i32);
let section_index =
azalea_world::chunk_storage::section_index(section_pos.y * 16, self.min_y) as usize;
@@ -205,7 +207,7 @@ impl CachedWorld {
Some(r)
}
- fn calculate_bitsets_for_section(&self, section_pos: ChunkSectionPos) -> CachedSection {
+ fn calculate_bitsets_for_section(&self, section_pos: SmallChunkSectionPos) -> CachedSection {
let bitsets = self
.with_section(section_pos, |section| {
let mut passable_bitset = FastFixedBitSet::<4096>::new();
@@ -248,8 +250,10 @@ impl CachedWorld {
pos: BlockPos,
cb: impl FnOnce(&SectionBitsets, usize) -> bool,
) -> bool {
- let (section_pos, section_block_pos) =
- (ChunkSectionPos::from(pos), ChunkSectionBlockPos::from(pos));
+ let (section_pos, section_block_pos) = (
+ SmallChunkSectionPos::from(pos),
+ ChunkSectionBlockPos::from(pos),
+ );
let index = u16::from(section_block_pos) as usize;
// SAFETY: we're only accessing this from one thread
let cached_blocks = unsafe { &mut *self.cached_blocks.get() };
@@ -285,8 +289,10 @@ impl CachedWorld {
}
fn get_block_state_at_pos(&self, pos: BlockPos) -> BlockState {
- let (section_pos, section_block_pos) =
- (ChunkSectionPos::from(pos), ChunkSectionBlockPos::from(pos));
+ let (section_pos, section_block_pos) = (
+ SmallChunkSectionPos::from(pos),
+ ChunkSectionBlockPos::from(pos),
+ );
let index = u16::from(section_block_pos) as usize;
self.with_section(section_pos, |section| section.get_at_index(index))
@@ -342,8 +348,10 @@ impl CachedWorld {
let rel_pos = pos;
let pos = pos.apply(self.origin);
- let (section_pos, section_block_pos) =
- (ChunkSectionPos::from(pos), ChunkSectionBlockPos::from(pos));
+ let (section_pos, section_block_pos) = (
+ SmallChunkSectionPos::from(pos),
+ ChunkSectionBlockPos::from(pos),
+ );
// we use this as an optimization to avoid getting the section again if the
// block is in the same section
@@ -436,7 +444,7 @@ impl CachedWorld {
check: impl FnOnce(BlockState) -> bool,
) -> bool {
let block_state = world
- .with_section(ChunkSectionPos::from(pos), |section| {
+ .with_section(SmallChunkSectionPos::from(pos), |section| {
section.get_at_index(u16::from(ChunkSectionBlockPos::from(pos)) as usize)
})
.unwrap_or_default();