mcpField
S
scenario-roblox-gameplay

scenario-roblox-gameplay

github.com/scenario-labs開発1.2k55 回インストール1 日前に更新
リポジトリ

scenario-roblox-gameplay について

Roblox Studio向けのゲームプレイシステム開発スキルで、戦闘、NPC、乗り物を扱います。テスト可能なルール、サーバー側の命中判定、Luneとプレイテストでの性能測定を重視します。

主な機能

  1. 01サーバー側の空間クエリによる戦闘
  2. 02NPCのステートマシンと経路探索
  3. 03NPC処理のスケジューリングとコスト測定
  4. 04飛翔体とコンボシステム
  5. 05制約を使った乗り物の構成

活用シーン

  1. 01サーバー検証型の近接戦闘の構築
  2. 02NPCの挙動と経路探索のテスト
  3. 03NPC数に応じたサーバー負荷の測定
  4. 04乗り物の操作機能の実装とテスト

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/scenario-labs/skills --skill scenario-roblox-gameplay

インストール後、Claude Code で/scenario-roblox-gameplayを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
critique.md
expert-notes.md
gui-paths.md
procedures.md
sources.md
scripts/
rbx_gameplay.py
scripts/agentkit/gameplay/
Car.luau
CarSafety.luau
Combo.luau
DebugDraw.luau
GameplayAudit.luau
GameplayInputs.luau
Hitbox.luau
lune_gameplay_audit.luau
lune_unit.luau
NpcBrain.luau
NpcPool.luau
NpcService.luau
PathGuard.luau
Projectile.luau
StateMachine.luau
scripts/agentkit/gameplay/boot/
GameplayClient.client.luau
GameplayServer.server.luau

詳細

Roblox のゲームプレイシステム(ゲームプレイシステムプログラマー)

対象環境:scenario-roblox-expert ツールキットを通じて操作する、macOS 上の Roblox Studio(2026 年 10 月ビルド)。

エキスパートレベルでは、ゲームプレイシステムとは Lune でテストされた純粋なルールであり、単一のサーバースケジューラーによってエンジンに接続され、計測されたサーバーコストを伴うプレイテストで実証されるものです。基本方針は、クライアントは意図を送信し、サーバーは空間クエリですべての命中を判定し、計測していない数値はリリースしないことです。ここに記載された兄弟スキルが利用可能なスキルに見当たらない場合は、ユーザーにインストールを依頼してください(npx skills add scenario-labs/skills --skill <name>)。無人で進める場合は、ツールのスキーマに基づいて作業を進め、該当箇所を明示してください。

必須の背景知識: scenario-roblox-expert(チャネル、レビューの反復、ツールキット、Roblox の最新の落とし穴)。

状況(2026-10-19): Studio 0.743 でライブテスト 23 件に合格(Edit プローブ、NPC ベンチマーク、ハント、デバッグ描画、コンボ、リモートのフラッド、スロットルを押したままの車とその降車、ムーバー、プレイテストサーバー内のすべてのドキュメントスニペット)。オフラインチェック 6 件に合格(Lune 仕様 23 件、キットファイル 15 件とスニペット 12 件に対する両方の型ソルバーでの luau-lsp)。未実施:2 プレイヤーでの戦闘(各テストクライアントで Studio ウィンドウを開く必要があります)、タッチデバイス、パスファインディングモディファイアーとリンクを経由するルート。

