猫山さんの雑記ぶろぐ。

パソコンマイクラその他のぶろぐですぅ

【Minecraft Bedrock Edition / 統合版】functionを使うことでの長所、短所、使い方。コマンドブロックの仕様。実行順序。

お久しぶりです。また忘れ去られていたブログの更新です。

iPadでブログを書いていたけど、パソコンのほうが圧倒的に書きやすいねこりゃ。タイピング速度もこっちのほうが早いし、練習にもなる...おっと、本題に入りましょう

 

 

〇そもそもfunctionとは―

functionという言葉に聞き慣れない人もいると思います。なので簡単に説明します。

 

functionを直訳すると「関数」という意味なります。さらに、関数とは

「ある集合の元、またはいくつかの集合からそれぞれに取った元の組に応じて、その集合(のうちの一つ)または他の集合の、一つの元が定まるという対応関係。」

 

(google)  という意味らしいです。ピンとこないです。

外のサイトも参照してみると

「与えられた文字や数値に対し、定められた処理を行って結果を返す機能のこと。表計算ソフトやプログラミング言語 などで利用される。関数ごとにさまざまな処理が割り当てられている。」

つまり、簡単に言うと決められた処理を行うって感じですかね。

パソコンを使っている人なら「ファンクションキー」「F1キー」とかって聞くと思います。

例を挙げると、firefoxブラウザでF11キーを押すと全画面化します。

「F11キーを押すと全画面化する処理をする」

呼び出すトリガー(きっかけ)は「F11キーを押す」こと。処理内容は「全画面化する」こと。

このように使うことができます。

Minecraftで言うfunctionとは―

Minecraftではあらかじめ処理するコマンドを一つのファイルに記入しておくことでfunctionコマンドでファイルに記入しているコマンドすべてを実行することができます。

mcfunctionファイル(以後関数ファイルと呼ぶ。)は拡張子.mcfunctionでビヘイビアパックの一つのファイルとしてMinecraftに読み込むことで使用できます。

※この記事では「.mcpack」拡張子でマイクラにリソースパックやビヘイビアパックを読み込ませる手順は記入しません。開発者用ディレクトリである「development_behavior_packs」ディレクトリに導入する方法のみ説明するのでご注意ください。

例えば、「test.mcfunction」という関数ファイルを用意して

中にこのように記入してみます。

f:id:nekoyama3:20190723224253p:plain

※注意:文字コードは必ずUTF-8として保存してください。各テキストエディタの設定から変更できると思います。これがUnicordだったりすると日本語が使用できなくなるなどのバグが発生します。

そしてこのファイルを読み込みマイクラで「/function test[.mcfunctionは不要]と実行します(※testスコアボードはあらかじめ作っておいてください)。そうすると

[実行者のプレイヤー名]スコアは(1-3)です。

とチャットに表示されると思います。

このように、test関数ファイルを呼び出すことで中に記入されている五つのコマンドを一度にすべて実行することができます。(実行順は一列目から、遅延はおよそ0.000秒)

一括で複数のコマンドを実行できるのがこのfunctionの強みです。

〇function導入方法(development)―

そもそもdevelopmentとは開発者を意味します。behavior_packsフォルダではなくdevelopment_behavior_packsフォルダに追加する理由としては、Minecraftの起動中にfunctionを編集したとき、/reloadコマンドでビヘイビアパックを再度読み込むことで編集が即時適応されるためです。自分としてははっきり言ってbehavior_packsを使う意味がよくわからないです。特にデメリットなどもありません。

まずbehavior packとしてフォルダを用意します。

そしたら、このような構成にします。

f:id:nekoyama3:20190723232304p:plain

manifestファイルは公式サイトからダウンロードしてください。

マニフェストを入れて関数ファイルも入れて環境が整ったらこのビヘイビアのフォルダ(以後ビヘイビアパックと呼ぶ)をdevelopment_behavior_packsにぶち込みます。

ちなみに場所は

Windowsの場合

C:\Users\ユーザ名\AppData\Local\Packages\Microsoft.MinecraftUWP_8wekyb3d8bbwe\LocalState\games\com.mojang

へ移動します。(Microsoft.MinecraftUWP_8wekyb3d8bbweの不規則文字列はアプデ毎に変わる?)

