## Custom Blocks Tutorial With ModAPI
This tutorial will show you how to make custom blocks with ModAPI. It will use my AsyncSink library to load the resources for the block.
This tutorial will be making a block with the durability of dirt that explodes when broken.

As always, we'll start with the default boilerplate starter code:
```javascript
(function CustomBlock() {
    ModAPI.meta.title("Custom Block Demo");
    ModAPI.meta.version("v1.0");
    ModAPI.meta.description("Adds a block that blows up when used.");
    ModAPI.meta.credits("By ZXMushroom63");
})();
```
Let's get our blocks texture done ahead of time.
In general, you use data URLs to store assets for mods. These are really inefficient, but this doesn't matter when the texture is 16x16 pixels. Make a texture (keep it nice and small) and convert it to a base64 data uri. I use [https://www.site24x7.com/tools/image-to-datauri.html](https://www.site24x7.com/tools/image-to-datauri.html) to convert my images.
Store this at the beginning of the function using a constant. Also use that constant to set the mod's icon.
```javascript
(function CustomBlock() {
    const texture = "data:image/png;base64, ";
    ModAPI.meta.title("Custom Block Demo");
    ModAPI.meta.version("v1.0");
    ModAPI.meta.description("Adds a block that blows up when used.");
    ModAPI.meta.credits("By ZXMushroom63");

    ModAPI.meta.icon(texture);
})();
```
Let's start work on the part of registering the custom block that occurs on both the server and the client: making a class and registering it as both a `Block` and a `BlockItem`, and adding it to the creative inventory.
```javascript
function BlockRegistrationFunction() {
    //future code here
}
```

In the `BlockRegistrationFunction()` function, add this nested function, which we'll use later to fixup the blockmap after we register new blocks.
```javascript
function BlockRegistrationFunction() {
    function fixupBlockIds() { //function to correct ids for block states after registering a new item
        var blockRegistry = ModAPI.util.wrap(ModAPI.reflect.getClassById("net.minecraft.block.Block").staticVariables.blockRegistry).getCorrective(); //get the blockregistry, corrected for weird property suffixes
        var BLOCK_STATE_IDS = ModAPI.util.wrap(ModAPI.reflect.getClassById("net.minecraft.block.Block").staticVariables.BLOCK_STATE_IDS).getCorrective(); //get the BLOCK_STATE_IDS variable, also corrected for weird teavm suffixes
        blockRegistry.registryObjects.hashTableKToV.forEach(entry => { //Go through the key-to-value map entries of ID to Block
            if (entry) { //if the entry exists
                var block = entry.value; //get the block
                var validStates = block.getBlockState().getValidStates(); //get the blocks valid states
                var stateArray = validStates.array || [validStates.element]; //get the array of valid states. TeaVM will use .array when there are multiple values, and .element when there is only one. This just accounts for edge cases.
                stateArray.forEach(iblockstate => { //For each valid block state
                    var i = blockRegistry.getIDForObject(block.getRef()) << 4 | block.getMetaFromState(iblockstate.getRef()); //Do some bitwise math to get the id for that blockstate
                    BLOCK_STATE_IDS.put(iblockstate.getRef(), i); //Store it in the BLOCK_STATE_IDS map.
                });
            }
        });
    }
}
```
To make our own block, we'll need the following data:
- The `Item` class
- The `Block` class
- The `super()` function for the `Block` class;
- A `CreativeBlock` tab. I'll use `tabBlock`
Since I'll be doing the equivalent of `@Override`ing the `blockBreak` method in java (to make the block explode when broken), i'll need to get the `blockBreak` method. (java equivalent of `super.blockBreak()` in the overrided method.)

