Skip to content

Custom Properties Data Generation

Maksym Uimanov edited this page Feb 12, 2026 · 1 revision

Custom Properties Data Generation

The Temporal API provides a comprehensive set of annotations for automatically registering item and block properties during data generation. These annotations eliminate the need for manual JSON property file creation by programmatically registering special behaviors and characteristics for registry objects.

Responsibilities / Purpose

  • Automates property registration: Generates property JSON files without manual asset creation
  • Enables special behaviors: Configures Minecraft-specific item and block properties
  • Integrates with data generation: Works seamlessly with NeoForge's data generation system
  • Supports game mechanics: Provides hooks into vanilla Minecraft gameplay systems

How it works

  1. Annotation processing: The framework scans fields annotated with property annotations
  2. Property extraction: Extracts property parameters from annotation values
  3. Data map generation: Creates appropriate data map JSON files
  4. Data generation: During data generation, property files are automatically generated

Item Properties

@Compostable

Makes items compostable in composters with configurable success chance.

@Compostable(chance = 1)
public static final DeferredItem<?> EXAMPLE_COMPOSTABLE_ITEM = ITEM_FACTORY.create("example_compostable_item");

Parameters:

  • chance (required): Float value between 0.0 and 1.0 representing compost success chance
  • replace (optional, default: false): Whether to replace existing compostable entries

Generated JSON:

{
  "values": {
    "example:example_compostable_item": {
      "chance": 1.0
    }
  }
}

Chance values:

  • 0.0: Never composts
  • 0.3: Low chance (like saplings)
  • 0.5: Medium chance (like most plants)
  • 0.65: High chance (like kelp)
  • 1.0: Always composts (like cake)

@FurnaceFuel

Makes items usable as fuel in furnaces with configurable burn time.

@FurnaceFuel(burnTime = 1000)
public static final DeferredItem<?> EXAMPLE_FUEL = ITEM_FACTORY.create("example_fuel");

Parameters:

  • burnTime (required): Integer representing burn time in ticks (20 ticks = 1 second)
  • replace (optional, default: false): Whether to replace existing fuel entries

Generated JSON:

{
  "values": {
    "example:example_fuel": {
      "burn_time": 1000
    }
  }
}

Burn time examples:

  • 200: Coal/Charcoal (10 seconds)
  • 100: Wood planks (5 seconds)
  • 1000: Custom fuel (50 seconds)
  • 16000: Lava bucket (800 seconds)

Block Properties

@Oxidizable

Makes blocks oxidizable over time, similar to copper blocks.

@Oxidizable(nextBlock = "example:example_oxidized_block")
public static final DeferredBlock<?> EXAMPLE_BLOCK = BLOCK_FACTORY.create("example_block", BlockPropertiesFactory.empty());

Parameters:

  • nextBlock (required): Resource location of the next oxidation stage block
  • replace (optional, default: false): Whether to replace existing oxidizable entries

Generated JSON:

{
  "values": {
    "example:example_block": {
      "next": "example:example_oxidized_block"
    }
  }
}

Oxidation stages: Create a chain of blocks with progressive oxidation:

// Stage 1: Unoxidized
@Oxidizable(nextBlock = "example:example_oxidized_stage_1")
public static final DeferredBlock<?> EXAMPLE_BLOCK = BLOCK_FACTORY.create("example_block");

// Stage 2: Lightly oxidized
@Oxidizable(nextBlock = "example:example_oxidized_stage_2")
public static final DeferredBlock<?> EXAMPLE_OXIDIZED_1 = BLOCK_FACTORY.create("example_oxidized_stage_1");

// Stage 3: Fully oxidized
public static final DeferredBlock<?> EXAMPLE_OXIDIZED_2 = BLOCK_FACTORY.create("example_oxidized_stage_2");

@Waxable

Makes blocks waxable to prevent oxidation, similar to copper blocks.

@Waxable(waxedBlock = "example:example_waxed_block")
public static final DeferredBlock<?> EXAMPLE_BLOCK = BLOCK_FACTORY.create("example_block", BlockPropertiesFactory.empty());

Parameters:

  • waxedBlock (required): Resource location of the waxed variant block
  • replace (optional, default: false): Whether to replace existing waxable entries

Generated JSON:

{
  "values": {
    "example:example_block": {
      "waxed": "example:example_waxed_block"
    }
  }
}

