scoreboardコマンドを駆使したRPG風のレベルシステム【マイクラ】

scoreboardコマンドを駆使したRPG風のレベルシステム【マイクラ】

この記事では、Minecraft Java Edition(バージョン1.20.1)の情報をもとに執筆しています。
そのほかのバージョンや機種などでの動作は保証できません。

本記事の内容
  • scoreboardコマンドを駆使してRPG風のレベルシステムを作る

こんにちは!
マインクラフターのなつめ(@natsume_717b)です。

なつめ

2016年3月からマイクラをプレイしています!
最近はコマンドやデータパックなどの技術的なものを勉強しています。

この記事では、RPGゲームなどのように一定の経験値を得ることでレベルアップする仕組みを解説していきます。

レベルが上がっていくごとに必要な経験値が増える仕組みも再現できましたので、ぜひ参考にしていただけると幸いです。

というわけで、さっそく見ていきましょう!

scoreboardコマンドを駆使してRPG風のレベルシステムを作る

マイクラで経験値のシステムを作ろうとする場合、scoreboardコマンドを扱う必要があります。
また、レベルが上がっていくごとに必要な経験値数を上げたい場合には、単純な計算方法ではいけません。

ということで、以前解説したステータスを作る仕組みを利用しつつ、経験値システムを作っていきます。

どのような計算をするのか

まずは、どのくらいの経験値でレベルアップしていくのかを決めておきます。

具体的には以下の通り。

  • レベルは1から120
  • 経験値はレベル1時点で10必要、レベル120時点で300000溜めることでレベルアップする状態
    (最大レベルを120と設定しますが、実際には121以降のレベルにも上がってしまします。なので、レベルの上限で止めるには別のコマンドが必要です)

というわけで、以下の数式を利用します。
先述したように【RPG風】レベルに応じてステータスを上昇させるコマンド【マイクラ】で使用したものを利用します。

これに具体的に数字を当てはめると

となります。

p乗に関しては、p=1として計算しています。
pの値を変更することで、レベルアップに必要な経験値の伸び率が変更可能です。

スコアボードを作成していく

というわけで、計算ができるようにスコアボードを作成、決まった値が入るものに関しては値を投入していきます。

特定の値が入るスコアボードの作成

まずは特定の値を投入させる5つのスコアボードから。
今回の場合は、特定の値として、1、10、119、1000、299990の5つを投入していきます。

先ほどの式には存在していない1000ですが、これはマイクラで計算する場合に必要となるので作成しておきます。

以下は1を投入するスコアボードの作成例です。

/scoreboard objectives add Sample_1 dummy
/scoreboard players set @a Sample_1 1

これと同じように、残り4つのスコアボードも作成します。

残りの4つはそれぞれ、Sample_10、Sample_119、Sample_1000、Sample_299990という名前で作成しています。

値が変動するスコアボードの作成

次はスコアボードの値が変動するスコアボードの作成です。
これは4種類あります。

現在のレベルを示すスコアボード、レベルをあげるかどうかの判断に用いるスコアボード、現在の経験値を示すスコアボード、経験値をカウントするスコアボードの作成です。

これらは必要な時にコマンドで値を投入していきますので、その時々で異なる数字が入ります。

また、それぞれをSample_Level、levelup_check、exp_now、count_expとします。

実際のコマンド

それでは、必要なスコアボードの用意ができたので実際に計算していきます。

大まかな順序としては、

  • 現在の経験値がレベルアップに必要な経験値分を超えているかどうかを判定
  • 上回っているならば、計算式にあたるコマンドとその他必要なコマンドを実行

となります。

現在の経験値がレベルアップに必要な経験値分を超えているかどうかを判定

というわけで、まずは経験値の判定からです。
常に判定する必要があるため、常時実行しておきましょう。

execute if score @p count_exp <= @p exp_now store result score @p levelup_check run scoreboard players operation @p count_exp > @p exp_now

ややこしいですが、ポイントは3つ。
実行する条件、コマンドの結果を保存、実行されるコマンドの3点ですね。

1.if score @p count_exp <= @p exp_now

if score @p count_exp <= @p exp_nowによって、count_expよりもexp_nowが大きい場合にコマンドが実行されます。

