skills/hytopia-physics/SKILL.md
Helps implement physics and collision in HYTOPIA SDK games. Use when users need rigid bodies, collision detection, raycasting, forces, or physics-based gameplay. Covers PhysicsComponent, colliders, raycasting, and physics simulation.
npx skillsauth add abstrucked/hytopia-skills hytopia-physicsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
This skill helps you implement physics and collision in HYTOPIA SDK games.
Documentation: https://dev.hytopia.com/sdk-guides/physics
Use this skill when the user:
import { Entity, PhysicsComponent, BoxCollider } from 'hytopia';
class PhysicsEntity extends Entity {
constructor() {
super();
this.addComponent(new PhysicsComponent({
mass: 1.0, // Kilograms
gravity: { x: 0, y: -9.81, z: 0 },
linearDamping: 0.1, // Air resistance
angularDamping: 0.1,
useGravity: true
}));
// Add collision shape
this.addComponent(new BoxCollider({
size: { x: 1, y: 1, z: 1 },
offset: { x: 0, y: 0.5, z: 0 }
}));
}
}
import { BoxCollider, SphereCollider, MeshCollider } from 'hytopia';
// Box collider
const box = new BoxCollider({
size: { x: 2, y: 1, z: 0.5 },
offset: { x: 0, y: 0, z: 0 }
});
// Sphere collider
const sphere = new SphereCollider({
radius: 0.5,
offset: { x: 0, y: 0.5, z: 0 }
});
// Mesh collider (from model)
const mesh = new MeshCollider({
modelUri: 'models/terrain.gltf',
convex: false // false = exact mesh, true = convex hull (faster)
});
import { Entity, PhysicsComponent } from 'hytopia';
class Projectile extends Entity {
physics: PhysicsComponent;
constructor() {
super();
this.physics = new PhysicsComponent({
mass: 0.1,
useGravity: true
});
this.addComponent(this.physics);
}
launch(direction: Vector3, force: number) {
// Apply impulse (instant force)
this.physics.applyImpulse(direction.multiply(force));
// Or apply continuous force
this.physics.applyForce(direction.multiply(force));
// Apply torque (rotation)
this.physics.applyTorque({ x: 0, y: 100, z: 0 });
}
}
import { World } from 'hytopia';
// Raycast from point in direction
const result = world.raycast(
{ x: 0, y: 10, z: 0 }, // Origin
{ x: 0, y: -1, z: 0 }, // Direction (normalized)
100 // Max distance
);
if (result.hit) {
console.log('Hit at:', result.position);
console.log('Hit entity:', result.entity);
console.log('Hit normal:', result.normal);
console.log('Hit distance:', result.distance);
}
// What is player looking at?
const raycast = world.raycast(
player.position,
player.lookDirection,
5 // Reach distance
);
if (raycast.hit) {
if (raycast.block) {
// Looking at a block
console.log('Block:', raycast.block.type);
}
if (raycast.entity) {
// Looking at an entity
console.log('Entity:', raycast.entity.id);
}
}
import { Entity, CollisionComponent } from 'hytopia';
class CollidableEntity extends Entity {
constructor() {
super();
const collision = new CollisionComponent();
collision.onCollisionEnter = (other) => {
console.log('Started colliding with:', other.id);
if (other instanceof Projectile) {
this.takeDamage(10);
}
};
collision.onCollisionExit = (other) => {
console.log('Stopped colliding with:', other.id);
};
collision.onCollisionStay = (other) => {
// Called every frame while colliding
};
this.addComponent(collision);
}
}
import { PhysicsComponent, CollisionLayer } from 'hytopia';
// Define what collides with what
const physics = new PhysicsComponent({
mass: 1,
collisionLayer: CollisionLayer.DEFAULT,
collisionMask: CollisionLayer.DEFAULT | CollisionLayer.PLAYER
});
// Layers: DEFAULT, PLAYER, ENEMY, PROJECTILE, TRIGGER, etc.
// Player doesn't collide with other players but collides with enemies
const playerPhysics = new PhysicsComponent({
collisionLayer: CollisionLayer.PLAYER,
collisionMask: CollisionLayer.DEFAULT | CollisionLayer.ENEMY | CollisionLayer.PROJECTILE
});
import { PhysicsMaterial } from 'hytopia';
const bouncyMaterial = new PhysicsMaterial({
friction: 0.5, // 0 = slippery, 1 = rough
restitution: 0.8, // 0 = no bounce, 1 = perfect bounce
density: 1.0 // Affects mass calculation
});
const iceMaterial = new PhysicsMaterial({
friction: 0.1,
restitution: 0.1
});
// Apply to collider
const collider = new BoxCollider({
size: { x: 1, y: 1, z: 1 },
material: bouncyMaterial
});
function isGrounded(entity: Entity): boolean {
const raycast = world.raycast(
entity.position,
{ x: 0, y: -1, z: 0 },
0.1 // Small distance below entity
);
return raycast.hit && raycast.distance < 0.05;
}
// Usage
if (isGrounded(player) && input.isPressed('space')) {
player.physics.applyImpulse({ x: 0, y: 10, z: 0 });
}
function applyExplosion(center: Vector3, radius: number, force: number) {
// Get all entities in radius
const entities = world.getEntitiesInRadius(center, radius);
for (const entity of entities) {
const direction = entity.position.subtract(center).normalize();
const distance = entity.position.distance(center);
const falloff = 1 - (distance / radius); // Stronger closer to center
if (entity.physics) {
entity.physics.applyImpulse(
direction.multiply(force * falloff)
);
}
}
}
development
Helps build and manage worlds in HYTOPIA SDK. Use when users need to create terrain, place blocks, manage chunks, or work with the world editor integration. Covers blocks, chunk loading, world generation, and build.hytopia.com workflow.
tools
Helps create and use plugins in HYTOPIA SDK games. Use when users need to add NPM packages, create reusable modules, or extend game functionality. Covers plugin requirements, installation, and best practices.
development
Helps save and load persistent data in HYTOPIA SDK games. Use when users need to save player progress, leaderboards, game state, or any data that persists across sessions. Covers PersistenceManager, global data, and player data.
development
Helps implement multiplayer features in HYTOPIA SDK games. Use when users need player management, server-authoritative gameplay, networking, or state synchronization. Covers Player class, server authority, network optimization, and player data.