mcpField
R
roblox-studio-emulation

roblox-studio-emulation

github.com/flatbedj测试与质量049 次安装6 周前更新
代码仓库

关于 roblox-studio-emulation

roblox-studio-emulation 是面向 Roblox Studio 开发者的测试技能,用于验证移动设备、多人交互和边界条件。它介绍菜单自动化、远程事件测试,以及如何说明验证结果的范围。

主要功能

  1. 01模拟触控和设备条件
  2. 02用 AppleScript 操作 Studio 测试菜单
  3. 03通过真实远程事件测试多人流程
  4. 04用客户端属性设置测试场景
  5. 05区分实测、逻辑验证与未测试

适用场景

  1. 01检查仅触控界面的行为
  2. 02无需第二客户端测试派对状态更新
  3. 03用合成输入测试逻辑分支

MCP 相关

该技能配合 Roblox Studio MCP 工具使用,并提及在切换模拟器后通过 `list_roblox_studios`、`set_active_studio` 和 `start_stop_play` 重新连接。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/flatbedj/roblox-skills --skill roblox-studio-emulation

安装后在 Claude Code 中输入/roblox-studio-emulation确认已加载。

详细介绍

模拟单人试玩无法触及的条件

仅靠 MCP 工具进行测试时,有两大类测试看起来无法完成,因此很容易想把它们推给用户。但这两类测试都可以自行完成。声称需要用户测试某项内容前,请先查看这里。

常规开发循环请参阅 roblox-studio-workflow;MCP 工具箱请参阅 roblox-studio-mcp。


1. 设备模拟(手机/平板/触控)——通过 Studio 菜单栏

Studio 不会向 macOS 辅助功能开放任何窗口(count windows → 0),因此你无法调整其窗口大小。 但它会开放整个菜单栏,足以操作 Test 菜单。

# one-time: the user must grant Terminal (or your host app) Accessibility permission
#   System Settings → Privacy & Security → Accessibility
# symptom if missing: "osascript is not allowed assistive access. (-1719)"

osascript -e 'tell application "Roblox Studio" to activate'
osascript -e 'tell application "System Events" to tell process "RobloxStudio" \
  to click menu item "Device Emulator" of menu 1 of menu bar item "Test" of menu bar 1'

进程名称是 RobloxStudio(不是 “Roblox Studio”,也不是 “RobloxStudioBeta”)。

确认设置确实生效,不要想当然——启动 Play 并读取实际值:

local cam = workspace.CurrentCamera
local UIS = game:GetService("UserInputService")
-- desktop: ~1920x1080, TouchEnabled=false
-- emulated: device-sized viewport, TouchEnabled=TRUE
return cam.ViewportSize, UIS.TouchEnabled

TouchEnabled = true 表示仅触控代码路径(摇杆间距、触控布局分支、POS_SHOWN 偏移)现已启用。

完整的 Test 菜单(实用项目):

项目说明
Device Emulator切换模拟状态
Controller Emulator / Player Emulator模拟游戏手柄/玩家状态
Start Test Session必须先启动,才能使用 Add Clients
Add Clients在 Play Solo 中不可用;在 Test Session 中可用
Toggle Client View、Pause Client、End Session控制多客户端会话

点击前先枚举项目并检查其启用状态:

osascript -e 'tell application "System Events" to tell process "RobloxStudio" \
  to get name of every menu item of menu 1 of menu bar item "Test" of menu bar 1'
osascript -e 'tell application "System Events" to tell process "RobloxStudio" \
  to get enabled of menu item "Add Clients" of menu 1 of menu bar item "Test" of menu bar 1'
限制
  • 选择特定设备(iPhone、iPad 等)需要使用窗口内的下拉菜单,而该菜单不会通过 AX 暴露。你只能使用当前选中的设备。如果需要特定宽度,请让用户设置一次——狭窄的手机屏幕最容易导致布局出错。
  • 切换模拟器会结束当前 Play 会话,并可能导致 MCP 链接断开。通过 list_roblox_studios → set_active_studio 重新连接,然后运行 start_stop_play。
  • 完成后请将模拟器切回关闭状态,否则之后的每张截图都会显示为触控设备。

2. 无需第二个客户端即可测试多人游戏功能——触发真实的远程事件

**这通常比启动多客户端会话更快、更精确。**服务器 VM 和客户端 VM 共享 DataModel,因此从服务器 VM 调用 FireClient 会到达真实的客户端模块,并触发其下游所有逻辑——信号处理程序、缓存状态、UI 刷新。

-- datamodel_type = "Server"
local Remotes = require(game:GetService("ReplicatedStorage"):WaitForChild("Shared").Remotes)
local plr = game.Players:GetPlayers()[1]

-- pretend the server told us we joined someone's party
Remotes.event("PartyUpdated"):FireClient(plr, {
    ownerUserId = 99999999, ownerName = "TestHost",
    members = { { userId = plr.UserId, name = plr.DisplayName } },
})

然后在客户端 VM 中断言可观测的实例状态(绝不要检查模块内部状态——VM 相互隔离,require 得到的是一个虚拟副本):

-- datamodel_type = "Client"
local on = 0
for _, p in game:GetService("CollectionService"):GetTagged("Plot") do
    for _, d in p:GetDescendants() do
        if d:IsA("ProximityPrompt") and d.Name == "PartyPrompt" and d.Enabled then on += 1 end
    end
end
return on

务必测试往返状态——触发“已加入”状态并进行断言,然后触发“已离开”状态(FireClient(plr, nil))并断言状态已恢复。单向测试会掩盖卡住的状态,这是更棘手的 bug(提示词一直隐藏 = 该玩家无法使用此功能)。

模拟前置条件

在客户端写入属性足以设置测试场景,因为客户端代码读取的是相同属性,而且 GetAttributeChangedSignal 会在本地触发:

-- datamodel_type = "Client" — pretend another player owns this plot
workspace.Map.Plots.Plot1:SetAttribute("OwnerUserId", 99999999)
-- ... run the test ...
workspace.Map.Plots.Plot1:SetAttribute("OwnerUserId", nil)  -- ALWAYS clean up
不适用的情况

如果代码要求被模拟的用户是真实在线的 Player,就无法用这种方法模拟。例如:某个轮询循环执行 Players:GetPlayerByUserId(owner),并清理任何未通过此检查的对象,那么你的设置会立即被撤销。表现为:创建的对象会在一秒内消失。

改用以下任一方法:

  • Test ▸ Start Test Session ▸ Add Clients,使用真实的第二个玩家;或
  • 在客户端 VM 中用合成输入对纯逻辑进行单元测试——逐字照搬已发布代码中的守卫条件/分支,并使用表格测试:
local cases = {
    { "nil payload",     nil,                 true  },
    { "empty string",    "",                  true  },
    { "garbage base64",  "!!!not-base64!!!",  true  },
    { "short buffer",    Base64.encode(short),true  },
    { "valid buffer",    Base64.encode(full), false },
}
-- assert blocked == expected for each; report N/N

这是有效且可报告的结果——但请明确说明这验证的是逻辑,而非完整的渲染路径。


如实报告

每次都要区分以下三种情况:

  • 实时验证——实际驱动功能并观察到了效果。
  • 逻辑验证——使用合成输入对分支进行了表格测试;完整路径未经测试。
  • 未经测试——如实说明,并明确指出测试还需要什么。

绝不要把“能编译,看起来也没问题”报告为已验证。

评论

支持 Markdown