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. 02测试 NPC 行为与寻路
  3. 03衡量不同 NPC 数量下的服务器开销
  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 游戏玩法系统(游戏玩法系统程序员)

目标平台:macOS 上的 Roblox Studio(2026 年 10 月构建版),通过 scenario-roblox-expert 工具包驱动。

在专家级别,游戏玩法系统是一套纯规则:在 Lune 中测试,由一个服务器调度器接入引擎,并通过实测服务器开销的试玩验证。核心原则:客户端发送意图,服务器通过空间查询判定每次命中,所有数值在未经测量前都不得上线。如果这里提到的某项关联技能不在你可用的技能中,请让用户安装它(npx skills add scenario-labs/skills --skill <name>);若无法获得协助,则根据工具架构继续操作,并标明缺失项。

必备背景: scenario-roblox-expert(通道、审查流程、工具包、当前 Roblox 中容易踩的坑)。

状态(2026-10-19): Studio 0.743 中 23 项实时测试通过(Edit 探测、NPC 基准测试、hunt、调试绘图、连击、远程调用洪泛、车辆及其在油门按住时的退出、移动器,以及试玩 Server 中的每个文档代码片段);6 项离线检查通过(23 项 Lune 规格、luau-lsp 在 15 个套件文件和 12 个代码片段上使用两种类型求解器检查)。尚未运行:双人战斗(每个测试客户端都会打开一个 Studio 窗口)、触控设备测试、经过路径寻找修饰器和连接的路线测试。

原则(专家级差异)

  1. 意图由客户端发起,命中由服务器判定。 客户端发送不带参数的 Attack;服务器根据自己的时钟选择连击步骤,并查询根部前方的盒形区域。空间查询取代 Touched(Ludius,gmz904QpfxU 00:01:15):客户端拥有的部件可以在服务器上的任意位置触发 Touched(Network ownership 文档)。验证和速率限制:scenario-roblox-networking。
  2. 了解查询会跳过什么。 Spherecast、Blockcast 和 Shapecast 会忽略起点所在的部件(veraktt,GtqFcyFgIXQ 00:19:33)。用重叠查询检查起点。Shapecast 的最终位置为 origin + direction.Unit * Distance;Position 是接触点(Crusherfire,EIOwGMZYidw 00:07:12)。使用 ExcludeInstances 或 IncludeInstances,绝不要使用 FilterDescendantsInstances,并为每次射击单独构建列表(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 共用一个调度器,并按目标数量测量。 每次 Heartbeat 处理一个分组,每个工作线程在预算内计算路径;感知先按距离筛选,再对静态几何体进行一次射线投射 [added]。测量结果基于 100 个 R15 NPC:服务器 60 fps,帧耗时 p95 为 17.6 ms,巡逻时 AI 每帧耗时 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 文档)。纯装饰性的人群可以使用客户端 Humanoid,每 5 s 为每个 NPC 更新一个属性(Suphi Kaner,JyMxrcqEzu8 00:13:50)。
  6. 大脑是带滞后的数据。 状态包含 onEnter、onStay、onExit,转换则以列表表示(Miller,Roblox Learn,nlVpAZEkxgo 00:00:57)。距离 5 studs 时进入 Attack,距离超过 6.5 时退出,失去视野 4 s 后放弃追击 [added]。寻路成功条件是 pcall 成功且 Status == Success(BrawlDev,ckA4fVkAjIA 00:15:48);仅当 Blocked 时的索引位于下一个航点或之后,才重新计算路径(Pathfinding 文档)。重新发出 MoveTo,因为它会在 8 s 后放弃。将路线代价集中在一个 Costs 表中(材质、PathfindingModifier 和 PathfindingLink 标签),不要编写特殊情况代码;仅在地面上、已加载的世界中,且距离小于 3,000 studs 时计算;移动失败时跳到该航点,而不是目标点(P12)。
  7. 眩晕会取消待处理的攻击。 受击者排队中的挥击会被丢弃,且在有限时长的眩晕期间拒绝其请求(ArTheDev,Aoc9HkGHu_8 00:02:57)。每次挥击每个角色只能命中一次,不能按肢体分别计算(Ludius 00:04:06)。使用持续 0.2 s 的 LinearVelocity 将 Humanoid 击退:一次 ApplyImpulse 让站立的假人移动了 1.2 studs,而 LinearVelocity 让其移动了 10.5 [measured]。
  8. 汽车由约束和所有权构成。 每个车轮使用一个 CylindricalConstraint 和一个 SpringConstraint,并连接到相同的附件;上限低于 0(Suphi Kaner,FVOowr2DXbM 00:10:19)。驾驶员坐在车内时拥有汽车(Network ownership 文档),服务器则持续检查速度;竞技赛车应使用 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 studs,距离 3.5 studs;抛射物使用半径 0.25 studs 的球体扫掠;载具采用下方的数值。

