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)
この流れは次のようになっています。
require()でTextUtilのModuleScriptを読む- ModuleScriptの
return TextUtilを受け取る 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()を使った設計にするか
といった話につなげていくと、より実践的に使いやすくなります。

