Robloxスクリプト入門|ModuleScriptの基本

Scriptは少し書けるようになってきたけれど、ModuleScriptはちょっと分かりにくいということはありませんか。

「Scriptと何が違うのか」
「どこに置けばいいのか」
require() って何をしているのか」

このあたりがぼんやりしたままだと、サンプルを写しても手応えが出にくいかと思います。
ModuleScriptは難しい仕組みというより、同じ処理を何度も書かないための部品として覚えると理解しやすいです。

この記事では、ModuleScriptの作り方から使い方まで順番に整理します。

目次

ModuleScriptとは何か

まずModuleScriptとは、ほかのScriptから読み込んで使うためのスクリプトです。

通常のScriptは、それ自体が動いて処理を進めます。
一方でModuleScriptは、単体で何かを進めるというより、必要なときに require() で呼び出して使う部品として使います。

たとえば、ゲームの中でこんな処理があるとします。

  • ダメージ計算をまとめる
  • アイテム名の一覧を持っておく

こうした「何か所でも使いたい処理」は、ModuleScriptにまとめると整理しやすくなります。

ModuleScriptを使うと何が楽になるのか

ModuleScriptをまだ使っていないと、同じような関数を別々のScriptに何回も書きがちです。

たとえば、スコアを文字列にする処理を2か所で使うとします。

local function formatScore(score)
    return tostring(score) .. " pts"
end

この関数を、あちこちのScriptに毎回書いていくと、

  • 修正が出たときに全部直す必要がある
  • 同じ名前でも中身が少しずつ違ってくる
  • どれが正しい版か分かりにくくなる

という状態になりやすいです。

そこでModuleScriptにまとめておけば、
必要な側はそれを呼ぶだけで済みます。

「同じものを1か所にまとめておける」
これが、最初に感じやすいModuleScriptの利点です。

ModuleScriptの基本形を見ておく

いちばん基本的な形は、テーブルに関数を入れて返す書き方です。

local TextUtil = {}

function TextUtil.FormatScore(score: number): string
    return tostring(score) .. " pts"
end

return TextUtil

このModuleScriptは TextUtil というテーブルを返しています。
その中に FormatScore() という関数が入っています。

見るポイントは2つです。

最後に return がある

ModuleScriptは、最後に値を返して終わります。
この返した値を、ほかのScriptが require() で受け取って使います。

関数をまとめて返している

1つの関数だけでも動きますが、
今後増やしやすいので、最初はテーブルでまとめて返す形が使いやすいです。

require() とは何か

ModuleScriptを使うときに避けて通れないのが require() です。

これは、ざっくり言うとModuleScriptを読み込んで、そこで返された値を受け取る処理です。

たとえば、さきほどの TextUtil を使う側はこう書けます。

local TextUtil = require(game.ServerScriptService.TextUtil)

local label = TextUtil.FormatScore(250)
print(label)

この流れは次のようになっています。

  1. require()TextUtil のModuleScriptを読む
  2. ModuleScriptの return TextUtil を受け取る
  3. TextUtil.FormatScore(250) を使えるようになる

ここが分かると、ModuleScriptの見え方がかなり変わります。
require() は「ModuleScriptの中身全部をコピーする」ではなく、「返された値を受け取る」処理です。

実際に1つ作る流れ

ここでは、ModuleScriptを作ってScriptから使うまでの最短の流れをまとめます。

StudioでModuleScriptを作る

Explorerで置きたい場所を選び、+ から ModuleScript を追加します。
名前は分かりやすくしておくのがおすすめです。今回は TextUtil にします。

中身は次のようにします。

local TextUtil = {}

function TextUtil.FormatCoin(amount: number): string
    return tostring(amount) .. " Coins"
end

return TextUtil

まずはこれだけで十分です。

Script側から読み込む

次に、別のScriptで読み込みます。

local TextUtil = require(game.ServerScriptService.TextUtil)

local message = TextUtil.FormatCoin(100)
print(message)

実行すると、100 Coins と出ます。

この時点で、
「ModuleScriptを作る → return する → require() で使う」
という基本の流れがつながります。

どこに置けばいいのか

ここも初心者が迷いやすいところです。

ModuleScriptはどこにでも無造作に置くより、誰が使うものかで場所を考えると整理しやすいです。

サーバー専用なら ServerScriptService

サーバーだけで使うModuleScriptなら、ServerScriptService に置く形が分かりやすいです。

たとえば、

  • 敵の出現管理
  • プレイヤーデータの保存処理
  • サーバーだけで使う計算処理

のようなものです。

サーバーとクライアントの両方で使うなら ReplicatedStorage

