hytopia-assets

Helps manage assets in HYTOPIA SDK games. Use when users need to load models, textures, audio, or UI elements. Covers asset loading, HytopiaUI, models, textures, sounds, and asset optimization.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "hytopia-assets" with this command: npx skills add abstrucked/hytopia-skills/abstrucked-hytopia-skills-hytopia-assets

HYTOPIA Assets & UI

This skill helps you manage assets and UI in HYTOPIA SDK games.

Documentation: https://dev.hytopia.com/sdk-guides/assets

When to Use This Skill

Use this skill when the user:

  • Wants to load 3D models (GLTF/GLB)
  • Needs to add textures or materials
  • Asks about playing sounds or music
  • Wants to create UI elements (HUD, menus)
  • Needs to optimize asset loading
  • Asks about default SDK assets

Core Asset Concepts

Loading Models

import { Model, Entity } from 'hytopia';

class Character extends Entity {
  constructor() {
    super();
    
    this.model = new Model({
      modelUri: 'models/character.gltf',
      scale: 1.0,
      rotation: { x: 0, y: 0, z: 0 }
    });
  }
}

// Load with animation
const animatedModel = new Model({
  modelUri: 'models/player.gltf',
  animationUri: 'animations/player-idle.gltf',
  loopAnimation: true
});

Using Default Assets

import { Model, BlockType } from 'hytopia';

// Default models included with SDK
const defaultModels = {
  player: 'hytopia:models/player.gltf',
  cube: 'hytopia:models/cube.gltf',
  sphere: 'hytopia:models/sphere.gltf'
};

// Default block textures
const defaultBlocks = {
  grass: BlockType.GRASS,
  dirt: BlockType.DIRT,
  stone: BlockType.STONE,
  wood: BlockType.WOOD,
  leaves: BlockType.LEAVES
};

Custom Textures

import { BlockType, Material } from 'hytopia';

// Create block with custom texture
const customBlock = new BlockType({
  id: 'my-mod:custom-block',
  name: 'Custom Block',
  textureUri: 'textures/custom-block.png',
  material: new Material({
    roughness: 0.8,
    metalness: 0.0
  })
});

Audio

Playing Sounds

import { Audio, Entity } from 'hytopia';

class SoundEntity extends Entity {
  playSound() {
    // One-shot sound
    this.playAudio({
      uri: 'sounds/explosion.mp3',
      volume: 1.0,
      pitch: 1.0,
      spatial: true,  // 3D positional audio
      range: 20       // Audible within 20 units
    });
  }
  
  playMusic() {
    // Looping background music
    this.playAudio({
      uri: 'music/background.mp3',
      volume: 0.5,
      loop: true,
      spatial: false  // Global audio
    });
  }
}

// Play at location
world.playAudioAtPosition(
  { x: 0, y: 10, z: 0 },
  { uri: 'sounds/ambient.mp3', volume: 0.3, range: 30 }
);

Audio Management

// Stop specific sound
entity.stopAudio('sounds/explosion.mp3');

// Stop all sounds on entity
entity.stopAllAudio();

// Fade out
entity.fadeAudio('music/background.mp3', 0, 2000);  // Fade to 0 over 2 seconds

HytopiaUI

Creating UI Elements

import { Player, UI } from 'hytopia';

// Send UI to player
player.sendUI({
  type: 'panel',
  id: 'hud',
  position: { x: 0.5, y: 0.9 },  // Normalized screen position
  anchor: 'center-bottom',
  children: [
    {
      type: 'text',
      id: 'score',
      text: 'Score: 0',
      style: { fontSize: 24, color: '#ffffff' }
    },
    {
      type: 'bar',
      id: 'health',
      value: 100,
      max: 100,
      style: { 
        width: 200, 
        height: 20, 
        backgroundColor: '#333333',
        fillColor: '#ff0000'
      }
    }
  ]
});

Updating UI

// Update specific element
player.updateUI('score', {
  text: `Score: ${player.getData('score')}`
});

player.updateUI('health', {
  value: player.getData('health'),
  max: 100
});

// Remove UI
player.removeUI('hud');

Interactive UI

player.sendUI({
  type: 'panel',
  id: 'menu',
  children: [
    {
      type: 'button',
      id: 'start-btn',
      text: 'Start Game',
      onClick: 'start-game'
    },
    {
      type: 'button',
      id: 'settings-btn',
      text: 'Settings',
      onClick: 'open-settings'
    }
  ]
});

// Handle clicks
player.onUIEvent = (event) => {
  if (event.elementId === 'start-btn') {
    startGame(player);
  } else if (event.elementId === 'settings-btn') {
    openSettings(player);
  }
};

Asset Organization

Recommended Structure

assets/
├── models/
│   ├── characters/
│   ├── items/
│   └── environment/
├── textures/
│   ├── blocks/
│   ├── ui/
│   └── effects/
├── audio/
│   ├── sfx/
│   ├── music/
│   └── ambient/
└── ui/
    ├── hud.json
    ├── menu.json
    └── inventory.json

Asset Loading Strategy

import { AssetManager } from 'hytopia';

// Preload critical assets
await AssetManager.preload([
  'models/player.gltf',
  'textures/crosshair.png',
  'sounds/jump.mp3'
]);

// Load on demand
function loadLevel(levelId: string) {
  return AssetManager.loadBatch([
    `levels/${levelId}/terrain.gltf`,
    `levels/${levelId}/skybox.png`
  ]);
}

Best Practices

  1. Optimize models - Use GLB format, limit polygon count
  2. Compress textures - Use appropriate formats (PNG for UI, compressed for 3D)
  3. Audio formats - MP3 for music, WAV for short SFX
  4. Lazy loading - Load assets only when needed
  5. Reuse materials - Don't create duplicate materials
  6. Atlas textures - Combine UI sprites into atlases

Common Patterns

Crosshair UI

player.sendUI({
  type: 'image',
  id: 'crosshair',
  position: { x: 0.5, y: 0.5 },
  anchor: 'center-center',
  source: 'textures/crosshair.png',
  style: { width: 32, height: 32 }
});

Damage Indicator

function showDamageIndicator(player: Player, damage: number) {
  player.sendUI({
    type: 'text',
    id: 'damage-text',
    position: { x: 0.5, y: 0.4 },
    anchor: 'center-center',
    text: `-${damage}`,
    style: { 
      fontSize: 36, 
      color: '#ff0000',
      fontWeight: 'bold'
    }
  });
  
  // Remove after delay
  setTimeout(() => player.removeUI('damage-text'), 1000);
}

Loading Screen

function showLoadingScreen(player: Player) {
  player.sendUI({
    type: 'panel',
    id: 'loading',
    fullScreen: true,
    style: { backgroundColor: '#000000' },
    children: [
      {
        type: 'text',
        text: 'Loading...',
        style: { fontSize: 48, color: '#ffffff' }
      },
      {
        type: 'progress',
        id: 'loading-bar',
        value: 0,
        max: 100,
        style: { width: 400, height: 20 }
      }
    ]
  });
}

function updateLoadingProgress(player: Player, percent: number) {
  player.updateUI('loading-bar', { value: percent });
  
  if (percent >= 100) {
    player.removeUI('loading');
  }
}

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

hytopia-multiplayer

No summary provided by upstream source.

Repository SourceNeeds Review
General

hytopia-world

No summary provided by upstream source.

Repository SourceNeeds Review
General

hytopia-entities

No summary provided by upstream source.

Repository SourceNeeds Review
General

hytopia-mobile

No summary provided by upstream source.

Repository SourceNeeds Review