このスコアボードの比較を言語化すると、現在の経験値が必要な経験値分よりも大きい時に実行しますよと言っている指示です。
つまり、レベルアップするだけの経験値を得ている状態ならば、コマンドを実行するということになります。

2.store result score @p levelup_check

store result score @p levelup_checkによって、コマンドの実行結果をスコアボード「levelup_check」に保存します。
今回はこの部分で、計算式のコマンド群を実行するかどうかを判別しています。

3.scoreboard players operation @p count_exp > @p exp_now

最後にscoreboard players operation @p count_exp > @p exp_nowということで、exp_nowがcount_expを超えた場合に、count_expの値をexp_nowに合わせるというもの。
このコマンド自体はそこまで重要度が高くありませんが、先ほどのstore resultで反映される値が決まる部分でもあります。

実行される条件と合わせて確実に1以上の値を示すこととなり、それによって計算式のコマンド群の実行を行うか否かを判断することができます。

上回っているならば、計算式にあたるコマンドとその他必要なコマンドを実行

先ほどのコマンドのstore resultによってlevelup_checkが1以上になったら、functionコマンドを実行するようにします。
(実行されるfunctionのファイル名はテキトーです。functionを起動するコマンドブロックはリピートで常時実行しておきましょう)

execute as @a[scores={levelup_check=1..}] if entity @s run function status:xxxx

mcfunctionの内容は以下の通り。

#levelup_checkの処理
execute as @a[scores={levelup_check=1..}] run scoreboard players set @s levelup_check 0

#レベルを計算用のものにコピーする
scoreboard players operation @p Copy_level = @p Sample_Level

#コピーしたレベルをもとに計算
scoreboard players operation @p Copy_level -= @p Sample_1
scoreboard players operation @p Copy_level *= @p Sample_1000
scoreboard players operation @p Copy_level /= @p Sample_119
scoreboard players operation @p Copy_level *= @p Sample_299990
scoreboard players operation @p Copy_level /= @p Sample_1000
scoreboard players operation @p Copy_level += @p Sample_10

#次のレベルアップに必要な経験値を更新
scoreboard players operation @p count_exp = @p Copy_level

#現在のレベルを上げる
scoreboard players add @p Sample_Level 1

#Copy_levelをリセット
scoreboard players set @p Copy_level 0

どういったコマンドであるかはコメント(#が文頭にある部分)の通りです。

また、1000という値を入れたスコアボードですが、割り算をする際に答えが0になるのを防ぐために使用しています。
1000を掛けることで答えが0になるのを防ぎ、その後1000で割ることで帳尻を合わせています。

そのほかの注意点として、今回は分かりやすくターゲットセレクターを@pにしてしまいましたが、1行目のようにexecuteコマンドでas @aを始めに指示しつつ@sを使った方がマルチにも対応でき、おすすめです。

実用するには

さて、ほとんどの準備はできました。
あとはレベルと必要経験値をレベル1時点に合わせればOKです。

/scoreboard players set @a count_exp 10
/scoreboard players set @a Sample_Level 1

これでレベル1の状態に出来ました。

レベル1の状態に出来たのならば、exp_nowに値を投入していくことで経験値を溜められます。
そして、必要経験値(count_exp)を超える値がexp_nowに確認できると、値の比較を監視しているコマンドによってレベルアップに必要なコマンド群が実行されます。

以下はexp_nowを20にするコマンドです。
レベル1の状態では10の経験値を溜めるとレベルアップするので、下記のコマンドを実行すればレベルアップの処理がされます。

/scoreboard players set @p exp_now 20

今回のコマンドでは、複数回分のレベルアップをするほど大量の経験値を1度に手に入れても、仕組み上1回だけしかレベルアップしないようになっています。

レベルアップに必要な経験値はp乗部分を1にしてしまっているため、綺麗な伸びをしません。
今回はあくまでもやり方を紹介、解説しているだけなので、各自p乗部分の値を様々試してみる方が良いです。

まとめ

というわけで、今回のまとめです。

ポイント
  • 値の比較を行って、レベルアップするかどうかの判断をしています。
  • レベルアップに必要な経験値は、複雑な計算式で割り出すことでRPGっぽくしています。

この記事は以上になります。

  • 【まとめ】functionコマンドの基本から応用【マイクラ】
  • 【まとめ】カスタムストラクチャーの実装・カスタム方法【マイクラ】