見出し画像

ゲームサーバー運用から生まれる魅力は無限大!

こんこよ~!🧪
カバー株式会社 技術開発本部 基盤チームのKです。
カバー株式会社では、ホロライブプロダクション所属タレントの配信予定が一目で分かる「ホロジュール」や、YouTube等の様々なサービスに関わるデータ収集や分析を行える社内向けツールなどを開発しています。私はその開発チームのマネージャーをしています。

私のチームでは、先に挙げたプロダクト以外にも様々なプロダクトやサービスの開発、運用を幅広く担当していますが、その中でも少し変わったものがあります。
それはMinecraft、Rust、ARKなどのゲームサーバー運用です。今回はこのゲームサーバー運用について、特にMinecraftに関する話題を中心に紹介させていただきます。


■ Minecraftの魅力

「世界で最も売れたゲーム」としても有名なMinecraft。未開の地を求めて広大な世界を冒険したり、クリエイティブを自由に発揮して建築をしたり、Minecraftが持つ魅力は種々様々あります。
そんなMinecraftについて、ホロライブプロダクションにおける配信コンテンツとして触れるときに皆さんはどんな魅力を感じていますでしょうか。

私が考える最大の魅力は「コミュニケーションツールとしての可能性」です。

先述したMinecraftが持つ魅力を前提に、タレントとタレントが一緒に遊ぶ場合はもちろん、それを視聴して下さるファンの皆さんとの間でもたくさんのコミュニケーションが生まれます。
事前に予定を合わせて行われるコラボ配信もあれば、その場でばったり出くわして始まるやり取りもあります。

コミュニケーションの手段も通話、テキストチャット、身振り手振りと様々で、言語の壁を越えて交流することも可能です。必ずしもやり取りがリアルタイムである必要もなく、看板に残されたメッセージや、知らない間に増えていた新しい建築物を巡って新たな物語が生まれることも多いです。
これらはMinecraftに限らず、RustやARKなどのいわゆるサンドボックス、サバイバル系のゲームに共通する醍醐味とも言えるでしょう。

また、いわゆる「雑談」とも相性が良く、最近の出来事や裏話を聞いたり、作業のお供や睡眠導入さながらにまったりとした時間を心地よいトークと共に過ごせるのも魅力のひとつですよね。
新しくキノコが生えてくるのを見守ったり、突然変異のウーパールーパーが生まれるのを待ち望んでいたら、気付くとすっかり寝落ちしていた…という経験が皆さんにもあるのではないでしょうか。

気付くとあっという間に数時間経っていることも…
【Minecraft】スカイブロック番外編:きのこを見守る【Skyblock3】(画像左)
【Minecraft】闇市店主、激激激レア青ウーパーチャレンジ!!【天音かなた/ホロライブ】(画像右)

通常の配信以外にも、Minecraftを題材にした大型企画が開催されることもあります。
これまでにも大運動会や夏祭り、TNTキャノン選手権など様々な企画が開催されており、今年に入ってからもholoX主催のドロケイや、ホロライブインドネシア主催のholoID Cupなども記憶に新しいです。
現実で行われるイベントさながらの盛り上がりや、笑いあり涙ありの「青春」さえも感じられたような気がしています。

2023年も様々な大型企画が開催されています
#ホロドロケイ 】holoXからの挑戦状‼ホロライブみんなで鬼ごっこ - 本配信【 Minecraft/ホロライブ 】(画像左)
【Minecraft】今年もやります「ホロ鯖夏祭り2023」に関してのご連絡です Organized by UsaKen【獅白ぼたん/ホロライブ】(画像右)
【企画発表】いくぞ!#ホロライブ大運動会2023 企画説明会 🏳 🌎 hololive Sports festival 2023【ホロライブ/さくらみこ】

また、本記事の執筆時点では、2023年もマイクラ大運動会が開催されることが発表されたばかりです。今年はどんなドラマが生まれるのか、是非本番までのお祭り感を楽しんで頂ければ幸いです。

このように、ゲームそのものが持つ魅力を起点に様々なコミュニケーションが生まれ、新たなコンテンツやコンテクストを生成するツールとしても無限大の可能性を秘めていると感じます。

■ ゲームサーバー運用とは

ゲームサーバー運用としてどのようなことをしているかについても触れていきます。
タレントの皆さんが遊んでいるMinecraftのサーバーは、Linuxサーバー上で稼働しています。
サーバーソフトウェアについては、以前はSpigotMCというプラグインサーバーを使用していました。しかし、主にレッドストーン回路やトロッコに関わる動作が不安定になってしまうことが多くなったため、現在はPaperMCというプラグインサーバーが使用されています。

Linuxに関する基本的な理解があれば、サーバーを稼働させること自体に高度な専門知識が求められるわけではありません。しかし、何らかの問題が発生した場合の解決には、エンジニア領域としてのサーバー知識以外にもMinecraft特有の知識や発想が求められる場合もあります。

・ 地下に巣くう大量ゾンビの謎