方針(エキスパートならではの差分)

  1. 意図はクライアントから、ヒット判定はサーバーで行います。 クライアントは引数なしで Attack を発火し、サーバーは自身のクロックからコンボの段階を決め、ルートの前方にあるボックスをクエリします。空間クエリは Touched の代わりになります(Ludius、gmz904QpfxU 00:01:15):クライアント所有のパーツは、サーバー上のどこでも Touched を発火できます(Network ownership doc)。検証とレート制限については、scenario-roblox-networking を参照してください。
  2. クエリが無視する対象を把握します。 Spherecast、Blockcast、Shapecast は、開始地点の内側にあるパーツを無視します(veraktt、GtqFcyFgIXQ 00:19:33)。オーバーラップクエリで開始地点を確認してください。Shapecast の最終位置は origin + direction.Unit * Distance で、Position は接触点です(Crusherfire、EIOwGMZYidw 00:07:12)。FilterDescendantsInstances は使わず、ExcludeInstances または IncludeInstances を使い、ショットごとにリストを作成してください(BrawlDev、u6I17z6ggUg 00:28:41)。
  3. スイープしてから移動し、dt 刻みで進めます。 移動を確定する前に、ステップ全体をキャストしてください(veraktt 00:12:22)。台形則による変位なら、フレームレートに依存しない経路になります(BrawlDev、0Dt-Ab8czPw 00:33:08)。Lune での計測では、30、60、240 Hz の結果は 0.001 studs 以内で一致し、オイラー法では 0.5 ずれます。
  4. すべての NPC に 1 つのスケジューラーを使い、対象数で計測します。 1 つの Heartbeat で毎フレーム 1 バケットを処理し、1 つのワーカーが予算内で経路を計算します。知覚処理はまず距離で絞り込み、静的ジオメトリに対してレイキャストを 1 回行います [追加]。R15 NPC 100 体で計測した結果、サーバーは 60 fps、フレーム p95 は 17.6 ms、巡回中の AI は 1 フレームあたり 0.14 ms、追跡中は 0.26 ms でした。物理ステップは 1.8 ms に増加しました。脳の処理より Humanoid の物理演算のほうがコストがかかるため、AgentKit の Stats を使って実際の体数で計測し、Humanoid ごとのコストを抑えてください。未使用の状態を無効にし、BreakJointsOnDeath を false にし、静的 NPC ではステートマシンを使わず、ウェーブ間でモデルをプールします(P5)。
  5. NPC のルートをサーバーに固定します。 プレイヤーの近くにいる非アンカーの NPC は、そのプレイヤーのクライアントによってシミュレーションされ、移動可能になります(計測では、固定されていない NPC が 6 studs 離れた位置でプレイヤーの所有になりました)。親子関係の設定後に SetNetworkOwner(nil) を呼び出してください(Network ownership doc)。純粋に装飾目的の群衆は、NPC ごとに 5 秒ごとに 1 つの属性を送るクライアント側 Humanoid として動作させることができます(Suphi Kaner、JyMxrcqEzu8 00:13:50)。
  6. 脳はヒステリシスを備えたデータです。 onEnter、onStay、onExit を持つ状態と、リスト形式の遷移を使います(Miller、Roblox Learn、nlVpAZEkxgo 00:00:57)。5 studs で Attack に入り、6.5 を超えたら抜け、視界を失ってから 4 秒後に諦めます [追加]。経路探索の成功条件は pcall と Status == Success の両方です(BrawlDev、ckA4fVkAjIA 00:15:48)。Blocked が発生した場合は、そのインデックスが次のウェイポイント以降のときに限り再計算してください(Pathfinding doc)。8 秒後に MoveTo は諦めるため、再度発行してください。特別扱いのコードではなく、1 つの Costs テーブルでルートのコスト(マテリアル、PathfindingModifier、PathfindingLink のラベル)を設定します。計算は地面の上で、読み込み済みのワールド内、3,000 studs 未満の範囲でのみ行ってください。移動に失敗した場合は、そのウェイポイントにスナップし、ゴールにはスナップしません(P12)。
  7. スタンは保留中のヒットをキャンセルします。 ヒットを受けたキャラクターのキューに入っている攻撃は破棄され、一定時間のスタン中はリクエストも拒否されます(ArTheDev、Aoc9HkGHu_8 00:02:57)。1 回のスイングにつきキャラクターごとに 1 回だけヒットさせ、部位ごとにはヒットさせません(Ludius 00:04:06)。LinearVelocity を 0.2 s 適用して Humanoid をノックバックさせます。立っているダミーに ApplyImpulse を 1 回適用すると 1.2 studs 動きましたが、LinearVelocity では 10.5 動きました [計測]。
  8. 車は拘束と所有権で構成します。 ホイールごとに、同じアタッチメントに CylindricalConstraint と SpringConstraint を 1 つずつ設定し、上限を 0 未満にします(Suphi Kaner、FVOowr2DXbM 00:10:19)。運転手が着席している間は車を運転手が所有し(Network ownership doc)、サーバーは速度をチェックします。競技用レースでは Server Authority を使います。ステアリングの符号は実機で確認してください。このキットの最初のビルドでは、D キーで左に曲がりました。重心は低く保ちます。密度の高い低いシャーシ、軽いボディ、低く中央に配置したシートを使います(FVOowr2DXbM 00:54:05)。降車時にはモーターを解除し、ばらばらのパーツにも同じ所有者を設定し、最も高い出口から出ます(P9, P14)。

