โ›๏ธ My First Minecraft Mod ยท Episode 2 of 6 ยท See All Episodes
๐Ÿชจ Episode 2 ยท Custom Block ยท Needs Episode 1 Complete

Crystal Block!
Your First Custom Block

Add a glowing Crystal Block to Minecraft it lights up in the dark, can be mined with a pickaxe and drops your Crystal Gem when broken. Time to build with your own block!

๐Ÿง‘ Ages 10+ โฑ๏ธ ~1.5 Hours โ›๏ธ Fabric 1.21 โœ“ Free
Your Progress 0 / 10 steps
Prefer no install? Change Minecraft from a plain folder instead. Plan a crafting recipe in our browser Datapack Studio and export a real datapack zip, with no Java and no mod loader. Open the Minecraft Mod Studio →
๐Ÿ“ฆ
Workshop reference pack: download an offline copy of every step in this workshop: โฌ‡ minecraft-custom-block-mod-reference.zip. Every code block also has a Copy button.
๐Ÿ’ป
How to run: Open your project in IntelliJ, then press the Run button to launch Minecraft with your mod!
1
๐Ÿงฑ
How Blocks Work in Fabric
Understand the difference between items and blocks before we write any code
Active
๐ŸŽฏ
Goal for this step

Understand what extra files a block needs compared to an item, so nothing surprises you later.

โ„น๏ธ
Blocks vs Items: In Minecraft, a Block is what sits in the world. A BlockItem is the item version you hold and place. Every block needs both registered. Blocks also need a blockstate JSON (describing which model to show) and a loot table (what drops when mined).

Files we'll create this episode

  • 1ModBlocks.java registers the Crystal Block (and its BlockItem)
  • 2models/block/crystal_block.json the 3D cube model
  • 3models/item/crystal_block.json the item version model
  • 4blockstates/crystal_block.json links state โ†’ model
  • 5textures/block/crystal_block.png the 16โœจ16 texture
  • 6loot_table/blocks/crystal_block.json what drops when mined
  • 7recipe/crystal_block.json crafting recipe
๐Ÿ’ก
That's more files than an item! But each one is small and follows the same pattern. Once you've done it once, you can add any block in minutes.
I understand blocks need both a Block and a BlockItem registered
I know blocks need a blockstate, model, texture, and loot table
๐Ÿง 
Knowledge Check
+15 XP
What two things must you register for a block that sits in the world?
AOnly a Block
BA Block and a BlockItem
COnly a texture
2
๐Ÿ“
Create ModBlocks.java
Register the Crystal Block and its BlockItem in Java
Locked
๐ŸŽฏ
Goal for this step

Create ModBlocks.java with the Crystal Block registered as a glowing, mineable block.

  • 1Open your CrystalMod project in IntelliJ. Right-click the crystalmod package โ†’ New โ†’ Java Class. Name it ModBlocks.
  • 2Replace the file contents with:
