A tool for working with Hytale's blockymodel files and exporting them as GLB (glTF Binary) or blockymodel (Hytale's Blockbench Format). Ships with two CLIs:
blockymerge- builds a player model by merging accessories (clothing, hair, face features, etc.) onto the base player model, based off a character config.item-to-glb- converts a standalone item blockymodel (weapons, armor, tools, etc.) to GLB, using its matching_Texture.png.
If you find this useful, consider using code jack in the Hytale Store
Try it online or use the API: https://hytl.skin/
Note: This project is provided as-is. No support or assistance will be provided. Please refer to the documentation and troubleshooting section for help.
- Merge multiple blockymodel files into a single model
- Apply gradient tinting to textures based on color specifications
- Export to GLB format (compatible with Blockbench and 3D viewers)
- Export to blockymodel format
- Automatic texture atlas generation
- Convert individual item blockymodels (weapons, armor, tools, etc.) to GLB via
item-to-glb
Pre-built binaries are available for Windows, Linux, and macOS (Intel & Apple Silicon):
- Latest Release - Download the latest version
- All Releases - Browse all releases
Each release includes:
blockymerge/blockymerge.exe- Main merger toolextract-assets/extract-assets.exe- Assets extraction utilityitem-to-glb/item-to-glb.exe- Single-item blockymodel → GLB converter
Quick Start:
- Download the archive for your platform from the latest release
- Extract the archive
- Follow the Setup instructions below to configure assets
- Go 1.21 or later (download)
- Access to the game assets and registry data
You can either download pre-built binaries from the releases page or build from source.
Option A: Use pre-built binaries (recommended)
- Download the archive for your platform from the latest release
- Extract the archive and make the binaries executable (on Linux/macOS:
chmod +x blockymerge extract-assets item-to-glb)
Option B: Build from source
git clone https://github.com/hytale-tools/blockymodel-merger.git
cd blockymodel-merger
go build -o blockymerge ./cmd/blockymerge
go build -o extract-assets ./cmd/extract-assets
go build -o item-to-glb ./cmd/item-to-glbThe assets/ directory should contain:
Characters/— character model files (.blockymodel) and texturesCosmetics/— cosmetic/accessory model filesTintGradients/— gradient textures for tinting
How to obtain assets:
-
Download
assets.zipfrom the Hytale Server Manual.Important: You need the server
assets.zip(not the client version), as it includes thedata/directory with registry JSON files. -
Use the extraction utility:
# If you downloaded pre-built binaries, extract-assets should already be available # If you built from source, you may need to build it first: # go build -o extract-assets ./cmd/extract-assets # Extract required folders from assets.zip ./extract-assets /path/to/assets.zip
This will extract and map:
Common/Characters→assets/Characters/Common/Cosmetics→assets/Cosmetics/Common/TintGradients→assets/TintGradients/Cosmetics/CharacterCreator→data/(registry JSON files)
The directory structure should match:
assets/
├── Characters/
│ ├── Player.blockymodel
│ ├── Player_Textures/
│ ├── Haircuts/
│ ├── Body_Attachments/
│ └── ...
├── Cosmetics/
└── TintGradients/
The extraction utility will also extract the data/ directory from the server assets.zip. This contains JSON registry files that map accessory IDs to their model files and textures:
Haircuts.json— hair style definitionsFaces.json— face texture definitionsEyes.json— eye style definitionsPants.json,Overtops.json, etc. — clothing definitionsGradientSets.json— gradient tint definitions- And other registry files...
Note: The client assets.zip does not include the data/ directory — you must use the server assets.zip from the Hytale Server Manual.
# Check that required directories exist
ls assets/Characters/Player.blockymodel
ls data/Haircuts.json
ls data/GradientSets.json# If you downloaded pre-built binaries, they should be in your current directory
# If you built from source, they should be in the project root
./blockymerge -h # Should show help text
./extract-assets -h # Should show help text (if available)
./item-to-glb -h # Should show flag list# Create a simple test character
echo '{"bodyCharacteristic": "Default.02", "haircut": "Scavenger_Hair.PitchBlack"}' > test-char.json
# Run the merger
./blockymerge -char test-char.json -out test
# Check output
ls output/test.*item-to-glb operates on standalone item blockymodels that are not extracted by
extract-assets. If you want to use it, extract the Common/Items/ folder from the
server assets.zip manually into assets/Items/.
Each item folder contains a .blockymodel alongside its matching _Texture.png (for example Bronze.blockymodel + Bronze_Texture.png). Some variants reuse another model's texture (e.g. Adamantite_Triple.blockymodel uses Adamantite_Texture.png) — pass -texture explicitly in those cases.
Expected structure after extraction:
assets/Items/
├── Armors/ (Bronze/, Iron/, Cobalt/, Mithril/, ... each with Chest/Head/Hands/Legs)
├── Weapons/ (Dagger/, Bow/, Sword/, Axe/, Spear/, ...)
├── Tools/ (Pickaxe/, Hammer/, Hatchet/, Fishing_Rod/, ...)
├── Consumables/
├── Trinkets/
├── Deployables/
├── Vehicles/
├── Projectiles/
├── Instruments/
├── Ingredients/
├── Torch/
└── ...
Quick verification:
./item-to-glb assets/Items/Weapons/Dagger/Bronze.blockymodel
ls output/Bronze.glbgo build -o blockymerge ./cmd/blockymerge
go build -o extract-assets ./cmd/extract-assets
go build -o item-to-glb ./cmd/item-to-glb./blockymerge -char <character.json> [options]| Flag | Default | Description |
|---|---|---|
-char |
(required) | Path to character JSON configuration file |
-out |
merged |
Output file name (without extension) |
-format |
both |
Output format: glb, blockymodel, or both |
-no-tint |
false |
Skip texture tinting (output raw greyscale) |
-debug |
false |
Print debug output showing node tree |
# Export as GLB only
./blockymerge -char my-character.json -out player -format glb
# Export both formats with debug output
./blockymerge -char my-character.json -out player -format both -debug
# Export without tinting
./blockymerge -char my-character.json -out player -no-tint./item-to-glb assets/Items/Weapons/Dagger/Bronze.blockymodel
./item-to-glb -model <path.blockymodel> -texture <path.png> -out <path.glb>| Flag | Default | Description |
|---|---|---|
-model |
(required or pass as positional arg) | Path to the item .blockymodel |
-texture |
<model-basename>_Texture.png (sibling file) |
Path to the texture PNG |
-out |
output/<basename>.glb |
Output GLB path |
-verbose |
false |
Print info messages |
Override -texture for variants that reuse another model's texture, e.g.
Adamantite_Triple.blockymodel uses Adamantite_Texture.png:
./item-to-glb \
-model assets/Items/Weapons/Bow/Adamantite_Triple.blockymodel \
-texture assets/Items/Weapons/Bow/Adamantite_Texture.pngCharacter JSON files define the appearance of a character. Each field is optional except for accessories you want to include.
Format: "AccessoryId.Color.Variant" where Color and Variant are optional.
{
"bodyCharacteristic": "Default.02",
"underwear": "Boxer.Turquoise",
"face": "Face_MakeUp",
"ears": "Elf_Ears",
"mouth": "Mouth_Makeup",
"haircut": "Scavenger_Hair.PitchBlack",
"facialHair": null,
"eyebrows": "Plucked.PitchBlack",
"eyes": "Large_Eyes.Pink",
"pants": null,
"overpants": "LongSocks_Striped.Black",
"undertop": "Mercenary_Top.Black",
"overtop": "OnePiece_ApronDress.Black",
"shoes": null,
"headAccessory": "Ribbon.White",
"faceAccessory": null,
"earAccessory": "AcornEarrings.Acorn.Both",
"skinFeature": null,
"gloves": "LongGloves_Savanna.Black",
"cape": "Cape_Wasteland_Marauder.BlueDark.NoNeck"
}Accessing cached character skin data:
If you have the game installed, you can access character skins you've created from the game's installation directory:
- Open the Hytale launcher
- Click the settings cog (⚙️)
- Click "Open Directory"
- Navigate to the
UserDatafolder - Open the
CachedPlayerSkinsfolder
You can copy character JSON files from this folder and use them directly with the tool:
./blockymerge -char /path/to/CachedPlayerSkins/your-character.json -out output-name| Slot | Description |
|---|---|
bodyCharacteristic |
Body type and skin tone (e.g., Default.02) |
underwear |
Base underwear layer |
face |
Face texture/makeup |
ears |
Ear shape (e.g., Elf_Ears, Default) |
mouth |
Mouth style |
haircut |
Hair style and color |
facialHair |
Beard/mustache |
eyebrows |
Eyebrow style and color |
eyes |
Eye style and color |
pants |
Pants layer |
overpants |
Over-pants layer (socks, skirts, etc.) |
undertop |
Under-top layer |
overtop |
Over-top layer (dresses, jackets, etc.) |
shoes |
Footwear |
headAccessory |
Head accessories (hats, ribbons, etc.) |
faceAccessory |
Face accessories (glasses, masks, etc.) |
earAccessory |
Ear accessories (earrings) |
skinFeature |
Skin features (freckles, etc.) |
gloves |
Hand/arm accessories |
cape |
Back accessories (capes, wings, etc.) |
Files are saved to the output/ directory:
<name>.glb- GLB model file<name>.blockymodel- BlockyModel JSON file<name>_atlas.png- Texture atlas
blockymodel-merger/
├── cmd/
│ ├── blockymerge/
│ │ └── main.go # CLI entry point
│ ├── extract-assets/
│ │ └── main.go # Assets extraction utility
│ └── item-to-glb/
│ └── main.go # Single-item blockymodel → GLB converter
├── pkg/
│ ├── blockymodel/ # BlockyModel parsing
│ ├── character/ # Character data loading
│ ├── export/ # GLB export
│ ├── merger/ # Model merging logic
│ ├── registry/ # Accessory registry
│ └── texture/ # Texture processing & atlas
├── assets/ # BlockyModel & texture assets
├── data/ # Accessory registry JSON files
└── output/ # Generated output files
- Go 1.21+
- Asset files in
assets/directory (see Setup section above) - Registry data in
data/directory (see Setup section above)
Make sure the data/ directory exists and contains the required JSON registry files. The tool looks for files like Haircuts.json, Faces.json, Eyes.json, etc.
Ensure assets/Characters/Player.blockymodel exists. This is the base player model that all characters are built from.
These are usually non-fatal - the tool will continue but the accessory may appear without textures. Check that:
- Texture paths in the registry JSON files are correct
- The texture files exist in the
assets/directory - Path separators match your OS (use forward slashes
/in JSON files)
- github.com/qmuntal/gltf - glTF/GLB encoding
GNU GPL v3 - see LICENSE file for details.