最初に確認すること

  • NPC の数、および NPC がダメージを与える、または受けるのか(サーバー)、それとも装飾としてのみ配置するのか(クライアント側の群衆)。
  • ヒット判定モデル:近接ボックス、ヒットスキャンレイ、または移動時間と落下を伴う投射物(Weapons キットのドキュメント)。
  • 競技向けかカジュアル向けか:競技向けの移動と乗り物は Server Authority に含めます (scenario-roblox-networking)。
  • プラットフォーム:最も一般的なデバイスはスマートフォンです。そのため、すべての戦闘アクションにキー、ゲームパッドのボタン、 および画面上のタッチボタンを割り当て、InputBinding.UIButton を介してバインドします (P7)。

未回答の場合のデフォルト:NPC はサーバー上に配置、バケット数は 6、毎秒 30 パス。近接ボックスは 5 × 5 × 5 スタッド、距離 3.5 スタッド。投射物のスイープには半径 0.25 スタッドの球体を使用し、車の数値は以下のとおりです。

手順

完全なコードとテスト結果:procedures.md。モジュール: scripts/agentkit/gameplay/。Python: scripts/rbx_gameplay.py。

  1. インストール。 目標:開いているプレースにキット、起動スクリプト、Input Action インスタンスを追加します。方法: rbx_gameplay.install(studio) が Edit で Source を書き込みます(P1)。GATE:プレイテストの Server で フックとリモートが確認でき、Client で GameplayInputs.Combat.Attack が確認でき、コンソールに起動エラーがないこと。
  2. クエリを調査。 目標:このビルドに関する事実を確認します。方法:Edit のプローブ(P2)。GATE:内部からの Spherecast が 奥側のパーツを返すこと。Shapecast の距離が、予想される移動距離から 0.05 スタッド以内であること。
  3. Lune でブレインを作成。 目標:読みやすく、テスト済みの判定テーブルを作成します。方法:StateMachine と NpcBrain(P4)。GATE:lune run lune_unit.luau が成功すること。
  4. 群衆とコスト。 目標:サーバーコストを把握します。方法:NpcService とベンチマーク(P5)。GATE:100 個のルートのうち、 クライアント所有のものが 0 個であること。各数でサーバーの fps と p95 を記録し、scenario-roblox-performance と予算に合意すること。
  5. 追跡。 目標:知覚、パス、近接攻撃を組み合わせます。方法:walk_to でプレイヤーを視界内に移動させ、 次に壁の後ろへ移動させます(P6)。パス失敗のルールとルートのコスト設定(P12)。GATE:NPC が壁の後ろにいるプレイヤーまで到達して ヒットを与えること。キャプチャを取得します。
  6. 戦闘。 目標:連打とスタンに耐えるコンボを作成します。方法:Input Action、意図を送るリモート、Combo、 Hitbox.box(P7)。Projectile を使った投射物(P8)。GATE:正面のダミー 2 体の体力が 58 で、後ろのダミーには 攻撃が当たっていないこと。連打しても、受け付けられたスイングの間隔が前回から 0.24 秒未満にならないこと。 0.2 スタッドの壁ですべての投射物が止まること。待機時間にかかわらず、user_keyboard_input は 0.13〜0.20 秒間隔で 押下を配信します。フラッドテストでは、クライアントスクリプトからリモートを呼び出します(P7)。
  7. 乗り物。 目標:走行と操舵ができ、横転しないこと。方法:Car.build、Car.serve、Car.controller (P9)。GATE:運転者がシャーシを所有すること。W を 3 秒間押すと、前方に 30 スタッドを超えて進むこと。W と D を同時に押すと、 右に 20 度を超えて曲がること。UpVector.Y が 0.8 を上回ること。降車時に所有権が自動に戻ること。 スロットルを押したまま降車すると車が停止すること(P14)。実行前と実行後のキャプチャを取得します。
  8. 監査とレビュー。 方法:GameplayAudit とリードの Audit(P3)、批評、 コンタクトシート 1 枚。GATE:エラーが 0 件であること。