両方から参照したい共通モジュールは、ReplicatedStorage に置く形がよく使われます。

たとえば、

  • アイテム定義
  • 共通の便利関数
  • 文字列整形
  • 設定値

のようなものです。

ただし、クライアントから見えて困る情報は置かない方が安心です。
この場合は読み飛ばしてOKですが、データ保存まわりや管理者向けの情報はサーバー側に寄せた方が安全です。

ModuleScriptは何を返せるのか

最初はテーブルを返す形だけ覚えれば十分ですが、
ModuleScriptは返り値を1つ返せます。

いちばん使いやすいのはテーブル

local ItemUtil = {}

function ItemUtil.IsRare(rarity: string): boolean
    return rarity == "Rare"
end

return ItemUtil

これが基本です。

設定値のテーブルを返すこともできる

local GameConfig = {
    MaxLevel = 50,
    DefaultSpeed = 16,
}

return GameConfig

この形なら、設定ファイルのように使えます。

関数1つだけを返すこともできる

local function Double(value: number): number
    return value * 2
end

return Double

ただ、入門段階ではテーブルを返す形の方が読みやすいことが多いです。
あとから関数を足しやすいのも、この形の良いところです。

よくあるつまずきポイント

基本だけのつもりでも、ここで止まりやすいポイントがあります。

return を書き忘れる

ModuleScriptは最後に値を返す前提なので、return を書き忘れると使う側で困ります。

local Test = {}

function Test.Hello()
    print("Hello")
end

このままだと、使う側で期待通りに扱えません。
まずは「最後に返しているか」を確認してみましょう。

require() の書き先を間違える

ModuleScriptそのものに require() を書いて自己参照のような形になると、混乱しやすいです。
require()使う側のScriptやLocalScriptに書く、と覚えておくと整理しやすいです。

ModuleScriptを普通のScriptのように置いて終わる

ModuleScriptは追加しただけでは目的を果たしません。
作ったあとに、どこかから require() して初めて役立つものです。

「作ったのに何も起きない」というときは、呼び出し側がまだないことがよくあります。

ModuleScriptは毎回最初から動くのか

ここは入門の時点でも軽く触れておくと、あとで混乱しにくいです。

ModuleScriptは、同じLuau環境では require() されたときに一度実行され、その返り値が使われます。
そのため、毎回まっさらな状態で再実行される感覚でいると、挙動が分かりにくくなることがあります。

とはいえ、最初のうちは細かく身構えなくて大丈夫です。
まずは、

  • ModuleScriptは部品
  • require() で使う
  • return で渡す

この3つを押さえておけば十分です。

最初の1本として作りやすいModuleScript

何を作ればいいか迷うときは、次のようなものが始めやすいです。

文字列を整えるモジュール

local TextUtil = {}

function TextUtil.FormatLevel(level: number): string
    return "Lv." .. tostring(level)
end

function TextUtil.FormatCoin(amount: number): string
    return tostring(amount) .. " Coins"
end

return TextUtil

設定値をまとめるモジュール

local GameConfig = {
    MaxPlayers = 8,
    DefaultWalkSpeed = 16,
    LobbyWaitTime = 20,
}

return GameConfig

単純な計算をまとめるモジュール

local DamageUtil = {}

function DamageUtil.Calculate(baseDamage: number, multiplier: number): number
    return baseDamage * multiplier
end

return DamageUtil

このあたりは、処理の流れを複雑にしなくても使い道が見えやすいです。
最初の1本としてちょうどいいかと思います。

まとめ

ModuleScriptは、最初に見ると少し構えてしまいやすい機能です。
でも実際には、「何度も使う処理を1か所にまとめるための仕組み」と考えるとかなり入りやすくなります。

今回のポイントを整理すると、次のようになります。

  • ModuleScriptはほかのScriptから使う部品
  • require() で読み込んで使う
  • 最後に return で値を返す
  • まずはテーブルを返す形で覚えると分かりやすい
  • 共通で使う関数や設定値の整理に向いている

最初は難しく見えても、
1つ作って、1回 require() して、関数を呼ぶ
ここまでできれば、ModuleScriptの基本はかなりつかめています。

次の段階では、

  • ModuleScriptに状態を持たせるかどうか
  • require() の挙動をどう考えるか
  • new() を使った設計にするか

といった話につなげていくと、より実践的に使いやすくなります。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

アラフォー会社員で、スマホ/ゲーム/AIが好き。

個人開発・ゲーム開発・ブログ運営・レビュー記事を
実体験を基にできるだけわかりやすく投稿していきます。

目次