WebDoors Specification
June 23, 2026 · View on GitHub
Table of Contents
- Overview
- Directory Structure
- Manifest Format
- Configuration System
- Discovery and Activation
- Requirements System
- Configuration Overrides
- Game Access
- Integration with BBS Features
- Examples
- Installation
- Best Practices
- Security Considerations
- Troubleshooting
Overview
WebDoors is BinktermPHP's system for integrating external web-based games, applications, and terminal connections into the BBS. Each WebDoor is a self-contained application with its own manifest file that describes its capabilities, requirements, and configuration options.
WebDoors are displayed to users through the /games interface and can integrate with BBS features like storage, leaderboards, and the credits system.
The key idea is that a WebDoor is not just an isolated browser game in an iframe. It runs as part of the platform, reusing BinktermPHP identity, session, and API services so it can behave like a real BBS subsystem instead of a disconnected sidecar.
Directory Structure
WebDoors are installed in the public_html/webdoors/ directory. Each WebDoor resides in its own subdirectory:
public_html/webdoors/
├── blackjack/
│ ├── webdoor.json # Required manifest file
│ ├── index.php # Entry point
│ ├── icon.svg # Game icon
│ └── assets/ # Game assets
├── hangman/
│ ├── webdoor.json
│ ├── index.html
│ └── ...
└── revpol/
├── webdoor.json
├── index.php
└── ...
Manifest Format
Each WebDoor must include a webdoor.json manifest file in its root directory. The manifest describes the game's metadata, requirements, and default configuration.
Manifest Schema
{
"webdoor_version": "1.0",
"game": {
"id": "unique-game-id",
"name": "Display Name",
"version": "1.0.0",
"author": "Author Name",
"description": "Brief description of the game",
"entry_point": "index.html",
"icon": "icon.svg",
"screenshots": []
},
"requirements": {
"min_host_version": "1.0",
"features": ["storage", "leaderboard", "credits"],
"permissions": ["user_display_name"]
},
"storage": {
"max_size_kb": 256,
"save_slots": 1
},
"multiplayer": {
"enabled": false
},
"config": {
"comment": "This is a comment that is for informational use only",
"custom_setting": "default_value"
}
}
Field Descriptions
webdoor_version (string, required)
Version of the WebDoor specification. Current version is "1.0".
game (object, required)
Core game metadata displayed to users.
id(string, required): Unique identifier for the game. Used in configuration and API calls.name(string, required): Display name shown in the games list.version(string, required): Game version (semantic versioning recommended).author(string, required): Creator or developer name.description(string, required): Brief description shown in the games list.entry_point(string, required): Entry file relative to the WebDoor directory (e.g.,"index.html","index.php").icon(string, optional): Icon filename relative to the WebDoor directory. Defaults to"icon.png".screenshots(array, optional): Array of screenshot filenames for future use.
requirements (object, optional)
Declares features and permissions the WebDoor needs.
min_host_version(string): Minimum BinktermPHP version required.features(array): List of BBS features the game requires:"storage": Persistent storage API"leaderboard": Leaderboard/high score API"credits": BBS credits system integration
permissions(array): User data the game needs access to:"user_display_name": Access to user's display name
storage (object, optional)
Storage requirements for games that save user data.
max_size_kb(integer): Maximum storage size per user in kilobytes.save_slots(integer): Number of save slots per user.
multiplayer (object, optional)
Multiplayer capabilities (reserved for future use).
enabled(boolean): Whether the game supports multiplayer.
config (object, optional)
Default configuration values. These serve as defaults and can be overridden by the sysop in config/webdoors.json.
Common configuration keys:
comment: An informational comment for someone editing the JSONdisplay_name: Override the game's display namedisplay_description: Override the game's description- Game-specific settings (varies by WebDoor)
Configuration System
WebDoors are configured through the config/webdoors.json file. This file controls which games are enabled and allows sysops to customize game settings.
Configuration File Location
config/webdoors.json
Configuration Format
{
"blackjack": {
"enabled": true,
"start_bet": 10,
"display_name": "21 Blackjack"
},
"hangman": {
"enabled": true
},
"revpol": {
"enabled": true,
"display_name": "Reverse Polarity BBS",
"display_description": "Connect to the Reverse Polarity BBS",
"host": "revpol.lovelybits.org",
"port": "22",
"proto": "ssh"
}
}
Configuration Fields
enabled(boolean, required): Whether the game is active and visible to users.- Custom settings: Any settings defined in the manifest's
configsection can be overridden here. display_name(string, optional): Override the game's display name in the games list.display_description(string, optional): Override the game's description.
Configuration Priority
- Sysop Configuration (highest priority): Values in
config/webdoors.json - Manifest Defaults (fallback): Values in the WebDoor's
webdoor.jsonconfig section - Code Defaults (lowest priority): Hardcoded defaults in the WebDoor's code
Discovery and Activation
Auto-Discovery
The system automatically discovers WebDoors by:
- Scanning
public_html/webdoors/for subdirectories - Looking for
webdoor.jsonin each subdirectory - Parsing valid manifests and registering the WebDoor
Admin Interface
Sysops manage WebDoors through Admin → WebDoors (/admin/webdoors-config), which provides:
- List of discovered WebDoors with enable/disable controls
- Add New Door panel listing directories that don't yet have a manifest — click Create Manifest to open the manifest editor for that directory
- Manifest editor for creating and editing
webdoor.jsonfiles through a form UI
To activate a new WebDoor:
- Place the door files under
public_html/webdoors/YOURDOOR/. - Go to Admin → WebDoors and find the directory in the Add New Door panel.
- Click Create Manifest, fill in the form, and save.
- Toggle the door on and click Save Configuration.
Requirements System
The requirements system ensures games only run when their dependencies are met.
Feature Requirements
Games can require BBS features:
"requirements": {
"features": ["storage", "leaderboard", "credits"]
}
If a required feature is not available, the game is not shown in the games list.
Permission Requirements
Games can request access to user data:
"requirements": {
"permissions": ["user_display_name"]
}
This declares what user information the game needs.
Checking Requirements
The system validates requirements before displaying games:
function checkManifestRequirements($manifest) {
$requirements = $manifest['requirements'] ?? [];
$features = $requirements['features'] ?? [];
// Check each required feature
foreach ($features as $feature) {
if (!isFeatureAvailable($feature)) {
return false;
}
}
return true;
}
Configuration Overrides
Display Name Override
Sysops can customize how games appear to users:
In manifest (public_html/webdoors/blackjack/webdoor.json):
{
"game": {
"name": "Blackjack"
}
}
In configuration (config/webdoors.json):
{
"blackjack": {
"enabled": true,
"display_name": "21 Card Game"
}
}
Users will see "21 Card Game" instead of "Blackjack" in the games list.
Description Override
Similarly, descriptions can be customized:
{
"blackjack": {
"enabled": true,
"display_description": "Classic card game - try to beat the dealer!"
}
}
Custom Settings
Game-specific settings from the manifest's config section can be overridden:
Manifest default:
{
"config": {
"start_bet": 10
}
}
Sysop override:
{
"blackjack": {
"enabled": true,
"start_bet": 25
}
}
Game Access
URL Structure
Games are accessed through standardized URLs:
- Game list:
/games - Play game:
/games/{game-id}
Where {game-id} is the directory name of the WebDoor (e.g., /games/blackjack).
Entry Points
When a user accesses /games/blackjack, the system:
- Loads the WebDoor's manifest
- Applies any configuration overrides
- Serves the file specified in
entry_point - Injects BBS context (user info, session, etc.)
Integration with BBS Features
User Authentication
WebDoors run within authenticated user sessions. Games can access:
- Username
- Display name (with permission)
- User ID
- Session token
Storage API
Games requiring persistent storage use the BBS storage API to save/load user data.
Leaderboard API
Games can submit high scores to the BBS leaderboard system for display on the main games page.
Credits System
Games can integrate with the BBS credits/economy system to charge for plays or award winnings.
Workflow: how a WebDoor interacts with the platform
- A user launches a WebDoor from
/gamesusing an authenticated browser session. - BinktermPHP discovers the WebDoor, loads its manifest, and applies sysop overrides.
- The WebDoor entry point runs inside the user's existing platform identity and session context.
- The WebDoor calls platform APIs for storage, leaderboards, credits, or user-facing data instead of implementing its own separate account system.
- Results show up back in the platform, whether that means saved progress, credit changes, or a shared leaderboard.
Example: Simple HTML5 Game
{
"webdoor_version": "1.0",
"game": {
"id": "mygame",
"name": "My Game",
"version": "1.0.0",
"author": "Your Name",
"description": "A simple HTML5 game",
"entry_point": "index.html",
"icon": "icon.png"
},
"requirements": {
"min_host_version": "1.0",
"features": ["leaderboard"]
}
}
Example: PHP-Based Application
{
"webdoor_version": "1.0",
"game": {
"id": "phpapp",
"name": "PHP Application",
"version": "1.0.0",
"author": "Your Name",
"description": "Server-side PHP application",
"entry_point": "index.php",
"icon": "icon.svg"
},
"requirements": {
"min_host_version": "1.0",
"features": ["storage", "leaderboard", "credits"],
"permissions": ["user_display_name"]
},
"storage": {
"max_size_kb": 100,
"save_slots": 3
},
"config": {
"difficulty": "normal",
"max_players": 10
}
}
Example: Terminal Gateway
{
"webdoor_version": "1.0",
"game": {
"id": "mybbs",
"name": "My BBS",
"version": "1.0.0",
"author": "Your Name",
"description": "Connect to my text-based BBS",
"entry_point": "index.php",
"icon": "icon.svg"
},
"requirements": {
"min_host_version": "1.0",
"permissions": ["user_display_name"]
},
"config": {
"display_name": "My BBS",
"display_description": "Connect to My BBS via telnet",
"host": "mybbs.example.com",
"port": "23",
"proto": "telnet"
}
}
Sysop configuration (config/webdoors.json):
{
"mybbs": {
"enabled": true,
"display_name": "Community BBS",
"host": "bbs.example.org",
"port": "23",
"proto": "telnet"
}
}
Installation
To install a new WebDoor:
-
Copy the WebDoor directory to
public_html/webdoors/:cp -r mygame/ public_html/webdoors/ -
Verify the manifest exists and is valid:
cat public_html/webdoors/mygame/webdoor.json -
Enable the game in
config/webdoors.json:{ "mygame": { "enabled": true } } -
Access the game at
/gamesor directly at/games/mygame
Best Practices
- Use semantic versioning for game versions
- Provide meaningful descriptions that help users understand what the game does
- Declare all requirements your game needs
- Include an icon (SVG or PNG) for better visual presentation
- Test with configuration overrides to ensure defaults work
- Document custom config options in your game's README
- Keep entry points simple - use
index.htmlorindex.php - Use unique game IDs that won't conflict with other WebDoors
Security Considerations
- User input validation: Always validate and sanitize user input
- Path traversal: Don't allow users to specify file paths
- SQL injection: Use prepared statements for database queries
- XSS protection: Escape output when displaying user-generated content
- Authentication: WebDoors run in authenticated sessions - verify the user
- File permissions: Ensure game files are readable but not writable by web server
- Configuration validation: Validate configuration values from
config/webdoors.json
Troubleshooting
Game not appearing in list
- Verify
webdoor.jsonexists and is valid JSON - Check that the game is enabled in
config/webdoors.json - Ensure requirements are met (features, permissions)
- Check file permissions on the WebDoor directory
Configuration not taking effect
- Verify
config/webdoors.jsonsyntax - Check that configuration keys match those in the manifest
- Restart PHP-FPM if using opcache
- Clear browser cache
Entry point not loading
- Verify
entry_pointpath is correct relative to WebDoor directory - Check file permissions on the entry point file
- Look for PHP errors in web server error log
Related Systems
- Architecture — where WebDoors fit into the platform
- Doors Overview — the broader door runtime and other door types
- API Reference — authenticated platform APIs used by browser features
- BinkStream Back-Channel — realtime events for live browser updates
- Credit System — credits and economy integration