流程

完整代码和测试结果:procedures.md。模块: scripts/agentkit/gameplay/;Python: scripts/rbx_gameplay.py。

  1. 安装。 目标:在打开的 place 中安装工具包、启动脚本和 Input Action 实例。方法: rbx_gameplay.install(studio) 会在 Edit 中写入 Source(P1)。验收关卡:Playtest 的 Server 能看到 hook 和 remotes;Client 能看到 GameplayInputs.Combat.Attack;控制台中没有启动错误。
  2. 探测查询。 目标:获取此构建版本的事实数据。方法:执行 Edit 探测(P2)。验收关卡:从内部发起的 Spherecast 会返回远处的部件;Shapecast 距离与预期行程相差不超过 0.05 studs。
  3. 在 Lune 中实现决策逻辑。 目标:获得清晰且经过测试的决策表。方法:使用 StateMachine 和 NpcBrain (P4)。验收关卡:lune run lune_unit.luau 通过。
  4. 人群和开销。 目标:明确服务端开销。方法:使用 NpcService 和基准测试(P5)。验收关卡:100 个根部件中有 0 个由客户端所有;记录每个数量下的服务端 fps 和 p95;与 scenario-roblox-performance 确定预算。
  5. 追猎。 目标:协同实现感知、寻路和近战。方法:walk_to 让玩家先进入视线,再移动到墙后(P6);制定寻路失败规则和路线定价(P12)。验收关卡:NPC 能到达墙后的玩家并命中;记录结果。
  6. 战斗。 目标:实现一个能抵御连发和眩晕的连击。方法:使用 Input Action、intent remote、Combo 和 Hitbox.box(P7);使用 Projectile 实现抛射物(P8)。验收关卡:两个正面的假人生命值均为 58,后方的假人未受影响;连发时,已接受的挥击间隔不小于 0.24 s;0.2-stud 厚的墙能挡住所有抛射物。无论等待多久,user_keyboard_input 都会以 0.13 至 0.20 s 的间隔发送按键;洪泛测试通过客户端脚本发送 remote(P7)。
  7. 载具。 目标:能够驾驶和转向,并保持平稳。方法:使用 Car.build、Car.serve、Car.controller (P9)。验收关卡:驾驶员拥有底盘;按住 W 3 s 后,载具向前移动超过 30 studs;同时按住 W 和 D 后,载具右转超过 20 degrees;UpVector.Y 保持在 0.8 以上;退出后所有权恢复为自动;在油门按住时离开会让载具停下(P14);记录前后状态。
  8. 审计和审查。 方法:使用 GameplayAudit、负责人执行的 Audit(P3)、审查和一张联系表。验收关卡: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.huge 表示永不通行Costs 键:材质、修改器和链接标签(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(射线)每次调用
悬挂刚度 3500、阻尼 200、自由长度 2.8Suphi Kaner
滑动限制上限 -1,下限 -2沿 Attachment0 X 轴(向上)
驱动MaxSpeed / radius、扭矩 5000、怠速 2000后轮
转向0.4 s 内转动 30 degrees车身前部的附件
汽车速度检查MaxSpeed 的 1.5 倍;1 s 内检查两次服务端,且车辆由驾驶员拥有时
100 个 NPC,实测60 fps、p95 17.6 ms、心跳 0.27 ms、物理 1.8 ms、发送速率 21.5 kbps巡逻中,服务端,Studio 0.743
单条路径,实测65 ms 墙钟时间(会让出执行权),0 次失败ComputeAsync,开放底板
投射,实测Spherecast 0.46、Raycast 0.30 microseconds50 studs,小型包含列表
汽车,实测3 s 行驶 177.9 studs,最高速度 51.0 studs/s;2.5 s 转向 112 degreesW,然后 W 加 D

质量门槛

  • 可测量:Lune 规格;rbx_check 错误数为 0;GameplayAudit 错误数为 0;NpcService.stats() (状态、客户端拥有的根部件、AI 毫秒数、路径);Server 中的 AgentKit Stats;假人生命值和命中次数;汽车样本(距离、朝向、UpVector.Y)。
  • 视觉:通过 rbx_review.contact_sheet 查看人群、墙后追捕、终结技后的假人、汽车驾驶前后的截图(不超过 1,600 px)。在 Visualization Options 中启用 Navigation mesh 或 Network owners,并用 DebugDraw 装饰器绘制路点和查询框,进行深度测试,确保截图中能看到它们(P13)。
  • 关键测试会记录客户端输入,并在输入与发送的按键不同时重新运行(P7)。

常见错误

错误症状修复
Touched 造成伤害隔墙命中、伤害异常在服务器上进行盒体查询
每个肢体返回一个结果每次挥击命中 3 到 5 次按角色模型对结果去重
投射物从墙内开始射击穿透墙壁首次扫描前进行重叠查询
每帧通过 Position 传送高速移动时发生穿透先扫描,再移动
FilterDescendantsInstances在新代码中属于已弃用的 API使用 ExcludeInstances、IncludeInstances
可查询调试部件射线检测停在自己的标记上将 CanQuery 设为 false(Crusherfire 00:10:42)
MoveToFinished:Wait()NPC 在 8 秒后冻结重新发出 MoveTo;处理 reached == false
在空中或地图加载前计算路径Status 异常,NPC 静止不动等待 FloorMaterial,并在加载完成后再执行(P12)
移动失败后直接传送到目标点NPC 会穿过墙壁传送到该路径点(P12)
在代码中规避危险特殊情况处理脆弱在 Costs 中为修改器标签设定成本(P12)
启用每个 Humanoid 的所有功能每个 NPC 都会增加物理步骤开销精简状态、使用对象池;静止时不启用状态机(P5)
调用 ComputeAsync 时未使用 pcall路径异常时脚本会终止使用 pcall 并检查 Status
NPC 根部未固定最近的客户端会移动 NPC调用 SetNetworkOwner(nil)
每个 NPC 一个循环开销随脚本数量增长使用一个调度器和分组
BodyVelocity已弃用的驱动器使用 LinearVelocity、VectorForce、AlignPosition
约束未设置 Attachment0无法移动,且不报错使用 GameplayAudit constraint-no-attachment
悬架上限为 0弹簧触底,汽车弹跳将上限设为 -1
读取 Throttle不支持游戏手柄模拟输入或触控输入使用 ThrottleFloat、SteerFloat
乘客拥有汽车驾驶员会遇到延迟在 Occupant 变化时重新分配所有权
只有一个固定出口侧汽车翻转时,玩家会掉到地图下方使用最高的出口点(P14)
离开时未重置马达值空车会继续行驶离开时释放马达(P14)
只能使用键盘进行战斗手机无法攻击绑定触控 UIButton(P7)

交接

  • 从 scenario-roblox-architecture 接收:RoundMachine 回合循环、用于带标签武器和危险物的 Binder、DamageService 插槽。
  • 交付给 scenario-roblox-networking:待验证的命中箱、弹道和技能规则(带回溯的 HitCheck)、用于可疑度评分的汽车速度标记、服务器权威设置。
  • 交付给 scenario-roblox-animation:NPC 的 State 和 Action 属性及连招步骤,用于驱动动画轨道;在服务器权威模式下,不缓存动画轨道。
  • 交付给 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 无需启用 beta。
  • 文档说明 RunService:BindToSimulation 需要 Workspace.UseFixedSimulation。在 0.743 中, 即使 place 从未设置该属性,它仍能在 Edit 和 Play 中运行(P11);脚本无法从 Studio MCP 上下文读取此属性,因此请在 Rojo 项目中显式设置。
  • Creator Store 模型已沙盒化(2026-05-13):FastCast 等供应商库应以源码形式提供。

参考资料

评论

支持 Markdown