(usage)=
# Usage

## File structure

The filter generates files for Minecraft RP and BP based on the files stored in its data folder. The data folder of the filter should be located in the `<regolith-filters-data>/shapescape_custom_blocks_generator` folder.

The files in the data folder of the filter must organized in a specific way.

### Global scope.json
In the root of the folder be the `scope.json` file, unless a different path is specified in the config of the filter. You can read more about the filter configuration in the {ref}`Installation<installation>` section of the documentation.

The `scope.json` file defines the variables used for evaluation of the template files, shared between all block groups.

## Block Groups
Blocks groups are folders that define the process of generating blocks. Single block group can define the generation process of multiple blocks. In simple projects you can have a single block group, that defines everything. In more complex projects it's recommended to split the blocks into multiple groups based on their properties.

Every block group folder must contain following files:
- `_scope.json`
- `_block_data.json` OR `_block_data.py` (only one of them)

Every subfolder of the filter data folder that contains these files is considered to be a block group.

### scope.json
The `_scope.json` file which is merged with the `_scope.json` file to define the variables specific to the block group.

### _blocks_data.json
The `_blocks_data.json` is the main file of the block group. It's described in detail in later sections of the documentaiton. The content of the `_block_data.json` file is evaluated using [json_template](https://github.com/Nusiq/regolith-filters/tree/master/json_template) and the data from the scope.

