name: bow-passive description: 弓パッシブの動作フローリファレンス。BowPassive モデル(bow.json)の4種スクリプト(hit/fired/flying/ground)、矢へのデータ埋め込み、dolphins_grace マーカーによる被弾エンティティ検出、PierceLevel による矢残存、飛翔中・着地後エフェクトなど弓パッシブ固有の仕組みを解説。弓パッシブのバグ修正、新規弓スキル追加、矢の挙動変更、着弾・飛翔・着地エフェクトの調整などで参照すること。bow, 弓, arrow, 矢, 着弾, hit, flying, ground, fired, tag_bow_arrow, on_arrow_hit, mafBowUsed, BowPassive などのキーワードで使う。
弓パッシブ動作フロー
弓パッシブ(BowPassive)は弓の発射・飛翔・着弾・着地の各フェーズでエフェクトを発動するスキルシステム。bow.json で定義され、4種のスクリプトタイプを持つ。
関連スキル
- passive: パッシブシステム全体。弓パッシブの effect ファイルは passive tick から呼ばれる
- magic-casting: 詠唱パイプライン
- ohmydat: プレイヤー個別ストレージ
- maf-export: Go ジェネレータのエクスポートパイプライン
1. データモデル(BowPassive)
ファイル: maf-command-generator/app/domain/model/bow/types.go
type BowPassive struct {
ID string // スラッグID
Name string // 表示名(最大80文字)
Role string // 役割説明(最大200文字)
Slots []int // 装備可能スロット
LifeSub *int // 矢の寿命短縮量(0〜1200 tick)
ScriptHit []string // 着弾時スクリプト(@s = 被弾エンティティ)
ScriptFired []string // 発射時スクリプト(effect ファイル末尾に追加)
ScriptFlying []string // 飛翔中スクリプト(矢が飛んでいる間毎 tick)
ScriptGround []string // 着地後スクリプト(矢が地面に刺さった後毎 tick)
}
4種のスクリプトタイプ
| スクリプト | 実行タイミング | @s | 生成先 |
|---|---|---|---|
ScriptFired | 弓発射時(effect ファイル末尾) | プレイヤー | generated/passive/effect/bow_{id}.mcfunction 内 |
ScriptFlying | 矢飛翔中(毎 tick) | 矢エンティティ | generated/bow/flying/{id}_flying.mcfunction |
ScriptGround | 矢着地後(毎 tick) | 矢エンティティ | generated/bow/ground/{id}_ground.mcfunction |
ScriptHit | 矢着弾時 | 被弾エンティティ | generated/passive/bow/{id}.mcfunction |
マスターデータ
ファイル: maf-command-generator/savedata/bow.json
2. 全体フロー概要
[発射フェーズ — 毎 tick]
passive/tick → run_effect → generated/passive/effect/bow_{id}
→ mafBowUsed >= 1 ? (弓を使ったか)
→ YES → 近くの矢を探す → bow/tag_bow_arrow でデータ埋め込み
→ ScriptHit あり → bow/prepare_hit_arrow(dolphins_grace マーカー付与)
→ ScriptFlying あり → tag @s add flying
→ ScriptGround あり → tag @s add ground
→ ScriptFired のコマンドを実行
[飛翔中 — 毎 tick]
magic/tick → bow/tick_flying
→ maf_bow_arrow + flying タグ + 飛行中の矢に対して:
→ bow/run_flying → generated/bow/flying/{id}_flying
[着地後 — 毎 tick]
magic/tick → bow/tick_ground
→ flying タグの除去(地面に刺さった矢)
→ hit タグの除去 + potion_contents 除去(地面に刺さった hit 矢)
→ ground タグの矢に対して:
→ bow/run_ground → generated/bow/ground/{id}_ground
[着弾検知 — advancement トリガー]
advancement/arrow_hit.json (player_hurt_entity)
→ passive/on_arrow_hit
→ advancement revoke(再発火可能に)
→ mafBowHit += 1(フラグのみ。処理は tick に委譲)
[着弾処理 — 次 tick]
passive/tick → mafBowHit >= 1 → bow/on_bow_hit
→ maf_bow_arrow タグ + shooterPlayerID 一致の矢を検索
→ bow/resolve_hit_arrow:
→ dolphins_grace(amp:80) を持つエンティティ(被弾者)に対して:
→ bow/run_bow_effect → generated/passive/bow/{id}
→ dolphins_grace マーカー除去
→ 矢を kill
3. 発射フェーズ(矢のタグ付け)
3a. effect ファイル(自動生成)
生成元: maf-command-generator/app/domain/export/bow.go の buildBowPassiveEffectBody()
生成先: datapacks/.../generated/passive/effect/bow_{id}.mcfunction
execute unless score @s mafBowUsed matches 1.. run return 0
execute store result storage maf:tmp bow_player_id int 1 run scoreboard players get @s mafPlayerID
execute as @e[type=arrow,distance=..2,nbt=!{inGround:1b},sort=nearest,limit=1] run function maf:bow/tag_bow_arrow {bow_id:"{id}",life:{lifeValue}}
execute as @e[type=arrow,distance=..2,tag=maf_bow_arrow,sort=nearest,limit=1] run function maf:bow/prepare_hit_arrow # ScriptHit ありの場合のみ
execute as @e[type=arrow,distance=..2,tag=maf_bow_arrow,sort=nearest,limit=1] run tag @s add flying # ScriptFlying ありの場合のみ
execute as @e[type=arrow,distance=..2,tag=maf_bow_arrow,sort=nearest,limit=1] run tag @s add ground # ScriptGround ありの場合のみ
{ScriptFired のコマンド群}
| 行 | 処理 | 条件 |
|---|---|---|
| mafBowUsed チェック | 弓使用がなければ即 return | 常に |
| bow_player_id 退避 | shooterPlayerID 書き込み用 | 常に |
| tag_bow_arrow | 矢にタグ + データ埋め込み | 常に |
| prepare_hit_arrow | hit タグ + dolphins_grace マーカー | ScriptHit 非空時 |
| tag flying | 飛翔エフェクト対象フラグ | ScriptFlying 非空時 |
| tag ground | 着地エフェクト対象フラグ | ScriptGround 非空時 |
| ScriptFired | 発射時の追加コマンド | ScriptFired 非空時 |
3b. mafBowUsed スコアボード
| ファイル | 処理 |
|---|---|
load.mcfunction | scoreboard objectives add mafBowUsed minecraft.used:minecraft.bow — バニラ統計から自動カウント |
system/score/afterscore.mcfunction | scoreboard players set @a mafBowUsed 0 — 毎 tick 末にリセット |
弓を使った tick だけ mafBowUsed >= 1 になる。次 tick にはリセットされるため、1回の射撃で1回だけ矢タグ付けが走る。
3c. bow/tag_bow_arrow.mcfunction(矢へのデータ埋め込み)
ファイル: datapacks/.../bow/tag_bow_arrow.mcfunction
# @s = arrow entity, args: bow_id, life
$data merge entity @s {Tags:["maf_bow_arrow"],PierceLevel:2b,item:{components:{"minecraft:custom_data":{maf:{bowId:"$(bow_id)"}}}}}
$data modify entity @s life set value $(life)s
data modify entity @s item.components."minecraft:custom_data".maf.shooterPlayerID set from storage maf:tmp bow_player_id
矢エンティティに書き込む情報:
| データ | 値 | 目的 |
|---|---|---|
Tags: ["maf_bow_arrow"] | 固定 | 弓パッシブ矢を @e セレクタで検索 |
PierceLevel: 2b | 固定 | 命中しても矢が消えないようにする(着弾処理後に手動 kill) |
custom_data.maf.bowId | 弓パッシブID | 着弾時・飛翔時・着地時にどのスキルか識別 |
life | 1200 - LifeSub | 矢の生存 tick |
custom_data.maf.shooterPlayerID | プレイヤーID | 着弾時にシューターの矢だけを処理するため |
3d. bow/prepare_hit_arrow.mcfunction(hit マーカー付与)
ファイル: datapacks/.../bow/prepare_hit_arrow.mcfunction
tag @s add hit
data merge entity @s {item:{components:{"minecraft:potion_contents":{custom_effects:[{id:"minecraft:dolphins_grace",duration:200,amplifier:80}]}}}}
hitタグ: 着弾処理対象であることを示す- dolphins_grace (amp:80): 矢が当たったエンティティに付与される被弾マーカー
3e. life 値の計算
lifeSub := 1200 // デフォルト: 即消滅
if entry.LifeSub != nil {
lifeSub = *entry.LifeSub
}
lifeValue := 1200 - lifeSub
| LifeSub | life 値 | 矢の飛行時間 |
|---|---|---|
| 未設定 (nil) | 0 | 即消滅 |
| 0 | 1200 | 60秒(バニラ標準) |
| 100 | 1100 | 55秒 |
| 1200 | 0 | 即消滅 |
注意: LifeSub 未設定時のデフォルトは 1200(life=0、即消滅)。実用的な弓パッシブでは必ず
LifeSubを明示的に指定すること。
4. 飛翔フェーズ(flying)
4a. bow/tick_flying.mcfunction
ファイル: datapacks/.../bow/tick_flying.mcfunction
execute as @e[type=arrow,tag=maf_bow_arrow,tag=flying,nbt=!{inGround:1b}] at @s run function maf:bow/run_flying with entity @s item.components."minecraft:custom_data".maf
magic/tick.mcfunction から直接呼ばれる(プレイヤーコンテキスト不要)。飛行中(inGround:0b)かつ flying タグ付きの弓矢に対して、矢の custom_data から bowId をマクロ引数として run_flying を呼ぶ。
4b. bow/run_flying.mcfunction
$function maf:generated/bow/flying/$(bowId)_flying
@s は矢エンティティ。ScriptFlying のコマンドは矢の位置で実行される。
5. 着地フェーズ(ground)
5a. bow/tick_ground.mcfunction
ファイル: datapacks/.../bow/tick_ground.mcfunction
# flying タグの矢が地面に刺さったら flying を除去
execute as @e[type=arrow,tag=maf_bow_arrow,tag=flying,nbt={inGround:1b}] run tag @s remove flying
# hit タグの矢が地面に刺さったら potion_contents 除去 + hit タグ除去
execute as @e[type=arrow,tag=maf_bow_arrow,tag=hit,nbt={inGround:1b}] run data remove entity @s item.components."minecraft:potion_contents"
execute as @e[type=arrow,tag=maf_bow_arrow,tag=hit,nbt={inGround:1b}] run tag @s remove hit
# ground タグの矢が地面に刺さったらエフェクト実行
execute as @e[type=arrow,tag=maf_bow_arrow,tag=ground,nbt={inGround:1b}] at @s run function maf:bow/run_ground with entity @s item.components."minecraft:custom_data".maf
magic/tick.mcfunction から直接呼ばれる。地面に刺さった矢に対する処理:
flyingタグ除去(飛翔エフェクト停止)hitタグ +potion_contents除去(地面に刺さった hit 矢の dolphins_grace を無効化)groundタグの矢に着地エフェクト実行
5b. bow/run_ground.mcfunction
$function maf:generated/bow/ground/$(bowId)_ground
@s は矢エンティティ。ScriptGround のコマンドは矢の位置で実行される。
6. 着弾フェーズ(hit)
着弾処理は 2段階に分離されている:
- advancement が即座にフラグを立てる(
passive/on_arrow_hit) - 次の tick ループで実際の処理を行う(
bow/on_bow_hit)
6a. Advancement トリガー
ファイル: datapacks/.../advancement/arrow_hit.json
{
"rewards": {
"function": "maf:passive/on_arrow_hit"
}
}
player_hurt_entity+direct_entity: arrow— プレイヤーが矢でエンティティを傷つけたとき発火@sは 攻撃側プレイヤー
6b. passive/on_arrow_hit.mcfunction
ファイル: datapacks/.../passive/on_arrow_hit.mcfunction
advancement revoke @s only maf:arrow_hit
scoreboard players add @s mafBowHit 1
フラグセットのみ。実処理は tick に委譲。
6c. bow/on_bow_hit.mcfunction(着弾処理本体)
ファイル: datapacks/.../bow/on_bow_hit.mcfunction
scoreboard players set @s mafBowHit 0
execute store result storage maf:tmp bow_player_id int 1 run scoreboard players get @s mafPlayerID
function maf:bow/process_hit_arrows with storage maf:tmp
data remove storage maf:tmp bow_player_id
passive/tick から mafBowHit >= 1 のとき呼ばれる。プレイヤーの mafPlayerID を使って、自分が撃った矢だけを処理する。
6d. bow/process_hit_arrows.mcfunction
$execute as @e[type=arrow,tag=maf_bow_arrow,nbt={item:{components:{"minecraft:custom_data":{maf:{shooterPlayerID:$(bow_player_id)}}}}}] at @s run function maf:bow/resolve_hit_arrow
shooterPlayerID が一致する maf_bow_arrow タグ付き矢を検索し、各矢に対して resolve_hit_arrow を実行。
6e. bow/resolve_hit_arrow.mcfunction
ファイル: datapacks/.../bow/resolve_hit_arrow.mcfunction
execute unless entity @e[nbt={active_effects:[{id:"minecraft:dolphins_grace",amplifier:80b}]},sort=nearest,limit=1,distance=..5] run return 0
data modify storage maf:tmp bow_passive set from entity @s item.components."minecraft:custom_data".maf
execute if entity @s[tag=hit] as @e[nbt={active_effects:[{id:"minecraft:dolphins_grace",amplifier:80b}]},sort=nearest,limit=1,distance=..5] at @s run function maf:bow/run_bow_effect with storage maf:tmp bow_passive
effect clear @e[nbt={active_effects:[{id:"minecraft:dolphins_grace",amplifier:80b}]},sort=nearest,limit=1,distance=..5] minecraft:dolphins_grace
kill @s
data remove storage maf:tmp bow_passive
| ステップ | 処理 | なぜ必要か |
|---|---|---|
| dolphins_grace チェック | 近くに被弾マーカー持ちがいなければ return | hit 以外の矢(flying/ground のみ)でも呼ばれうるため |
| データ退避 | 矢の custom_data.maf を maf:tmp bow_passive にコピー | kill 後はデータ取得不可 |
| hit チェック + エフェクト実行 | hit タグ付き矢の場合のみ被弾エンティティでエフェクト実行 | ScriptHit がある矢だけ |
| マーカー除去 | dolphins_grace (amp:80) を除去 | 副作用防止 |
| 矢 kill | 矢エンティティを除去 | PierceLevel で残存した矢の後始末 |
| クリア | 一時ストレージ削除 | ゴミデータ残留防止 |
6f. 被弾エンティティの検出方式(dolphins_grace マーカー方式)
矢の potion_contents に仕込んだ dolphins_grace (amplifier:80) が命中時に被弾エンティティへ付与される。このエフェクトを持つエンティティ=被弾エンティティとして正確に特定できる。
| 特性 | 内容 |
|---|---|
| 特定精度 | 高い。amplifier:80 は通常付与されない特殊値 |
| 複数命中 | PierceLevel:2b により貫通。全被弾エンティティにエフェクト発動 |
| クリア必須 | 泳ぎ速度上昇の副作用を防ぐため必ず effect clear |
6g. bow/run_bow_effect.mcfunction
$function maf:generated/passive/bow/$(bowId)
maf:tmp bow_passive ストレージから bowId を受け取り、マクロで generated/passive/bow/{id}.mcfunction にディスパッチ。@s は被弾エンティティ。
7. 生成パイプライン(Go 側)
7a. 成果物の分離
ファイル: maf-command-generator/app/domain/export/bow.go
BuildBowArtifacts(master)
→ []BowEffectFunction — effect ファイル(弓検知 + 矢タグ付け + ScriptFired)
→ []BowHitFunction — hit ファイル(ScriptHit)
→ []BowFlyingFunction — flying ファイル(ScriptFlying)
→ []BowGroundFunction — ground ファイル(ScriptGround)
| 成果物 | パス | 内容 | ID 形式 |
|---|---|---|---|
| effect | generated/passive/effect/bow_{id}.mcfunction | 弓検知 + 矢タグ付け + ScriptFired | bow_ プレフィックス付き |
| hit | generated/passive/bow/{id}.mcfunction | 着弾時エフェクト | そのまま |
| flying | generated/bow/flying/{id}_flying.mcfunction | 飛翔中エフェクト | _flying サフィックス |
| ground | generated/bow/ground/{id}_ground.mcfunction | 着地エフェクト | _ground サフィックス |
注意: ScriptHit / ScriptFlying / ScriptGround が空の場合、対応するファイルは生成されない(既存ファイルも削除される)。
7b. ファイル書き出し
ファイル: maf-command-generator/app/domain/export/bow.go の WriteBowArtifacts()
effect と hit は passive と同じディレクトリ(passiveEffectDir, passiveBowDir)に出力される。flying と ground は generated/bow/ 配下の専用ディレクトリに出力される。
8. magic/tick.mcfunction からの呼び出し
execute as @a at @s run function maf:passive/tick # パッシブ tick(effect 実行 + mafBowHit チェック)
function maf:bow/tick_flying # 飛翔中エフェクト(全矢対象)
function maf:bow/tick_ground # 着地エフェクト(全矢対象)
tick_flying と tick_ground はプレイヤーコンテキスト不要なのでグローバルに呼ばれる。
9. 設計上の注意点
PierceLevel の必要性
通常の矢は命中で消滅する。矢が消えると custom_data が失われるため、PierceLevel:2b で貫通属性を付けて矢を残存させる。着弾処理後に resolve_hit_arrow で手動 kill する。
dolphins_grace マーカー方式の注意点
hitタグのない矢(flying/ground のみ)にはprepare_hit_arrowが呼ばれないため、dolphins_grace は付与されないtick_groundで地面に刺さったhit矢のpotion_contentsを除去するため、地面への着弾で誤検出は起きないeffect clearを忘れるとエンティティに泳ぎ速度上昇が残り続ける
shooterPlayerID によるフィルタリング
bow/process_hit_arrows で shooterPlayerID が一致する矢だけを処理する。複数プレイヤーが弓を使った場合でも、各プレイヤーは自分の矢だけを処理する。
LifeSub デフォルト値の罠
LifeSub が nil(未設定)の場合、デフォルトの lifeSub は 1200 になり、life = 0 で矢が即消滅する。新規弓パッシブには必ず LifeSub を設定すること。
10. 弓パッシブ追加手順
savedata/bow.jsonにエントリ追加life_subを設定(推奨: 100 程度)- 必要なスクリプトを記述:
script_hit: 着弾時コマンド(@s= 被弾エンティティ)script_fired: 発射時追加コマンド(@s= プレイヤー)script_flying: 飛翔中コマンド(@s= 矢、毎 tick)script_ground: 着地後コマンド(@s= 矢、毎 tick)
make run/exportで生成- 確認: 各スクリプトに対応するファイルが生成されていること
- ゲーム内テスト: 弓パッシブ付き武器で各フェーズの動作を確認
11. 関連ファイル一覧
Generator(Go)
| ファイル | 役割 |
|---|---|
maf-command-generator/app/domain/model/bow/types.go | BowPassive 構造体 |
maf-command-generator/app/domain/export/bow.go | BuildBowArtifacts, buildBowPassiveEffectBody, WriteBowArtifacts |
maf-command-generator/savedata/bow.json | 弓パッシブマスターデータ |
Datapack(手書き)
| ファイル | 役割 |
|---|---|
bow/tag_bow_arrow.mcfunction | 矢へのデータ埋め込み(マクロ関数) |
bow/prepare_hit_arrow.mcfunction | hit マーカー(hit タグ + dolphins_grace)付与 |
bow/on_bow_hit.mcfunction | 着弾処理エントリ(フラグリセット + process_hit_arrows 呼び出し) |
bow/process_hit_arrows.mcfunction | shooterPlayerID で矢をフィルタして resolve |
bow/resolve_hit_arrow.mcfunction | 個別矢の着弾解決(エフェクト実行 + クリア + kill) |
bow/run_bow_effect.mcfunction | hit スクリプトへのマクロディスパッチ |
bow/tick_flying.mcfunction | 飛翔中矢の毎 tick 処理 |
bow/run_flying.mcfunction | flying スクリプトへのマクロディスパッチ |
bow/tick_ground.mcfunction | 着地矢の毎 tick 処理 |
bow/run_ground.mcfunction | ground スクリプトへのマクロディスパッチ |
passive/on_arrow_hit.mcfunction | 着弾検知(advancement コールバック、フラグセットのみ) |
advancement/arrow_hit.json | 矢着弾の Advancement トリガー |
Datapack(自動生成)
| ファイル | 役割 |
|---|---|
generated/passive/effect/bow_{id}.mcfunction | 弓検知 + 矢タグ付け + ScriptFired |
generated/passive/bow/{id}.mcfunction | 着弾時エフェクト(ScriptHit) |
generated/bow/flying/{id}_flying.mcfunction | 飛翔中エフェクト(ScriptFlying) |
generated/bow/ground/{id}_ground.mcfunction | 着地エフェクト(ScriptGround) |