Skip to content

nodecraft/hytale-skin-renderer

Repository files navigation

HytaleSkinRenderer

A high-performance Rust library and CLI tool for rendering Hytale character skins and animations. Parses .blockymodel and .blockyanim files to produce PNG stills, animated GIFs, and WebM videos.

Features

  • Multiple Output Formats: PNG stills, animated GIFs, and WebM videos
  • PlayerDB Integration: Fetch player skins directly using username or UUID
  • Cosmetic Support: Full cosmetic registry with haircuts, clothing, accessories, and more
  • Multiple Camera Presets: Headshot, full body, isometric, bust, and directional views
  • Tint Gradients: Apply skin tones and color customization via tint gradient maps
  • Multi-threaded Rendering: Parallel frame rendering with configurable worker threads
  • Supersampling: Anti-aliasing through higher resolution rendering and downsampling
  • Batch Processing: Render multiple animations from a directory
  • GPU Acceleration: Optional GPU rendering backend (via gpu feature)

Installation

Prerequisites

  • Rust 1.70+ (2021 edition)
  • FFmpeg (required for GIF and WebM encoding)

Build from Source

# Clone the repository
git clone https://github.com/nodecraft/hytale-skin-renderer.git
cd hytale-skin-renderer

# Build release binary
cargo build --release

# Optional: Build with GPU support
cargo build --release --features gpu

The binary will be available at target/release/hytale-renderer.

Usage

Basic Commands

# Show all available options
cargo run -- --help

# Render a still image (default pipeline)
cargo run -- --pipeline body --output player.png

# Render an animated GIF
cargo run -- --pipeline gif --output animation.gif

# Render a WebM video
cargo run -- --pipeline webm --output animation.webm

Render Pipelines

The CLI supports three rendering pipelines via the --pipeline flag:

Pipeline Description Default Output
body Static PNG renders with multiple camera views all_views_render-{view}.png
gif Animated GIF from blockyanim animation.gif
webm Animated WebM video from blockyanim idle_animation.webm

Camera Presets

Use --camera to select a camera angle:

  • legacy - Original camera position
  • full-body-front - Front-facing full body view
  • front-right - Angled front-right view
  • back-right - Angled back-right view
  • front-left - Angled front-left view
  • back-left - Angled back-left view
  • headshot - Close-up head shot
  • isometric-head - Isometric head view
  • player-bust - Upper body/bust shot

Fetching Skins from PlayerDB

Render a player's skin directly by username or UUID:

cargo run -- --skin "PlayerName" --output player_render.png

Animation Options

# Set output FPS (default: 30)
cargo run -- --pipeline gif --fps 60 --output smooth.gif

# Set animation duration in seconds
cargo run -- --pipeline webm --length-seconds 5.0 --output five_seconds.webm

# Set number of animation cycles
cargo run -- --pipeline gif --cycles 3 --output looped.gif

# Batch render all animations in a directory
cargo run -- --pipeline gif \
  --animations-dir "assets/Common/Characters/Animations/Default" \
  --recursive \
  --output "output/{anim_name}.gif"

Quality Options

# Set output size (width and height)
cargo run -- --size 1024 --output hd_render.png

# Enable supersampling (2x renders at 2048x2048, downsamples to 1024x1024)
cargo run -- --size 1024 --supersample 2 --output smooth_render.png

# Configure worker threads
cargo run -- --pipeline gif --workers 8 --encode-workers 4 --output animation.gif

Full Example

cargo run -- \
  --pipeline webm \
  --model "assets/Common/Characters/Player.blockymodel" \
  --animation "assets/Common/Characters/Animations/Default/Idle.blockyanim" \
  --texture "assets/Common/Characters/Player_Textures/Player_Greyscale.png" \
  --skin "PlayerUsername" \
  --camera full-body-front \
  --size 512 \
  --supersample 2 \
  --fps 30 \
  --cycles 2 \
  --workers 4 \
  --output "player_idle.webm"

CLI Reference

