AI-Assisted E2E Testing Workflow
RbxSync enables AI agents (Claude, Cursor, etc.) to autonomously test Roblox games through MCP (Model Context Protocol). This guide explains how to set up and use AI-powered end-to-end testing.
Overview
AI-assisted E2E testing allows AI agents to:
- Write code and sync changes to Studio instantly
- Start playtests and capture console output
- Control characters using pathfinding and actions
- Observe game state including health, inventory, and nearby objects
- Query server data like currency, DataStores, and services
- Wait for conditions to verify game behavior
- Iterate autonomously based on test results
This creates a development loop where an AI can implement features, test them in a real game environment, observe results, and fix issues without human intervention.
Prerequisites
Before using AI-assisted testing:
RbxSync server running
bashrbxsync serveStudio connected
- RbxSync plugin installed in Roblox Studio
- Plugin connected (green indicator in widget)
- A game open with at least one spawn point
MCP configured
- AI client (Claude Code, Cursor, etc.) configured with RbxSync MCP server
- See MCP Setup for configuration details
HTTP Requests enabled (for interactive bot testing)
- Required for:
bot_observe,bot_move,bot_action,bot_query_server,bot_wait_for,bot_command - NOT required for:
run_test(uses script injection) - See HTTP Requirement below
- Required for:
The Testing Loop
AI-assisted testing follows a cycle:
┌─────────────────────────────────────────────────────────────┐
│ 1. Write Code │
│ └─ AI writes/modifies Luau scripts │
├─────────────────────────────────────────────────────────────┤
│ 2. Sync to Studio │
│ └─ sync_to_studio pushes changes │
├─────────────────────────────────────────────────────────────┤
│ 3. Start Playtest │
│ └─ run_test starts F5 session with output capture │
├─────────────────────────────────────────────────────────────┤
│ 4. Observe & Act │
│ ├─ bot_observe → Get position, health, inventory │
│ ├─ bot_move → Navigate to locations/objects │
│ ├─ bot_action → Equip tools, interact, jump │
│ └─ bot_query_server → Check server-side state │
├─────────────────────────────────────────────────────────────┤
│ 5. Verify Results │
│ ├─ Check console output for errors │
│ ├─ bot_wait_for → Wait for conditions │
│ └─ Validate expected state changes │
├─────────────────────────────────────────────────────────────┤
│ 6. Iterate │
│ └─ If issues found, return to step 1 │
└─────────────────────────────────────────────────────────────┘MCP Tools Reference
Core Workflow Tools
| Tool | Purpose | When to Use |
|---|---|---|
sync_to_studio | Push local file changes to Studio | After editing code |
run_test | Start playtest with console capture | To test game behavior |
run_code | Execute Luau in plugin context | Setup test fixtures, spawn items |
Bot Control Tools
| Tool | Purpose | When to Use |
|---|---|---|
bot_observe | Get player state (position, health, inventory) | Check current game state |
bot_move | Pathfind to location or object | Navigate to NPCs, items, areas |
bot_action | Equip tools, interact, jump | Perform gameplay actions |
bot_query_server | Execute Luau on game server | Check DataStores, currency, services |
bot_wait_for | Wait for condition to be true | Verify async state changes |
Detailed Tool Usage
run_test
Start an automated playtest and capture all console output.
{
"duration": 30,
"mode": "Play"
}Parameters:
duration- Test length in seconds (default: 5)mode- "Play" for solo, "Run" for server simulation
Returns: Console output grouped by errors, warnings, and prints with timestamps.
bot_observe
Get current game state during playtest.
{
"type": "state"
}Types:
state- Full snapshot: position, health, inventory, nearby objectsnearby- Objects within radiusnpcs- NPCs/humanoids within radiusinventory- Tools in backpackfind- Search for objects by name (use withqueryparameter)
Example response:
{
"position": {"x": 0, "y": 5, "z": 0},
"health": 100,
"maxHealth": 100,
"inventory": ["Sword", "Health Potion"],
"equipped": "Sword",
"nearbyObjects": [
{"name": "ShopNPC", "distance": 15.2, "className": "Model"}
]
}bot_move
Navigate character using PathfindingService.
{
"objectName": "ShopNPC"
}Or by coordinates:
{
"position": {"x": 50, "y": 5, "z": 30}
}Returns: Whether destination was reached, final position, and path length.
bot_action
Perform character actions.
{
"action": "equip",
"name": "Sword"
}Actions:
equip- Equip tool by nameunequip- Unequip current toolactivate- Activate equipped tool (attack, use)deactivate- Stop tool activationinteract- Trigger nearby ProximityPromptjump- Make character jump
bot_query_server
Execute Luau code on the game server (requires active playtest).
{
"code": "return game.Players:GetPlayers()[1].leaderstats.Coins.Value"
}Use this to check:
- Player currency/stats
- DataStore values
- Server-side game state
- Service configurations
bot_wait_for
Wait for a condition to become true (polling-based).
{
"condition": "workspace:FindFirstChild('SpawnedItem') ~= nil",
"timeout": 10,
"context": "server"
}Parameters:
condition- Luau code returning booleantimeout- Max wait in seconds (default: 30)poll_interval- Check interval in ms (default: 100)context- "server" or "client" (default: server)
Example Workflows
Testing a Shop System
Goal: Verify player can buy an item from shop.
1. bot_observe type="find" query="Shop"
→ Find shop location
2. bot_move objectName="ShopNPC"
→ Navigate to shop
3. bot_action action="interact"
→ Open shop UI
4. bot_query_server code="return player.leaderstats.Coins.Value"
→ Record initial coins
5. bot_command type="ui" command="clickButton" args={"path": "ShopUI.BuyButton"}
→ Purchase item
6. bot_wait_for condition="player.Backpack:FindFirstChild('HealthPotion')"
→ Wait for item to appear
7. bot_observe type="inventory"
→ Verify item in inventory
8. bot_query_server code="return player.leaderstats.Coins.Value"
→ Verify coins decreasedTesting Combat
Goal: Verify weapon deals damage to enemies.
1. bot_observe type="inventory"
→ Check available weapons
2. bot_action action="equip" name="Sword"
→ Equip weapon
3. bot_observe type="npcs" radius=50
→ Find nearby enemies
4. bot_move objectName="TrainingDummy"
→ Navigate to target
5. bot_action action="activate"
→ Attack
6. bot_wait_for condition="workspace.TrainingDummy.Humanoid.Health < 100"
→ Wait for damage
7. bot_query_server code="return workspace.TrainingDummy.Humanoid.Health"
→ Verify damage dealtTesting Checkpoint System
Goal: Verify checkpoints save player position.
1. bot_observe type="state"
→ Get spawn position
2. bot_move objectName="Checkpoint1"
→ Navigate to checkpoint
3. bot_action action="interact"
→ Activate checkpoint
4. run_code code="game.Players:GetPlayers()[1]:LoadCharacter()"
→ Force respawn
5. bot_wait_for condition="game.Players:GetPlayers()[1].Character ~= nil"
→ Wait for respawn
6. bot_observe type="state"
→ Verify position near checkpoint (not original spawn)Example Claude Prompts
These prompts demonstrate how to instruct AI agents for testing:
Feature Testing
"Test that the player can buy a sword from the shop. Navigate to the shop NPC, interact with it, purchase the sword, and verify it appears in inventory."
Regression Testing
"Verify the checkpoint system saves player position correctly. Touch a checkpoint, die, and confirm you respawn at the checkpoint instead of the original spawn point."
Error Detection
"Run a 60-second playtest and report any errors or warnings in the console. Pay special attention to nil errors or script timeouts."
Integration Testing
"Test the full onboarding flow: spawn in, collect the tutorial sword, defeat the practice dummy, and verify the quest completion popup appears."
Performance Testing
"Check for errors when loading a large inventory. Use run_code to give the player 100 items, then verify the inventory UI displays correctly."
HTTP Requirement for Bot Testing
Interactive bot testing tools communicate with the game during playtests via HTTP. This requires enabling HTTP requests in your Roblox game settings.
Which Tools Need HTTP?
| Tool | Requires HTTP | Notes |
|---|---|---|
run_test | ❌ No | Uses script injection, works without HTTP |
run_code | ❌ No | Executes in plugin context, no HTTP needed |
sync_to_studio | ❌ No | Uses plugin API |
bot_observe | ✅ Yes | Queries game state via HTTP |
bot_move | ✅ Yes | Sends movement commands via HTTP |
bot_action | ✅ Yes | Sends action commands via HTTP |
bot_query_server | ✅ Yes | Executes server-side code via HTTP |
bot_wait_for | ✅ Yes | Polls conditions via HTTP |
bot_command | ✅ Yes | Sends generic commands via HTTP |
How to Enable HTTP Requests
- In Roblox Studio, go to Home → Game Settings (or File → Game Settings)
- Navigate to the Security tab
- Enable Allow HTTP Requests
- Click Save
Published Games
For published games, this setting affects both Studio testing and the live game. HTTP requests are disabled by default for security. Only enable if you understand the implications.
Why HTTP is Required
During a playtest, the bot tools need to communicate with the running game server to:
- Read player state (position, health, inventory)
- Send movement and action commands
- Execute server-side Luau code
- Poll for condition changes
The RbxSync plugin creates HTTP endpoints during playtests that the bot tools call. Without HTTP enabled, these requests will fail with connection errors.
Troubleshooting HTTP Issues
If bot commands fail with "HTTP request failed" or similar errors:
- Verify HTTP is enabled - Check Game Settings → Security
- Check firewall settings - Ensure localhost connections are allowed
- Verify playtest is running - HTTP endpoints only exist during playtests
- Check plugin connection - Plugin must show green indicator
Limitations
Plugin Context vs Game Context
run_codeexecutes in plugin context (edit mode)- Can modify instances, spawn items, set properties
- Cannot access runtime game services directly
bot_query_serverexecutes in game server context (play mode)- Can read player stats, DataStores, runtime state
- Requires active playtest
No Direct Input Simulation
Roblox's VirtualInputManager is internal-only. The bot system uses programmatic APIs instead:
Humanoid:MoveTo()instead of WASDTool:Activate()instead of mouse clickProximityPrompt:InputHoldBegin()instead of E key
This means some input-dependent features may not be testable.
Polling-Based Observation
State observation uses polling (not events). For optimal performance:
- Limit
bot_observecalls to ~10/second - Use
bot_wait_forfor async conditions - Batch queries when possible
Pathfinding Constraints
- Maximum efficient path: ~500 studs before recompute
- Cannot climb TrussParts by default
- May get stuck on complex geometry (has stuck detection)
Troubleshooting
"Bot command timeout"
Cause: No playtest running or plugin disconnected.
Fix:
- Ensure playtest is active (F5 in Studio)
- Verify plugin shows green connection indicator
- Check
rbxsync serveis running
"No character found"
Cause: Character hasn't spawned yet.
Fix:
- Add delay after starting playtest
- Use
bot_wait_forwith character spawn condition:json{"condition": "game.Players:GetPlayers()[1].Character ~= nil"}
Movement not reaching destination
Cause: Obstacles blocking path or destination unreachable.
Fix:
- Use
bot_observe type="nearby"to debug surroundings - Try moving to a nearby accessible point first
- Check for dynamic obstacles spawned after path computation
"Server query failed"
Cause: Code error or LoadStringEnabled not set.
Fix:
- Verify Luau syntax is correct
- Check Studio output for
[RbxSync] loadstring available - Ensure playtest is running (not just edit mode)
UI interactions failing
Cause: UI path incorrect or element not visible.
Fix:
- Use
bot_observe type="state"to seevisibleUIlist - Verify exact path:
ScreenGui.Frame.Button - Ensure UI is enabled and visible before clicking
Best Practices
- Observe before acting - Always check state before issuing commands
- Use wait_for for async - Don't assume instant state changes
- Handle failures gracefully - Check return values, implement retries
- Keep tests focused - One behavior per test for clear debugging
- Log test progress - Use
run_codeto print test markers - Test incrementally - Verify each step before combining into flows
Related Documentation
- Bot Testing Reference - Detailed API reference for bot tools
- E2E Testing in VS Code - VS Code-specific testing features
- MCP Tools - Complete MCP tool reference
- MCP Setup - Configuring MCP clients
