fix: Ability to force the game to start for a benchmark. - #17
fix: Ability to force the game to start for a benchmark.#17webbrain-one wants to merge 1 commit into
Conversation
Add `Playtime = true` configuration attribute. When enabled, displays a popup prompting the user to start the game via RunService:Run() with an option to suppress the message. Closes AsynchronousAI#7
📝 WalkthroughWalkthroughThe plugin adds a disabled-by-default ChangesPlaytime benchmark startup
Estimated code review effort: 2 (Simple) | ~10 minutes Suggested reviewers: Sequence Diagram(s)sequenceDiagram
participant BenchmarkPlugin
participant PersistentSetting
participant ConfirmationPrompt
participant RunService
BenchmarkPlugin->>PersistentSetting: Check suppression setting
BenchmarkPlugin->>ConfirmationPrompt: Prompt when playtime is enabled
ConfirmationPrompt-->>BenchmarkPlugin: Return confirmation and do-not-show-again choice
BenchmarkPlugin->>PersistentSetting: Store suppression choice
BenchmarkPlugin->>RunService: Defer Run() when accepted
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/index.server.tsx`:
- Line 20: Update the setting lookup in the suppressed initialization to call
Plugin.GetSetting with only the Scriptbench_SuppressPlayPrompt key, then apply a
strict boolean check to the returned Variant so an unset result does not enable
suppression.
- Around line 27-28: Update the checked branch around plugin settings and the
deferred RunService.Run call to persist the accepted decision in its own
setting, separate from Scriptbench_SuppressPlayPrompt. On subsequent plugin
loads, read that stored decision and defer RunService.Run only when it is
accepted; preserve the declined behavior. Add regression coverage for accepted
and declined checked flows across two loads.
- Around line 22-26: Replace the unsupported plugin.PromptGlobalConfirm call in
the confirmation flow with a supported PluginGui API, preserving the auto-start
prompt and “Do not show again” behavior. Use the resulting supported GUI
interaction to determine the accepted and checked states without relying on
undeclared methods or adding a runtime shim.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: ddaa5519-5642-491f-a8a0-b6ca08dd1ee1
📒 Files selected for processing (2)
src/configurations.tssrc/index.server.tsx
| if (RunService.IsRunMode()) return; | ||
|
|
||
| if (PLAYTIME) { | ||
| const suppressed = plugin.GetSetting("Scriptbench_SuppressPlayPrompt", false); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
rg -n --hidden --glob '!node_modules' --glob '!dist' 'GetSetting|Scriptbench_SuppressPlayPrompt|interface Plugin|class Plugin' .Repository: AsynchronousAI/scriptbench
Length of output: 1827
🌐 Web query:
Roblox Plugin GetSetting API signature optional second argument
💡 Result:
The Roblox Plugin:GetSetting API does not have an optional second argument [1][2][3]. The official method signature is defined as Plugin:GetSetting(key: string): Variant [1][2]. It accepts only a single string argument representing the key of the setting to retrieve [1][4]. If you need to provide a default value when a setting does not exist, you should handle the nil return value in your Lua code [1][5]. A common pattern is to use the or operator: local value = plugin:GetSetting("MyKey") or defaultValue [5]
Citations:
- 1: https://create.roblox.com/docs/reference/engine/classes/Plugin/GetSetting
- 2: https://create.roblox.com/docs/reference/engine/classes/Plugin.md
- 3: https://robloxapi.github.io/ref/class/Plugin.html
- 4: https://roblox.fandom.com/wiki/Class:Plugin/GetSetting
- 5: https://devforum.roblox.com/t/help-with-pluginsetsetting-and-getsetting/1757295
🏁 Script executed:
printf '%s\n' '--- package and type files ---'
git ls-files | rg '(^|/)(package\.json|tsconfig[^/]*\.json|.*\.d\.ts)$'
printf '%s\n' '--- relevant source ---'
cat -n src/index.server.tsx | sed -n '1,45p'
printf '%s\n' '--- Plugin and GetSetting declarations ---'
rg -n -C 4 --hidden --glob '!node_modules' --glob '!dist' \
'GetSetting\s*\(|declare.*Plugin|interface Plugin|type Plugin' \
. --glob '*.d.ts' --glob '*.ts' --glob '*.tsx' --glob '*.luau'Repository: AsynchronousAI/scriptbench
Length of output: 13625
🏁 Script executed:
node - <<'JS'
const fs = require('fs');
const path = 'src/index.server.tsx';
const source = fs.readFileSync(path, 'utf8');
const match = source.match(/plugin\.GetSetting\(([^)]*)\)/);
if (!match) throw new Error('GetSetting call not found');
const args = match[1].split(',').map(s => s.trim()).filter(Boolean);
console.log(JSON.stringify({ call: match[0], argumentCount: args.length, arguments: args }));
JSRepository: AsynchronousAI/scriptbench
Length of output: 313
Call Plugin:GetSetting with one argument. Plugin:GetSetting accepts only the setting key. Use a strict boolean check for the unset Variant result.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/index.server.tsx` at line 20, Update the setting lookup in the suppressed
initialization to call Plugin.GetSetting with only the
Scriptbench_SuppressPlayPrompt key, then apply a strict boolean check to the
returned Variant so an unset result does not enable suppression.
Source: MCP tools
| const [accepted, checked] = plugin.PromptGlobalConfirm( | ||
| "Auto-Start Game", | ||
| "Would you like to automatically start the game simulation for benchmarks?", | ||
| "Do not show again" | ||
| ); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🔴 Critical | 🏗️ Heavy lift
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Find project-local declarations or implementations.
rg -n '\bPromptGlobalConfirm\b' . || true
# Inspect installed roblox-ts declarations when dependencies are present.
if [ -d node_modules/@rbxts/types ]; then
rg -n '\bPromptGlobalConfirm\b|\binterface Plugin\b' \
node_modules/@rbxts/types || true
fiRepository: AsynchronousAI/scriptbench
Length of output: 252
🏁 Script executed:
set -euo pipefail
printf '%s\n' '--- tracked files ---'
git ls-files | sed -n '1,120p'
printf '%s\n' '--- project metadata ---'
for f in package.json tsconfig.json src/index.server.tsx; do
if [ -f "$f" ]; then
printf '\n--- %s ---\n' "$f"
cat -n "$f"
fi
done
printf '%s\n' '--- Plugin API references ---'
rg -n '\bPlugin\b|PromptGlobalConfirm|PLAYTIME|plugin\.' src package.json tsconfig.json 2>/dev/null || trueRepository: AsynchronousAI/scriptbench
Length of output: 22539
🏁 Script executed:
set -euo pipefail
printf '%s\n' '--- local type declarations ---'
fd -a -t f . | rg '(^|/)(types|.*\.d\.ts)(/|$)' | sed -n '1,160p'
rg -n '\bPromptGlobalConfirm\b|\binterface Plugin\b|\bdeclare (global|const) plugin\b' \
--glob '!bun.lock' --glob '!Scriptbench.rbxm' . || true
printf '%s\n' '--- locked Roblox types version ---'
rg -n -C 3 'node_modules/@rbxts/types|`@rbxts/types`@' bun.lock || true
printf '%s\n' '--- PLAYTIME definition and references ---'
cat -n src/configurations.ts | sed -n '1,70p'
rg -n -C 3 '\bPLAYTIME\b' srcRepository: AsynchronousAI/scriptbench
Length of output: 5615
🌐 Web query:
Official Roblox Creator Hub Plugin class API reference: determine whether Plugin:PromptGlobalConfirm exists and identify the supported confirmation-dialog API, if any.
💡 Result:
The method Plugin:PromptGlobalConfirm does not exist in the official Roblox Plugin class API [1][2]. There is no built-in, native API provided by the Plugin class for creating generic confirmation dialogs [1][2]. Developers requiring such functionality typically implement custom dialog systems by creating a GUI using a PluginGui (such as a DockWidgetPluginGui) and managing the input events manually [3][4]. While developers often seek native solutions, common practice involves building modular UI components or using community-created libraries to handle confirmation flows, as no standardized, engine-level confirmation-dialog method is exposed for plugins [5][6]. Additionally, PluginGui:BindToClose can be used to intercept the closing of a plugin window, where a custom confirm button can be injected to require user interaction before the window closes [3][4].
Citations:
- 1: https://create.roblox.com/docs/reference/engine/classes/Plugin
- 2: https://create.roblox.com/docs/reference/engine/classes/Plugin.md
- 3: https://create.roblox.com/docs/reference/engine/classes/PluginGui.md
- 4: https://robloxapi.github.io/ref/class/PluginGui.html
- 5: https://devforum.roblox.com/t/theres-any-way-to-use-rostrap-confirmationdialog-on-a-plugin/1769523
- 6: https://devforum.roblox.com/t/plugin-ui-toolkit/24908
🏁 Script executed:
set -euo pipefail
tmpdir="$(mktemp -d)"
trap 'rm -rf "$tmpdir"' EXIT
curl -fsSL \
'https://registry.npmjs.org/@rbxts%2ftypes/1.0.880' \
-o "$tmpdir/metadata.json"
tarball="$(jq -r '.dist.tarball' "$tmpdir/metadata.json")"
curl -fsSL "$tarball" -o "$tmpdir/types.tgz"
if tar -tzf "$tmpdir/types.tgz" | grep -qE '(^|/)PromptGlobalConfirm|(^|/)Plugin\.d\.ts'; then
tar -xzf "$tmpdir/types.tgz" -C "$tmpdir"
rg -n '\bPromptGlobalConfirm\b|\binterface Plugin\b' "$tmpdir/package" || true
else
printf '%s\n' 'No matching Plugin declaration file or PromptGlobalConfirm symbol in the package archive.'
fiRepository: AsynchronousAI/scriptbench
Length of output: 254
🏁 Script executed:
set -euo pipefail
tmpdir="$(mktemp -d)"
trap 'rm -rf "$tmpdir"' EXIT
curl -fsSL \
'https://registry.npmjs.org/@rbxts%2ftypes/1.0.880' \
-o "$tmpdir/metadata.json"
tarball="$(jq -r '.dist.tarball' "$tmpdir/metadata.json")"
curl -fsSL "$tarball" -o "$tmpdir/types.tgz"
tar -xzf "$tmpdir/types.tgz" -C "$tmpdir"
printf '%s\n' '--- matching declarations ---'
rg -n '\bPromptGlobalConfirm\b|\binterface Plugin\b|\bclass Plugin\b' \
"$tmpdir/package" || true
printf '%s\n' '--- declaration files containing Plugin ---'
find "$tmpdir/package" -type f \( -name '*.d.ts' -o -name '*.d.luau' \) \
-print0 | xargs -0 rg -l '\bPlugin\b' | sed -n '1,80p'Repository: AsynchronousAI/scriptbench
Length of output: 985
Replace the unsupported PromptGlobalConfirm call. Plugin in @rbxts/types@1.0.880 and the Roblox API do not define this method. The repository has no declaration or runtime shim. Implement the confirmation flow with a supported PluginGui API.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/index.server.tsx` around lines 22 - 26, Replace the unsupported
plugin.PromptGlobalConfirm call in the confirmation flow with a supported
PluginGui API, preserving the auto-start prompt and “Do not show again”
behavior. Use the resulting supported GUI interaction to determine the accepted
and checked states without relying on undeclared methods or adding a runtime
shim.
Source: MCP tools
| if (checked) plugin.SetSetting("Scriptbench_SuppressPlayPrompt", true); | ||
| if (accepted) task.defer(() => RunService.Run()); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n -C 8 \
'Scriptbench_SuppressPlayPrompt|accepted|checked|RunService\.Run' .Repository: AsynchronousAI/scriptbench
Length of output: 6694
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- tracked candidates ---'
git ls-files | rg '(^|/)(src/index\.server\.tsx|.*(test|spec).*\.(ts|tsx|lua|luau)|package\.json|tsconfig.*|README.*)$' | head -200
printf '%s\n' '--- index.server.tsx ---'
cat -n src/index.server.tsx
printf '%s\n' '--- PromptGlobalConfirm and setting API references ---'
rg -n -C 6 'PromptGlobalConfirm|GetSetting|SetSetting|Scriptbench_SuppressPlayPrompt|RunService\.Run' src package.json README.md 2>/dev/null || true
printf '%s\n' '--- package scripts ---'
if [ -f package.json ]; then
node -e 'const p=require("./package.json"); console.log(JSON.stringify(p.scripts||{}, null, 2))'
fiRepository: AsynchronousAI/scriptbench
Length of output: 14240
🌐 Web query:
Roblox Studio Plugin PromptGlobalConfirm return values checked do not show again
💡 Result:
There is no native method named PromptGlobalConfirm in the Roblox Plugin API. It is likely you are either referring to a custom-implemented UI module or are encountering a misunderstanding regarding available Studio plugin dialogs [1][2][3]. Because there is no native "PromptGlobalConfirm" method, there is no built-in "do not show again" return value functionality associated with it. If you are using a third-party plugin or custom module that provides a message box or confirmation dialog, you must handle "do not show again" logic manually using standard plugin data storage methods [4][5]. To implement a "do not show again" feature in your own plugin, follow these steps: 1. Use plugin settings to store the user's preference. Roblox plugins provide the:SetSetting and:GetSetting methods specifically for persisting small bits of data, such as user preferences, across sessions [5]. 2. Before displaying your custom dialog or confirmation GUI, check the stored setting using:GetSetting. 3. If the setting indicates the user has chosen not to see the prompt again, skip the display logic. 4. If the user checks a "do not show again" box in your custom UI, save that choice using:SetSetting so it persists for future sessions [4][5]. If you were looking for standard ways to prompt users in Studio, the Plugin object provides methods like PromptForExistingAssetId, but these do not include "do not show again" persistence out of the box [6][3]. For custom interfaces, developers typically create a custom PluginGui (via Plugin:CreateDockWidgetPluginGui) and manage the UI state manually [2][7][8].
Citations:
- 1: https://devforum.roblox.com/t/nativemsgbox-studio-matching-message-boxes-for-plugins/2037878
- 2: https://create.roblox.com/docs/reference/engine/classes/PluginGuiService
- 3: https://create.roblox.com/docs/reference/engine/classes/Plugin
- 4: https://devforum.roblox.com/t/how-to-make-a-never-show-again-button-for-a-gui/2713960
- 5: https://devforum.roblox.com/t/plugin-development-in-a-nutshell/1318723
- 6: https://create.roblox.com/docs/reference/engine/classes/Plugin.md
- 7: https://create.roblox.com/docs/reference/engine/classes/PluginGui
- 8: https://create.roblox.com/docs/studio/plugins
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
def current_startup(suppressed, accepted=None, checked=None):
runs = False
writes = []
if not suppressed:
if checked:
writes.append(("Scriptbench_SuppressPlayPrompt", True))
if accepted:
runs = True
return runs, writes
cases = [
("accepted-and-checked", False, True, True),
("declined-and-checked", False, False, True),
]
for name, suppressed, accepted, checked in cases:
first = current_startup(suppressed, accepted, checked)
second = current_startup(True)
print(name)
print(" first_load:", first)
print(" next_load:", second)
PY
printf '%s\n' '--- test infrastructure and prompt API declarations ---'
git ls-files | rg '(^|/)(.*\.(test|spec)\.(ts|tsx|lua|luau)|.*\.d\.ts$|package\.json)$' | head -200
rg -n 'PromptGlobalConfirm|interface Plugin|declare.*Plugin|GetSetting\(' . --glob '!src/index.server.tsx' --glob '!src/settings.ts' 2>/dev/null || trueRepository: AsynchronousAI/scriptbench
Length of output: 3264
Persist and apply the auto-start decision.
When checked is true, persist accepted separately from Scriptbench_SuppressPlayPrompt. On later plugin loads, run RunService.Run() when the stored decision is accepted, and do not run it when the stored decision is declined. Add regression coverage for both checked flows across two loads.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/index.server.tsx` around lines 27 - 28, Update the checked branch around
plugin settings and the deferred RunService.Run call to persist the accepted
decision in its own setting, separate from Scriptbench_SuppressPlayPrompt. On
subsequent plugin loads, read that stored decision and defer RunService.Run only
when it is accepted; preserve the declined behavior. Add regression coverage for
accepted and declined checked flows across two loads.
Closes #7
Summary by CodeRabbit