Flag Description Default
--pipeline Render pipeline (body, gif, webm) body
--model, -m Path to .blockymodel file assets/Common/Characters/Player.blockymodel
--animation, -a Path to .blockyanim file assets/.../Idle.blockyanim
--animations-dir Directory of animations (batch mode) -
--recursive Recursively search animations directory false
--texture, -t Path to base texture PNG assets/.../Player_Greyscale.png
--output, -o Output file path (supports {anim_name}, {view} placeholders) varies by pipeline
--skin PlayerDB username or UUID -
--skin-config Path to skin configuration JSON skin.json
--tint-gradients Path to tint gradients folder assets/Common/TintGradients
--fallbacks Path to haircut fallbacks JSON assets/.../HaircutFallbacks.json
--camera Camera preset varies by pipeline
--size, -s Output image size (width & height) 1024 (body), 512 (gif/webm)
--supersample Supersampling factor 1
--fps Target frames per second 30
--length-seconds Output duration in seconds -
--cycles, -c Number of animation cycles 1
--workers Number of render worker threads (0 = auto) 0
--encode-workers Number of encoder threads (0 = ffmpeg default) 0
--backend Rendering backend (auto, cpu, gpu) auto

Library Usage

Add to your Cargo.toml:

[dependencies]
hytale-skin-renderer = { path = "path/to/hytale-skin-renderer" }

Basic Example

use hytale_skin_renderer::render_blockymodel_to_png;
use std::path::Path;

fn main() -> hytale_skin_renderer::Result<()> {
    let model_path = Path::new("assets/Common/Characters/Player.blockymodel");
    let texture_path = Path::new("assets/Common/Characters/Player_Textures/Player_Greyscale.png");
    
    let image = render_blockymodel_to_png(
        model_path,
        Some(texture_path),
        1024,  // width
        1024,  // height
    )?;
    
    image.save("output.png")?;
    Ok(())
}

Project Structure

src/
├── main.rs              # CLI entry point
├── lib.rs               # Library exports
├── animation.rs         # Animation parsing and playback
├── asset_provider.rs    # Asset loading abstraction
├── camera.rs            # Camera presets and projection
├── cosmetics.rs         # Cosmetic registry and loading
├── cosmetic_attachment.rs
├── error.rs             # Error types
├── geometry.rs          # 3D geometry generation
├── math.rs              # Math utilities
├── models.rs            # Blockymodel/blockyanim parsing
├── output.rs            # PNG/GIF/WebM export
├── playerdb.rs          # PlayerDB API integration
├── render_pipeline.rs   # High-level render orchestration
├── scene.rs             # Scene graph management
├── skin.rs              # Skin configuration
├── texture.rs           # Texture loading and sampling
└── renderer/
    ├── mod.rs           # Renderer core
    ├── clip.rs          # Clipping utilities
    ├── config.rs        # Render configuration
    ├── debug.rs         # Debug utilities
    ├── face.rs          # Face rendering
    ├── gpu.rs           # GPU backend (optional)
    ├── math.rs          # Renderer math
    ├── postprocess.rs   # Post-processing effects
    └── rasterizer.rs    # CPU rasterization

tests/
├── integration.rs       # Full pipeline tests
├── geometry_tests.rs    # Geometry unit tests
├── lighting_tests.rs    # Lighting unit tests
└── renderer_tests.rs    # Renderer unit tests

assets/                  # Game assets (models, textures, animations)

Testing

# Run all tests
cargo test

# Run specific test suite
cargo test --test integration
cargo test --test geometry_tests
cargo test --test lighting_tests
cargo test --test renderer_tests

Dependencies

  • serde / serde_json - JSON parsing for configs and model data
  • image - Image loading and PNG/GIF encoding
  • glam - Fast linear algebra (vectors, matrices)
  • clap - CLI argument parsing
  • reqwest - HTTP client for PlayerDB API
  • zip - Asset archive handling
  • wgpu (optional) - GPU rendering backend
  • FFmpeg (external) - Video encoding for GIF/WebM

License

See LICENSE for details.

About

Rust based Hytale skin rendering tool. Supports animations!

Resources

License

Contributing

Stars

Watchers

Forks

Sponsor this project

 

Packages

 
 
 

Contributors

Languages