Skip to main content
BlockTypeDefinition manages custom block definitions in behavior packs, including components, states, permutations, and traits.

BlockTypeDefinition

Class Signature

class BlockTypeDefinition implements IManagedComponentSetItem, IDefinition {
  // Properties
  readonly id: string;
  readonly shortId?: string;
  readonly typeId: string;
  readonly shortTypeName: string;
  readonly title: string;
  readonly isLoaded: boolean;
  readonly behaviorPackFile?: IFile;
  readonly data?: IBlockTypeBehaviorPack;
  readonly isCustom: boolean;
  
  // Component management
  getComponent(id: string): IManagedComponent | undefined;
  addComponent(id: string, componentOrData: any): ManagedComponent;
  removeComponent(id: string): void;
  ensureComponent(id: string, defaultData?: any): IManagedComponent;
  getComponents(): IManagedComponent[];
  getAllComponents(): IManagedComponent[];
  getComponentsInBaseAndPermutations(id: string): IManagedComponent[];
  
  // States and properties
  getStates(): any;
  getStateList(): string[];
  getExpandedStateList(): string[];
  getStateValues(stateId: string): (string | number | boolean)[] | undefined;
  addState(name: string, type: BlockStateType): void;
  removeState(name: string): void;
  
  // Permutations
  getPermutations(): IBlockPermutation[];
  getManagedPermutations(): ManagedPermutation[] | undefined;
  getPermutationByCondition(condition: string): IBlockPermutation | undefined;
  addPermutation(condition: string): void;
  addNextPermutation(): void;
  getMissingPermutations(): string[];
  
  // Traits
  getPlacementDirectionTrait(): any;
  getPlacementPositionTrait(): any;
  ensurePlacementDirectionTrait(): void;
  removePlacementDirectionTrait(): void;
  ensurePlacementPositionTrait(): void;
  removePlacementPositionTrait(): void;
  
  // Loading and persistence
  static async ensureOnFile(file: IFile, handler?): Promise<BlockTypeDefinition>;
  async load(): Promise<void>;
  persist(): boolean;
  
  // Utilities
  getFormatVersion(): number[] | undefined;
  async getFormatVersionIsCurrent(): Promise<boolean>;
  getGeometryList(): string[] | undefined;
  getTextureList(): string[] | undefined;
  getLootTablePaths(): string[];
  getCustomComponentIds(): string[];
}

Creating and Loading Blocks

import { BlockTypeDefinition } from 'minecraft-creator-tools';

// Load from file
const blockDef = await BlockTypeDefinition.ensureOnFile(file);

// Access block data
console.log('Block ID:', blockDef.id);
console.log('Block type:', blockDef.typeId);
console.log('Block title:', blockDef.title);
console.log('Is custom:', blockDef.isCustom);

Working with Components

// Add components to base block
blockDef.addComponent('minecraft:destructible_by_mining', {
  seconds_to_destroy: 2.0
});

blockDef.addComponent('minecraft:friction', {
  value: 0.6
});

blockDef.addComponent('minecraft:geometry', {
  identifier: 'minecraft:geometry.full_block'
});

blockDef.addComponent('minecraft:material_instances', {
  '*': {
    texture: 'my_block',
    render_method: 'opaque'
  }
});

// Get a component
const friction = blockDef.getComponent('minecraft:friction');
if (friction) {
  const value = friction.getProperty('value');
  console.log('Friction:', value);
}

// Ensure component exists
const lightEmission = blockDef.ensureComponent('minecraft:light_emission', {
  emission: 10
});

// Get all components
const components = blockDef.getComponents();
for (const comp of components) {
  console.log('Component:', comp.id);
}

Block States

Block states define variable properties:
import { BlockStateType } from 'minecraft-creator-tools';

// Add boolean state
blockDef.addState('custom:is_active', BlockStateType.boolean);

// Add integer state
blockDef.addState('custom:power_level', BlockStateType.number);

// Add string state
blockDef.addState('custom:color', BlockStateType.string);

// Get state list
const states = blockDef.getStateList();
// Returns: ['custom:is_active', 'custom:power_level', 'custom:color']

// Get state values
const powerValues = blockDef.getStateValues('custom:power_level');
// Returns: [0, 1, 2]

// Get expanded state list (includes trait states)
const expandedStates = blockDef.getExpandedStateList();
// Includes states from traits like minecraft:cardinal_direction

// Remove state
blockDef.removeState('custom:color');

Block Permutations

Permutations change block properties based on state values:
// Add permutation
blockDef.addPermutation("q.block_state('custom:is_active') == true");

// Get permutations
const perms = blockDef.getPermutations();
for (const perm of perms) {
  console.log('Condition:', perm.condition);
}

// Get managed permutations (easier to work with)
const managedPerms = blockDef.getManagedPermutations();
if (managedPerms) {
  for (const perm of managedPerms) {
    const glowComp = perm.getComponent('minecraft:light_emission');
    if (glowComp) {
      console.log('This permutation glows');
    }
  }
}