```javascript
function BlockRegistrationFunction() {
    function fixupBlockIds() {
        //...
    }

    var ItemClass = ModAPI.reflect.getClassById("net.minecraft.item.Item");
    var BlockClass = ModAPI.reflect.getClassById("net.minecraft.block.Block");
    
    var blockSuper = ModAPI.reflect.getSuper(blockClass, (x) => x.length === 2); //Get the super function for the block

    var creativeBlockTab = ModAPI.reflect.getClassById("net.minecraft.creativetab.CreativeTabs")
        .staticVariables
        .tabBlock; //The block tab in the creative inventory
        
    var breakBlockMethod = blockClass.methods.breakBlock.method; //Get the break block method

    //new code will go here
}
```
Next, we're going to define a regular javascript class using the [constructor function](https://www.w3schools.com/js/js_object_constructors.asp) syntax. Inside the function, we'll call the `blockSuper` function retrieved from `ModAPI.reflect.getSuper()`. We'll also need to manually set the default block state, and put our block into the correct creative tab. We also need to call a ModAPI function called `ModAPI.reflect.prototypeStack`, which emulates extending classes in Java/TeaVM.\
\
For this custom block, we're also going to override the `breakBlock` method for our custom block's class, and make it spawn an explosion when broken.
```javascript
function BlockRegistrationFunction() {
    // ...

    function MyCustomBlock() { //Define constructor function for our custom block
        blockSuper(this, ModAPI.materials.rock.getRef()); //Call block super function with the current MyCustomBlock instance, and the material we want to use.
        this.$defaultBlockState = this.$blockState.$getBaseState(); //Set the default block state
        this.$setCreativeTab(creativeBlockTab); //Set the creative tab to the creativeBlockTab variable from earlier.
    }
    ModAPI.reflect.prototypeStack(BlockClass, MyCustomBlock); //The equivalent of `MyCustomBlock extends Block` in Java.

    //Override the breakBlock function in the custom block's prototype
    //We are using a $ prefix because the method needs to be useable by TeaVM without ModAPI's intervention. The process is fairly standard, just put a $ before the actual method's name.
    //As for the $ in the arguments, I use that to represent a raw TeaVM object.
    MyCustomBlock.prototype.$breakBlock = function ($world, $blockpos, $blockstate) {
        var world = ModAPI.util.wrap($world); //Wrap the $world argument to make it easy to use without stupid $ prefixes
        var blockpos = ModAPI.util.wrap($blockpos); //Wrap the $blockpos argument to make it easy to use without stupid $ prefixes

        world.newExplosion(
            null, //Exploding entity. This would usually be a primed TNT or a creeper, but null is used when those aren't applicable.
            blockpos.getX() + 0.5, //The X position of the explosion.
            blockpos.getY() + 0.5, //The Y position of the explosion.
            blockpos.getZ() + 0.5, //The Z position of the explosion.
            9, //The explosion strength. For reference, 3=creeper, 6=charged creeper, 5=bed in nether/end
            1, //Should the ground be set on fire after the explosion. 1=yes, 0=no
            0 //Should the explosion have smoke particles. 1=yes, 0=no
        ); //Call the newExplosion method on the world.

        return breakBlockMethod(this, $world, $blockpos, $blockstate); //Call the original breakBlock method. ( Equivalent of `super.breakBlock(world, blockpos, blockstate);` )
    }

    // We'll add an internal registration function here
}
```

That's the block class done! Let's start writing the internal registration function, which will contain the code that actually registers our block with IDs and other important things. This is going to be a nested function, so we'll be defining it inside of `BlockRegistrationFunction`.
This function will do the following steps:
- Make an instance of our block.
- Register it as a Block using `ModAPI.keygen.block()` to get the block ID.
- Register it as a BlockItem.
- Use the `fixupBlockIds` function from earlier to clean up the block registry.
- Define it on the `ModAPI.blocks` global, so other mods can interact with the custom block.
- Return the block's instance, for future use.
After the function, we'll check if `ModAPI.materials` has been initialised. If it hasn't, we are on the server and we have to wait for the bootstrap event. Otherwise, we'll go ahead and register our block.