サーバー内にたくさんの建築物が立てられ発展していく中で、特定条件下で極端にゲーム動作が重くなったり、ラグが頻発してしまうなどの問題が起きてしまうことがあります。

重くなる要因のひとつとしてワールド内に存在するオブジェクトの増加が挙げられますが、ある日の調査で地下深くに数百体単位の大量のゾンビが密集しており、その周辺が異常に重くなっていることに気付きました。小さな空間があればどこにでもスポーンしてしまうゾンビですが、近くにプレイヤーがいない場合は自動でデスポーン(消滅)する仕様になっているので、通常ここまで密集することはないはずです。

しかし、調べていくうちに落ちているアイテムを拾ったゾンビはデスポーンしなくなる、という仕様であることが分かりました。では地下深くのゾンビ達が何を拾っていたかというと、なんとニワトリが産んだ卵でした。

ニワトリを含む友好的なMobは基本的にデスポーンしないので、うっかり地下に迷い込んだ1匹のニワトリが消滅することのないゾンビを日々増やし続けていた…という何とも厄介なエピソードです。

■ 競技ギミックの実装

#ホロライブ運動会2022 】第三回‼秋のマイクラホロライブ大運動会🏳 - 主催者視点【 Minecraft/ホロライブ 】

2022年に開催された大運動会企画では、競技ギミックの一部について実装のお手伝いをさせていただける機会がありました。それまでも簡易的な実装の経験はありましたが、凝ったギミックの実装はもちろん初めてということで、私自身勉強しながらチャレンジの気持ちで臨みました。

Minecraftでギミック類を実装する方法はいくつかあるのですが、このときはデータパックと呼ばれる仕組みを用いて実装しました。
Minecraftでは様々なコマンドが用意されており、任意のアイテムをプレイヤーに付与するgiveコマンドや、プレイヤーを任意の場所にテレポートさせるtpコマンドなどがあります。
このコマンドを自由に組み合わせて関数(function)として定義することで、複数のコマンドを一纏めにすることが出来ます。定義した関数はfunctionコマンドで呼び出すことが出来ます。

また、Minecraftの世界では1秒間に20回の更新処理のループが走っており、1回あたりのループをtickと呼びます。ここで、先ほどの関数や任意のコマンドを1tick毎に呼び出すよう定義することも出来ます。if文のような条件分岐を書くことも出来るので「プレイヤーが指定されたブロックの上に立ったら、治癒のポーションを付与して30ブロック離れた場所にテレポートさせる」といったことが表現できるようになります。

このようにデータパックの仕組みを用いると、コマンドや条件を組み合わせて、通常のMinecraftのルールとは異なるギミックを実装することが出来るようになります。
ただし、逆に言うと、用意されているコマンドや条件以外のことを表現することは出来ない(あるいは、工夫が必要)ということにもなります。

・ リレーの実装例

リレーの競技ギミックを例に考えてみます。まずは、リレー競技の基本的なルールを定義してみます。

  1. 第一走者がスタートし、決められたコースを1周走る。

  2. 1周走ったら、次の走者にバトンを渡す。

  3. バトンを渡された走者は、同様に決められたコースを1周走る。

  4. 2~3をチームの人数分繰り返し、最後の走者が1周走り切ったらゴール。

このような流れでしょうか。では、このルールを満たすにはどのように実装すれば良いでしょうか。

・ 決められたコースを1周走る

まずはこの部分です。文章で書くと当たり前すぎる内容なのですが、これを正しく判定しようとすると意外と難しいです。まず、コース内のコーナー付近を中心にいくつかのチェックポイントを定義することにしました。「プレイヤーが指定した範囲内の座標に存在するか」をチェックすることが出来るのでこの判定に使います。

定義が細かいほど判定の精度は上がりますが、今回は5箇所としました

さらに、Minecraftにはスコアボード(scoreboard)という仕組みがあり、変数のようなものを持たせることが出来ます。これらを組み合わせて、以下のような判定をするように関数を定義し、競技中毎tick実行するようにします。

  • 現在の走者がチェックポイント1の範囲内に存在しており、スコアボードの値が0のとき、スコアボードの値を1に更新する。

  • 現在の走者がチェックポイント2の範囲内に存在しており、スコアボードの値が1のとき、スコアボードの値を2に更新する。

  • 現在の走者がチェックポイント5の範囲内に存在しており、スコアボードの値が4のとき、1周走り切ってゴールしたとみなす。

他のチェックポイントも同じ要領で判定します

このようにチェックポイントを順番に通過しているかを判定することで、決められたコースを正しく1周走ったことを判定することが出来そうです。

・ 次の走者にバトンを渡す

次にこの部分です。なお、バトンを受け渡す動作としては、次の走者を攻撃(パンチ)することで行われるようにします。先ほど出てきたスコアボードですが、Minecraft内でプレイヤーが行った行動などによって自動的にスコアを変動させるように定義することが出来ます。
例えば、プレイヤーがダメージを受けた時や、逆にダメージを与えた時などをスコア変動の条件に出来るので、受け渡す動作はこの値の変動を見て判定することにします。

