アドオン詳細解説 - ブロック
目次 (折りたたみ可)
ファイル・フォルダの場所
(ビヘイビア)
┣ manifest.json
┣ pack_icon.png
┗ blocks
┗ 〇〇.json
作成の流れ
ブロック本体に加えてテクスチャも追加するので、ビヘイビアとリソース両方が必要になります。
- blocksフォルダに新しくJSONを新規作成する
- ブロックのテクスチャを追加する
- terrain_texture.jsonを編集or新規作成する
- blocks.jsonを編集or新規作成する
(+ ブロックのジオメトリを追加する) - .langファイルを編集or新規作成する
ブロックを定義するJSON
これはブロックが定義できるための最小限の内容です。ゼロから作る場合はこれをコピペするといいでしょう。
{
"format_version": "1.16.100",
"minecraft:block": {
"description": {
"identifier": "test:my_block"
},
"components": {
// コンポーネント
}
}
}
主な構成
{
"format_version": "1.16.100",
"minecraft:block": {
"description": {
"identifier": "test:my_block"
},
"components": {
// コンポーネント
}
}
}
大きく関わってくるのがこの赤い枠で囲った部分で、もっと言えばその中の{ }内にコンポーネントを書き足していきます。
発展的な構成
{
"format_version": "1.16.100",
"minecraft:block": {
"description": {
"identifier": "test:my_block",
"properties": {
"test:my_property": [ 0, 1 ]
// ...
}
},
"permutations": [
{
"components": {
// コンポーネント
},
"condition": "q.block_property('test:my_property') == 1"
}
// ...
],
"components": {
// コンポーネント
},
"events": {
// イベント
}
}
}
プロパティ、パーミュテーション、イベントを用いてより複雑な仕様をもったブロックを作ることができます。
イベント
イベントをトリガーする(呼び出す)ことができる特定のコンポーネントによって呼び出され、指定したイベントファンクションを動作させます。
イベントトリガー系コンポーネント
↓ 呼び出す
イベント
{
"format_version": "1.16.100",
"minecraft:block": {
"description": {
"identifier": "test:my_block"
},
"components": {
"minecraft:〇〇": { // イベントトリガー系コンポーネント
"event": "test" // 呼び出すイベントを指定
}
},
"events": {
"test": { // イベント名
// イベントファンクション
}
}
}
}
プロパティ・パーミュテーション
プロパティを定義して、ハーフブロックの上付き・下付きのようにブロック自体は同じでも「状態」が異なるものとして扱うことができます。
プロパティの値は、真偽値、整数値、文字列のみで、定義するときに長さを決定する必要があります。
パーミュテーションはプロパティなどの条件(condition)を元に、コンポーネントを上書きしたり追加したりするのに使います。
{
"format_version": "1.16.100",
"minecraft:block": {
"description": {
"identifier": "test:my_block",
"properties": {
"test:my_property_bool": [ false, true ],
"test:my_property_int": [ 0, 1, 2, 3 ],
"test:my_property_string": [ "a", "b", "c" ]
// ...
}
},
"permutations": [
{
"components": {
// コンポーネント
},
"condition": "q.block_property('test:my_property') == 1"
}
// ...
],
"components": {
// コンポーネント
}
}
}
「状態」は主にイベントを介して操作します。
- set_block_propertyイベントファンクションを用いてプロパティを変更
- パーミュテーションの"conditon"で現在のプロパティと比較
- 該当するパーミュテーションのコンポーネントで元のコンポーネントを上書きする
具体例
シンプルなブロック
JSONがシンプルになるように性質を選んできています。
{
"format_version": "1.16.100",
"minecraft:block": {
"description": {
"identifier": "ex:block01"
},
"components": {
"minecraft:block_light_emission": 1.0,
"minecraft:creative_category": {
"category": "construction"
},
"minecraft:destroy_time": 1.0,
"minecraft:explosion_resistance": 5.0,
"minecraft:loot": "loot_tables/blocks/block01.json",
"minecraft:map_color": "#64ec86"
}
}
}
このお手本ブロックは以下のような性質を持ちます:
- 明るさレベル最大で光る
- クリエイティブインベントリでは「建造物」カテゴリにある
- 壊すのにかかる時間は1.0秒
- 爆発耐性は5.0
- ルートテーブルは「loot_tables/blocks/block01.json」を参照
- 地図での表示色は #64ec86
オリジナル作業台
{
"format_version": "1.16.100",
"minecraft:block": {
"description": {
"identifier": "ex:block02"
},
"components": {
"minecraft:crafting_table": {
"grid_size": 3,
"crafting_tags": [ "my_craft" ],
"custom_description": "UIに表示する作業台の名前"
}
// +その他のコンポーネント
}
}
}
クラフトのマスは3x3のみです。"crafting_tags"はレシピの"tags"と対応させて同じタグを持ったレシピのクラフトしかできないようにします。
特殊な形のブロック
{
"format_version": "1.16.100",
"minecraft:block": {
"description": {
"identifier": "ex:block03"
},
"components": {
"minecraft:geometry": "geometry.geometry_block",
"minecraft:material_instances": {
"*": {
"material": "opaque",
"texture": "geometry_block" // TerrainID
}
}
// +その他のコンポーネント
}
}
}
minecraft:geometryコンポーネントを使うときはminecraft:material_instancesコンポーネントも必須です。
特別な場所にしか置けないブロック
{
"format_version": "1.16.100",
"minecraft:block": {
"description": {
"identifier": "ex:simple_block"
},
"components": {
"minecraft:placement_filter": {
"conditions": [
{
"allowed_faces": [ "up" ],
"block_filter": [ "minecraft:grass", "minecraft:dirt" ]
},
{
"allowed_faces": [ "up", "down" ],
"block_filter": [ "minecraft:stone" ]
}
]
}
// +その他のコンポーネント
}
}
}
この場合、草ブロックと土の上面と石の上下面にだけ置けます。
半透明のブロック
{
"format_version": "1.16.100",
"minecraft:block": {
"description": {
"identifier": "ex:block04"
},
"components": {
"minecraft:material_instances": {
"*": {
"material": "blend",
"texture": "blend_block" // TerrainID
}
}
// +その他のコンポーネント
}
}
}
アイテムを持って右クリorタップするとコマンドが実行されるブロック
{
"format_version": "1.16.100",
"minecraft:block": {
"description": {
"identifier": "ex:block11"
},
"components": {
"minecraft:on_interact": {
"event": "ex:interact",
"target": "self",
"condition": "q.get_equipped_item_name('main_hand') == 'cobblestone'"
}
// +その他のコンポーネント
},
"events": {
"ex:interact": {
"run_command": "setblock ~ ~1 ~ cobblestone"
}
}
}
}
丸石を持って右クリック/タップしたときのみ丸石がブロックの上に/setblockされます。
アイテム(2種類)を持って右クリorタップするとコマンドが実行されるブロック
{
"format_version": "1.16.100",
"minecraft:block": {
"description": {
"identifier": "ex:block12"
},
"components": {
"minecraft:on_interact": {
"event": "ex:interact",
"target": "self",
"condition": "q.get_equipped_item_name('main_hand') == 'cobblestone' || q.get_equipped_item_name('main_hand') == 'dirt'"
}
},
"events": {
"ex:interact": {
"sequence": [
{
"condition": "q.get_equipped_item_name('main_hand') == 'cobblestone'",
"trigger": {
"condition": "(1.0)",
"event": "ex:setblock_cobblestone",
"target": "self"
}
},
{
"condition": "q.get_equipped_item_name('main_hand') == 'dirt'",
"trigger": {
"condition": "(1.0)",
"event": "ex:setblock_dirt",
"target": "self"
}
}
]
},
"ex:setblock_cobblestone": {
"run_command": { "command": "setblock ~ ~1 ~ cobblestone" }
},
"ex:setblock_dirt": {
"run_command": { "command": "setblock ~ ~1 ~ dirt" }
}
}
}
}
このブロックに右クリック/タップをするとき、
- 丸石をもってると丸石を上に/setblock
- 土を持っていると土を上に/setblock
原木のように向きが変わるブロック
{
"format_version": "1.16.100",
"minecraft:block": {
"description": {
"identifier": "ex:block13",
"properties": {
"ex:rotation": [ 1, 2, 3 ]
}
},
"permutations": [
{
"components": { "minecraft:rotation": [ 0, 0, 0 ] },
"condition": "q.block_property('ex:rotation') == 1"
},
{
"components": { "minecraft:rotation": [ 90, 0, 0 ] },
"condition": "q.block_property('ex:rotation') == 2"
},
{
"components": { "minecraft:rotation": [ 0, 0, 90 ] },
"condition": "q.block_property('ex:rotation') == 3"
}
],
"components": {
"minecraft:geometry": "geometry.block", // 普通のブロックの形のジオメトリ
"minecraft:material_instances": {
"*": { // 全面
"texture": "log_side",
"render_method": "alpha_test"
},
"up": { // 上面
"texture": "log_top",
"render_method": "alpha_test"
},
"down": "up" // 下面(上面と同じ指定)
},
"minecraft:on_player_placing": {
"event": "ex:on_placed"
}
// +その他のコンポーネント
},
"events": {
"ex:on_placed": { // 下,上で0, 北,南で1, 西,東で2
"set_block_property": { "ex:rotation": "math.floor(q.block_face/2)+1" }
}
}
}
}
壁のみに張り付くタイプの向きが変わるブロック
{
"format_version": "1.16.100",
"minecraft:block": {
"description": {
"identifier": "ex:block14",
"properties": {
"ex:rotation": [ 2, 3, 4, 5 ]
}
},
"permutations": [
{
"components": { "minecraft:rotation": [ 0, 0, 0 ] },
"condition": "q.block_property('ex:rotation') == 2"
},
{
"components": { "minecraft:rotation": [ 0, 180, 0 ] },
"condition": "q.block_property('ex:rotation') == 3"
},
{
"components": { "minecraft:rotation": [ 0, 90, 0 ] },
"condition": "q.block_property('ex:rotation') == 4"
},
{
"components": { "minecraft:rotation": [ 0, -90, 0 ] },
"condition": "q.block_property('ex:rotation') == 5"
}
],
"components": {
"minecraft:on_player_placing": {
"event": "on_placed"
},
"minecraft:placement_filter": {
"conditions": [
{ "allowed_faces": [ "side" ] }
]
}
// +その他のコンポーネント
},
"events": {
"on_placed": {
"set_block_property": { "ex:rotation": "q.block_face" }
}
}
}
}
壁にしか置けないようになっています。トリップワイヤーフックなどがそうです。
すべての側面に張り付くタイプの向きが変わるブロック
{
"format_version": "1.16.100",
"minecraft:block": {
"description": {
"identifier": "ex:block15",
"properties": {
"ex:rotation": [ 0, 1, 2, 3, 4, 5 ]
}
},
"permutations": [
{
"components": { "minecraft:rotation": [ 180, 0, 0 ] },
"condition": "q.block_property('ex:rotation') == 0"
},
{
"components": { "minecraft:rotation": [ 0, 0, 0 ] },
"condition": "q.block_property('ex:rotation') == 1"
},
{
"components": { "minecraft:rotation": [ -90, 0, 0 ] },
"condition": "q.block_property('ex:rotation') == 2"
},
{
"components": { "minecraft:rotation": [ 90, 0, 0 ] },
"condition": "q.block_property('ex:rotation') == 3"
},
{
"components": { "minecraft:rotation": [ 0, 0, 90 ] },
"condition": "q.block_property('ex:rotation') == 4"
},
{
"components": { "minecraft:rotation": [ 0, 0, -90 ] },
"condition": "q.block_property('ex:rotation') == 5"
}
],
"components": {
"minecraft:on_player_placing": {
"event": "ex:on_placed"
}
// +その他のコンポーネント
},
"events": {
"ex:on_placed": {
"set_block_property": { "ex:rotation": "q.block_face" }
}
}
}
}
たとえばボタンなどがそうです。
フェンス風隣の同じブロックとつながるブロック
{
"format_version": "1.16.100",
"minecraft:block": {
"description": {
"identifier": "ex:block16",
"properties": {
"ex:direction": [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ]
}
},
"permutations": [
{
"components": {
"minecraft:entity_collision": { "origin": [ -2.0, 0.0, -2.0 ], "size": [ 4.0, 16.0, 4.0 ] },
"minecraft:pick_collision": { "origin": [ -2.0, 0.0, -2.0 ], "size": [ 4.0, 16.0, 4.0 ] }
},
"condition": "q.block_property('ex:direction') == 0"
},
{
"components": {
"minecraft:entity_collision": { "origin": [ -2.0, 0.0, -8.0 ], "size": [ 4.0, 16.0, 10.0 ] },
"minecraft:pick_collision": { "origin": [ -2.0, 0.0, -8.0 ], "size": [ 4.0, 16.0, 10.0 ] }
},
"condition": "q.block_property('ex:direction') == 1"
},
{
"components": {
"minecraft:entity_collision": { "origin": [ -8.0, 0.0, -2.0 ], "size": [ 10.0, 16.0, 4.0 ] },
"minecraft:pick_collision": { "origin": [ -8.0, 0.0, -2.0 ], "size": [ 10.0, 16.0, 4.0 ] }
},
"condition": "q.block_property('ex:direction') == 2"
},
{
"components": {
"minecraft:entity_collision": { "origin": [ -8.0, 0.0, -8.0 ], "size": [ 10.0, 16.0, 10.0 ] },
"minecraft:pick_collision": { "origin": [ -8.0, 0.0, -8.0 ], "size": [ 10.0, 16.0, 10.0 ] }
},
"condition": "q.block_property('ex:direction') == 3"
},
{
"components": {
"minecraft:entity_collision": { "origin": [ -2.0, 0.0, -2.0 ], "size": [ 4.0, 16.0, 10.0 ] },
"minecraft:pick_collision": { "origin": [ -2.0, 0.0, -2.0 ], "size": [ 4.0, 16.0, 10.0 ] }
},
"condition": "q.block_property('ex:direction') == 4"
},
{
"components": {
"minecraft:entity_collision": { "origin": [ -2.0, 0.0, -8.0 ], "size": [ 4.0, 16.0, 16.0 ] },
"minecraft:pick_collision": { "origin": [ -2.0, 0.0, -8.0 ], "size": [ 4.0, 16.0, 16.0 ] }
},
"condition": "q.block_property('ex:direction') == 5"
},
{
"components": {
"minecraft:entity_collision": { "origin": [ -8.0, 0.0, -2.0 ], "size": [ 10.0, 16.0, 10.0 ] },
"minecraft:pick_collision": { "origin": [ -8.0, 0.0, -2.0 ], "size": [ 10.0, 16.0, 10.0 ] }
},
"condition": "q.block_property('ex:direction') == 6"
},
{
"components": {
"minecraft:entity_collision": { "origin": [ -8.0, 0.0, -8.0 ], "size": [ 10.0, 16.0, 16.0 ] },
"minecraft:pick_collision": { "origin": [ -8.0, 0.0, -8.0 ], "size": [ 10.0, 16.0, 16.0 ] }
},
"condition": "q.block_property('ex:direction') == 7"
},
{
"components": {
"minecraft:entity_collision": { "origin": [ -2.0, 0.0, -2.0 ], "size": [ 10.0, 16.0, 4.0 ] },
"minecraft:pick_collision": { "origin": [ -2.0, 0.0, -2.0 ], "size": [ 10.0, 16.0, 4.0 ] }
},
"condition": "q.block_property('ex:direction') == 8"
},
{
"components": {
"minecraft:entity_collision": { "origin": [ -2.0, 0.0, -8.0 ], "size": [ 10.0, 16.0, 10.0 ] },
"minecraft:pick_collision": { "origin": [ -2.0, 0.0, -8.0 ], "size": [ 10.0, 16.0, 10.0 ] }
},
"condition": "q.block_property('ex:direction') == 9"
},
{
"components": {
"minecraft:entity_collision": { "origin": [ -8.0, 0.0, -2.0 ], "size": [ 16.0, 16.0, 4.0 ] },
"minecraft:pick_collision": { "origin": [ -8.0, 0.0, -2.0 ], "size": [ 16.0, 16.0, 4.0 ] }
},
"condition": "q.block_property('ex:direction') == 10"
},
{
"components": {
"minecraft:entity_collision": { "origin": [ -8.0, 0.0, -8.0 ], "size": [ 16.0, 16.0, 10.0 ] },
"minecraft:pick_collision": { "origin": [ -8.0, 0.0, -8.0 ], "size": [ 16.0, 16.0, 10.0 ] }
},
"condition": "q.block_property('ex:direction') == 11"
},
{
"components": {
"minecraft:entity_collision": { "origin": [ -2.0, 0.0, -2.0 ], "size": [ 10.0, 16.0, 10.0 ] },
"minecraft:pick_collision": { "origin": [ -2.0, 0.0, -2.0 ], "size": [ 10.0, 16.0, 10.0 ] }
},
"condition": "q.block_property('ex:direction') == 12"
},
{
"components": {
"minecraft:entity_collision": { "origin": [ -2.0, 0.0, -8.0 ], "size": [ 10.0, 16.0, 16.0 ] },
"minecraft:pick_collision": { "origin": [ -2.0, 0.0, -8.0 ], "size": [ 10.0, 16.0, 16.0 ] }
},
"condition": "q.block_property('ex:direction') == 13"
},
{
"components": {
"minecraft:entity_collision": { "origin": [ -8.0, 0.0, -2.0 ], "size": [ 16.0, 16.0, 10.0 ] },
"minecraft:pick_collision": { "origin": [ -8.0, 0.0, -2.0 ], "size": [ 16.0, 16.0, 10.0 ] }
},
"condition": "q.block_property('ex:direction') == 14"
},
{
"components": {
"minecraft:entity_collision": { "origin": [ -8.0, 0.0, -8.0 ], "size": [ 16.0, 16.0, 16.0 ] },
"minecraft:pick_collision": { "origin": [ -8.0, 0.0, -8.0 ], "size": [ 16.0, 16.0, 16.0 ] }
},
"condition": "q.block_property('ex:direction') == 15"
}
],
"components": {
"minecraft:geometry": "geometry.fence", // 全方向に伸びていてそれぞれの腕が別のボーン
"minecraft:material_instances": { // geometryを使う場合は必須
"*": {
"texture": "planks",
"render_method": "opaque"
}
},
"minecraft:part_visibility": { // ※ "q.block_property(ex:direction)"は0~15の整数
"rules": {
"north": "math.mod(q.block_property('ex:direction'), 2)", // 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1
"east": "math.mod(math.floor(q.block_property('ex:direction')/2), 2)", // 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1
"south": "math.mod(math.floor(q.block_property('ex:direction')/4), 2)", // 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1
"west": "q.block_property('ex:direction') > 7" // 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1
}
},
"minecraft:ticking": {
"looping": true,
"range": [ 0, 0 ],
"on_tick": { "event": "checking", "target": "self" }
}
},
"events": {
"checking": {
"set_block_property": { // 北 + 2×東 + 4×南 + 8×西 (それぞれの方角からつながってる(=1)かつながっていないか(=0)が返ってくる)
"ex:direction": "q.block_neighbor_has_any_tag(0,0,-1,'my_fence')+2*q.block_neighbor_has_any_tag(1,0,0,'my_fence')+4*q.block_neighbor_has_any_tag(0,0,1,'my_fence')+8*q.block_neighbor_has_any_tag(-1,0,0,'my_fence')"
}
}
}
}
}
バニラのブロックとつながるようにするためにはぜんぶ指定する必要があります。
当たり判定などはMolangが対応してないのでパーミュテーションで一つずつ指定するしかないです。
できないこと
- バニラのブロックに変更を加える