```javascript
function BlockRegistrationFunction() {
    // ...

    function MyCustomBlock() {
        //...
    }
    ModAPI.reflect.prototypeStack(BlockClass, MyCustomBlock);
    MyCustomBlock.prototype.$breakBlock = function ($world, $blockpos, $blockstate) {
        //...
    }

    function internalRegistration() {
        //Make an instance of the custom block
        var custom_block = (new MyCustomBlock())
            .$setHardness(3.0) //Set the block hardness. -1 is unbreakable, 0 is instant, 0.5 is dirt, 1.5 is stone.
            .$setStepSound(BlockClass.staticVariables.soundTypePiston) //Set the step sound. For some reason, the stone sounds are named `soundTypePiston`
            .$setUnlocalizedName(
                ModAPI.util.str("custom_block") //Set the translation ID. ModAPI.util.str() is used to convert it into a Java string
            );
        BlockClass.staticMethods.registerBlock0.method( //Use the registerBlock0 method to register the block.
            ModAPI.keygen.block("custom_block"), //Get a working numeric ID from a text block ID
            ModAPI.util.str("custom_block"), //The text block id
            custom_block //The custom block instance
        );
        ItemClass.staticMethods.registerItemBlock0.method(custom_block); //Register the block as a valid item in the inventory.
        fixupBlockIds(); //Call the fix up block IDs function to clean up the block state registry.
        ModAPI.blocks["custom_block"] = custom_block; //Define it onto the ModAPI.blocks global.
        
        return custom_block; //Return the function
    }

    if (ModAPI.materials) { // Check if ModAPI.materials has been initialised. If it isn't, we are on the server which loads after mods.
        return internalRegistration(); //We are on the client. Register our block and return the block's instance for texturing and model registration.
    } else {
        ModAPI.addEventListener("bootstrap", internalRegistration); //We are on the server. Attatch the internalRegistration function to the bootstrap event
    }
}
```
Let's finish off. We'll append the `BlockRegistrationFunction` to the server, and call it on the client. Then, we'll add a [library listener](../apidoc/events.md#using-library-load-events) to wait until the [AsyncSink](../../examplemods/AsyncSink.js) library loads.
When it's loaded, we'll:
- Add a AsyncSink reload listener that registers our block to `RenderItem`.
- Set the translated name
- Make an in-memory resource pack for the block model and textures
```javascript
(function CustomBlock() {
    const texture = "...";
    //...
    function BlockRegistrationFunction() {
        //...
    }

    ModAPI.dedicatedServer.appendCode(BlockRegistrationFunction); //Run the code on the server
    var custom_block = BlockRegistrationFunction(); //Get the registered block instance

    ModAPI.addEventListener("lib:asyncsink", async () => { //Add an asyncronous listener to AsyncSink loading.
        ModAPI.addEventListener("custom:asyncsink_reloaded", ()=>{
            ModAPI.mc.renderItem.registerBlock(custom_block, ModAPI.util.str("custom_block"));
        });
        AsyncSink.L10N.set("tile.custom_block.name", "My Custom Block"); //Set the name of the block

        //Required boilerplate for block and item models.
        AsyncSink.setFile("resourcepacks/AsyncSinkLib/assets/minecraft/models/block/custom_block.json", JSON.stringify(
            {
                "parent": "block/cube_all",
                "textures": {
                    "all": "blocks/custom_block"
                }
            }
        ));
        AsyncSink.setFile("resourcepacks/AsyncSinkLib/assets/minecraft/models/item/custom_block.json", JSON.stringify(
            {
                "parent": "block/custom_block",
                "display": {
                    "thirdperson": {
                        "rotation": [10, -45, 170],
                        "translation": [0, 1.5, -2.75],
                        "scale": [0.375, 0.375, 0.375]
                    }
                }
            }
        ));
        AsyncSink.setFile("resourcepacks/AsyncSinkLib/assets/minecraft/blockstates/custom_block.json", JSON.stringify(
            {
                "variants": {
                    "normal": [
                        { "model": "custom_block" },
                    ]
                }
            }
        ));

        //Finally, fetch the texture and store it.
        AsyncSink.setFile("resourcepacks/AsyncSinkLib/assets/minecraft/textures/blocks/custom_block.png", await (await fetch(
            texture
        )).arrayBuffer());
    });
})();
```
And with that, we've finished the arduos process of registering a block with ModAPI! Load the complete mod into an EaglerForgeInjector build, along with [AsyncSink](../../examplemods/AsyncSink.js).

[Find the completed code here](../../examplemods/Tutorial_Custom_Block.js)