### _blocks_data.py
The `_blocks_data.py` is an alternative to the `_blocks_data.json` file. The file is executed using the Python interpreter. The content of the file must evaluate to a valid data structure for the `_block_data.json` file. Pyhton syntax is more flexible than JSON files (even if they're evaluated with json_template) but might be harder to read.

## Generated files

Currently, the filter is capable of generating/modifying the following files for the Behavior Pack and Resource Pack:
- `RP/animations/cb2.animation.json` - a file containing the animations used by attachables to get them into the correct position when held by the player.
- `RP/attachables/cb2/<block variant name>_spawn_egg.attachable.json` - the attachable definitions.
- `RP/entity/cb2/<block variant name>.entity.json`- the client-side of the block entities used to define the spawn egg texture of the block entities.
- `RP/models/entity/cb2_cube.geo` - the geometry of the cubic attachables.
- `RP/textures/attachable/cb2/cube_<index>.png` - the cubic attachable textures.
- `RP/item_texture.json` - the item texture file is modified by the filter. It's used to define the textures for the spawn eggs.
- `RP/blocks.json` - the blocks file is modified by the filter. It's used to define the sounds of the blocks.
- `BP/animation_controllers/cb2.bp_ac.json` - a Behavior Pack animation controller for all block entities.
- `BP/blocks/cb2/<block name>.block.json` - block files.
- `BP/entities/<block variant name>.behavior.json` - the behaviors of the block entities.
- `BP/loot_tables/cb2/<block variant name>.loot.json` - loot tables of the blocks used to define that the blocks should drop themselves when broken.
- `BP/recipes/<block variant name>.recipe.json` - recipes for the blocks.
- `RP/textures/item/spawn_egg/*.png` - the spawn egg textures of the block entities.

The filter currently doesn't generate and geometries or model textures, these have to be added to the resource pack using other tools.

## _blocks_data.json file structure

The `_blocks_data.json` file is used to define a group of blocks that share the same namespace. This section explains the structure of the file.

### The root of the file

*_blocks_data.json*
```json
{
    "namespace": "shapescape",
    "blocks": {
        // ...
    }
}
```

The main body of the file currently only contains two properties:
- `namespace` - the namespace reused by files generated by the filter as namespaces (for example, the namespace in the block identifiers).
- `blocks` - a dictionary that contains the definitions of the blocks. The keys of the dictionary are the names of the blocks.

## The `"blocks"->[block]` object

The block definitions are stored in the `blocks` dictionary of the `_blocks_data.json` file.

*_blocks_data.json->"blocks"->[block]*
```json
{
    "self_drop": true,
    "translation": "{frame} Chair With {cushion} Cushion",
    "rotation_type": "rotate_front_both",
    "sound": "wood",
    "block_entity_properties": {
        "spawn_egg_texture": "example_texture",
        "place_sound": "use.stone"
    },
    "block_template": "block_template.block.json",
    "block_template_override": {
        // ...
    },
    "recipe_template": "recipe_template.recipe.json",
    "recipe_template_override": {
        // ...
    },
    "shared_variant": {
        // ...
    },
    "variants": {
        // ...
    },
    "block_entity_properties": {
        // ...
    }
}
```

Properties:
- `self_drop: bool` - a boolean that defines whether the block should drop itself when broken. If omitted, the block will not drop itself.
- `translation: str` - a string that defines a pattern for creating the name of the block or the spawn egg that spawns the entity that places down the block. It can include references to the translations defined in the block variants using the curly brackets `{}` (see `variants` property below).
- `rotation_type: str` - a string that defines the rotation type of the block. If omitted, the block will not have any rotation properties. Possible values:
    - `"align_front_xyz"` - the block has 3 rotation states based on its **alignment** to the grid on the **X**, **Y** or **Z** axis. The **front face** of the model aligns to or away from the player.
    - `"align_top_xyz"` - the block has 3 rotation states based on its **alignment** to the grid on the **X**, **Y** or **Z** axis. The **top face** of the model aligns to or away from the player. This is similar to `minecraft:log`.
    - `"align_front_xz"` - the block has 2 rotation states based on its **alignment** to the grid on the **X** or **Z** axis. The **front face** of the model aligns to or away from the player (but it can't face up or down).
    - `"align_top_xz"` - the block has 2 rotation states based on its **alignment** to the grid on the **X** or **Z** axis.  The **top face** of the model aligns to or away from the player (but it can't face up or down).
    - `"rotate_front_vertical"` - the block can be facing **north**, **south**, **east** or **west**. The **front face** of the model is always facing the player that places down the block but can't rotate up or down. This is similar to `minecraft:chest`.
    - `"rotate_top_vertical"` - the block can be facing **north**, **south**, **east** or **west**. The **top face** of the model is always facing the player that places down the block but can't rotate up or down.
    - `"rotate_front_both"` - the block can be facing **north**, **south**, **east**, **west**, **up** or **down**. The **front face** of the model is always facing the player that places down the block and can rotate up or down.
    - `"rotate_top_both"` - the block can be facing **north**, **south**, **east**, **west**, **up** or **down**. The **top face** of the model is always facing the player that places down the block and can rotate up or down.
- `sound: str` - a short name of the sounds used by the block. This is a reference to a sound defined in the `RP/sounds.json` file.
- `texture: str` - an optional property that defines the texture of the block. It's only useful for the blocks that don't use the custom `minecraft:geometry` and `minecraft:material_instances` components. The value is copied directly into the `textures` property of the `blocks.json`.
- `block_entity_properties: dict` - properties of the block entity. This is only used if the block has rotation or multiple variants. Simple blocks without variants or rotation don't need a block entity to be placed in the world, so the entity is not generated for them.
    - `spawn_egg_texture: str` - a reference to the texture defined in the `RP/textures/item_texture.json` file. If the block has multiple variants, the actual texture name referenced by the spawn egg is `{spawn_egg__name}_{variant_suffix}` where the `{variant_suffix}` is the suffix of the variant. The process of generating the suffixes is described in different section of the documentation.
    - `place_sound: str` - the sound played when the block is placed. If omitted, it uses the sound based on the `sound` property using pattern `use.{sound}` where `{sound}` is the value of the `sound` property. This sound is played using the `playsound` command when the block entity is spawned.
    - `attachable: dict` - **Defning attachables is explained in detail in a separate section (below).**
    - `entity_override: dict` - Overrides the `minecraft:entity` property of the block entity behavior. This is useful when you work with filters that require defining some of the custom properties directly in the behavior fils (for example the content guide generator uses custom properties to define the description of the entity).
- `block_template: str` - specifies the path to a behavior pack block.json file that serves as a template for the block. The path is relative to the same directory as the _blocks_dat_file that it is referenced in. The block template allows for the usage of scope, which you can learn about in the scope section.
- `block_template_override: dict` - allows you to overwrite data in the block template. You can modify the `description: {}` and `components: {}` sections using the same syntax as in the behavior pack's block.json file. This feature is particularly useful when you have a more general block template but need to make changes or additions to the components and descriptions for a specific block that deviates from the template.
- `recipe_template: str` - specifies the path to a behavior pack recipe.json file that serves as a template for the recipe of the block. The path is relative to the same directory as the _blocks_dat_file that it is referenced in.
- `recipe_template_override: dict` - allows you to overwrite data in the recipe template. For convenience the filter expects to get code inside the `minecraft:recipe_shaped`, `minecraft:recipe_shapeless`, `minecraft:recipe_furnace`, `minecraft:recipe_brewing_mix`, so you can for example directly write `pattern: {}`. This feature is particularly useful when you have a more general block recipe template but need to make changes or additions to the pattern and ingredients for a specific block that deviates from the template.
- `shared_variant: dict` - used to define commonly used components of the shared variants of the block. The shared variants are a [product](https://en.wikipedia.org/wiki/Rule_of_product) of the variant groups of the block. For example, if you have a variant group which redefines the color of the block as red, green or blue and another group which redefines the material of the block as metal or wooden, the filter would generate 6 shared variants - "red metal", "red wooden", "green metal", "green wooden", "blue metal" and "blue wooden". In the generated block file, the shared variants are defined as block permutations. The components defined in the `shared_variant` object are added to each of the permutations and can be overwritten by specific variants that also have a property called `shared_variant` (explained in the next section).
- `variants: dict` - defines variant groups. Variant grups are used to define different variants of the block regarding some specific aspect of the block. Every variant in the group is an object that various properties of the block related to the aspect. The variants are explained in detail in the next section.

## The `"blocks"->[block]->"blocke_entity_properties" -> "attachable"` object
The "attachable" object of the "block_entity_properties" allows you to configure how the attachable of the spawn egg of the block entity is rendered. This property is optional and omitting it will result in no attachable being created.

Attachables have two settings - assets and offset.
- `assets: dict` - sets the assets of the attachable.
- `offset: dict` - sets the offset of the attachable in the player's hand.

*_blocks_data.json->"blocks"->[block]->"block_entity_properties" -> "attachable"*
```json
{
    "assets": {
        // ...
    },
    "offset": {
        // ...
    }
}
```
The `assets` object has two properties - texture and geometry.

*_blocks_data.json->"blocks"->[block]->"block_entity_properties" -> "attachable"->"assets"*
```json
{
    "texture": {
        "nort": "TERRAIN_TEXTURE:example_texture",
        "south": "TERRAIN_TEXTURE:example_texture",
        "east": "TERRAIN_TEXTURE:example_texture",
        "west": "RP:textures/example_texture",
        "up": "RP:textures/example_texture",
        "down": "RP:textures/example_texture"
    },
    // OR
    // "texture": "example_texture"

    "geometry": "geometry.example_geometry"
}
```

The `texture` property defines a reference to an existing texture in the resource pack. It can be either an object that defines a separate texture for each side of the block - "north", "south", "east", "west", "up" and "down", or a string that defines a single texture.

If you define the `texture` as an object with multiple sides, the filter will assume that your model is a cubic model and you won't need to provide the geometry (the filter will generate the geometry automatically). The filter will also generate a single texture image by combining the provided images to use with the generated model.


```{note}
Generating textures is necessary because attachables don't support using multiple textures at once (unlike blocks). This is a workaround to create an attachable that looks like a block.
```

If you define the `texture` as a single string, then you need to specify the geometry of the attachable. In most cases this will be the same geometry and texture as the block, but in some cases it may be necessary to create a special texture manually.

There are two ways to write the texture path string:
- Using the `TERRAIN_TEXTURE:` prefix means that the filter should look for the texture in the resource pack using the `terrain_texture.json` file.
- Using the `RP:` prefix means that the provided texture is a direct reference to a file in the resource pack **without the `.png` extension** (which is added automatically).

The `geometry` property defines the geometry of the attachable. It's just a reference to the geometry identifier.

The `offset` property defines the offsets applied to the geometry of the attachable in the player's hand. There are 6 values you can set:
- `position_1st_person: list[float | str]` - the default value: `[-4, 29, -4]`
- `rotation_1st_person: list[float | str]` - the default value: `[-128, -131, 3]`
- `scale_1st_person: list[float | str]` - the default value: `[0.35, 0.35, 0.35]`
- `position_3rd_person: list[float | str]` - the default value: `[0, 18, -4]`
- `rotation_3rd_person: list[float | str]` - the default value: `[31, -47, -20]`
- `scale_3rd_person: list[float | str]` - the default value: `[0.35, 0.35, 0.35]`

All properties are 3 element lists that are copied directly into the animation files. Using string is allowed because the animation can use molang.

## The `"blocks"-> [block] -> "variants" -> [variant]` object

The variant groups are lists of objects where every object defines a different configuration of some aspect of the block. A block can define multiple variant groups each of which can have multiple variants. The actual variants of the block generated by the filter are a [product](https://en.wikipedia.org/wiki/Rule_of_product) of combining the variant groups.

```json
{
    "variant_name": {
        "translation": "Oak",
        "id_suffix": "o",
        "components": {
            // ...
        },
        "recipe": {
            // ...
        },
        "shared_variant": {
            // ...
        }
    },
    // ...
}
```

- `translation: str` - a string that defines the translation variable for generating the names of the spawn eggs of the entities used for placing down the block variants.
- `id_suffix: str` - a string that defines the suffix of the block's id. The actual id of the block is `{block_name}_{variant_suffix}` where `{variant_suffix}` is the suffix of the variant. The process of generating the suffixes is described in different section of the documentation. It does not allow the `_` character.
- `components: dict` - This works the same as `block_template_override` and is used to put specific components into the permutation related to the variant.
- `recipe: dict` - This works the same as `recipe_template_override` and is used to override specific recipe parameters.
- `shared_variants: dict`- This parameter is used to overwrite specific parameters of the shared variants.


For example, a variant of "material" called "oak" is supposed to overwrite the material instance defined as "material" in the minecraft:material_instances object defined in the shared material. The necessary code is then just for the definition of that material, ignoring other parameters, as this will be merged for the combinations. This means it would be:
    ``` json
    "minecraft:material_instances": {
        "material": {
            "texture": "oak"
        }
    }
    ```
You can learn more about variants in the block files generation section.

## Generating the variant suffixes

The actual variants of the blocks generated by the filter are based on the [product](https://en.wikipedia.org/wiki/Rule_of_product) of the variant groups defined in block definition in `_blocks_data.json` file. The names of the files generated, certain identifiers and references to textures use the suffixes based on the properties defined in the variants. The suffixes are generated by the filter based on the following rules:
- If the variant defines the `id_suffix` property it is used in the full suffix of the variant.
- If the `id_suffix` is not defined than the index of the variant in the variant group is used instead (the indexing starts from 0).
- The full suffix is based on 1 item for each variant group by joining the suffixes of the variants in the group with underscore charcter (`_`).
- If there is multiple variant groups in the `variants` property, the order in which they are defined matters. The suffixes are merged with underscores using the same order.

Example:
```
    // ...
    "variants": {
        "frame": [
            {
                "id_suffix": "o"
                // ...
            },
            {
                "id_suffix": "s"
                // ...
            }
        ],
        "cushion": [
            {
                "id_suffix": "r"
                // ...
            },
            {
                "id_suffix": "g"
                // ...
            },
            {
                "id_suffix": "b"
                // ...
            }
        ]
    }
    // ...
```
The generated suffixes would be: `_o_r`, `_s_r`, `_o_g`, `_s_g`, `_o_b`, `_s_b`.


```{warning}
Keep in mind that using long suffixes can cause issues with the file path limit of 80 characters. It is suggested to use one letter abreviations if possible.
```
