見出し画像

[ROBLOX]ゲーム開発④(アーキテクチャ)

前回まででスタートからゴールまでのシーンが完成したので、

今回はステージクリアの処理を追加してみようと思たのだが、そのためにはスクリプトを利用することになる。いろいろ見様見真似で組んでゆけば動くものは作れそうだが、Robloxのスクリプトに纏わる仕組みやルールを少し掘り下げて理解してからのほうが良い気がしたので、今回は色々調べてみた


スクリプトについて

Robloxでゲームのルールや特殊な挙動を制御するためにはスクリプトを組む必要がある。使われる言語はLUAというスクリプト言語だ。小さくて軽くてシンプルなのが売りで、昔からゲームの組み込みスクリプトとしてよく利用されている。なにかしか他の言語を習得している人なら1時間ぐらい勉強すれば一通り理解できてしまうほどシンプルだ。

-- Hello Worldを出力する関数を定義
function printHelloWorld()
    print("Hello World")
end

-- 関数を呼び出す
printHelloWorld()

LUAは一見、昔ながらの手続き型言語のように見えるのだが、データ配列を記述するためのテーブルが非常に汎用性が高くストラクチャやクラスのような使い方ができ、オブジェクト指向なプログラミングも可能だ

-- Personというテーブル(クラスのようなもの)を定義
local Person = {}
Person.__index = Person  -- Personテーブル自身をメタテーブルとして使用

function Person:new(name, age)  -- コンストラクタの定義
    local obj = setmetatable({}, Person)
    obj.name = name
    obj.age = age
    return obj
end

function Person:speak()  -- Personクラスのメソッド定義
    print("Hello, my name is " .. self.name .. " and I am " .. self.age .. " years old.")
end

-- Personのインスタンスを作成
local person1 = Person:new("John Doe", 30)

-- メソッドを呼び出す
person1:speak()  -- 出力: Hello, my name is John Doe and I am 30 years old.

また、LUAはラムダ式もサポートしており、柔軟な言語仕様と合わせることでHaskellのような関数型プログラミングも再現できてしまう

コルーチン

LUAのもう一つの便利な機能としてコールーチン(軽量スレッド)がある
これにより非同期処理や並行処理が簡単に書けてしまう

-- コルーチンの定義
function counter(max)
    for i = 1, max do
        coroutine.yield(i)  -- 現在のカウントを返し、一時停止
    end
end

-- コルーチンの作成
local co = coroutine.create(counter)

-- コルーチンの実行と出力
for i = 1, 5 do
    local status, value = coroutine.resume(co, 5)
    if status then
        print("Count:", value)
    else
        print("Coroutine finished")
    end
end

シンプルながらも柔軟性が高く広範囲な用途にうまくマッチすることができる。さすが30年現役であり続ける言語だけある

デメリット

ただ、LUAはデータ型が動的だったり、デフォルトでグローバルスコープを持っていたりなど、どんな書き方をしてもそれなりに動いてしまうので、バグが発見しにくかったり、未熟なプログラマーが書くと凄まじいコードができあがって、誰も(本人さえも)解読不能に陥ったりする
また、他の言語のように標準関数が充実していないので、普通なら関数をコールすれば済むだけの処理も自前で用意しなければいけないことも起きる
スレッドは疑似スレッドでマルチコアを使うわけではないので、並列処理で時間が短くなるわけでもない

アーキテクチャについて

Robloxは一般的なオンラインゲームと同様にクライアントサーバーモデルで動いている
ゲーム空間の管理はすべてサーバー側で行いクライアントは定期的にサーバーと通信し更新されたゲーム情報を取得して最新の状態を表示する
また、クライアント側で何かしか状態を変更したい場合はサーバーにアップデートのリクエストを出す
パソコン本体で例えれば、サーバーがCPUやメモリでクライアントはモニタやキーボードなどのI/O機器の役割を行うモデルだ

Robloxのスクリプトを組む際はサーバーサイドとクライアントサイドどちらで実行するべき処理なのかある程度理解している必要がある
そして、どう記述すればどのタイミングでサーバー又はクライアントがスクリプトを実行するかも理解しておく必要がある
ここはRobloxでゲームを開発するための難しいポイントだと思う
しかし従来のゲーム開発であれば、複数の専門のエンジニアが分担して担っていた作業を全て一人でも開発できるように設計されているのはRobloxのすごいところだ

