Uploading Custom PEBL Tests
Quick Summary: Upload your own PEBL test scripts to use in studies, with automatic compilation to WebAssembly for browser-based testing.
What You'll Learn
- Who can upload custom tests and tier requirements
- How to prepare your PEBL test for upload
- The three-step upload process
- Understanding file selection and validation
- Managing storage quotas and rate limits
- Troubleshooting common upload errors
- Managing and deleting uploaded tests
Overview
The custom test upload system allows researchers to run their own PEBL (Psychology Experiment Building Language) tests through the online platform. Your PEBL scripts are compiled to WebAssembly, enabling participants to complete tests directly in their web browsers without installing any software.
Who can upload custom tests:
- Researcher+ tier accounts
- Institutional tier accounts
- Users with special upload permission granted by administrators
What you need:
- PEBL test script(s) packaged as a .zip file
- Main test file with a
Start()function - Optional: Library files, media assets, translation files
- Storage quota available in your account
Technical note: Tests are compiled using Emscripten to WebAssembly, typically taking 30-90 seconds per test. The platform handles compilation automatically—you don't need any special tools installed.
Before You Upload: Preparing Your Test
Required File Structure
Your .zip file should contain:
- Main test file (
.pbl): Must contain aStart()function - Library files (optional): Additional
.pblfiles with helper functions - Media assets (optional): Images, sounds, or other resources
- Translation files (optional): JSON files for multi-language support
Example Directory Structure
my-stroop-test.zip
├── stroop.pbl # Main test file (has Start() function)
├── helper-functions.pbl # Library file
├── images/
│ ├── red-word.png
│ └── blue-word.png
├── translations/
│ ├── stroop.pbl-en.json
│ └── stroop.pbl-es.json
└── params/
└── stroop.pbl.schema.json
PEBL Script Requirements
Your main test file must:
- Contain a
define Start()function - Use valid PEBL syntax
- Reference only files included in your .zip
Example minimal test:
define Start() {
gWin <- MakeWindow("BLACK")
instructions <- "This is my custom test. Press any key to begin."
Draw()
WaitForKeyPress()
# Your test logic here
WaitForKeyPress()
}
File Size Limits
- Maximum .zip size: 50 MB (configurable by platform)
- Storage quota per user: Varies by tier (typically 1-5 GB)
- Individual test bundle: Compiled tests typically 5-20 MB
Step-by-Step Upload Process
Step 1: Access the Upload Page
- Log in to your researcher account
- Navigate to Custom Tests from the main menu
- Click "Upload Custom Test"
Storage Quota Display:
- Green: Under 75% usage
- Orange: 75-90% usage
- Red: Over 90% usage or at limit
If you're at your storage limit, you'll need to delete existing tests before uploading new ones.
Step 2: Upload Your .zip File
Method 1: Drag & Drop
- Drag your .zip file onto the upload zone
- The file name and size will appear
- Click "🔍 Analyze .zip File"
Method 2: Browse
- Click anywhere in the upload zone
- Select your .zip file from the file browser
- Click "🔍 Analyze .zip File"
- .zip file is extracted to a temporary directory
- All
.pblfiles are detected - PEBL syntax is validated for each file
- Files with
Start()function are identified as potential main test files
Analysis takes: 5-15 seconds depending on .zip size
Step 3: Select Test Files
After analysis, you'll see a table of all .pbl files found in your .zip:
Table columns:
- Main: Radio button—select which file is your main test (must have
Start()function) - Library: Checkbox—select additional files to include in the build
- Filename: Relative path within your .zip
- Type: "Test File" (has
Start()) or "Library" (helper functions) - Validation: Syntax check result (✓ Valid, ✗ Syntax Error, or Not Validated)
How to select files:
- Choose main test: Click the radio button for your main test file
- Only files with
Start()function can be selected as main test - You must select exactly one main file
- Choose libraries (optional): Check boxes for any library files your test needs
- Library files contain helper functions used by your main test
- You can select 0 or more library files
- Enter display name: Provide a friendly name for your test
- Example: "Modified Stroop Task with Feedback"
- This name appears in the study builder
- Add description (optional): Brief description of what your test measures
- Maximum 500 characters
- Helps you and collaborators identify the test later
Step 4: Create Test & Build
- Review your selections
- Click "✅ Create Test & Build"
- Wait for the build process to complete (30-90 seconds)
- Test record is created in the database
- Build is queued for compilation
- Emscripten compiles your PEBL code to WebAssembly
- Test bundle (.data, .js, .wasm files) is created
- Files are stored in
runtime/test-bundles/custom/
Build progress indicator shows:
- "Creating test and starting build..."
- Spinner animation
- Estimated time: 30-90 seconds
On success:
- ✅ "Upload successful!" message appears
- You'll see your auto-generated test ID (e.g.,
custom_my_stroop_123) - Automatic redirect to Manage Custom Tests page
Managing Your Custom Tests
After uploading, view all your tests at Custom Tests > Manage Custom Tests.
Test statuses:
- 🟢 Active: Build succeeded, test is ready to use
- 🟡 Building: Currently compiling to WebAssembly
- 🔴 Build Failed: Compilation errors occurred
- ⏸️ Queued: Waiting for build to start
Using Custom Tests in Studies
- Go to My Studies > Select a study > Manage Tests tab
- Your custom tests appear in the "Available Tests" list with a "🔧 Custom" badge
- Click "Add" to include the test in your study
- Configure parameters just like built-in tests
custom_ in their test ID.
Viewing Build Logs
If a build fails:
- Go to Manage Custom Tests
- Click on the failed test
- View the Build Log section
- Common errors include:
- Missing
Start()function - Syntax errors in PEBL code
- Missing media files referenced in code
- Exceeding memory limits during compilation
Deleting Custom Tests
Important: You cannot delete a test that is currently used in any study.
To delete a test:
- Go to Manage Custom Tests
- Find the test you want to delete
- Click "Delete"
- Confirm deletion
- Test record from database
- Compiled WebAssembly bundles (.data, .js, .wasm)
- Uploaded source files
- Build queue entries
Storage quota is freed immediately after deletion.
If deletion fails with "Test is in use":
- Go to each study using this test
- Remove the test from the study's test list
- Return to Manage Custom Tests and try deleting again
Storage Quotas and Rate Limits
Storage Quotas
Each tier has a storage limit for custom tests:
- Free tier: 0 GB (cannot upload)
- Student tier: 0 GB (cannot upload)
- Researcher tier: 1 GB
- Researcher+ tier: 3 GB
- Institutional tier: 10 GB
How storage is calculated:
- Only compiled bundle size counts toward quota (not source .zip)
- Bundles typically compress well (10-20 MB per test)
- Deleted tests free up quota immediately
- Quota is per-user, not per-study
Rate Limits
To prevent abuse, upload rate limits apply:
- Default limit: 5 uploads per 60 minutes
- If exceeded: Must wait until oldest upload is 60 minutes old
- Resets: Rolling window (not fixed intervals)
Rate limit message example:
"Rate limit exceeded! Please wait until 3:45 PM before uploading again."
Common Issues
Problem: "Your account does not have permission to upload custom tests"
Solution: Upgrade to Researcher+ tier or higher, or contact support to request upload permission.
Why this happens: Only higher-tier accounts can upload custom tests to prevent abuse and manage server resources.
Problem: "No .pbl files found in archive"
Solution:
- Ensure your .zip contains
.pblfiles (not nested in subdirectories that the system can't detect) - Check that files have
.pblextension (case-sensitive on some systems) - Verify the .zip was created correctly (try extracting it manually first)
Why this happens: The system scans for .pbl files in the .zip and couldn't find any.
Problem: "Syntax Error" shown for .pbl files
Solution:
- Download and test your .pbl file locally using native PEBL
- Fix any syntax errors (missing
define, unmatched parentheses, etc.) - Common PEBL syntax mistakes:
- Forgetting
definekeyword before function names - Missing
Endafterif/loopblocks - Using undefined variables
- Incorrect function parameter syntax
Why this happens: The platform validates PEBL syntax before allowing upload to prevent build failures.
Problem: "Build Failed" status after upload
Solution:
- Click on the test in Manage Custom Tests
- View the Build Log for detailed error messages
- Common build failures:
- Missing media files: Your code references images/sounds not in the .zip
- Memory exceeded: Test is too complex or has memory leaks
- Emscripten errors: Compatibility issues with WebAssembly compilation
Why this happens: Even if syntax is valid, the WebAssembly compilation can fail due to runtime issues or resource limits.
Problem: "Storage quota exceeded"
Solution:
- Go to Manage Custom Tests
- Delete unused tests to free up space
- Consider upgrading to a higher tier for more storage
Problem: "Cannot delete test that is in use"
Solution:
- The error message lists which studies are using the test
- Go to each study's Manage Tests tab
- Click "Remove" next to your custom test
- Return to Manage Custom Tests and delete again
Problem: Test works locally but fails online
Solution: Common differences between native PEBL and WebAssembly version:
- File paths: Use relative paths, not absolute paths
- External commands: System commands (like
SystemCall) don't work in browser - Network access: Limited HTTP functionality
- Fonts: May need to include custom fonts in your .zip
- Performance: Some operations slower in browser
Debugging tips:
- Check browser console for JavaScript errors
- Test with a minimal PEBL script first
- Gradually add complexity to isolate issues
Best Practices
Before Uploading
- ✅ Test locally first: Run your PEBL test natively before uploading
- ✅ Use relative paths: All file references should be relative to test directory
- ✅ Include all dependencies: Fonts, images, sounds, libraries
- ✅ Validate syntax: Fix all PEBL syntax errors before zipping
- ✅ Organize clearly: Use descriptive filenames and folder structure
- ✅ Keep it simple: Start with minimal version, add complexity incrementally
File Organization
- 📁 Put media in subdirectories (images/, sounds/)
- 📁 Put translations in translations/ directory
- 📁 Put parameter schemas in params/ directory
- 📁 Name files descriptively (stroop-task.pbl, not test1.pbl)
Testing
- 🧪 Upload a test version first before using in active studies
- 🧪 Test with multiple browsers (Chrome, Firefox, Safari)
- 🧪 Test on mobile devices if participants will use them
- 🧪 Run through entire test to check for errors
Naming
- 🏷️ Use descriptive display names ("Emotional Stroop with Neutral Condition")
- 🏷️ Include version numbers if iterating ("Stroop v2.1")
- 🏷️ Add descriptions to help future you remember what each test does
Storage Management
- 💾 Delete old test versions when uploading new ones
- 💾 Monitor your storage quota regularly
- 💾 Remove tests from studies before deleting
- 💾 Archive source .zip files locally (platform may not store them forever)
Examples
Example 1: Simple Custom Reaction Time Test
Scenario: You created a basic reaction time test and want to deploy it online.
File structure:
reaction-time.zip
└── reaction-time.pbl
reaction-time.pbl:
define Start() {
gWin <- MakeWindow("BLACK")
## Instructions
instructions <- "Press the spacebar as fast as you can when you see the circle."
ShowText(instructions, gWin)
WaitForKeyPress()
## Trial loop
results <- []
loop(trial, Sequence(1, 10, 1)) {
## Random delay
Wait(RandomUniform(500, 2000))
## Show stimulus
circle <- Circle(gVideoWidth/2, gVideoHeight/2, 50, MakeColor("red"), 1)
AddObject(circle, gWin)
Draw()
t1 <- GetTime()
## Wait for response
WaitForKeyPress(" ")
rt <- GetTime() - t1
## Hide stimulus
RemoveObject(circle, gWin)
Draw()
## Store result
PushOnEnd(results, rt)
}
## Save data
FilePrint(gFileOut, "trial,rt")
loop(i, Sequence(1, Length(results), 1)) {
FilePrint(gFileOut, i + "," + Nth(results, i))
}
## Thank you
ShowText("Thank you! Press any key to finish.", gWin)
WaitForKeyPress()
}
define ShowText(text, win) {
label <- EasyLabel(text, gVideoWidth/2, gVideoHeight/2, win, 24)
Draw()
return label
}
Upload steps:
- Create reaction-time.zip containing reaction-time.pbl
- Upload to platform
- Select reaction-time.pbl as Main file
- Display name: "Simple Reaction Time Test"
- Click "Create Test & Build"
custom_reaction_time_12345
Example 2: Complex Test with Libraries and Media
Scenario: Multi-file Stroop task with images and translations.
File structure:
stroop-complete.zip
├── stroop.pbl # Main test
├── stroop-stimuli.pbl # Stimulus generation library
├── stroop-analysis.pbl # Data analysis functions
├── images/
│ ├── red-word-red.png
│ ├── red-word-blue.png
│ └── instructions.png
└── translations/
├── stroop.pbl-en.json
└── stroop.pbl-es.json
Upload steps:
- Upload stroop-complete.zip
- After analysis, select:
- Main: stroop.pbl
- Libraries: stroop-stimuli.pbl ✓, stroop-analysis.pbl ✓
- Description: "Image-based Stroop task with congruent/incongruent trials and multilingual support"
- Click "Create Test & Build"
Related Topics
- Parameter Variants - Create multiple configurations for your custom tests
- Custom Translations - Add multi-language support to your tests
- Account Settings - View your tier and storage quota
- Managing Studies - Add custom tests to your studies
- Technical FAQ - Learn about WebAssembly compilation
Advanced: Understanding the Build Process
What Happens During Compilation
- Source extraction: .zip file extracted to
custom_tests/user_{id}/{test_id}/ - File validation: PEBL syntax checking on all selected files
- Emscripten compilation:
- Selected .pbl files compiled to C++
- C++ compiled to WebAssembly (.wasm)
- JavaScript loader created (.js)
- Data package created (.data)
custom_{test_id}.{data,js,wasm}
- Deployment: Bundle copied to
runtime/test-bundles/custom/
Build Output Files
For a test with ID custom_my_test_123:
runtime/test-bundles/custom/
├── custom_my_test_123.data # Virtual filesystem (media, .pbl files)
├── custom_my_test_123.js # JavaScript loader
├── custom_my_test_123.js.metadata # File manifest
└── custom_my_test_123.wasm # WebAssembly binary (not always present)
Troubleshooting Build Logs
Example log (success):
[INFO] Starting build for test custom_reaction_time_12345
[INFO] Compiling PEBL source files: reaction-time.pbl
[INFO] Emscripten compilation started
[INFO] Creating data bundle
[INFO] Build completed in 42 seconds
[INFO] Bundle size: 8.3 MB
Example log (failure):
[INFO] Starting build for test custom_stroop_99999
[INFO] Compiling PEBL source files: stroop.pbl, stroop-lib.pbl
[ERROR] Compilation failed: images/stimulus.png not found
[ERROR] Referenced in: stroop.pbl line 45
[ERROR] Build failed after 15 seconds
Common error patterns:
not found: Missing file (add to .zip)syntax error: PEBL code invalid (fix syntax)out of memory: Test too large (simplify or reduce media size)permission denied: File permissions issue (contact support)
Need more help?
- Check Troubleshooting Guide for more solutions
- Contact support with your test ID and build log for assistance
- Visit the PEBL manual for PEBL language questions: http://pebl.sourceforge.net