Androidはうろ覚えだとルートディレクトリかどっかにgamesっていうディレクトリがあると思うのでそっからcom.mojangへ

iOSは純正のファイルアプリからMincraftを開いてgames/com.mojangへ

一応説明しましたが、iOSAndroidでfunctionを開発するのははっきり言って面倒の極みです。実際に経験したことがありますが、パソコンで開発しているとアホらしくなるほどディレクトリの移動やマイクラの起動の繰り返しが大変です。何度も調整する人には携帯端末での開発は極めて困難だと思います。このブログではWindowsだということを前提に説明していきます。

 そしたら

development_behavior_packsフォルダにさっきのフォルダを入れてワールド設定時のビヘイビア パック でマニフェストファイルに書かれているファイル名を選んで導入して終わりです。

 〇function導入終了、実用―その前に確認

さて、このfunctionをどのように導入して使用するかっていうのをこの時点で理解できていたらありがたいです。

ここでクイズ!!

正解率6割を下回ったら(&上の手順でマイクラで動作させられなかったら)最初からやり直したほうがいいかも? Q10の下に答えが出ます。

Q.1>functionを和訳すると意味は何になるか。

Q.2>developmentを和訳すると意味は何になるか。

Q.3>behavior_packsではなくdevelopment_behavior_packにビヘイビアパックを導入する利点は何か。

Q.4>関数ファイルの拡張子を答えよ。

Q.5>関数ファイルをMinecraft内で実行するコマンドを答えよ。

Q.6>開発者フォルダに導入したビヘイビアパックの関数ファイルをMinecraft起動中に編集し、その編集を即時反映させるコマンドを答えよ。

Q.7>関数ファイルにコマンドを二文記入した。一文目のコマンドと二文目に生じる遅延はおよそ何ミリ秒か(1s=1000ms)

Q.8>functionの強みはコマンドをどのように実行できることなのか。

Q.9>「ファンクションキーを押すと指定された処理を行う」のような仕組みを何というか。

Q.10>scoreboardコマンドとは何を制御するコマンドか。

 

Answer.

1.関数 / 2.開発者(実際は開発という意味だが触れないでおく。開発者は正式にはdeveloper) / 3.Minecraft起動中の編集しても即時適応できる。 / 4.「.mcfunction」/ 5.「/function」 / 6.「/reload」 / 7.0ms(ほぼない) / 8.あらかじめ設定された処理を一括で実行する / 9.関数 / 10.スコア(プレイヤーが所持する各スコアボードの数値の管理、スコアボードの作成削除リストアップその他)

 

 〇function導入終了、実用―

合格出来ましたか?それでは、後世に入っていきます。まずは長所と短所から紹介していきます。

個人の偏見等も混じっているのでそこ辺りは悪しからず。

長所

・コマンドブロックの数を削減できる

・コマンドブロックの数を削減することで描画的な軽量化につながる

・一覧にまとめているので大規模なコマンド連も見やすい

・見やすく編集することもできる。

・ワールド依存じゃなく実行できる。

長所としてこんな感じです。これが一番大きいです。

短所

・エラーが出ないためミスの特定が大規模になるほど難しくなる

・reloadコマンドがあるとはいえ修正が面倒

・コマンドを実行する数だけ負荷はかかる

・条件付き実行が使えない。

 短所はこんな感じ。

自分はfunctionでボスを作ったりミニゲームを作ったりしていますが、200-600行のコマンドを一つのコマンドブロックで実行できるので非常に便利です。しかもテキストエディタによっては文字列置き換え機能もあるので、そちらも重宝しています。

見やすさについては、自分が実際に作ったボスのfunctionを見てもらいたい。

f:id:nekoyama3:20190724005139p:plain

これをきれいっていう上級者は流石にいないでしょう。なかなか難しいです。というよりは、最初は文字列最初にシャープ記号を置いてコメントを追加していたけど、慣れてコメントがなくても理解できるようになってきたのでそういうのは省いています。

#ここから必殺技「***」の開始  等のようにコメントを追加する

まぁtellrawコマンドの日本語の説明をみて大体この辺りが個の必殺技って察してる感じ。このボスのfunctionは比較的簡単なほうです。スコア加算してって指定範囲内で必殺技を実行するだけの部分が大部分なので。

↓tellrawコマンド。今から転空ホーミング改旋風という技が実行されるのが分かる。