サーバーとクライアントの役割分担

概略としては以下のような役割分担になる

クライアント側で実行する処理

  • ユーザーインターフェース
    プレイヤーのHUD、メニュー、ダイアログボックスなどのインタラクティブなUI要素の操作

  • クライアント固有の視覚効果
    プレイヤー固有のエフェクトやアニメーション(例: 爆発、光の効果、サウンド再生)

  • プレイヤー入力の処理
    マウスクリックやキーボード入力といった直接的なプレイヤーの操作

  • カメラコントロール
    プレイヤーのカメラの動きや視点の変更

サーバー側で実行する処理

  • ゲームの主要ロジック
    スコアの計算、ゲームの状態管理、勝敗判定など、ゲーム全体に影響する中核的な処理

  • マルチプレイヤー間のデータ同期
    プレイヤー間で共有されるデータ(位置情報、スコア、ゲーム内イベント)の同期

  • セキュリティ対策
    チートやハックから保護するために重要なデータ(プレイヤーの進捗、インベントリ、通貨)の処理

サーバー/クライアントを使い分ける方法

RobloxのスクリプトにはScriptLocalScriptの2種類ある
前者がサーバーで実行されるスクリプトで後者がクライアントで実行されるスクリプトだ

また、スクリプトの役割と起動されるタイミングに応じて特別なフォルダが用意されている

ServerScriptService
サーバースクリプトを置く場所
厳重なアクセス制限があり、クライアントからはアクセスできない。セキュリティが必要なスクリプトや、クライアントに知られたくない重要なゲームロジック(例:スコア計算、ゲーム進行管理など)を配置するのに適した場所
主にゲーム全体の管理、サーバーサイドのメインロジック、プレイヤー間のインタラクションを制御するためのスクリプトなんかはここに置く

ServerStorage
サーバーからしかアクセスできないストレージ
セキュリティが必要なゲーム進行に必須となる重要なデータを保存する

ReplicatedStorage
データやリソースをサーバーとクライアント間で共有するための専用の場所で、ゲームのロジックやデータの同期に使用する
クライアントとサーバーの両方からアクセス可能で、オブジェクトは物理的なインタラクションのためではなく、データの共有やゲーム管理のために使用する

StarterPlayerScripts

プレイヤーがゲームに参加するときに自動的にそのプレイヤーのクライアントにロードされるローカルスクリプトを格納する場所
カメラ設定、ユーザーインターフェース、キーボードやマウスの入力処理など、プレイヤーに対して共通の機能を提供する

プレイヤーがゲームに入るたびにロードされる
プレイヤーがリスポーンしてもリセットされない

StarterCharacterScripts

StarterPlayerScriptsと似ているが、プレイヤーのキャラクター(アバター)が生成されるたびに、そのキャラクターに関連するローカルスクリプトを格納する場所
キャラクター固有の動作や能力、たとえば特定のジャンプ力、スピードの変更、または特殊なアクションをキャラクターに付与する目的で使われる

プレイヤーのキャラクターが毎回生成される際にロードされる
プレイヤーがリスポーンするたびにリセットされる

StarterGui
プレイヤーのGUIに関するローカルスクリプトを配置する。新しいプレイヤーがゲームに参加するかリスポーンするたびにロードされる

StarterPack
ゲームに参加した全てのプレイヤーに提供されるツールや武器などのアイテムがここに送られる。ここにローカルスクリプトを配置すると、アイテムがプレイヤーによって装備されたときに実行される

ReplicatedFirst
ゲームの他の部分よりも先にクライアントにロードされるスクリプトやアセットが配置される。主に初期ロード画面や初期設定に関するローカルスクリプトを配置する

Workspaceについて

Workspaceにはシーンを構築するメッシュやエフェクトなど様々なオブジェクトが配置されている
これらはすべてサーバーサイドで管理されており、操作にはサーバースクリプトを使うが、データを更新するとそれらの修正はリアルタイムでクライアントに同期される

敵を動かすだけにとどまらず、地面に穴をあけたり、家を建てたり、シーン全体を編集できる柔軟性の高さがRoblox最大の魅力だ

動的な世界を構築できるので、アイデアの幅がとても広がる

次回からは具体的なスクリプト制作を進めてゆこうと思う


いいなと思ったら応援しよう!

この記事が参加している募集