hytale-custom-blocks
npx skills add https://github.com/mnkyarts/hytale-skills --skill hytale-custom-blocks
Agent 安装分布
Skill 文档
Creating Custom Hytale Blocks
Complete guide for defining custom block types with all available properties and configurations.
When to use this skill
Use this skill when:
- Creating new block types
- Configuring block rendering (textures, models)
- Setting up block physics (support, bouncy, climbable)
- Making blocks farmable with growth stages
- Adding crafting benches
- Defining block interactions
- Setting up block sounds and particles
- Managing block states
Block Asset Structure
Blocks are defined as JSON assets in your plugin’s asset pack:
my-plugin/
âââ assets/
âââ Server/
âââ Content/
âââ BlockTypes/
âââ my_custom_block.blocktype
âââ my_crop.blocktype
âââ my_bench.blocktype
Basic Block Definition
File: my_custom_block.blocktype
{
"DisplayName": {
"en-US": "Custom Block"
},
"Description": {
"en-US": "A custom block with special properties"
},
"DrawType": "Cube",
"Texture": "MyPlugin/Textures/custom_block",
"Material": "Stone",
"Tags": {
"Category": ["Building", "Decorative"]
}
}
Block Properties Reference
Core Properties
| Property | Type | Description |
|---|---|---|
DisplayName |
LocalizedString | Localized display name |
Description |
LocalizedString | Localized description |
Parent |
String | Inherit from another block type |
Tags |
Object | Category tags for filtering |
Rendering Properties
| Property | Type | Default | Description |
|---|---|---|---|
DrawType |
Enum | Cube |
Cube, Model, Empty |
Texture |
String | – | Texture path for cube rendering |
TextureTop |
String | – | Top face texture |
TextureSide |
String | – | Side faces texture |
TextureBottom |
String | – | Bottom face texture |
Model |
String | – | Model asset for DrawType=Model |
Shader |
String | – | Custom shader |
Opacity |
Float | 1.0 | Block opacity (0-1) |
AlphaBlend |
Boolean | false | Enable alpha blending |
RandomRotation |
Boolean | false | Random Y rotation on place |
VariantRotation |
Enum | – | Rotation variant mode |
FlipType |
Enum | – | Random flipping mode |
RotationOffset |
Float | 0 | Rotation offset in degrees |
Physics Properties
| Property | Type | Default | Description |
|---|---|---|---|
Material |
String | – | Physics material type |
IsSolid |
Boolean | true | Collision enabled |
IsReplaceable |
Boolean | false | Can be replaced when placing |
HasGravity |
Boolean | false | Falls like sand |
BlockFaceSupport |
Object | – | Support provided to neighbors |
RequiredBlockFaceSupport |
Object | – | Support needed from neighbors |
Movement Properties
| Property | Type | Default | Description |
|---|---|---|---|
Climbable |
Boolean | false | Can be climbed (ladders) |
Bouncy |
Float | 0 | Bounce factor (0-1) |
Drag |
Float | 0 | Movement drag |
Friction |
Float | 1 | Surface friction |
SpeedMultiplier |
Float | 1 | Walk speed multiplier |
Behavior Properties
| Property | Type | Default | Description |
|---|---|---|---|
IsUsable |
Boolean | false | Right-click interaction |
IsStackable |
Boolean | true | Can be placed adjacent |
ItemId |
String | – | Item dropped when broken |
LightLevel |
Integer | 0 | Light emission (0-15) |
LightColor |
Color | white | Light color |
Flammable |
Boolean | false | Can catch fire |
FlammableSpread |
Integer | 0 | Fire spread rate |
Draw Types
Cube (Default)
Standard voxel block with 6-sided textures:
{
"DrawType": "Cube",
"Texture": "MyPlugin/Textures/stone",
"TextureTop": "MyPlugin/Textures/stone_top"
}
Model
Custom 3D model:
{
"DrawType": "Model",
"Model": "MyPlugin/Models/custom_model",
"BoundingBox": "MyPlugin/BoundingBoxes/custom_box"
}
Empty
Invisible block (air-like, for logic):
{
"DrawType": "Empty",
"IsSolid": false
}
Block Physics System
Block Face Support
Define which faces provide support:
{
"BlockFaceSupport": {
"Top": {
"Type": "Full",
"SupportStrength": 100
},
"Bottom": {
"Type": "Full",
"SupportStrength": 100
},
"North": { "Type": "Full" },
"South": { "Type": "Full" },
"East": { "Type": "Full" },
"West": { "Type": "Full" }
}
}
Support Types: Full, Partial, None, Center
Required Support
Define what support the block needs:
{
"RequiredBlockFaceSupport": {
"Bottom": [
{
"Type": "Full",
"Match": "REQUIRED"
}
]
}
}
Match Types:
REQUIRED– Must have this supportIGNORED– Don’t careDISALLOWED– Must NOT have this support
Gravity Blocks
{
"HasGravity": true,
"GravityDelay": 5,
"PhysicsDrop": {
"GatherType": "Shovel",
"Drops": [
{
"Item": "minecraft:sand",
"Quantity": 1
}
]
}
}
Block Gathering/Breaking
Breaking Configuration
{
"Gathering": {
"Breaking": {
"GatherType": "Pickaxe",
"Power": 2,
"Quality": 1,
"Drops": [
{
"Item": "my_plugin:custom_ore",
"Quantity": {
"Min": 1,
"Max": 3
},
"Chance": 1.0
}
]
},
"Harvest": {
"GatherType": "Hoe",
"Quality": 1,
"Drops": [
{
"Item": "my_plugin:seeds",
"Quantity": 1
}
]
},
"SoftBlock": {
"Enabled": true,
"Drops": [
{
"Item": "my_plugin:dust",
"Quantity": 1
}
]
}
}
}
Gather Types: Hand, Pickaxe, Axe, Shovel, Hoe, Sword
Block States
Define different visual/behavioral states:
{
"States": {
"powered": {
"Values": ["true", "false"],
"Default": "false"
},
"facing": {
"Values": ["north", "south", "east", "west"],
"Default": "north"
}
},
"StateData": {
"powered=true,facing=north": {
"Model": "MyPlugin/Models/powered_north"
},
"powered=true,facing=south": {
"Model": "MyPlugin/Models/powered_south"
},
"powered=false": {
"Model": "MyPlugin/Models/unpowered"
}
}
}
Farming Blocks
Create crops with growth stages:
{
"DisplayName": { "en-US": "Wheat" },
"DrawType": "Model",
"FarmingData": {
"Stages": [
{
"Model": "Hytale/Models/Crops/wheat_stage_0",
"GrowthTime": 300,
"LightRequired": 8
},
{
"Model": "Hytale/Models/Crops/wheat_stage_1",
"GrowthTime": 300,
"LightRequired": 8
},
{
"Model": "Hytale/Models/Crops/wheat_stage_2",
"GrowthTime": 300,
"LightRequired": 8
},
{
"Model": "Hytale/Models/Crops/wheat_stage_3",
"GrowthTime": 0,
"LightRequired": 0,
"IsFinalStage": true
}
],
"Modifiers": {
"Biome": {
"Plains": 1.2,
"Desert": 0.5
},
"Weather": {
"Rain": 1.3
}
},
"SpreadSettings": {
"Enabled": true,
"Chance": 0.1,
"Radius": 2
},
"RequiredSoil": ["Hytale:Farmland", "Hytale:Dirt"]
}
}
Crafting Benches
Create blocks that open crafting interfaces:
Standard Crafting Bench
{
"DisplayName": { "en-US": "Workbench" },
"DrawType": "Model",
"Model": "MyPlugin/Models/workbench",
"IsUsable": true,
"Bench": {
"Type": "Crafting",
"Categories": ["MyPlugin:BasicCrafting", "MyPlugin:AdvancedCrafting"],
"GridSize": {
"Width": 3,
"Height": 3
},
"OutputSlots": 1
}
}
Processing Bench
{
"Bench": {
"Type": "Processing",
"Categories": ["MyPlugin:Smelting"],
"InputSlots": 1,
"FuelSlots": 1,
"OutputSlots": 1,
"ProcessingTime": 200,
"FuelTypes": ["Hytale:Coal", "Hytale:Charcoal"]
}
}
Diagram Crafting Bench
{
"Bench": {
"Type": "DiagramCrafting",
"Categories": ["MyPlugin:BlueprintCrafting"],
"DiagramSlot": true,
"MaterialSlots": 6,
"OutputSlots": 1
}
}
Block Sounds
{
"BlockSound": "MyPlugin/BlockSounds/metal",
"AmbientSound": {
"Sound": "MyPlugin/Sounds/machine_hum",
"Volume": 0.5,
"Radius": 8
}
}
Standard BlockSound sets: Stone, Wood, Metal, Glass, Dirt, Sand, Grass, Gravel, Snow, Wool
Block Particles
{
"BreakParticle": "MyPlugin/Particles/stone_break",
"AmbientParticle": {
"Particle": "MyPlugin/Particles/sparkle",
"SpawnRate": 2,
"Radius": 0.5
},
"FootstepParticle": "MyPlugin/Particles/dust"
}
Block Interactions
Define custom interactions via the Interaction system:
{
"Interactions": {
"Use": "MyPlugin:MyBlockInteraction",
"Attack": "MyPlugin:MyBlockAttackInteraction"
}
}
Interaction Types
| Type | Trigger |
|---|---|
Use |
Right-click |
Attack |
Left-click |
Look |
Look at block |
Touch |
Walk into block |
Complete Example: Custom Ore
{
"DisplayName": {
"en-US": "Mythril Ore"
},
"Description": {
"en-US": "A rare ore found deep underground"
},
"DrawType": "Cube",
"Texture": "MyPlugin/Textures/mythril_ore",
"Material": "Stone",
"LightLevel": 3,
"LightColor": { "R": 0.5, "G": 0.8, "B": 1.0 },
"Tags": {
"Category": ["Ore", "Mining"]
},
"Gathering": {
"Breaking": {
"GatherType": "Pickaxe",
"Power": 4,
"Quality": 3,
"Drops": [
{
"Item": "MyPlugin:RawMythril",
"Quantity": { "Min": 1, "Max": 2 }
}
]
}
},
"BlockFaceSupport": {
"Top": { "Type": "Full" },
"Bottom": { "Type": "Full" },
"North": { "Type": "Full" },
"South": { "Type": "Full" },
"East": { "Type": "Full" },
"West": { "Type": "Full" }
},
"BlockSound": "Hytale/BlockSounds/Stone",
"BreakParticle": "MyPlugin/Particles/mythril_break",
"AmbientParticle": {
"Particle": "MyPlugin/Particles/mythril_sparkle",
"SpawnRate": 0.5
}
}
Complete Example: Door Block
{
"DisplayName": { "en-US": "Wooden Door" },
"DrawType": "Model",
"Material": "Wood",
"IsUsable": true,
"States": {
"open": {
"Values": ["true", "false"],
"Default": "false"
},
"facing": {
"Values": ["north", "south", "east", "west"],
"Default": "north"
},
"half": {
"Values": ["upper", "lower"],
"Default": "lower"
}
},
"StateData": {
"open=false,facing=north,half=lower": {
"Model": "MyPlugin/Models/door_closed_lower_n"
},
"open=true,facing=north,half=lower": {
"Model": "MyPlugin/Models/door_open_lower_n"
}
},
"IsSolid": false,
"Interactions": {
"Use": "MyPlugin:DoorInteraction"
},
"PlacementSettings": {
"RotationMode": "PlayerFacing",
"MultiBlock": {
"Pattern": [
{ "Offset": [0, 1, 0], "State": "half=upper" }
]
}
},
"BlockSound": "Hytale/BlockSounds/Wood",
"RequiredBlockFaceSupport": {
"Bottom": [
{ "Type": "Full", "Match": "REQUIRED" }
]
}
}
Registering Blocks from Plugin Code
For dynamic block registration:
@Override
protected void setup() {
// Listen for block type loading
getEventRegistry().register(
LoadedAssetsEvent.class,
BlockType.class,
this::onBlockTypesLoaded
);
}
private void onBlockTypesLoaded(LoadedAssetsEvent<BlockType> event) {
// Access loaded block types
BlockType myBlock = event.getAssetStore().get("MyPlugin:my_custom_block");
if (myBlock != null) {
getLogger().atInfo().log("Custom block loaded: %s", myBlock.getDisplayName());
}
}
Block Events
Handle block-related events:
@Override
protected void setup() {
// Block break event
getEntityStoreRegistry().registerSystem(new BreakBlockHandler());
// Block place event
getEntityStoreRegistry().registerSystem(new PlaceBlockHandler());
// Block use event
getEntityStoreRegistry().registerSystem(new UseBlockHandler());
}
public class BreakBlockHandler extends EntityEventSystem<EntityStore, BreakBlockEvent> {
public BreakBlockHandler() {
super(BreakBlockEvent.class);
}
@Override
public void handle(int index, ArchetypeChunk<EntityStore> chunk,
Store<EntityStore> store, CommandBuffer<EntityStore> buffer,
BreakBlockEvent event) {
BlockType blockType = event.getBlockType();
Vector3i position = event.getPosition();
// Custom logic here
if (blockType.getId().equals("MyPlugin:protected_block")) {
event.setCancelled(true);
}
}
}
Troubleshooting
Block Not Rendering
- Verify
DrawTypeis correct - Check texture path exists
- Ensure asset pack is registered in manifest
Block Breaking Instantly
- Check
Materialproperty - Verify
GatherTypeandPowersettings - Ensure tool requirements are set
Physics Not Working
- Verify
BlockFaceSupportconfiguration - Check
RequiredBlockFaceSupportmatches - Ensure
IsSolidis true
See references/block-materials.md for material properties.
See references/block-states.md for advanced state management.