// Get permutation by condition
const activePerm = blockDef.getPermutationByCondition(
  "q.block_state('custom:is_active') == true"
);

// Get missing permutations (combinations not yet defined)
const missing = blockDef.getMissingPermutations();
// Returns: array of condition strings for undefined state combinations

// Add next missing permutation
blockDef.addNextPermutation();

Block Traits

Traits add predefined state sets and behaviors:
// Add placement direction trait
blockDef.ensurePlacementDirectionTrait();
// Adds states: minecraft:cardinal_direction, minecraft:facing_direction

const dirTrait = blockDef.getPlacementDirectionTrait();
if (dirTrait) {
  console.log('Enabled states:', dirTrait.enabled_states);
}

// Remove direction trait
blockDef.removePlacementDirectionTrait();

// Add placement position trait
blockDef.ensurePlacementPositionTrait();
// Adds states: minecraft:block_face, minecraft:vertical_half

const posTrait = blockDef.getPlacementPositionTrait();

// Remove position trait
blockDef.removePlacementPositionTrait();

Geometry and Textures

// Get geometry references
const geometryList = blockDef.getGeometryList();
// Returns: ['minecraft:geometry.full_block', 'geometry.custom_block']

// Get texture references
const textureList = blockDef.getTextureList();
// Returns: ['my_block', 'my_block_active']

// Set texture via catalog
await blockDef.setBlockCatalogTexture(project, 'up', 'my_texture_top');
await blockDef.setBlockCatalogTexture(project, 'down', 'my_texture_bottom');
await blockDef.setBlockCatalogTexture(project, 'north', 'my_texture_side');

Custom Components

// Get custom component IDs
const customComponents = blockDef.getCustomComponentIds();
// Returns: ['custom:on_interact', 'custom:tick']

// Add custom component with generated TypeScript
await blockDef.addCustomComponent(projectItem, 'custom:on_break');
// Creates TypeScript file and registers component

Loot Tables

// Get loot table paths
const lootTables = blockDef.getLootTablePaths();
// Returns: ['loot_tables/blocks/my_block.json']

Block JSON Structure

{
  "format_version": "1.20.0",
  "minecraft:block": {
    "description": {
      "identifier": "custom:my_block",
      "states": {
        "custom:is_active": [false, true],
        "custom:power_level": [0, 1, 2, 3]
      },
      "traits": {
        "minecraft:placement_direction": {
          "enabled_states": ["minecraft:cardinal_direction"]
        }
      }
    },
    "components": {
      "minecraft:destructible_by_mining": {
        "seconds_to_destroy": 2.0
      },
      "minecraft:geometry": {
        "identifier": "minecraft:geometry.full_block"
      },
      "minecraft:material_instances": {
        "*": {
          "texture": "my_block",
          "render_method": "opaque"
        }
      }
    },
    "permutations": [
      {
        "condition": "q.block_state('custom:is_active') == true",
        "components": {
          "minecraft:light_emission": {
            "emission": 10
          },
          "minecraft:material_instances": {
            "*": {
              "texture": "my_block_active",
              "render_method": "opaque"
            }
          }
        }
      },
      {
        "condition": "q.block_state('custom:power_level') >= 2",
        "components": {
          "minecraft:light_emission": {
            "emission": 15
          }
        }
      }
    ]
  }
}

Complete Example

import { 
  BlockTypeDefinition, 
  BlockStateType 
} from 'minecraft-creator-tools';

// Load block definition
const blockDef = await BlockTypeDefinition.ensureOnFile(file);

// Set up block
blockDef.id = 'custom:energy_generator';

// Add states
blockDef.addState('custom:is_active', BlockStateType.boolean);
blockDef.addState('custom:energy_level', BlockStateType.number);

// Add placement direction trait
blockDef.ensurePlacementDirectionTrait();

// Add base components
blockDef.addComponent('minecraft:destructible_by_mining', {
  seconds_to_destroy: 3.0
});

blockDef.addComponent('minecraft:geometry', {
  identifier: 'geometry.energy_generator'
});

blockDef.addComponent('minecraft:material_instances', {
  '*': {
    texture: 'energy_generator_off',
    render_method: 'opaque'
  },
  'up': {
    texture: 'energy_generator_top',
    render_method: 'opaque'
  }
});

// Add permutation for active state
blockDef.addPermutation(
  "q.block_state('custom:is_active') == true"
);

const activePerm = blockDef.getPermutationByCondition(
  "q.block_state('custom:is_active') == true"
);

if (activePerm && activePerm.components) {
  activePerm.components['minecraft:light_emission'] = { emission: 12 };
  activePerm.components['minecraft:material_instances'] = {
    '*': {
      texture: 'energy_generator_on',
      render_method: 'opaque'
    }
  };
}

// Add custom component
await blockDef.addCustomComponent(projectItem, 'custom:generate_energy');

// Save
blockDef.persist();

console.log('Block created successfully!');

Block State Types

enum BlockStateType {
  string = 0,
  boolean = 1,
  number = 2
}

Build docs developers (and LLMs) love