skills/hytopia-plugins/SKILL.md
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.
npx skillsauth add abstrucked/hytopia-skills hytopia-pluginsInstall 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 create and use plugins in HYTOPIA SDK games.
Documentation: https://dev.hytopia.com/sdk-guides/plugins
Use this skill when the user:
In HYTOPIA, a plugin and an NPM package are synonymous. You can:
Plugins cannot make outbound network requests. The HYTOPIA runtime blocks external requests except to whitelisted internal services.
// NOT ALLOWED - will be blocked
fetch('https://external-api.com/data');
axios.get('https://some-service.com');
// ALLOWED - internal HYTOPIA services
// (handled through SDK APIs)
Plugins must be published publicly on NPM. HYTOPIA's deployment pipeline automatically installs packages from package.json.
// package.json
{
"dependencies": {
"lodash": "^4.17.21",
"my-hytopia-plugin": "^1.0.0"
}
}
HYTOPIA reserves the right to blacklist plugins that violate their Developer Terms of Use:
Install plugins like any NPM package:
# Using bun
bun add lodash
# Using npm
npm install lodash
# Using yarn
yarn add lodash
Then import and use:
import _ from 'lodash';
const shuffledPlayers = _.shuffle(world.players);
const groupedByTeam = _.groupBy(world.players, p => p.getData('team'));
my-hytopia-plugin/
├── package.json
├── src/
│ └── index.ts
├── dist/
│ └── index.js
└── README.md
{
"name": "my-hytopia-plugin",
"version": "1.0.0",
"description": "A useful plugin for HYTOPIA games",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"files": ["dist"],
"keywords": ["hytopia", "plugin", "game"],
"author": "Your Name",
"license": "MIT",
"peerDependencies": {
"hytopia": "^1.0.0"
}
}
// src/index.ts
import { Entity, Player, World } from 'hytopia';
export interface DamageNumberOptions {
duration?: number;
color?: string;
fontSize?: number;
}
export class DamageNumbers {
private world: World;
private options: DamageNumberOptions;
constructor(world: World, options: DamageNumberOptions = {}) {
this.world = world;
this.options = {
duration: 1000,
color: '#ff0000',
fontSize: 24,
...options
};
}
show(player: Player, damage: number, position: { x: number, y: number, z: number }) {
const id = `damage-${Date.now()}`;
player.sendUI({
type: 'text',
id,
text: `-${damage}`,
worldPosition: position,
style: {
color: this.options.color,
fontSize: this.options.fontSize,
fontWeight: 'bold'
}
});
setTimeout(() => {
player.removeUI(id);
}, this.options.duration);
}
showToAll(damage: number, position: { x: number, y: number, z: number }) {
for (const player of this.world.players) {
this.show(player, damage, position);
}
}
}
export default DamageNumbers;
import DamageNumbers from 'my-hytopia-plugin';
const damageNumbers = new DamageNumbers(world, {
duration: 1500,
color: '#ffff00'
});
// When entity takes damage
entity.onDamage = (damage: number) => {
damageNumbers.showToAll(damage, entity.position);
};
// hytopia-utils/src/index.ts
export function randomInRange(min: number, max: number): number {
return Math.random() * (max - min) + min;
}
export function randomElement<T>(array: T[]): T {
return array[Math.floor(Math.random() * array.length)];
}
export function clamp(value: number, min: number, max: number): number {
return Math.min(Math.max(value, min), max);
}
export function lerp(a: number, b: number, t: number): number {
return a + (b - a) * t;
}
// hytopia-health-system/src/index.ts
import { Entity, Player } from 'hytopia';
export class HealthComponent {
private entity: Entity;
private maxHealth: number;
private currentHealth: number;
onDeath?: () => void;
onDamage?: (damage: number, remaining: number) => void;
onHeal?: (amount: number, remaining: number) => void;
constructor(entity: Entity, maxHealth: number = 100) {
this.entity = entity;
this.maxHealth = maxHealth;
this.currentHealth = maxHealth;
}
takeDamage(amount: number): boolean {
this.currentHealth = Math.max(0, this.currentHealth - amount);
this.onDamage?.(amount, this.currentHealth);
if (this.currentHealth <= 0) {
this.onDeath?.();
return true; // Entity died
}
return false;
}
heal(amount: number) {
this.currentHealth = Math.min(this.maxHealth, this.currentHealth + amount);
this.onHeal?.(amount, this.currentHealth);
}
getHealth(): number {
return this.currentHealth;
}
getMaxHealth(): number {
return this.maxHealth;
}
getHealthPercent(): number {
return this.currentHealth / this.maxHealth;
}
}
// hytopia-spawn-system/src/index.ts
import { World, Player, Vector3 } from 'hytopia';
export class SpawnSystem {
private world: World;
private spawnPoints: Vector3[] = [];
private usedSpawns: Set<number> = new Set();
constructor(world: World) {
this.world = world;
}
addSpawnPoint(position: Vector3) {
this.spawnPoints.push(position);
}
getSpawnPoint(): Vector3 {
// Find unused spawn
for (let i = 0; i < this.spawnPoints.length; i++) {
if (!this.usedSpawns.has(i)) {
this.usedSpawns.add(i);
return this.spawnPoints[i];
}
}
// All used, pick random
return this.spawnPoints[Math.floor(Math.random() * this.spawnPoints.length)];
}
releaseSpawnPoint(position: Vector3) {
const index = this.spawnPoints.findIndex(
p => p.x === position.x && p.y === position.y && p.z === position.z
);
if (index !== -1) {
this.usedSpawns.delete(index);
}
}
spawnPlayer(player: Player) {
const spawn = this.getSpawnPoint();
player.setPosition(spawn);
}
}
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.
development
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.
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.