hytopia-world

📁 abstrucked/hytopia-skills 📅 11 days ago
4
总安装量
2
周安装量
#54313
全站排名
安装命令
npx skills add https://github.com/abstrucked/hytopia-skills --skill hytopia-world

Agent 安装分布

opencode 2
claude-code 2
mcpjam 1
openhands 1
zencoder 1
crush 1

Skill 文档

HYTOPIA World Building

This skill helps you build and manage worlds in HYTOPIA SDK games.

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

When to Use This Skill

Use this skill when the user:

  • Wants to create terrain or place blocks programmatically
  • Needs to work with chunk loading/unloading
  • Asks about world generation or procedural terrain
  • Wants to integrate with build.hytopia.com world editor
  • Needs to save/load world data
  • Asks about block types, textures, or custom blocks

Core World Concepts

Basic Block Placement

import { World, BlockType } from 'hytopia';

// Place a single block
world.setBlock({ x: 0, y: 0, z: 0 }, BlockType.GRASS);

// Remove a block
world.setBlock({ x: 0, y: 0, z: 0 }, BlockType.AIR);

// Get block at position
const block = world.getBlock({ x: 0, y: 0, z: 0 });

Creating Custom Blocks

import { BlockType, Block } from 'hytopia';

const customBlock = new BlockType({
  id: 'my-mod:custom-block',
  name: 'Custom Block',
  textureUri: 'textures/custom.png',
  isSolid: true,
  opacity: 1.0
});

// Register the block
world.blockRegistry.register(customBlock);

World Generation

import { World, BlockType } from 'hytopia';

class TerrainGenerator {
  generateChunk(chunkX: number, chunkZ: number, world: World) {
    for (let x = 0; x < 16; x++) {
      for (let z = 0; z < 16; z++) {
        const worldX = chunkX * 16 + x;
        const worldZ = chunkZ * 16 + z;
        
        // Simple heightmap
        const height = Math.floor(Math.sin(worldX * 0.1) * 5 + 10);
        
        for (let y = 0; y < height; y++) {
          const block = y === height - 1 ? BlockType.GRASS : BlockType.DIRT;
          world.setBlock({ x: worldX, y, z: worldZ }, block);
        }
      }
    }
  }
}

Loading World from Editor

import { World } from 'hytopia';
import worldData from './assets/world.json';

// Load world created in build.hytopia.com
world.loadFromJSON(worldData);

Chunk Management

Chunk Loading

// Enable chunk loading around players
world.chunkLoadingEnabled = true;
world.chunkLoadRadius = 8; // chunks

// Custom chunk loader
world.onChunkLoad = (chunkX, chunkZ) => {
  // Generate or load chunk data
  terrainGenerator.generateChunk(chunkX, chunkZ, world);
};

world.onChunkUnload = (chunkX, chunkZ) => {
  // Save chunk data if needed
};

Manual Chunk Control

// Load specific chunk
world.loadChunk(0, 0);

// Unload chunk
world.unloadChunk(0, 0);

// Check if chunk is loaded
const isLoaded = world.isChunkLoaded(0, 0);

Build.hytopia.com Integration

Exporting from Editor

  1. Build your world at https://build.hytopia.com
  2. Export as JSON
  3. Place in assets/world.json

Loading Exported World

import worldData from './assets/world.json';

world.loadFromJSON(worldData, {
  // Options
  clearExisting: true,  // Remove existing blocks
  offset: { x: 0, y: 0, z: 0 }  // Apply offset
});

Best Practices

  1. Use chunk loading for large worlds – don’t load everything at once
  2. Batch block operations – set multiple blocks at once when possible
  3. Save modified chunks – persist player changes
  4. Use block palettes – define reusable block combinations
  5. Optimize collision – mark non-solid blocks appropriately

Common Patterns

Placing Structure

function placeStructure(world: World, position: Vector3, structure: Block[][]) {
  for (let y = 0; y < structure.length; y++) {
    for (let x = 0; x < structure[y].length; x++) {
      for (let z = 0; z < structure[y][x].length; z++) {
        const block = structure[y][x][z];
        if (block !== BlockType.AIR) {
          world.setBlock({
            x: position.x + x,
            y: position.y + y,
            z: position.z + z
          }, block);
        }
      }
    }
  }
}

Raycast Block Placement

// Place block where player is looking
const raycast = world.raycast(player.position, player.lookDirection, 5);
if (raycast.hit) {
  const placePos = raycast.position.add(raycast.normal);
  world.setBlock(placePos, BlockType.STONE);
}