数値

値既定値相対値
思考頻度NPC ごとに毎秒 10 回60 fps の 6 バケット
パス予算毎秒 30 回サーバー全体
検知、攻撃、離脱範囲60、5、6.5 studsターゲットのルート。追跡範囲は検知範囲の 1.5 倍
視界喪失4 s最後に視認した時点
Humanoid MoveTo タイムアウト8 s思考のたびに再発行
パス制限3,000 studs、20,000 ノード。どちらも不正な Status として失敗開始地点から目標地点まで(P12)
経路コスト既定値は 1、最後の手段は 20~1,000、決して使用しない場合は math.hugeCosts のキー:マテリアル、モディファイア、リンクラベル(P12)
タッチボタン72 px、右下、ジャンプボタンと重ならない位置PreferredInput が Touch の場合のみ表示。レイアウト確認:scenario-roblox-ui(P7)
コンボダメージ10、12、20ステップ 1~3
コンボ間隔0.30、0.30、0.45 s、許容誤差 0.8直前に受け付けられた攻撃
フィニッシャーのノックバックLinearVelocity 45 studs/s を 0.2 s、MaxForce は質量 × 重力 × 20攻撃者から離れる方向
連鎖受付時間、フィニッシャーロック、スタン0.9、0.6、0.35 s最後の攻撃または被弾
キャスト距離1,024 studs(形状キャスト)、15,000(レイ)1 回の呼び出しあたり
サスペンション剛性 3500、減衰 200、自由長 2.8Suphi Kaner
スライド制限上限 -1、下限 -2Attachment0 の X 軸(上方向)に沿う
駆動MaxSpeed / radius、トルク 5000、アイドル 2000後輪
ステアリング0.4 s で 30 度車体前方のアタッチメント
車速チェックMaxSpeed の 1.5 倍、1 s 内に 2 回ドライバーが所有している間、サーバー側で実行
NPC 100 体、測定値60 fps、p95 17.6 ms、ハートビート 0.27 ms、物理演算 1.8 ms、送信 21.5 kbps巡回中、サーバー、Studio 0.743
パス 1 件、測定値壁時計時間 65 ms(yield を含む)、失敗 0 件ComputeAsync、空のベースプレート
キャスト、測定値Spherecast 0.46、Raycast 0.30 マイクロ秒50 studs、小規模な include リスト
車、測定値3 s で 177.9 studs、最高速度 51.0 studs/s。2.5 s で 112 度W、次に W + D

品質ゲート

  • 測定可能な項目:Lune の仕様、rbx_check のエラー数が 0、GameplayAudit のエラー数が 0、NpcService.stats()(状態、クライアント所有のルート、AI の処理時間(ms)、経路)、Server 上の AgentKit Stats、ダミーの体力とヒット数、車両のサンプル(距離、方位、UpVector.Y)。
  • 視覚的な項目:群衆、壁の向こう側からの追跡、フィニッシャー後のダミー、運転前後の車両を撮影し、rbx_review.contact_sheet(1,600 px 以下)で確認します。Visualization Options で Navigation mesh または Network owners をオンにし、DebugDraw アドーンメントでウェイポイントとクエリボックスを描画します。撮影画像に表示されるよう、深度テストを有効にします(P13)。
  • キーテストではクライアントの入力を記録し、送信したキーと異なる場合は再実行します(P7)。

よくある間違い

