Defining a Non-Amplifying Seal in JSON
Seals are defined in JSON files. Let's define a seal named sweeping blade. This seal will do a ton of damage and aoe. It can mine stone.When right-clicked, it will strip logs and turn grass into stone!
{
"id": "sweeping_blade",
"type": "offensive"
}
This is the JSON file defining our new sweeping blade seal. We put it in data/<namespace>/seals/<path>.json.
These are just the basic fields that are mandatory for every seal. Id has to be the name of your seal, all lowercase, with an underscore instead of space. type can only be offensive, passive, or amplifying. Please see Amplifying Seals for defining an amplifying seal.
Texture
This seal has no texture. To add one, you add two fields to the seal json.
{
"id": "sweeping_blade",
"type": "offensive",
"activeTexture": "<namespace>:item/wands/activated/sweeping_blade",
"texture": "<namespace>:item/seals/sweeping_blade_seal"
}
The field texture is the texture in your inventory. The activeTexture texture defines the texture that will be overlaid on top of the wand texture. Doing it this way, makes it so that custom wands can be added without having to add entirely new seal textures.
Damage
To add attack damage the seal, we need to add a single field to it. The field attackDamage is the damage that the wand will deal.
{
"id": "sweeping_blade",
"type": "offensive",
"activeTexture": "<namespace>:item/wands/activated/sweeping_blade",
"texture": "<namespace>:item/seals/sweeping_blade_seal",
"attackDamage": 3
}
AOE
In order to add aoe to the seal, we need to add this object to the JSON file:
{
"aoe": {
"aoeDamageMultiplier": 0.5,
"range": 3,
"maxMobCount": 50
}
}
Mining
Adding this to your JSON will make the wand damage a max of 50 mobs, within three blocks of range with half of the damage that was dealt to the original mob
Now we notice that it cannot mine stone efficiently. This can be fixed by adding a mining object in the json. For reference, the mining speed of wood is 2, stone is 4, iron is 6, diamond is 8, gold is 12, and netherite is 9. Instead of putting "#minecraft:blocks/mineable/axe" for block that can be mined with axes, you can put "axe". This will locate a file named axe.json in minecraft:blocks/mineable/.
There are several more Optional mining-related fields that can be added to the mining Object. veinMine is an int that specifies the amount of the same block adjacent to it that can be mined. Defaults to zero. areaMine is an int similar to vein mine. The difference is that area mine will mine all the blocks in an area of the int area in the shape of shape that are of equal or lesser hardness than the block mined (for example, if I made area equal to five and shape equal to sphere, it would mine all blocks of equal harness withing a sphere with a radius of five). fortune adds the value of level (int) in fortune (cannot be used with silk_touch). silkTouch adds silk touch (cannot be used with fortune)
{
"mining": {
"miningSpeed": 8,
"miningBlocks": "axe",
"miningLevel": "diamond"
}
}
Predefined Use Functions
These are predefined! Skip to Custom Use Actions if you want to make a custom one! Use functions are stored as arrays, so that multiple can be added per seal. Let's make one that strips logs.
{
"useFunctions": [
{
"action": "asm:strip:wood"
}
]
}
This is a simple use function. These are functions created in code that can be referenced easily through JSONs. There are several predefined asm ones: strip_wood, till_dirt, pave_dirt, cause_explosion, damage_wand, hurt (damage wand), and break_block.
The Id of this use function is equal to action.
Several fields need to be added depending on the predefined use action. These are as follows:
- for cause_explosion the field needed is explosionStrength (int)
- for hurt the field needed is amount (int)
- for break_block, there is an Optional field aoe (int). This field allows aoe mining
Custom Use Functions
Now we get to the complex stuff! This system was implemented so anyone can make use functions without Java code or custom Mods. There are a large amount of ways that these are customizable! Let's make one that turns grass into stone.
Several fields are mandatory when creating a custom seal. This function is activated when an item is used while looking at a block. A mandatory field is action. There is one more field, id tht can be added to the use function. This can be helpful for custom amplifying seals.
There are several actions to choose from. Each do vastly different things. They are as follows: + change_block + change_block_state + summon_entity
Change Block Action
If action is change_block, there needs to be a new object named updateBlock. This requires several more fields. The block field can either be a block or block tag. These are the blocks to be replaced by the block in result, another mandatory field that has to be a block. This function with the id of "axe_to_stone" changes all blocks mineable with an axe into stone.
{
"customAction": {
"id": "axe_to_stone",
"action": "change_block",
"updateBlock": {
"block": "#minecraft:blocks/mineable/axe",
"result": "minecraft:stone"
}
}
}
Change Block State
If action is change_block_state, there needs to be a new object named state. This object contains states to override. The following example shows code that will make a furnace lit.
{
"customAction": {
"type": "useOn",
"action": "change_block_state",
"state": {
"lit": true
}
}
}
Summon Entity Action
If action is summon_entity, there is only one field that needs to be added. The entity field is the id of the entity to summon
{
"customAction": {
"type": "useOn",
"action": "summon_entity",
"entity": "minecraft:pig"
}
}
Conditionals
You can add multiple conditions to your seal use function. This will make it so the use action only gets triggered if this condition is true. Add a conditions array to the customAction object. This array can store multiple conditions.
Each condition has a type. This can be: has_effect, exp_level, is_block_relative_to, is_block_looking_at, or has_item.
Has Effect Condition
If type is has_effect, a field named effect is needed. This is the id of the effect. Another field named effectLevel is optional. This is the level of the effect, defaults to zero. The following makes the use function only take effect if the player has speed three.
{
"conditions": [
{
"type": "has_effect",
"effect": "minecraft:speed",
"effectLevel": 3
}
]
}
Exp Level Condition
Two fields are needed when type is exp_level. One of these is mode. It can either be points or levels. The value points makes it count points, while levels makes it count levels. The other required field is amount. This is the amoint of the value in mode that will be counted. The following conditional makes the useFunction only activate if the player has five xp levels.
{
"conditions": [
{
"type": "exp_level",
"mode": "levels",
"amount": 5
}
]
}
Has Item Condition
The has_item requires two fields, item and amount. item is the id of the item. amount is the amount of the item. This JSON condition only activates if the player has 23 diamonds with the nbt tag of valuable to true
There is another, optional field named nbt. This is an object that contains any nbt information the item has to have
{
"conditions": [
{
"type": "has_item",
"item": "minecraft:diamond",
"amount": 23,
"nbt": {
"valuable": true
}
}
]
}
Is Block Relative To Condition
The is_block condition checks what the block relative to the player's feet is. Position is a required field, and array. This is the pos relative to the player's feet (for example: [0, -1, 0] would be below the feet). Block is another mandatory field. It is the id (can be a block tag) of the block to check for. An optional field is block_state. This is the block state of the block the player is looking at. The following is an example to check if the block below the player's feet is a lit furnace that is facing east.
{
"conditions": [
{
"type": "is_block_relative_to",
"pos": [0, -1, 0],
"block": "minecraft:redstone_block",
"block_state": {
"lit": true,
"facing": "east"
}
}
]
}
Is Block Looking At Condition
The is block looking at condition checks what the block that the player is looking at is. block is the only mandatory field. It is a block tag or the id of the block to check for. An optional field is block_state. This is the block state of the block the player is looking at. The second optional field is pos. This is the position relative to the block the player is looking at (as an array). This example code will check if the block below the block the player is looking at is a powered observer.
{
"conditions": [
{
"type": "is_block_looking_at",
"pos": [0, -1, 0],
"block": "minecraft:observer",
"block_state": {
"powered": true
}
}
]
}
Inheritance
Inheritance is a way to simplify your JSON. It can make your seal take things from other seals. If there is a use function borrowed from another seal that is enhanced by an amplifying seal, this seal can also be amplified. To stop this from happening, you can add a field keep_amplifications and set it to false. You can add multiple inheritances
Here is a list of the required fields and what they do: + seal; the id of the seal to inherit from + target; what to inherit + keep_amplifications; be targeted by same amplification seals as the inherited seal; defaults to true
A list of valid targets:
+ damage; all damage and aoe
+ damage.aoe; only aoe settings
+ damage.aoe.damageMultiplier; only aoe damage multiplier
+ damage.aoe.range; only aoe range
+ damage.aoe.maxMobCount; only aoe max mob count
+ damage.damage; only damage, not aoe
+ useFunction; all use functions
+ useFunction[\
{
"inheritance": [
{
"seal": "asm:scythe",
"target": "damage.aoe",
"keep_amplifications": false
}
]
}
This can be added into the json file to make the aoe the same as that of a scythe, but seals affecting scythe aoe will not affect it.