Skip to content

Physics System Overview

The Physics System handles entity movement, collision detection, and physical simulation. It uses an ECS-based approach with velocity components, collision detection modules, and configurable hitboxes.

  • Physics: com.hypixel.hytale.server.core.modules.physics
  • Collision: com.hypixel.hytale.server.core.modules.collision
  • Hitbox: com.hypixel.hytale.server.core.modules.entity.hitboxcollision
  • Velocity: com.hypixel.hytale.server.core.modules.splitvelocity
┌─────────────────────────────────────────────────────────────────┐
│ Physics System │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌────────────────────────┐ │
│ │ Velocity │ │ Collision │ │ Hitbox │ │
│ │ Component │ │ Module │ │ Component │ │
│ └──────┬───────┘ └──────┬───────┘ └────────────┬───────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ Physics Provider / Systems │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────────┐ │ │
│ │ │ Force │ │Collision│ │Movement │ │ Response │ │ │
│ │ │ Accum. │ │Detection│ │ Update │ │ Handling │ │ │
│ │ └─────────┘ └─────────┘ └─────────┘ └─────────────┘ │ │
│ └──────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘

Stores entity velocity with server and client versions:

package com.hypixel.hytale.server.core.modules.physics.component;
public class Velocity {
// Set velocity
public void set(double x, double y, double z);
public void set(Vector3d velocity);
// Add force
public void addForce(Vector3d force);
// Get velocity
public Vector3d getVelocity();
public Vector3d getClientVelocity();
public double getSpeed();
// Instructions for velocity changes
public void addInstruction(Vector3d velocity, VelocityConfig config,
ChangeVelocityType type);
public List<Instruction> getInstructions();
}

Physical properties of an entity:

package com.hypixel.hytale.server.core.modules.physics.component;
public class PhysicsValues {
// Default values
public static final double DEFAULT_MASS = 1.0;
public static final double DEFAULT_DRAG_COEFFICIENT = 0.5;
public static final boolean DEFAULT_INVERTED_GRAVITY = false;
// Properties
public double getMass();
public void setMass(double mass);
public double getDragCoefficient();
public void setDragCoefficient(double coefficient);
public boolean isInvertedGravity();
public void setInvertedGravity(boolean inverted);
}

Entity collision bounds:

package com.hypixel.hytale.server.core.modules.entity.component;
public class BoundingBox {
// Main bounding box
public Box getBoundingBox();
public void setBoundingBox(Box box);
// Detail boxes for complex shapes
public Map<String, DetailBox[]> getDetailBoxes();
public void setDetailBoxes(Map<String, DetailBox[]> boxes);
}

Central collision detection system:

package com.hypixel.hytale.server.core.modules.collision;
public class CollisionModule extends JavaPlugin {
// Get singleton
public static CollisionModule get();
// Find collisions along movement path
public static CollisionResult findCollisions(
Box collider,
Vector3d position,
Vector3d velocity,
CollisionResult result,
IComponentAccessor accessor
);
// Validate position against collisions
public static boolean validatePosition(
World world,
Box collider,
Vector3d position,
CollisionResult result
);
// Block collisions (far distance)
public static void findBlockCollisionsIterative(...);
// Block collisions (short distance)
public static void findBlockCollisionsShortDistance(...);
// Entity collisions
public static void findCharacterCollisions(...);
// Intersection detection
public static void findIntersections(...);
}
  1. Force Accumulation

    • External forces, accelerations, impulses collected
    • Gravity applied based on entity properties
    • Fluid forces (buoyancy, drag) calculated
  2. Velocity Update

    • Forces integrated to velocity
    • Resistance applied (ground/air)
    • Velocity clamped to limits
  3. Movement Computation

    • Delta position calculated from velocity
    • Swept collision detection performed
    • Movement path adjusted for collisions
  4. Collision Response

    • Block collisions: bounce, slide, or stop
    • Entity collisions: impact callbacks
    • Trigger blocks: events fired
    • Damage blocks: damage applied
  5. State Update

    • Position updated
    • Velocity updated (post-collision)
    • Physics state set (Active/Resting/Inactive)
// Fluid densities
public static final double DENSITY_AIR = 1.2;
public static final double DENSITY_WATER = 998.0;
// Material masks
public static final int MASK_EMPTY = 1;
public static final int MASK_FLUID = 2;
public static final int MASK_SOLID = 4;
public static final int MASK_SUBMERGED = 8;
public static final int MASK_DAMAGE = 16;

The physics system supports multiple numerical integration methods:

MethodClassAccuracyPerformance
Symplectic EulerPhysicsBodyStateUpdaterSymplecticEulerLowFast
MidpointPhysicsBodyStateUpdaterMidpointMediumMedium
Runge-Kutta 4PhysicsBodyStateUpdaterRK4HighSlow
StateDescription
ActiveActively simulating physics
RestingStationary on support surface
InactivePhysics simulation disabled

Entities transition to Resting when velocity is near zero and supported by a block. They wake up when support blocks change.

Configures velocity resistance:

package com.hypixel.hytale.server.core.modules.splitvelocity;
public class VelocityConfig {
float groundResistance = 0.82f;
float groundResistanceMax;
float airResistance = 0.96f;
float airResistanceMax;
float threshold = 1.0f;
ThresholdStyle style; // Linear or non-linear
}
import com.hypixel.hytale.server.core.modules.collision.CollisionModule;
import com.hypixel.hytale.server.core.modules.collision.CollisionResult;
import com.hypixel.hytale.server.core.modules.physics.component.Velocity;
import com.hypixel.hytale.server.core.modules.physics.component.PhysicsValues;
import com.hypixel.hytale.server.core.modules.entity.component.BoundingBox;
import com.hypixel.hytale.math.Box;
import com.hypixel.hytale.math.Vector3d;
public class PhysicsExample {
public void applyKnockback(Ref<EntityStore> entityRef,
IComponentAccessor accessor,
Vector3d knockback) {
// Get velocity component
Velocity velocity = accessor.getComponent(entityRef, Velocity.getComponentType());
// Apply knockback force
velocity.addForce(knockback);
}
public boolean checkCollision(World world,
Ref<EntityStore> entityRef,
IComponentAccessor accessor,
Vector3d movement) {
// Get bounding box
BoundingBox bbox = accessor.getComponent(entityRef, BoundingBox.getComponentType());
Box collider = bbox.getBoundingBox();
// Get current position
TransformComponent transform = accessor.getComponent(entityRef,
TransformComponent.getComponentType());
Vector3d position = transform.getPosition();
// Check for collisions
CollisionResult result = new CollisionResult();
CollisionModule.findCollisions(collider, position, movement, result, accessor);
return result.hasBlockCollisions();
}
}