間違い症状修正
Touchedでダメージを与える壁越しに当たる、ダメージを悪用されるサーバーでボックスクエリを行う
部位ごとに結果を1つずつ返す1回のスイングで3~5回ヒットするキャラクターモデルごとに結果をキーにする
壁の中から飛翔体が発射される弾が通り抜ける最初のスイープ前にオーバーラップクエリを行う
フレームごとにPositionでテレポートする高速移動時にすり抜けるスイープしてから移動する
FilterDescendantsInstances新しいコードでは非推奨のAPIExcludeInstances、IncludeInstances
デバッグ用パーツがクエリ対象になっているキャストが独自のマーカーで止まるCanQueryをfalseにする(Crusherfire 00:10:42)
MoveToFinished:Wait()8秒後にNPCがフリーズするMoveToを再実行し、reached == falseに対処する
マップの読み込み前、または空中でパスを計算するStatusが不正になり、NPCが動かなくなるFloorMaterialを待ち、読み込み完了を条件にする(P12)
移動に失敗した後、目的地にスナップさせるNPCが壁をすり抜けるそのウェイポイントにスナップさせる(P12)
コードで危険物を回避する場当たり的な特別処理が増えるCostsでコストを設定したモディファイアラベルを使う(P12)
すべてのHumanoidを完全に有効化するNPCごとに物理演算の負荷が増えるステートを絞り込み、プールを使い、静止時はステートマシンを使わない(P5)
pcallなしでComputeAsyncを実行する不正なパスでスクリプトが停止するpcallとStatusを併用する
NPCのルートが固定されていない最も近いクライアントがNPCを動かすSetNetworkOwner(nil)を設定する
NPCごとにループを1つずつ使うスクリプトが増えるほどコストが増えるスケジューラーを1つにし、バケットを使う
BodyVelocity非推奨のムーバーLinearVelocity、VectorForce、AlignPosition
Attachment0なしのConstraint何も動かず、エラーも出ないGameplayAudit constraint-no-attachment
サスペンションの上限が0スプリングが底付きし、車が跳ねる上限を-1にする
Throttleを読み取るゲームパッドやタッチ操作でアナログ入力ができないThrottleFloat、SteerFloat
乗客が車の所有者になっている運転手にラグが発生するOccupantの変更時に割り当て直す
固定された片側の降車位置車が横転すると、プレイヤーがマップの下に落ちる最も高い降車位置を使う(P14)
降車時にモーター値を残す無人の車が走り続ける降車時にモーターを解除する(P14)
キーボードのみの戦闘スマートフォンでは攻撃できないタッチ用のUIButtonバインディングを使う(P7)

引き継ぎ

  • scenario-roblox-architecture から受け取るもの:RoundMachine のラウンドループ、タグ付けされた武器とハザード用の Binder、DamageService のスロット。
  • scenario-roblox-networking に引き渡すもの:検証するヒットボックス、飛翔体、アビリティのルール(巻き戻しを使う HitCheck)、疑いスコア用の車の速度フラグ、Server Authority の設定。
  • scenario-roblox-animation に引き渡すもの:トラックを駆動する NPC の State および Action 属性とコンボの手順。Server Authority ではトラックをキャッシュしません。
  • scenario-roblox-vfx-audio に引き渡すもの:インパクトエフェクト用のヒット位置、法線、ステップ。
  • scenario-roblox-ui に引き渡すもの:プロンプトと再マッピング用の GameplayInputs コンテキストとアクション。
  • scenario-roblox-performance に引き渡すもの:NPC のベンチマーク数値と予算。
  • scenario-roblox-luau と共有するもの:固定ステップのコード(BindToSimulation)と Deferred イベントのルール。

Roblox に関する最新情報

  • RaycastParams と OverlapParams:ExcludeInstances と IncludeInstances は、FilterDescendantsInstances と FilterType に取って代わります(2026-04-07)。RaycastParams.Margin と SizeGradient はリファレンスに記載されていますが、0.743 でどちらかを設定すると「not enabled yet」が発生します(P2)。太いレイには Spherecast を使ってください。
  • 衝突グループは workspace にあります(RegisterCollisionGroup、CollisionGroupSetCollidable)。PhysicsService のメソッドは非推奨です。
  • PathfindingService:CreatePath と Path:ComputeAsync を使用してください。FindPathAsync と ComputeRawPathAsync は非推奨です。PathfindingModifier と PathfindingLink にベータ版は必要ありません。
  • RunService:BindToSimulation は Workspace.UseFixedSimulation が必要とドキュメントに記載されています。0.743 では、この設定を一度も行っていない place でも Edit と Play で実行されました(P11)。スクリプトから Studio MCP コンテキストのプロパティを読み取れないため、Rojo プロジェクトで明示的に設定してください。
  • Creator Store のモデルはサンドボックス化されています(2026-05-13)。FastCast などのベンダーライブラリはソースとして取り込んでください。

参考資料

コメント