ModBlocks.java
package com.example.crystalmod; import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents; import net.minecraft.block.AbstractBlock; import net.minecraft.block.Block; import net.minecraft.block.MapColor; import net.minecraft.item.BlockItem; import net.minecraft.item.Item; import net.minecraft.item.ItemGroups; import net.minecraft.registry.Registries; import net.minecraft.registry.Registry; import net.minecraft.sound.BlockSoundGroup; import net.minecraft.util.Identifier; public class ModBlocks { public static final Block CRYSTAL_BLOCK = registerBlock( "crystal_block", new Block(AbstractBlock.Settings.create() .mapColor(MapColor.CYAN) .strength(3.0f, 4.0f) // hardness, blast resistance .luminance(state -> 10) // glow level (0-15) .requiresTool() // needs pickaxe to drop .sounds(BlockSoundGroup.AMETHYST_BLOCK)) ); private static Block registerBlock(String name, Block block) { registerBlockItem(name, block); return Registry.register(Registries.BLOCK, Identifier.of(CrystalMod.MOD_ID, name), block); } private static Item registerBlockItem(String name, Block block) { return Registry.register(Registries.ITEM, Identifier.of(CrystalMod.MOD_ID, name), new BlockItem(block, new Item.Settings())); } public static void registerModBlocks() { ItemGroupEvents.modifyEntriesEvent(ItemGroups.BUILDING_BLOCKS) .register(entries -> entries.add(CRYSTAL_BLOCK)); } }
โ„น๏ธ
luminance(state -> 10) makes the block glow with brightness 10 (like a glowstone is 15, torch is 14). requiresTool() means it only drops when mined with the correct tool (pickaxe).
ModBlocks.java created with CRYSTAL_BLOCK field
No red import errors (use Alt+Enter to fix if needed)
๐Ÿง 
Knowledge Check
+15 XP
In ModBlocks.java, what does luminance(state -> 10) do?
AMakes the block glow at brightness 10
BMakes the block 10 blocks tall
CSets the hardness to 10
3
๐ŸŽฏ
Register ModBlocks in CrystalMod.java
Call your new registerModBlocks() method so the block loads on startup
Locked
๐ŸŽฏ
Goal for this step

Add one line to CrystalMod.java so your block gets registered when the game starts.

  • 1Open CrystalMod.java.
  • 2In the onInitialize() method, add a call to ModBlocks.registerModBlocks(); put it before the ModItems line:
CrystalMod.java onInitialize()
@Override public void onInitialize() { ModBlocks.registerModBlocks(); // โ† add this line ModItems.registerModItems(); LOGGER.info("Crystal Mod loaded! ๐Ÿ’Ž"); }
๐Ÿ’ก
Blocks must be registered before items because the BlockItem references the Block object. Registering blocks first avoids any ordering issues.
ModBlocks.registerModBlocks() added to onInitialize()
๐ŸŽ“ Teacher Note Step 3Students commonly forget that blocks need a BlockItem too, a block without a BlockItem exists in the world but can't be picked up or placed from inventory. Also watch for the registration order: blocks must be registered before items because BlockItem holds a reference to the Block object.
๐Ÿšจ Stuck? Block won't register or game crashes
  • Cannot find symbol: ModBlocks check ModBlocks.java is in the com.example.crystalmod package and the package declaration at the top of the file matches.
  • Block not in creative inventory confirm registerModBlocks() adds the block via ItemGroupEvents with entries.add(CRYSTAL_BLOCK).
  • Game crashes on startup make sure ModBlocks.registerModBlocks() is called before ModItems.registerModItems() in CrystalMod.java.
  • Block is invisible when placed the blockstate or model JSON is missing or named wrong. Check Step 6.
๐Ÿง 
Knowledge Check
+15 XP
Why must registerModBlocks() be called from CrystalMod.java?
ASo the block is registered when the game starts
BTo draw the block texture
CTo create the crafting recipe
4
๐ŸŽจ
Create the Block Texture
Draw a 16โœจ16 crystal texture for your block's six faces
Locked
๐ŸŽฏ
Goal for this step

Create a PNG texture for the Crystal Block and save it in the right folder.

  • 1In your project's resources/assets/crystalmod folder, create a new subfolder: textures/block.
  • 2Use Pixel Studio or any image editor to draw a 16โœจ16 crystal texture. Try cyan/teal shades with lighter spots for a crystal-like appearance.
  • 3Save it as crystal_block.png in the textures/block/ folder.
๐ŸŽจ
Look at Minecraft's amethyst block or glass textures for inspiration simple semi-transparent looking patterns with lighter edges work really well for crystals!
crystal_block.png created at assets/crystalmod/textures/block/
๐Ÿง 
Knowledge Check
+15 XP
What size is a standard Minecraft block texture?
A8x8 pixels
B16x16 pixels
C32x32 pixels
5
๐Ÿ“ฆ
Create Block & Item Model JSON Files
Tell Minecraft which texture to use and what shape the block is
Locked
๐ŸŽฏ
Goal for this step

Create two JSON model files one for the block in the world, one for it as a held/placed item.

Block model (the 3D cube)

  • 1In assets/crystalmod, create the folder models/block.
  • 2Create the file crystal_block.json inside it:
assets/crystalmod/models/block/crystal_block.json
{ "parent": "block/cube_all", "textures": { "all": "crystalmod:block/crystal_block" } }

Item model (what you hold)

  • 3In assets/crystalmod/models/item (which you created in Episode 1), create crystal_block.json:
assets/crystalmod/models/item/crystal_block.json
{ "parent": "crystalmod:block/crystal_block" }
โ„น๏ธ
The item model just points to the block model, Minecraft knows how to render a block model as an item automatically. Nice and simple!
models/block/crystal_block.json created
models/item/crystal_block.json created
๐Ÿง 
Knowledge Check
+15 XP
What is the job of the block model JSON?
AIt tells Minecraft which texture to use and the shape
BIt sets the block hardness
CIt stores the crafting recipe
6
๐Ÿ”€
Create the Blockstate JSON
Link the block's state to its model required for every block
Locked
๐ŸŽฏ
Goal for this step

Create the blockstates JSON this tells Minecraft which model to use for the block's default state.

  • 1In assets/crystalmod, create the folder blockstates.
  • 2Inside it create the file crystal_block.json:
assets/crystalmod/blockstates/crystal_block.json
{ "variants": { "": { "model": "crystalmod:block/crystal_block" } } }
โ„น๏ธ
Some blocks have many variants (like stairs or slabs that can face different directions). Our Crystal Block only has one variant the empty string "" means "default state".
  • 3Add the block's name to your en_us.json language file:
    "block.crystalmod.crystal_block": "Crystal Block"
blockstates/crystal_block.json created
en_us.json updated with block name
๐ŸŽ“ Teacher Note Step 6A pink/magenta checkerboard block means a missing texture or wrong path. Ask students to open the Gradle run console and search for "crystalmod" any missing resource errors are listed there. Common path mistake: "textures/blocks/" (with an s) instead of the correct "textures/block/".
๐Ÿšจ Stuck? Block shows as pink/black checkerboard
  • Pink checkerboard = missing texture. The PNG must be at assets/crystalmod/textures/block/crystal_block.png folder is block, not blocks.
  • Blockstate not found the JSON must be at assets/crystalmod/blockstates/crystal_block.json folder is blockstates (with an s, unlike texture).
  • JSON syntax error a missing comma or bracket breaks the whole file. Paste your JSON at jsonlint.com to check.
  • Block model not found block model goes in models/block/ and the item model goes in models/item/. Two separate files in two separate folders!
๐Ÿง 
Knowledge Check
+15 XP
What does the blockstate JSON do?
ALinks the block state to its model
BStores the block loot
CSets the block sound
7
๐Ÿ’ฐ
Add a Loot Table Drop Crystal Gem When Mined
Tell Minecraft what items to drop when the Crystal Block is broken
Locked
๐ŸŽฏ
Goal for this step

Create a loot table so that mining the Crystal Block drops 1 Crystal Gem.

  • 1In src/main/resources, navigate to the data folder. Create the path: data/crystalmod/loot_table/blocks/
  • 2Create the file crystal_block.json inside it:
data/crystalmod/loot_table/blocks/crystal_block.json
{ "type": "minecraft:block", "pools": [ { "rolls": 1, "bonus_rolls": 0, "entries": [ { "type": "minecraft:item", "name": "crystalmod:crystal_gem" } ], "conditions": [ { "condition": "minecraft:survives_explosion" } ] } ] }
โ„น๏ธ
rolls: 1 means drop 1 item. survives_explosion means creepers won't drop the gem (realistic behaviour blow up a block and you lose the loot!). Remove that condition if you want it to always drop.
loot_table/blocks/crystal_block.json created
๐Ÿง 
Knowledge Check
+15 XP
What does the loot table control?
AWhat items drop when the block is mined
BWhat the block looks like
CHow bright the block glows
8
๐Ÿ”จ
Add a Crafting Recipe
Let players craft the Crystal Block using 9 Crystal Gems in a 3โœจ3 grid
Locked
๐ŸŽฏ
Goal for this step

Create a crafting recipe so players can turn 9 Crystal Gems into 1 Crystal Block (like iron ingots โ†’ iron block).

  • 1In data/crystalmod, create a recipe folder.
  • 2Create the file crystal_block.json inside it:
data/crystalmod/recipe/crystal_block.json
{ "type": "minecraft:crafting_shaped", "pattern": [ "GGG", "GGG", "GGG" ], "key": { "G": { "item": "crystalmod:crystal_gem" } }, "result": { "id": "crystalmod:crystal_block", "count": 1 } }
๐Ÿ’ก
Want a different recipe? Change the pattern! "G G" with spaces means the middle column is empty. You could make a 2โœจ2 recipe using just 4 gems by using only the top-left 2โœจ2 area of the pattern.
data/crystalmod/recipe/crystal_block.json created
๐Ÿง 
Knowledge Check
+15 XP
How many Crystal Gems make the Crystal Block recipe in this step?
A4
B9
C16
9
๐Ÿƒ
Run Minecraft & Test Your Block!
Launch the game and place your glowing Crystal Block in the world
Locked
๐ŸŽฏ
Goal for this step

Launch Minecraft, find your Crystal Block in creative mode, place it and see it glow!

  • 1In IntelliJ, select Minecraft Client from the run dropdown and click โœจ Play.
  • 2Create or open a creative world.
  • 3Press E โ†’ search for Crystal Block. It should appear in the Building Blocks tab.
  • 4Place it in the world. It should look like your texture and glow in the dark!
  • 5Switch to Survival mode (/gamemode survival) and try to mine it you'll need a pickaxe, and it should drop a Crystal Gem when broken.
  • 6Test the crafting recipe: open a crafting table and fill all 9 slots with Crystal Gems you should get 1 Crystal Block.
โš ๏ธ
If the block appears purple/black (missing texture) check the texture file is exactly named crystal_block.png and is in the right folder. Check the blockstates JSON matches that name too.
Crystal Block appears in creative inventory
Block glows in the dark when placed
Mining with a pickaxe drops a Crystal Gem
Crafting recipe works in a crafting table
๐Ÿง 
Knowledge Check
+15 XP
How do you test your new block in-game?
ALaunch Minecraft and place the block in the world
BOpen the texture file
CRefresh the browser
10
๐ŸŒŸ
Challenge: Tweak Your Block's Properties
Experiment with hardness, glow level, sounds and map colour
Locked
๐ŸŽฏ
Goal for this step

Customise your Crystal Block's properties to make it exactly the way you want it.

๐ŸŽจ
Try changing these values in your block settings and see what happens:
  • 1Glow: Change luminance(state -> 10) to 15 for maximum brightness, or 4 for a subtle glow.
  • 2Hardness: Change strength(3.0f, 4.0f) to strength(50.0f, 1200.0f) to make it as hard as obsidian!
  • 3Sound: Try BlockSoundGroup.GLASS, BlockSoundGroup.METAL or BlockSoundGroup.STONE each gives a different sound when walked on and mined.
  • 4Map colour: Try MapColor.BLUE, MapColor.PURPLE or MapColor.EMERALD_GREEN this changes the colour the block shows on a map.
  • 5Reload Minecraft after each change to see it work.
I tried at least one property change and saw it work
๐Ÿง 
Knowledge Check
+15 XP
Which setting controls how bright the Crystal Block glows?
Astrength()
Bluminance()
CmapColor()
๐ŸŽ‰๐Ÿชจ๐Ÿ’Ž๐ŸŽŠโœจ
You Built a Custom Block!

You now know how to add blocks, textures, blockstates, loot tables and crafting recipes to Minecraft. Episode 3 adds a magic food item with potion effects!

๐Ÿช Episode 3: Magic Cookie โ†’ ⭐ View My Progress & Certificates

This workshop was free and took many hours to build. If it helped you learn something new, consider supporting the project.

☕ Support on Ko-fi

๐Ÿงฉ Minecraft Modding Order

Drag the Minecraft Forge modding steps into the correct order:

Add the texture PNG to assets
Create the model JSON file
Add it to a Creative Tab
Register it in the mod event bus
Create your item or block class
Set up the Forge MDK project