# ダメージを受けるとスコアが変動
scoreboard objectives add damage_dealt minecraft.custom:minecraft.damage_dealt


# ダメージを与えるとスコアが変動
scoreboard objectives add damage_taken minecraft.custom:minecraft.damage_taken

ただし、これだけでは正しく判定することが出来ません。なぜなら、プレイヤーがダメージを受けたことはスコアの変動から分かりますが、誰から(あるいはどのように)ダメージを受けたかまでは分からないからです。例えば、受け渡し動作でパンチされた場合も、高所からの落下でダメージを受けた場合も、同じようにスコアが変動します。

また、パンチされた場合も、パンチしたのが同じチームのメンバーかどうかも分からないですし、同じチームであったとしても現在の走者かどうかも分かりません。
とはいえ、パンチされたことを条件にする場合、このスコア変動を利用する方法しか思い付かなかったので、さらに判定条件を増やして何とか実装を考えてみます。

Minecraftにはタグ(tag)という仕組みがあり、プレイヤーに自由にタグを設定することが出来ます。「赤組」「リレー参加者」など、設定出来る内容や個数も自由です。
まずは、赤組に所属するプレイヤーが5人いると仮定して、全員に「赤組」のタグを設定しておきます。

続いて、リレー競技に参加するプレイヤーが3人だった場合、その3人にだけ「リレー参加者」のタグを設定しておきます。さらに、リレーがスタートしたら、現在の走者は各チーム1人ずつのはずなので、リレー参加者のうちスタート時点でスタート付近に立っていたプレイヤーに「現在の走者」のタグを設定しておきましょう。

  • 「赤組」:A、B、C、D、E

  • 「リレー参加者」:A、C、D

  • 「現在の走者」:C

タグの状況をまとめると上記のようになっているはずです。
現在コースを走っているのはプレイヤーCで、ゴール付近でバトンタッチを待っているのはプレイヤーAかプレイヤーDのはずです。

さらに、バトンを受け渡す動作が正しく行われる時、ダメージを与えた時のスコア(これをdamage_takenとします)が変動するのはプレイヤーCのはずです。同様に、ダメージを受けた時のスコア(これをdamage_dealtとします)が変動するのもプレイヤーAかプレイヤーDのはずです。
また、バトンタッチは必ずゴール付近で行われるはずなので、先ほどと同じようにチェックポイントを定義しておきましょう。ここまで整理出来るとバトンタッチの判定が出来そうです。

バトンタッチはゴールライン上で行われるとは限らないため、少し広めに定義しておきます
  • 条件(1) 「赤組」「リレー参加者」であり、「現在の走者」であり、スコアボードdamage_takenの値が変動しており、チェックポイントの範囲内に存在しているプレイヤー

  • 条件(2) 「赤組」「リレー参加者」であり、「現在の走者」ではなく、スコアボードdamage_dealtの値が変動しており、チェックポイントの範囲内に存在しているプレイヤー

少し複雑ですが、上記の条件(1)、(2)の両方を同時に満たすプレイヤーがそれぞれ1人ずつの場合に、赤組のバトンタッチが成立したと判定することが出来そうです。
条件(1)を満たすプレイヤーの「現在の走者」タグを削除し、代わりに条件(2)を満たすプレイヤーに「現在の走者」タグを設定すれば、2周目以降の判定も同じように行うことが出来ます。

・ リレー実装まとめ

さて、お気づきの方もいるかもしれませんが、上記の判定では十分に正確であるとは言えない部分も存在します。使用出来るコマンドや条件の限界だったりする部分もありますが、わざと逸脱した行動を取らない限りは進行上問題ないだろうと意図的に妥協を選択した部分もあります。
また、どうしても力技のような実装になってしまうことも多く、改めて振り返ってみてももっと良い方法を見つけられなかったのかなと考える部分も多々ありました。

一方で、普段行っているようなサーバーサイドのプログラミングと違って、限られた手札を使ってパズルを解いているような新鮮な気持ちになったりもしています。これとこれを組み合わせたらこういうことも表現出来るのではないか?と、新しい発想を生み出すトレーニングとしても役に立った経験でした。

Minecraftとプログラミングに興味がある方は、例に挙げたリレー競技をよりスマートに実装する方法を考えたり、別の競技ギミックを実装してみたり、是非色々とチャレンジしてみてください!

■ まとめ

今回は、特にMinecraftに関する話題を中心に、コンテンツとしての魅力やゲームサーバー運用についての一部を紹介させていただきました。

ゲームサーバー運用に関しては、私のチームとして何か価値を届けようというわけではなく、魅力あるゲームであることを大前提に、普段から盛り上げて遊んで下さるタレントの皆さんが主役です。
また、タレントの皆さんはもちろん、遊んでいる姿を見て一緒に楽しんで下さるファンの方があってこそ、コンテンツとしても最大限の魅力を発揮します。これからも是非お楽しみいただければ幸いです。
最後までご覧いただきありがとうございました。