roblox-networking について
Roblox 開発者向けに、クライアントとサーバー間の通信やネットワークセキュリティを扱うリファレンススキルです。権限管理、検証、悪用対策に加え、レート制限スクリプトと関連資料を含みます。
主な機能
- 01クライアント・サーバー間の権限原則
- 02RemoteEvent と RemoteFunction の使い分け
- 03サーバー検証と状態の権威管理
- 04ネットワーク所有権と物理検証
- 05一般的な悪用への対策
- 06プレイヤー別レート制限スクリプト
活用シーン
- 01リモート引数と呼び出し頻度の確認
- 02サーバー権威型の戦闘や経済設計
- 03車両などの物理オブジェクトの所有権確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ nonlooped/ roblox-suite --skill roblox-networkingインストール後、Claude Code で/roblox-networkingを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/exploits-and-defenses.mdremote-and-bindable-patterns.mdserver-authority-and-validation.mdscripts/RateLimiter.luatests/RateLimiter.spec.lua詳細
roblox-networking
主要な資料: https://create.roblox.com/docs/projects/client-server 、https://create.roblox.com/docs/scripting/security/security-tactics (サーバー権限に関する手法)、scripting/security/ セクション全体(security-tactics、defensive-design、client-server-boundary、network-ownership、access-control など)、events/remote と bindable、および関連する Engine クラス(RemoteEvent、RemoteFunction、Bindable*、RunService など)。
権限の境界
ゲームの状態とシミュレーションはサーバーが権限を持ちます。クライアントは応答性を高めるためにシミュレーションを行い、サーバーの指示に従って描画します。不正利用される可能性があるもの(経済、進行状況、戦闘結果、対戦プレイでの移動)は、サーバーで検証またはシミュレーションする必要があります。
通信ツール
RemoteEvent。境界を越えて送信する、一方向の通信です。
- クライアント → サーバー:
RemoteEvent:FireServer(...)→ サーバーのハンドラーは(player, ...)を受け取ります - サーバー → クライアント:
FireClient(player, ...)またはFireAllClients(...)
RemoteFunction。リクエストとレスポンスを行います(処理は一時停止します)。
- クライアント:
InvokeServer(...)→ サーバーのOnServerInvoke(player, ...) - サーバーから
InvokeClientを呼び出すこともできます(あまり一般的ではなく、注意点があります)。
重大な警告:
RemoteFunction:InvokeClientは、対象のクライアントが値を返すまでサーバーの処理を一時停止します。悪意のあるクライアントや応答の遅いクライアントによって呼び出しが保留状態になり、サーバーが無期限に停止する可能性があります。サーバーからクライアントへの呼び出しは避けてください。どうしても使う場合はタイムアウトを設け、クライアントを信頼できないものとして扱ってください。
BindableEvent / BindableFunction。同じ側でのみ使用します(サーバーモジュール同士、またはクライアントモジュール同士の通信)。ネットワークの境界を越えることはありません。
一般則:クライアントは 意図 を送信します。サーバーが 結果 を決定して複製するか、通常の Instance の複製処理に任せます。
サーバー権限の手法
- クライアントのすべてのアクションを検証します(距離、頻度、前提条件、スタミナ、視線など)。
- 重要なシステムはサーバーでシミュレーションします(または、少なくとも重要な部分を再実行します)。
- leaderstats やクライアントから見える値ではなく、サーバーのテーブルまたは Attributes を信頼できる情報源として使用します。
- 対戦ゲームでの移動や物理演算には、Roblox の物理演算とネットワーク所有権、サーバーによる検証と補正を活用します。
- 各クライアントに必要なものだけを複製します(インベントリ全体を毎フレーム配信しないでください)。
移動の検証や物理演算などについては、公式のサーバー権限に関する手法のページを参照してください。
ネットワーク所有権
固定されていないパーツとアセンブリにはネットワーク所有者がいます(通常は近さやクライアントの処理能力に応じて、最も近いプレイヤーまたはサーバーになります)。所有者は、遅延を抑えるためにローカルで物理演算をシミュレーションします。サーバーは BasePart:SetNetworkOwner(player or nil) を呼び出して、接続されたアセンブリ全体の所有権を設定できます。固定されたパーツは常にサーバーが所有し、手動で所有者を変更することはできません。
乗り物、飛翔体、押して動かせるオブジェクトなどでは特に重要です。誤用すると、ほかのプレイヤーから見た動きが不自然になったり、簡単に不正利用されたりします。
一般的なエクスプロイトの種類と防御策
- 高速移動/飛行/ノークリップ:サーバー側で移動を検証するか、物理演算の所有権を管理し、位置を補正します。
- リモートのスパム/複製:プレイヤーごとのレート制限、サーバー側のクールダウン、引数の検証を組み合わせます。
- LocalScript の挿入/フリーモデルのバックドア:アセットを監査し、Capabilities を使用して、サーバー側で検証します。
- leaderstats やクライアントから見える値の改ざん:表示専用として扱います。権威ある状態はサーバーのテーブルまたは DataStore に保持します。
- 情報漏えい:秘密のモデルをレプリケーションされる場所に配置しないでください。ストリーミングやサーバー専用のストレージ(ServerStorage/ServerScriptService)を使用し、クライアントから見える場所に機密性の高いジオメトリやトリガーを置かないようにします。
CanQueryと衝突グループは機密性を保護する機能ではありません。影響するのは空間クエリと物理衝突のみであり、レプリケーションやレンダリングには影響しません。
レート制限のパターン(シンプルですが効果的): プレイヤーごと、アクションの種類ごとに、直近のアクション時刻を記録するテーブルを用意します。Remote の受信時に差分を確認します。不正利用があれば警告するか、キックします。
Capabilities(実験的なセキュリティレイヤー):
スクリプトの Capabilities を使うと、スクリプトに許可する操作を細かく制限できます。現在は実験段階です。使用するには、Workspace.SandboxedInstanceMode = Enum.SandboxedInstanceMode.Experimental を設定し、その後、スクリプトまたは親コンテナ(Model/Folder)に Sandboxed = true を設定して SecurityCapabilities の値を割り当てます。これにより、スクリプトは Capabilities セットに含まれる操作のみ実行できるようになります。
アクセス制御と機密性
- クライアントから見える範囲:Instance ストリーミングで制御します。クライアントに正確なレイアウトを知られたくない場合は、機密性の高いジオメトリを Workspace に配置せず、可能な限りサーバー専用のコンテナを使用します。
- 機密データ(正確な経済システムの計算式、ドロップ率、アンチチートのパラメーター)はサーバー上に保持してください。
安全な収益化とデータフロー(他のスキルとの連携)
- 購入プロンプトはクライアント側で表示します。
- ゲームパスの場合:
wasPurchased == trueの場合に限り、PromptGamePassPurchaseFinished内で特典を付与し、PlayerAdded時にUserOwnsGamePassAsyncで所有権を再確認します。 - 開発者向け製品とサブスクリプションの場合:サーバー側の
ProcessReceiptコールバック内でのみ、検証と特典の付与を行います。 - DataStore への書き込みはサーバーの Script からのみ行います。
- 「X を購入したのでアイテムをください」と伝えるクライアントの Remote は無視するか、ヒントとして扱い、サーバー側で再検証する必要があります。
実践的な配置ルール
- 権威あるロジック、経済システム、進行状況、戦闘の判定、データストアへのアクセス → ServerScriptService またはサーバー専用モジュール。
- UI、入力処理、見た目の予測、ローカル VFX → クライアント(LocalScripts、または PlayerGui 配下のクライアントモジュール、あるいは IsClient 分岐を使って ReplicatedStorage から読み込むモジュール)。
- 共有する純粋関数/定数/Remote の定義 → ReplicatedStorage のモジュール(両側で読み込まれますが、実行時のコンテキストはそれぞれ異なります)。
判断に迷う場合は、どこでも RunService のコンテキスト確認を使用してください。
スクリプト
scripts/RateLimiter.lua:レビュー済みのプレイヤーごと/アクションごとの制限機能です。最小間隔の強制、トークン容量と補充、アクションキーの割り当て数の上限、拒否理由に対応しています。専用インスタンスのクリーンアップを切断するにはdestroy()を呼び出してください。RateLimiter.defaultは共有シングルトンです。
参考資料のインデックス
- exploits-and-defenses.md:移動のエクスプロイト、Remote の不正利用、アセットのバックドア、データの漏えいを確認します。
- remote-and-bindable-patterns.md:イベントと関数のどちらを使うか選択したり、通信ペイロードを定義したりします。
- server-authority-and-validation.md:Remote の引数を検証し、クールダウンを適用したり、クライアント側の予測を確認したりします。