Waxable pairs: Create matching unwaxed and waxed blocks:

// Unwaxed version
@Waxable(waxedBlock = "example:example_waxed_block")
public static final DeferredBlock<?> EXAMPLE_BLOCK = BLOCK_FACTORY.create("example_block");

// Waxed version (no @Waxable annotation needed)
public static final DeferredBlock<?> EXAMPLE_WAXED_BLOCK = BLOCK_FACTORY.create("example_waxed_block");

Entity Properties

@ParrotImitation

Makes entities imitable by parrots with configurable sound.

@ParrotImitation(soundEvent = "example:example_sound")
public static final DeferredHolder<EntityType<?>> EXAMPLE_ENTITY = ENTITY_FACTORY.create("example_entity");

Parameters:

  • soundEvent (required): Resource location of the sound event for parrot imitation
  • replace (optional, default: false): Whether to replace existing parrot imitation entries

Generated JSON:

{
  "values": {
    "example:example_entity": {
      "sound": "example:example_sound"
    }
  }
}

@MonsterRoomMob

Makes entities spawn in monster rooms with configurable weight.

@MonsterRoomMob(weight = 50)
public static final DeferredHolder<EntityType<?>> EXAMPLE_ENTITY = ENTITY_FACTORY.create("example_entity");

Parameters:

  • weight (required): Integer representing spawn weight in monster rooms
  • replace (optional, default: false): Whether to replace existing monster room mob entries

Generated JSON:

{
  "values": {
    "example:example_entity": {
      "weight": 50
    }
  }
}

Weight examples:

  • 8: Zombie (common)
  • 10: Skeleton (common)
  • 20: Spider (uncommon)
  • 50: Custom mob (rare)
  • 100: Very rare mob

Villager Properties

@RaidHeroGift

Makes items available as raid hero gifts with a configurable loot table.

@RaidHeroGift(lootTablePath = "example:raids/hero_gift")
public static final DeferredItem<?> EXAMPLE_GIFT = ITEM_FACTORY.create("example_gift");

Parameters:

  • lootTablePath (required): Resource location of the loot table for hero gifts
  • replace (optional, default: false): Whether to replace existing raid hero gift entries

Generated JSON:

{
  "values": {
    "example:example_gift": {
      "loot_table": "example:raids/hero_gift"
    }
  }
}

Loot table requirements: The loot table must be created separately:

// data/example/loot_tables/raids/hero_gift.json
{
  "type": "minecraft:gift",
  "pools": [
    {
      "rolls": 1,
      "entries": [
        {
          "type": "minecraft:item",
          "name": "example:example_gift"
        }
      ]
    }
  ]
}

Property File Locations

Generated property files are placed in specific data map locations:

Item Properties

  • Compostables: data/neoforge/data_maps/item/compostables.json
  • Furnace fuels: data/neoforge/data_maps/item/furnace_fuels.json
  • Raid hero gifts: data/neoforge/data_maps/villager_profession/raid_hero_gifts.json

Block Properties

  • Oxidizables: data/neoforge/data_maps/block/oxidizables.json
  • Waxables: data/neoforge/data_maps/block/waxables.json

Entity Properties

  • Parrot imitations: data/neoforge/data_maps/entity_type/parrot_imitations.json
  • Monster room mobs: data/neoforge/data_maps/entity_type/monster_room_mobs.json

When to use

  • @Compostable: Plant-based items, food waste, organic materials
  • @FurnaceFuel: Wood items, coal alternatives, custom fuel sources
  • @Oxidizable: Metal blocks, weatherable materials, decorative blocks
  • @Waxable: Blocks that should have wax protection variant
  • @ParrotImitation: Mobs with unique sounds, ambient creatures
  • @MonsterRoomMob: Hostile mobs for dungeon generation
  • @RaidHeroGift: Valuable items, special rewards, unique loot

Extension Points

The annotation system integrates with Temporal API's metadata processing:

  • Automatic file generation: Creates appropriate data map JSON files
  • Property validation: Ensures correct parameter types and ranges
  • Replace functionality: Allows overriding existing vanilla properties
  • Cross-mod compatibility: Works with NeoForge's property system
  • Extensible design: Easy to add new property types

Each annotation maps to a specific property registration strategy that handles the data map generation logic, allowing for easy extension and customization of the property system.

Clone this wiki locally