Skip to main content

steel_core/physics/
mod.rs

1//! Physics engine for entity movement with vanilla Minecraft parity.
2//!
3//! This module implements the core physics simulation for moving entities through
4//! the world with proper collision detection, including:
5//! - Step-up mechanics (climbing blocks ≤ `max_up_step` height)
6//! - Sneak-edge prevention (staying on block edges while crouching)
7//! - VoxelShape-based collision using AABB lists
8//!
9//! The implementation closely follows vanilla's `Entity.move()` method to ensure
10//! 1:1 movement validation for anti-cheat purposes.
11
12use steel_registry::{
13    blocks::{BlockRef, block_state_ext::BlockStateExt},
14    vanilla_blocks,
15};
16use steel_utils::{BlockStateId, Identifier};
17
18pub mod collision;
19pub(crate) mod entity_move;
20pub mod movement_validation;
21pub(crate) mod physics_state;
22pub mod shapes;
23
24// Public API
25pub use collision::{
26    CollisionWorld, WorldCollisionProvider, has_block_collision, has_collision,
27    is_colliding_with_new_shapes,
28};
29pub(crate) use entity_move::move_entity;
30pub use entity_move::{MoveResult, MoverType};
31pub(crate) use movement_validation::ClientAuthoredMovementState;
32pub use movement_validation::{
33    MOVEMENT_ERROR_THRESHOLD, MovementCollisionValidation, movement_error_delta,
34};
35pub(crate) use physics_state::EntityPhysicsState;
36pub use shapes::{collide, join_is_not_empty, merged_face_occludes, translate_shape};
37
38/// Collision epsilon used for AABB deflation (vanilla constant).
39pub const COLLISION_EPSILON: f64 = 1.0e-5;
40
41/// Returns whether this block's collision behavior is owned by an extensible namespace.
42pub(crate) fn block_has_extensible_collision_behavior(block: BlockRef) -> bool {
43    block.key.namespace != Identifier::VANILLA_NAMESPACE
44}
45
46fn block_may_expand_collision_cursor(block: BlockRef, has_large_static_shape: bool) -> bool {
47    block_has_extensible_collision_behavior(block)
48        || block.config.dynamic_shape
49        || block == &vanilla_blocks::MOVING_PISTON
50        || has_large_static_shape
51}
52
53/// Returns whether this state's collision behavior requires live reads around callbacks.
54pub(crate) fn block_state_has_extensible_collision_behavior(state: BlockStateId) -> bool {
55    block_has_extensible_collision_behavior(state.get_block())
56}
57
58/// Returns whether a state may require Vanilla's expanded block-collision cursor.
59pub(crate) fn block_state_may_expand_collision_cursor(state: BlockStateId) -> bool {
60    block_may_expand_collision_cursor(
61        state.get_block(),
62        state
63            .get_static_collision_shape()
64            .has_large_collision_shape(),
65    )
66}