execute @e[type=!player,tag=bosscreeper,scores={bosstime=6000}] ~ ~ ~ tellraw @a {"rawtext":[{"text":"§d<enemy> §9「流星群IV類・転空ホーミング改旋風」"}]}

さて、このfunction実に591行 約57,000文字によって構成されているわけですが、例えばtp @s ^ ^ ^0.32 facing @pという部分はエンティティをプレイヤーの方向に動かすコマンドなのですがこれをtp @s ^ ^ ^0.32 fasing @pと書いてみましょう。スペルミスで実行されなくなります。

↓facingのcの部分を指定してもわかりずらいのが分かると思います。

f:id:nekoyama3:20190724010037p:plain

たった一文字のミスでそのコマンドが実行される致命傷につながる場合があり、しかもcとsの違いを数万文字の中から探し出すとなれば非常に難しくなります。これが弱点です。慣れれば行けるのかもしれませんがこんなの見つけられたらプログラマー道完全に進んでますね。

 

これらの長所や短所を理解した上で、「コマンドブロックで構成する」「関数ファイルで構成する」を的確に決めることが重要となってきます。

 うげっ...ここまででもう4400文字も書いてんのかよ...ここまで読んでる人もあんまりいなさそうですが...続けます

 〇追記・スコア流れ管理―

スコアを1加算し続けて指定範囲内で指定コマンドを実行することでfunctionで数十秒数分の遅延を追加することができます。

自分が作ったボスのfunctionでは6000..6550までが最後の必殺技、最初へループする点が6555と設定しています。6000は毎秒20加算するとして300秒...五分の遅延、6550なので初実行から5分後、27.5秒実行する、という仕組みになっています。

 〇条件付き実行が使えない!!!回避手段―

さらっと短所で紹介した

・条件付き実行が使えない。

これが致命傷だろ!って思う人もいると思います。ほかにもtestforで検知してRSコンパレータで出力する手段などもfunctionでは使えません。そちらの回避手段を紹介。

〇functionのに続けて条件付き前文と条件付き文をつなげる

例えばこんな関数ファイルを用意したとします

↓tradeディレクトリ内のexchange.mcfunctionファイルを指す

trade/exchange.mcfunction

give @p dirt

clear @p emerald 0 1

#条件付きで実行したいgive @p redstone 3

replaceitem entity @p slot.armor.head 0 leather_healmet 0

replaceitem entity @p slot.armor.chest 0 leather_chestplate 0

replaceitem entity @p slot.armor.legs 0 leather_leggings 0

replaceitem entity @p slot.armor.foot 0 leather_boots 0

もちろん条件付きをfunctionで実行することはできません。

f:id:nekoyama3:20190724013849p:plain

オレンジ...インパルスコマンドブロック 青...チェーン

このように条件前実行文と条件実行文を別途にすることで実行付きを適応できるようになります。ただし、functionの全処理の前か後しか指定できないので注意。この場合

trade/exchange.mcfunction

give @p dirt

replaceitem entity @p slot.armor.head 0 leather_healmet 0

replaceitem entity @p slot.armor.chest 0 leather_chestplate 0

replaceitem entity @p slot.armor.legs 0 leather_leggings 0

replaceitem entity @p slot.armor.foot 0 leather_boots 0

  チェーン

clear @p emerald 0 1

条件付き give @p redstone 3

という処理順にすることで解決することができます。。

functionと条件付きが逆でも問題はないです。条件付きでfunctionを実行するなど一部の実行だけをfunctionにするという手段もあります。少しややこしなりますがハイブリットで関数とコマブロで実行するようにすることでこういうデメリットを飛ばすこともできます。

ハイブリットの場合ややこしくなるという点が一番の短所。関数名を少し工夫しないとわかりにくいかも。

ちなみにこの手段は後記でも使えない検知系-ブロック検知でもRSコンパレータを使用したハイブリット式が有効だと思います。

 

〇エンティティの検知-スコアボード

エンティティを検知するときはtestforコマンドでRSコンパレータ出力しているっていう人も多いと思います。が、こちらは別の方法で代用することができます。

それこそが、対象「リセット→加算→実行」方法です。

序盤で出した自作ボスのfunction

ファイルでこの機構が使われているので引用してみます。

