Pallets & Assets
DigitalHeaven organizes everything into pallets: packages of related assets like avatars, materials, textures, and models.
Pallets
Section titled “Pallets”A pallet is a folder with a pallet.dh manifest and whatever assets it needs.
Pallet IDs
Section titled “Pallet IDs”Pallets use reverse-DNS identifiers:
io.mltn.avatars.mltn-mayutech.azuki.avatars.mayucom.example.my-avatar
This prevents naming conflicts and shows ownership. The ID also determines the folder path: io.mltn.avatars.mltn-mayu lives at Source/io.mltn/avatars/mltn-mayu/.
Manifest: pallet.dh
Section titled “Manifest: pallet.dh”Every pallet needs a manifest:
{ "id": "io.mltn.avatars.mltn-mayu", "name": "mltn Mayu", "version": "0.0.1", "author": "mltn", "dependencies": { "tech.azuki.avatars.mayu": "^3.0.0" }}Assets
Section titled “Assets”An asset is any file inside a pallet: definition files (.dh-avatar, .dh-mat, etc.) or binary resources (.png, .glb, .wav). The exception is sidecar files (e.g. sprite.png.dh-tex-settings), which carry import settings for a neighboring file and are consumed during compilation rather than included as assets. See dh.texture — Sidecar Files for details.
Referencing Assets
Section titled “Referencing Assets”Within the same pallet, just use the relative path:
{ "texture": "textures/body-diffuse.png"}Across pallets, prefix with the pallet ID and a : separator:
{ "baseMesh": "tech.azuki.avatars.mayu:models/body.glb"}This is called a barcode: pallet.id:path/to/asset.
Resolution Rules
Section titled “Resolution Rules”- No
:in the path → local reference within the current pallet - Has
:→ everything before it is the pallet ID, everything after is the path - Paths are relative to the pallet root
Inheritance
Section titled “Inheritance”Assets can inherit from other assets, even across pallets, and override specific properties.
{ "inherits": "io.mltn.avatars.mltn-mayu:avatar.dh-avatar", "patches": [ // Only the patches that differ { "$type": "dh.set-material", "target": "Body", "slot": 0, "path": "materials/custom-skin.dh-mat" } ]}Inheritance works at every level: avatars, objects, materials, rigs. You only define what’s different.
The compiler resolves all inheritance chains at build time. The compiled output has everything flattened, no unresolved references.
Platform Overrides
Section titled “Platform Overrides”Platform-specific data lives in a platforms/ subdirectory alongside your universal definitions:
Directorymy-avatar/
- avatar.dh-avatar Universal
Directorymaterials/
- skin.dh-mat Universal material
Directoryplatforms/
Directoryvrchat/
- avatar-descriptor.jsonc
Directoryunity/
Directorymaterials/
- skin.dh-mat Unity-specific shader overrides
Directoryresonite/
- avatar-metadata.jsonc
When building for a platform, the compiler loads the universal definition first, then applies any matching overrides from platforms/{platform}/.
Organizing Your Pallet
Section titled “Organizing Your Pallet”Shared assets go in type-based folders at the pallet root. Self-contained features (accessories, outfits) get their own subdirectory with everything co-located:
Directorymy-pallet/
- pallet.dh
- avatar.dh-avatar
Directorytextures/ Shared textures
- body-diffuse.png
- body-normal.png
- body-orm.dh-tex
Directorymodels/ Shared models
- body.glb
Directoryrigs/ Shared rigs
- humanoid.dh-rig
Directorymaterials/ Shared materials
- skin.dh-mat
- eyes.dh-mat
Directoryaccessories/ Self-contained features
Directoryglasses/
- glasses.dh-obj
- model.glb
- material.dh-mat
- lens.png
Directorypiercing/
- piercing.dh-obj
- model.glb
- material.dh-mat
The rule: shared/base assets in type folders at root; self-contained features get their own directory with everything they need inside.
Version Control
Section titled “Version Control”Designed for Git:
- Commit:
Source/(your source files),Scripts/(your custom scripts) - Ignore:
Pallets/(compiled output),.dh/(cache)
The workspace init generates .gitignore and .gitattributes automatically. The .gitattributes file sets up Git LFS for binary assets (.glb, .fbx, .png, .jpg, etc.), so make sure you have Git LFS installed if you’re using those.