第4章:MODの作り方
MOD開発の基礎知識
Garry’s ModのMOD開発は、主にLuaスクリプト言語を使用して行われます。Luaは比較的習得しやすい言語でありながら、Garry’s Modの強力なAPIと組み合わせることで、非常に高度な機能を実現できます。
必要なツールと環境
- テキストエディタ:
- Visual Studio Code (VSCode):最も推奨されるエディタ。豊富な拡張機能(GLua Highlighting、LuaLSなど)により開発効率が大幅に向上。
- Sublime Text:軽量で高速なエディタ。GMod Luaプラグインあり。
- Notepad++:Windows向けの多機能エディタ。
- 注意:Wordpadのようなリッチテキストエディタは使用しないこと。プレーンテキスト形式で保存する必要があります。
- Garry’s Mod本体:
- MODのテストとデバッグに必須。
- コンソール (
~
キー) を有効にしておくこと。
- バージョン管理システム (推奨):
- Git:コードの変更履歴を管理し、共同開発を容易にする。
- GitHubやGitLabなどのプラットフォームと連携。
- 画像編集ソフト (オプション):
- GIMP (無料)、Photoshop (有料) など。
- カスタムテクスチャやUI要素の作成に。
- 3Dモデリングソフト (オプション):
- Blender (無料)、3ds Max (有料)、Maya (有料) など。
- カスタムモデルの作成に。
Lua言語の基本
MOD開発を始める前に、Luaの基本的な概念を理解しておくことが重要です:
- 変数:
local myVariable = "Hello"
- データ型:
nil
,boolean
,number
,string
,function
,userdata
,thread
,table
- テーブル:
local myTable = { key = "value", 10, name = "GMod" }
- 制御構文:
if/then/elseif/else/end
,for
,while
,repeat/until
- 関数:
function MyFunction(arg1, arg2) ... return result end
- コメント:
-- 一行コメント
,--[[ 複数行コメント ]]
GLuaの基本構造
Garry’s ModのMODは特定のフォルダ構造とファイル命名規則に従います。
- アドオンフォルダ:
GarrysMod/garrysmod/addons/
内にアドオン名のフォルダを作成 (例:my_first_addon
)
- 基本ファイル構造:
addons/my_first_addon/lua/autorun/server/sv_init.lua
(サーバーサイド初期化)addons/my_first_addon/lua/autorun/client/cl_init.lua
(クライアントサイド初期化)addons/my_first_addon/lua/autorun/sh_init.lua
(共有初期化)addons/my_first_addon/addon.json
(アドオン情報ファイル)
- addon.json:
{
"title": "My First Addon",
"type": "tool",
"tags": ["fun", "roleplay"],
"ignore": [
"*.psd",
"*.vcproj",
"*.svn*"
]
}
- クライアント/サーバー/共有:
- サーバーサイド (SERVER):ゲームロジック、データ管理、プレイヤー間のインタラクションなど。
sv_*.lua
やinit.lua
。 - クライアントサイド (CLIENT):HUD描画、エフェクト、サウンド、入力処理など。
cl_*.lua
。 - 共有 (Shared):両方で必要な定義、関数、設定など。
sh_*.lua
。 AddCSLuaFile("path/to/file.lua")
:サーバーからクライアントへLuaファイルを送信する必須関数。
- サーバーサイド (SERVER):ゲームロジック、データ管理、プレイヤー間のインタラクションなど。
簡単なMODの作成例
1. カスタムチャットコマンド
目的:/hello
と入力すると「Hello, [プレイヤー名]!」と表示する。
手順:
- アドオンフォルダ作成:
addons/my_chat_command/
- サーバーサイドファイル作成:
lua/autorun/server/sv_chatcmd.lua
sv_chatcmd.lua:
--[[---------------------------------------------------------------------------
カスタムチャットコマンド /hello
---------------------------------------------------------------------------]]
-- フックを使用してチャットメッセージを監視
hook.Add("PlayerSay", "MyHelloCommand", function(ply, text, teamOnly)
-- メッセージが "/hello" かどうかチェック
if string.lower(text) == "/hello" then
-- プレイヤーに挨拶メッセージを送信
ply:ChatPrint("Hello, " .. ply:Nick() .. "!")
-- 元のチャットメッセージが表示されないようにする
return ""
end
end)
print("My Hello Command Loaded!")
- addon.json 作成:
{
"title": "My Hello Command",
"type": "util",
"tags": ["fun"]
}
- ゲームを再起動してテスト。チャットで
/hello
と入力。
2. シンプルなカスタムツール
目的:クリックしたプロップを赤色にするツール。
手順:
- アドオンフォルダ作成:
addons/my_color_tool/
- ツールスクリプト作成:
lua/weapons/gmod_tool/stools/color_red.lua
color_red.lua:
--[[---------------------------------------------------------------------------
クリックしたプロップを赤色にするツール
---------------------------------------------------------------------------]]
TOOL.Category = "Construction"
TOOL.Name = "#tool.color_red.name"
TOOL.Command = nil
TOOL.ConfigName = ""
-- ツールが選択されたときの情報
if CLIENT then
language.Add("tool.color_red.name", "Red Color Tool")
language.Add("tool.color_red.desc", "Makes props red when you click them.")
language.Add("tool.color_red.0", "Primary: Color prop red")
end
-- ツール使用時の処理 (サーバーサイド)
function TOOL:LeftClick(trace)
-- サーバーサイドでのみ実行、またはクライアントからサーバーへリクエストを送る
if not SERVER then return true end
-- クリックした先にエンティティがあり、それがプロップかチェック
if not IsValid(trace.Entity) or not trace.Entity:IsPlayer() and not trace.Entity:IsNPC() then
-- エンティティが有効で、プレイヤーやNPCではない場合
local ent = trace.Entity
-- 色を赤に設定 (R=255, G=0, B=0, Alpha=255)
ent:SetColor(Color(255, 0, 0, 255))
-- 成功したことを示す
return true
end
-- 失敗したことを示す
return false
end
-- ツールガンに表示されるコントロールパネル (クライアントサイド)
function TOOL.BuildCPanel(panel)
panel:AddControl("Header", { Text = "#tool.color_red.name", Description = "#tool.color_red.desc" })
end
- addon.json 作成:
{
"title": "Red Color Tool",
"type": "tool",
"tags": ["construction"]
}
- ゲームを再起動し、ツールガン (Tool Gun) の「Construction」カテゴリから「Red Color Tool」を選択してプロップをクリック。
Luaプログラミングの高度なテクニック
基本的なMOD作成に慣れたら、より高度なテクニックを学び、洗練されたMODを開発しましょう。詳細は enhanced_lua_programming.md
を参照してください。ここでは主要なポイントを抜粋します。
効率的なコード構造
- モジュール化:コードを機能ごとにファイル分割し、
include()
やrequire()
で読み込む。 - 名前空間:グローバル変数の汚染を防ぐためにテーブルを使用 (
MyAddon = MyAddon or {}
)。 - ファイル構成:
server/
,client/
,shared/
フォルダを適切に使い分ける。
メモリと性能の最適化
- テーブルの再利用:頻繁に作成・破棄されるテーブルは再利用 (
table.Empty()
)。 - ローカル変数とキャッシング:頻繁にアクセスするグローバル関数や値をローカル変数にキャッシュ。
- LuaJIT最適化:型の一貫性を保ち、ホットループを最適化。
ネットワーク通信の最適化
- ネットメッセージのプーリング:
util.AddNetworkString()
でメッセージタイプを登録し、効率的に送受信。 - データ圧縮:大きなデータは
util.Compress()
/util.Decompress()
で圧縮。 - 送信頻度の制御:必要な情報のみ、適切な頻度で送信。
フックシステムの高度な活用
- カスタムフック:独自のイベントシステムを作成 (
hook.Run("MyCustomEvent", ...)
)。 - 既存フックの拡張:元のフック関数を保存し、独自の処理を追加後に呼び出す。
メタテーブルとオブジェクト指向
- 既存クラスの拡張:
FindMetaTable("Player")
などでメタテーブルを取得し、メソッドを追加。 - カスタムクラスシステム:Luaのテーブルとメタテーブルを使って独自のクラス構造を実装。
非同期プログラミング
- コルーチン:時間のかかる処理を分割実行 (
coroutine.create
,coroutine.yield
,coroutine.resume
)。 - タイマー:
timer.Simple
,timer.Create
を使って遅延実行や定期実行。
デバッグとプロファイリング
- 高度なデバッグ関数:
PrintTable
,debug.traceback
などを活用。 - パフォーマンス測定:
SysTime()
を使ってコードの実行時間を計測。 - カスタムエラーハンドリング:
pcall
やカスタムログシステムでエラーを管理。
カスタムコンテンツの作成
カスタムモデルとテクスチャ
- モデリング:
- Blenderなどの3Dソフトでモデルを作成。
- Source Engineに適したポリゴン数と構造を意識。
- UVマッピングとテクスチャ座標の設定。
- テクスチャリング:
- GIMPやPhotoshopでテクスチャを作成。
- VTF (Valve Texture Format) 形式に変換 (VTFEditを使用)。
- ノーマルマップ、スペキュラマップなども作成可能。
- コンパイル:
- QCファイル (モデル定義ファイル) を作成。
- Crowbarなどのツールを使ってSMD/DMXファイルをMDL (モデル) 形式にコンパイル。
- VMT (Valve Material Type) ファイルでテクスチャとシェーダーを設定。
- GModへの統合:
models/
フォルダにMDLファイルを配置。materials/
フォルダにVTFとVMTファイルを配置。- Luaスクリプトから
util.PrecacheModel()
やEntity:SetModel()
で使用。
カスタムサウンド
- サウンド作成:
- Audacity (無料) などの音声編集ソフトでサウンドを作成・編集。
- WAVまたはMP3形式で保存。
- GModへの統合:
sound/
フォルダにサウンドファイルを配置。- Luaスクリプトから
sound.PlayFile()
やEntity:EmitSound()
で再生。 sound.Add()
でカスタムサウンドエイリアスを登録可能。
MODのデバッグとテスト
コンソールを使ったデバッグ
print()
:変数やメッセージをコンソールに出力。lua_run <コード>
:コンソールから直接Luaコードを実行。lua_openscript <ファイル名>
:特定のLuaファイルを実行。developer 1
:詳細なデバッグ情報を表示。- エラーメッセージの解読:エラーが発生したファイル名と行番号を確認。
デバッグツールの活用
- GMod Lua Debugger (GLua):VSCode拡張機能。ブレークポイント、ステップ実行、変数監視などが可能。
- Wiremod E2 Debugger:Expression 2コードのデバッグに特化。
- カスタムデバッグコマンド:
concommand.Add()
で独自のデバッグ用コマンドを作成。
テスト手法
- ユニットテスト:個々の関数やモジュールを独立してテスト。
- 統合テスト:複数のモジュールを連携させてテスト。
- マルチプレイヤーテスト:専用サーバーやListenサーバーで複数人での動作を確認。
- ストレステスト:大量のエンティティやプレイヤーで負荷をかけてテスト。
- 異なる環境でのテスト:異なるOSやハードウェア構成での動作確認。
Steam Workshopへの公開
準備
- アドオンの整理:
- 不要なファイル(ソースファイル、バックアップなど)を削除。
addon.json
に正確な情報を記述。- スクリーンショットやアイコン画像を用意。
- サムネイル画像:
- 512×512ピクセルのJPEGまたはPNG画像。
- アドオンの内容を魅力的に表現。
アップロードツール
- gmpublish.exe:
GarrysMod/bin/
フォルダにある公式アップロードツール。- コマンドラインまたはGUIで使用可能。
- 使用方法 (GUI):
gmpublish.exe
を起動。- 「Create」タブを選択。
- 「Addon Path」にアドオンフォルダを指定。
- 「Icon Path」にサムネイル画像を指定。
- 「Title」と「Type」を入力。
- 「Tags」を選択。
- 「Publish」ボタンをクリック。
- 使用方法 (コマンドライン):
gmpublish create -addon "path/to/your/addon" -icon "path/to/your/icon.jpg"
- 更新:
- 「Update」タブを選択。
- 更新したいアドオンを選択。
- 必要に応じて情報を変更。
- 「Publish」ボタンをクリック。
Workshopページの管理
- 説明文の編集:アドオンの詳細な説明、使い方、クレジットなどを記述。
- スクリーンショット/動画の追加:アドオンの魅力を視覚的に伝える。
- 変更履歴の記載:アップデート内容を明確に伝える。
- コメントへの対応:ユーザーからのフィードバックに対応し、バグ報告を受け付ける。
- 依存関係の明記:他のアドオンが必要な場合は明記する。
まとめと次のステップ
Garry’s ModのMOD開発は、Luaスクリプトを基本に、モデル、テクスチャ、サウンドなどのカスタムコンテンツ作成、そしてSteam Workshopでの共有まで、幅広いスキルが求められます。簡単なチャットコマンドから始め、徐々にカスタムツール、エンティティ、ゲームモードへとステップアップしていくのが良いでしょう。
高度なテクニックを習得し、デバッグとテストを丁寧に行うことで、より高品質で安定したMODを作成できます。コミュニティのリソースを活用し、他の開発者と交流することもスキルアップに繋がります。
次のステップとしては、以下のような目標が考えられます:
- より複雑なSWEPやSENTの作成
- 独自のゲームモード開発
- WiremodやExpression 2の習得
- 3Dモデリングやテクスチャ作成スキルの向上
- オープンソースプロジェクトへの貢献
MOD開発の世界は奥深く、常に新しい発見があります。あなたの創造力を活かして、Garry’s Modの世界をさらに豊かにしていきましょう。
コメント