①execute @e[c=1,type=armor_stand,tag=bce2] ~ ~ ~ scoreboard players set @s bosstime 0
②execute @e[c=1,type=armor_stand,tag=bce2] ~ ~ ~ execute @e[type=!player,tag=bosscreeper] ~ ~ ~ scoreboard players set @e[c=1,type=armor_stand,tag=bce2] bosstime 1
③execute @e[c=1,type=armor_stand,tag=bce2,scores={bosstime=0}] ~ ~ ~ kill @s

長ったらしいですが許してください()

①ではbce2というタグのアーマースタンドのbosstimeを0に設定します

②ではbce2がexecuteでbosscreeperタグがbce2のbosstimeを1に設定します

③ではbosstimeが0のbce2を殺害します

0に設定(リセット)→bosscreeperタグ経由の実行(条件で加算)→条件不成立(スコア未加算)で殺害(実行)

このように、エンティティを経由したスコア加算を使用することでエンティティの検知をできます。

ここでコマンドブロックの仕様についての説明を入れていきます。

 

基本として、1秒に生じるtickは20tickなので、1s=20tick 反復コマンドブロックは毎秒20回繰り返していることになります。

①から③だけが入ったfunctionを反復で実行してみます。

①実行→(0tick)→②→0tick→③

↑←←←←←←1tick←←←←↓

 functionの中では遅延は発生しません。ですがfunctionの実行が終了した後次回function最初の①を実行するまでには1tickの遅延が発生します。

反復コマンドブロックは毎秒20回/20tick分実行するといいました。つまり、0.05秒の遅延が発生するのです。

何が言いたいかというとこの一括処理(見地から実行まで)をほぼゼロ遅延で行う作業を毎秒20回行うため、RSコンパレータより高精度かつ高速で実行できるのです。この検知方法はfunctionを使わずとも有益だと思います。

ちなみに、コマンドブロックの仕様として

execute @e[type=armor_stand] ~ ~ ~ tp @s ^ ^ ^0.2 facing @p

を反復で実行したとき1秒に移動する距離は

0.2block×20tick=4block/s

となります。これを活用することでエンティティの移動にも活用していくことができます。

 〇コマンドの実行順序!!!―

 いよいよ最終章です。繊細な部分としてコマンドの実行順序が大きくかかわってきます。

ややこしい部分ですが、これを見てみてください。関数ファイルの中味です。

scoreboard players add @p score 1

execute @p ~ ~ ~ execute @s[scores={score=1..5}] ~ ~ ~ say *

 そしてもう一つ

execute @p ~ ~ ~ execute @s[scores={score=1..5}] ~ ~ ~ say *

scoreboard players add @p score 1

 2つの順番が違うだけですが、これを反復で実行してみます。

1回目

上のコマンドはスコアが1加算された後、score=1..5に引っかかっているのでsayコマンドは実行されます。

対して下のコマンドはスコアが加算される前に1..5を指定しているのでスコアを持っていない現在は実行されません。

5回目

上のコマンドはスコア5に1加算されて6になるのでsayコマンドは実行されません。

対して下のコマンドはスコア5でsayコマンドが実行されたあとスコアが加算されます。

 

このように順番がずれるだけで周期単位でずれることがあるのです、この場合反復なら0.05秒の遅延なので大差ないかもしれませんが、インパルスならかなり変わってくると思います。このように実行手順はプログラミングにも共通して重要なのです。

 

加算して一定以上条件でキルする、一定以上条件でキルして加算する、この場合はかなりの差になると思います。色々なパターンがあるので気を付けてみてみてください。

 〇最後に―

最後辺りは少し関数ファイルから遠ざかりましたが、functionについて、導入方法、長所短所とハイブリッド、条件回避、エンティティ完全デジタル検知、周期と遅延について自分の知っている範囲で説明しました。

Minecraftのこういう部分の説明をしているサイトは非常に少ないので、少しでも役に泣てたならばと思います。でも、難しくてコマンドにもあまり慣れていない人には参考にならなかったかも...?

まぁ、ほぼ自己満なんで()

全部読んで理解できた人はプログラマーとしてそれ関連に本当に興味を抱いてる人なんじゃないかな。頑張って。

それでは、今回は3時間くらいブログを書いてた気がするがとりあえずここまでで。

コメントいただけると幸いです

ぐっばい☆