AmpleWeb-AI - Vision & Text-Based LLM Agent Edition
This repo is an AI-enhanced edition of AmpleWeb, configured as a specialized standalone experimental platform for Vision-Based AI Agents (LLM + Vision). Currently, it targets retro text adventure games (such as Zork) on the Apple II series to implement and run autonomous AI-assisted gameplay. By leveraging multi-modal large language models (such as Gemini 2.5/3.5 Flash, GPT-4o-mini, and Claude 3.5 Sonnet), AmpleWeb-AI allows an AI agent to "look" at the emulator canvas (running retro machines like the Apple IIe) via real-time screenshots, read the text, reason, and automatically dispatch keystroke sequences to play text adventure games autonomously.
MAME WASM (Canvas Screen)
โ WebGL readPixels() + vertical flip
Base64 PNG Screenshot
โ multimodal Vision API (Gemini / GPT / Claude)
Text Command (e.g. "GO EAST")
โ DOM KeyboardEvent sequence (async, 60ms/char)
Emscripten WASM Input
-
Decoupled & Non-Invasive: The AI layer treats MAME WASM as a complete black box. It reads the canvas via WebGL pixel extraction and sends keypresses via DOM events โ no WASM code modifications needed.
-
WebGL Framebuffer Capture: The canvas
getContextis intercepted at boot to forcepreserveDrawingBuffer: true, thengl.readPixels()extracts raw GPU pixels with Y-axis vertical flip correction. This produces a clear, pixel-perfect screenshot even on WebGL-rendered canvases. -
Asynchronous Typist: Each keystroke is dispatched (
keydownโ delay โkeyup) sequentially with a configurable delay between characters, preventing Emscripten frame loop input skipping. -
Dual Modes (Vision & Low-Token Text): Switch between
Vision Mode(captures pixel-perfect screenshots) andText Mode(directly reads Apple II text memory buffer from WASM memory for extremely low token cost, no external OCR required).-
Direct RAM Access (DMA Tech): Employs exported C helper APIs (
_emscripten_get_main_ram_wasm_offsetand_emscripten_get_aux_ram_wasm_offset) to fetch the exact WASM linear memory offset of the physical Main and Aux RAM pointers. This allows directHEAPU8reading of screen memory (0x400/0x800) with 100% precision and zero delay, completely bypassing fragile heap scanning. -
Advanced 80-Column Decoupled Decoding: Solves the character pair flipping bug (where
"ZORK I"gets garbled into"I R OKI") using Dynamic Dual-Base Pairing to automatically resolve the dynamically-allocated Main and Aux RAM heaps without hardcoded 65,536-byte offset assumptions. It applies a Self-Correcting Way A/Way B Heuristic that runs both odd/even column interleaving patterns concurrently, measuring character density via/[A-Za-z]/gto auto-select the perfectly formatted text stream. -
Force 80-Col Override: Adds a "Force 80-Col" toggle switch in the UI. Because software-level 80-column hardware register reads (e.g.
RD80COL) can sometimes be desynced or unstable under MAME's Emscripten core, checking this option overrides auto-detection and forces the dual-bank interleaving decoder, guaranteeing flawless 80-column text extraction. -
Incremental Chatbot Diffing: In
Text Mode, the frontend compares the current screen text with the previous turn using LCS Suffix-Prefix matching and command markers. It isolates and transmits only the newly printed game output (e.g."Opening the mailbox reveals a leaflet."instead of the full room description). This reduces repetitive token costs by over 90% and keeps the context history extremely clean and focused.
-
Direct RAM Access (DMA Tech): Employs exported C helper APIs (
-
Chain-of-Thought (CoT) Reasoning: Prompts the AI to output its reasoning process before deciding the command. The system prompt templates require the LLM to output a
Reasoning:block followed by aCommand:line. The frontend parses the multi-line response, extracting only the clean action command for typing, which unlocks deeper logical planning and reduces repetitive "guessing" loops. -
Extended LLM Providers: Support for Gemini 3.5 Flash, GPT-4o-mini, Claude 3.5 Sonnet, NVIDIA NIM, Groq, Ollama Cloud, LM Studio (Local), Ollama (Local), and Custom Providers.
-
Conversation History Limit: Customizable turn history memory buffer (configurable
$N$ turns from0to20) to eliminate AI "goldfish brain" repetition. Automatically formatted for Gemini, Claude, and OpenAI APIs. -
Auto-Retry on API Overload: A
fetchWithRetrywrapper automatically retries on503/429errors using exponential backoff (up to 3 retries), so transient API demand spikes never crash the AI loop.
Before enabling the AI, you must have the emulator running:
- In the left panel, select a machine (e.g.
Apple //e (Enhanced)). - In the bottom-right panel โ Media tab, mount a game disk (e.g. a Zork .dsk file). You can use the ๐ URL button to load directly from a URL.
- Click the Launch button. Wait until the emulator header shows
โ Running(green badge).
Important
The AI can only operate while the emulator is actively running. The Enable button is intentionally greyed out at all other times.
Click the AI tab in the upper-right settings panel. You will see:
| Setting | Description | Default |
|---|---|---|
| AI Agent Status | ๐ด Disabled / ๐ข Enabled toggle button | Disabled |
| Mode | Choose: ๐ผ๏ธ Vision Mode (transmits base64 screenshots, consumes more tokens) or ๐ Text Mode (Low Token) (directly parses emulator text buffer from WASM memory, extremely cheap/low-token) |
Vision Mode |
| Force 80-Col | Forced 80-column text mode override. If characters get garbled or split into odd spacing during Text Mode, check this box to force the dual-bank interleaving decoder | unchecked |
| Provider | Choose: Mock Simulator, Gemini 3.5 Flash, OpenAI GPT-4o-mini, Claude 3.5 Sonnet, NVIDIA NIM, Groq, Ollama Cloud, LM Studio (Local), Ollama (Local), Custom Provider |
Mock Simulator |
| API Key | Your LLM provider's secret key (stored locally in browser, never sent to third-party servers) | โ |
| API URL | Base endpoint URL for the selected provider (editable, visible for OpenAI-compatible options) | (auto-filled) |
| Model | The model name to request from the provider API (editable, visible for OpenAI-compatible options) | (auto-filled) |
| Tick Rate (sec) | How often (in seconds) the AI captures screen and decides the next command | 15 |
| Type Delay (ms) | Millisecond delay between each character keystroke (keep at 60ms to avoid WASM input skipping) | 60 |
| Max Tokens | Maximum output token limit for the LLM response (increase if AI responses are being truncated) | 1000 |
| History Limit | Turn limit of conversation history (screen states + AI actions) sent in request to prevent "goldfish brain" (configurable from 0 to 20) |
5 |
| Temperature | Sampling temperature for the model (range: 0.0 to 2.0, lower is more deterministic, higher is more creative) |
0.6 |
| System Prompt | Natural language instructions for the AI (what game it's playing, how to behave). Automatically syncs with current Mode templates | Zork preset |
-
Gemini 3.5 Flash (Recommended โ fastest and most affordable):
- Go to Google AI Studio
- Click "Create API Key" โ copy the key
- Paste it into the API Key field and select Gemini 3.5 Flash as Provider.
-
OpenAI GPT-4o-mini:
- Go to platform.openai.com/api-keys
- Create a new key and paste it in.
-
Claude 3.5 Sonnet:
- Go to console.anthropic.com
- Create an API key and paste it in.
-
Groq (Fast inference, free tier available):
- Go to console.groq.com
- Create an API key and paste it in. Select Groq as Provider.
Note
All API keys are stored only in your browser's localStorage. They are never committed to source code or sent to any third-party server other than your chosen LLM provider directly.
- Click ๐ด Disabled โ it will toggle to ๐ข Enabled.
- Switch to the bottom-right panel โ "AI Agent" tab to monitor activity.
| Element | What it shows |
|---|---|
| Status badge | Idle (grey) โ Thinking (yellow) โ Typing (green) โ Error (red) |
| Vision Screen Capture | A live thumbnail of what the AI "sees" โ the current emulator canvas frame |
| Agent Execution Log | Timestamped log of every action: capture, API call, command received, characters typed, retry warnings |
A healthy cycle looks like:
[HH:MM:SS] AI Agent Enabled - Starting loop
[HH:MM:SS] Capturing emulator screen...
[HH:MM:SS] Calling LLM API (gemini)...
[HH:MM:SS] AI Command received: "OPEN MAILBOX"
[HH:MM:SS] Successfully typed command: "OPEN MAILBOX"
If the server is busy (503/429), the retry system handles it automatically:
[HH:MM:SS] [Retry] API returned 503 (busy/limit). Retrying in 1.5s... (Attempt 1/3)
[HH:MM:SS] [Retry] API returned 503 (busy/limit). Retrying in 3.8s... (Attempt 2/3)
[HH:MM:SS] AI Command received: "GO NORTH"
| Error | Cause | Fix |
|---|---|---|
API key is required for gemini |
No API key entered | Enter your key in the API Key field |
Gemini API error: 404 |
Wrong model name or endpoint | Update to latest code (model is auto-set to gemini-3.5-flash) |
Empty response from Gemini API |
MAX_TOKENS too low (Gemini 3.5 uses tokens for internal reasoning too) |
Increase Max Tokens to 1000 or higher |
AI Agent repeatedly types LOOK |
Canvas is black (WebGL buffer cleared) โ needs latest AI layer code | git pull and re-deploy; the preserveDrawingBuffer fix resolves this |
Error: Emulator canvas not found |
Emulator is not running | Launch the emulator first, wait for the Running badge |
503 high demand (no retry shown) |
Outdated code without retry logic | git pull and re-deploy for auto-retry support |
Want to test the pipeline without spending API credits?
- Set Provider to Mock Simulator.
- Set Tick Rate to
5seconds. - Enable the AI.
- Watch as the AI automatically steps through a pre-scripted Zork sequence:
LOOKโOPEN MAILBOXโTAKE LEAFLETโREAD LEAFLETโGO EASTโGO NORTHโGO WEST...
This verifies that screenshot capture, keystroke injection, and the AI loop are all working correctly before you use a real API key.
Important
Pure Client-Side: AmpleWeb runs entirely in your browser. No backend, no server-side emulation, and zero installation required.
| Feature | Ample (macOS Native) | AmpleWeb (Web) | Notes |
|---|---|---|---|
| Language | Objective-C (Cocoa) | React + TypeScript (Vite) | 1:1 UI replica using modern web standards |
| Installation | .dmg Image / Homebrew | Zero Install (Web-based) | Runs directly via URL |
| MAME Integration | Built-in Custom Core | MAME WASM (Universal) | High-performance Emscripten-compiled binary |
| UI | Native macOS Components | Pixel-Perfect CSS Replica | Includes Dark/Light Mode & Tab Persistence |
| File System | Native HFS/ProDOS Access | VFS + Local Folder Mapping | Support for mounting local folders via File System Access API |
| Data Persistence | Direct Disk Write | Save-on-Change Guard | Detects VFS changes and prompts to save locally when ejecting, changing files, or loading URLs |
| Video Support | Metal / OpenGL / BGFX | WebGL / BGFX WASM | Full BGFX effects (CRT-Geom, Scanlines, etc.) |
| XML Config (.cfg) | Plist / Native MAME .cfg | Decoupled LocalStorage + VFS mapping | Built-in XML Configuration Editor supporting instant editing, direct local import/export, and decoupled persistence per specific clone model (e.g. macpd280 / macpd280c) |
- Visual Precision: Support for Window 1x-4x modes, Integer Fit (Sharp) mode, and Full Screen (Fit-to-Screen) scaling.
- Square Pixel Support: Fully enabled and operational "Square Pixel" mode which disables aspect-ratio correction, passing
-nokeepaspectto the WASM core for a perfect 1:1 hardware pixel grid rendering. - Comprehensive Library: Full support for Apple I, II, III, and Macintosh families.
- International Localization: Proper support for localized Apple IIe/IIee/IIep variants (DE, FR, ES, SE, UK) with accurate character sets and boot logos.
- Peripheral Support: Supports auto-injection for SCSI, CFFA2, Mouse cards, and Memory expansion.
- Dynamic ROM Management: Automatically fetches required device ROMs (e.g.,
a2mouse.zip) for selected slot peripherals, preventing boot crashes. - Advanced Video: Fully enabled and operational BGFX screen chains (including scanline and CRT Geom filters), utilizing WebGL hardware acceleration for authentic retro visuals.
- Personalized UI: Full support for Dark/Light Mode switching, faithfully replicating the macOS native visual aesthetics.
- Slot Configuration Consistency: Improved slot initialization logic to respect "None" (empty) selections across UI refreshes, matching the high standards of the native macOS and Windows/Linux ports.
- Background Run & Audio Support: The emulator keeps running and playing sound in the background when the browser window loses focus. (Requires keeping the page in a separate, non-minimized window; do not minimize the window or switch to other tabs in the same browser window, as browsers automatically suspend background tabs).
- Premium Collapsible Drawers: Both left (Machine List) and right (Settings Panel) lanes utilize smooth CSS hardware-accelerated transitions and absolute floating drawer pull handles (
โ/โถ) that automatically nest into sidebar inner edges when expanded. - Fully Resizable Workspace: The interface features a flexible layout. Drag the horizontal divider in the right settings panel to seamlessly adjust the vertical height of the System Settings and Machine Configuration frames.
- Active Workspace Resizing: Synchronized manual drag-to-resize operations with MAME's WASM engine. Adjusting the left sidebar or right settings panel width dynamically dispatches
resizeevents to ensure real-time viewport and pointer coordination mapping alignment. - Mobile Overlay Drawers & Auto-Collapse: On phone screens (width <= 800px), sidebars transition to fixed overlay drawer panels with rich box-shadows, leaving the emulator canvas at 100% fullscreen height. Includes auto-collapsing states triggered dynamically on window resize or initial load to keep the UI clean and focused.
- Unconfigurable Slot Dropdowns Cleanup: Automatically hides blank, useless select dropdowns for built-in/unchangeable slot lanes (where
options.length <= 1), turning their labels into clean bold section headers while keeping selectable sub-slots (e.g. floppy drives) perfectly functional underneath. - Light Theme Contrast & Interactive Polish: Fixed the high-contrast visibility issue of the "๐บ Full Screen" badge button in light theme, replacing hardcoded styles with dynamic theme-aware coloring, and added smooth micro-animations (scale/fade transitions) on hover and active click actions.
- Local Directory Mapping (/share): Map any local host folder directly to the emulator's VFS for seamless data exchange.
- Save back to Local (Save-on-Change Guard): Any write operations to virtual disks/hard disks during emulator runtime are automatically tracked. Clicking Eject (
โ๏ธ ), selecting a Local File (๐), or inserting a URL (๐) will trigger a safety check, prompting you to save changes back to your local filesystem first, preventing accidental data loss. - Capture Persistence: Export generated AVI video and WAV audio captures directly to your local device (avoid long recordings to prevent browser memory buffer overflow).
- Deep Linking & Complete URL Persistence: Pre-configure machines, slots, and media via URL parameters; supports automatic startup (URL ending with
&autoboot) for seamless demos. All query string flags stay fully persisted in your browser's address bar after launching, allowing instant manual page reloads (F5). Use the new ๐ Share button next to the machine name in the header to copy a fully-restored, self-launching deep link instantly to your clipboard! - URL-Based Media Loading: Mount disks directly from any external URL using the
?media=slotId:http://...parameter or via the new ๐ URL Button in the Media tab. - Automatic ZIP Unzipping: Support for loading
.zipdisk images from URLs or local selection. Automatically extracts valid images (.dsk, .do, .po, etc.) for mounting. - Recursive Device Dependencies: Automatically resolves sub-dependencies for slot peripherals (e.g.,
a2mouseneedingm68705p3). - Persistent Configuration: Machine and slot selections are automatically saved in local storage. Refreshing or "Stopping" the emulator no longer loses your current setup.
- Internal Controls: Dedicated UI buttons for MAME UI (Scroll Lock) and MAME Menu (Tab) to facilitate easier access to internal emulator settings.
- Zero-Setup ROMs: Multi-server failover engine for automatic firmware downloading and caching in IndexedDB.
- Intelligent Machine Reset: Automatically clears previous slot configurations and media mounts when switching between different machines. This ensures a clean slate and prevents "configuration pollution" when transitioning from specialized URL-based sessions.
- Indeterminate Progress Spinner Loader: The loading overlay features a beautiful, rotating circular spinner next to status text (replacing crude jumpy 0-100% bars), providing a highly polished, professional loading feel. Canvas is always centered from the start.
- Audio/Video Synchronization: Screen and sound now start simultaneously. The emulator overlay is removed the instant MAME's runtime initializes (
onRuntimeInitialized), the same moment audio begins, eliminating the previous 1โ2 second audio-before-video gap. - Built-in XML Configuration Editor: Edit and tweak MAME's low-level system configuration XML directly from the UI. Features intelligent syntax preservation, auto-correction of the target
<system name="...">tags, dynamic on-launch driver translation (e.g.macpd280/macpd280c), and fully responsive equal-width operations (Read, Save, Export, Import, Reset) presented in a single centered row. - Corsfix Sponsored Proxy: Cross-origin media downloads are proudly powered by Corsfix.
AmpleWeb features a powerful URL parameter mapping engine (Deep Linking) that allows you to pre-configure and share precise emulator environments, peripherals, disk media, window dimensions, and shader effects.
| Parameter | Alias | Expected Values | Description |
|---|---|---|---|
m |
โ | Machine identifier (e.g., apple2ee, apple2gsr1) |
Sets the target Apple/Macintosh model system to load. |
d |
โ | Encoded string (e.g., Apple+%2F%2Fe+%28enhanced%29) |
Sets the human-readable description shown in the UI. |
s |
โ | Comma-separated slot-value pairs (e.g., ramsize:64K,sl4:mouse,sl6:diskiing) |
Pre-configures slot peripherals, memory cards, and internal settings. |
media |
โ | slotId:URL or slotId:filename |
Mounts external disk images directly from a URL. Supports .zip, .dsk, .2mg, .hdv, .woz, etc. |
extra or ?extra |
โ | Raw MAME OSD arguments (e.g., -port,:a2video:a2_video_config,3) |
Inject custom low-level MAME options or port overrides (with automatic query string typos handling). |
autoboot |
โ | Flag or numeric (e.g., &autoboot or &autoboot=0 or &autoboot=5) |
Triggers automated machine launch. Accepts a custom delay value n in seconds (0 to 10). n=0 or valueless flag launches instantly. (Clicking the "Stop" button during emulation automatically strips this parameter to prevent endless restart loops). |
You can pass these to configure display settings on startup. Note that choosing any shader effect automatically switches the rendering method to hardware-accelerated BGFX WebGL:
| Parameter | Alias / Synonyms | Allowed Values | Description |
|---|---|---|---|
windowMode |
window_mode, wm, w |
1x, 2x, 3x, 4x, fit, integer-fit |
Window scale. fit fits to screen; integer-fit locks scaling to exact integer multipliers for ultra-sharp pixels. |
videoShader |
video_shader, shader, effect, bgfxEffect, bgfx_effect |
none, scanlines, crt-geom, crt-geom-deluxe, hq2x, lcd-grid |
Display filter. Values can use underscores or hyphens interchangeably. |
| videoMethod | video_method, vm |
soft, bgfx, opengl |
Rendering backend engine. |
Here are some real-world combination examples to demonstrate the URL deep linking capabilities:
-
Apple IIe Enhanced with BGFX CRT Shader, 64K RAM, Mouse Card, Video-7 configuration & Auto-boot:
https://anomixer.github.io/ample/?m=apple2ee&d=Apple+%2F%2Fe+%28enhanced%29&s=ramsize%3A64K%2Csl4%3Amouse%2Csl6%3Adiskiing%2Csl6%3Adiskiing%3A0%3A525%2Csl6%3Adiskiing%3A1%3A525%2Csl7%3Acffa202%2Caux%3Aext80%2Csl7%3Acffa202%3Acffa2_ata%3A0%3Ahdd%2Csl7%3Acffa202%3Acffa2_ata%3A1%3Ahdd&extra=-port,:a2video:a2_video_config,3&media=hard1:https://github.com/a2stuff/a2d/releases/download/v1.6-alpha2/A2DeskTop-1.6-alpha2-en.zip&autoboot&w=fit&shader=crt-geom(Features demonstrated:
mfor model,sslots mapping,extrafor Video-7 OSD settings,mediafor external .zip HDD image,autoboottimer,wwindow mode override, andshaderfor BGFX CRT display filter) -
Apple IIgs ROM 01 with 1.25MB RAM, Floppy & CFFA2 HDD drives & Auto-boot:
https://anomixer.github.io/ample/?m=apple2gsr1&d=Apple+IIgs+%28ROM01%29&s=ramsize%3A1280K%2Csmartport%3Afdc%3A0%3A525%2Csmartport%3Afdc%3A1%3A525%2Csmartport%3Afdc%3A2%3A35dd%2Csmartport%3Afdc%3A3%3A35dd%2Csl7%3Acffa2%2Csl7%3Acffa2%3Acffa2_ata%3A0%3Ahdd%2Csl7%3Acffa2%3Acffa2_ata%3A1%3Ahdd&media=hard1:https://github.com/a2stuff/a2d/releases/download/v1.6-alpha2/A2DeskTop-1.6-alpha2-en.zip&autoboot
- Disk Mounting Limits: Due to browser VFS limitations, disks can only be mounted before launching the machine. Real-time disk swapping is not supported (Alternative: Use the "Local Directory Mapping" feature in the Paths tab and mount via MAME's internal UI from the
/sharedirectory). - Core Stability: Machines highlighted in yellow may not function correctly due to underlying emulation core limitations.
- Audio Latency: There may be slight audio lag, which is a known limitation of MAME WASM.
- Execution Speed: Speed gains are limited by the WASM architecture; settings like 500% or Max speed may not be achievable.
- Disabled Features: Due to compatibility issues, the following features are currently disabled: Debug and Generate VGM.
- Browser Limits: Large AVI captures may exceed browser memory buffers if recorded for extended periods.
No setup required. Enjoy the classic 80s computing experience directly in your browser: ๐ Main Site
We have pre-configured two instant-launch retro systems containing Apple II Desktop for you:
- Launch Apple IIe (enhanced) (with Video-7 RGB, BGFX Hardware Acceleration & Autoboot)
- Launch Apple IIgs (ROM01) (with 1.25MB RAM, CFFA2 HDD controller & Autoboot)
- A modern web browser ( Chrome, Edge, or Opera recommended for File System Access API support).
-
One-Click Start (Recommended):
- Windows: Run
AmpleWeb.bat - Linux/macOS: Run
./AmpleWeb.sh(requireschmod +x AmpleWeb.sh) The scripts will automatically check the environment, install dependencies, download ROMs, and start the server.
- Windows: Run
-
Manual Start (For Developers):
- Install dependencies:
npm install - Download ROMs: Run
download_roms.ps1- The system detects missing files in
public/romsand launches the high-speed multi-threaded downloader. - You can select sources (CallApple, MDK, etc.) or provide a custom URL.
- Downloaded
.zipfiles are stored inpublic/romsfor immediate use by the WASM frontend.
- The system detects missing files in
- (Optional) To rebuild
public/wasm/mame.wasm.gz(currently powered by a custom MAME 0.288-patched core), use the MameWasm project to build the binary, then compress it to.gz. - Launch server:
npm run devornode server.jsOpenhttp://localhost:5173to start playing.
- Install dependencies:
| File/Directory | Description |
|---|---|
AmpleWeb.bat / .sh |
One-Click Start Scripts. Automatically checks env, installs deps, downloads ROMs, and starts server. |
download_roms.ps1 |
ROM Downloader. PowerShell script with interactive menus and automatic patching logic. |
rom_manager_cli.py |
Download Engine. Python-based multi-threaded (50-threads) tool with failover support. |
server.js |
Local Dev Server. Handles npm install, environment preparation, and auto-opens browser. |
src/App.tsx |
Main application logic, UI layout, and state management. |
src/core/wasm_loader.ts |
MAME WASM bridge, VFS management, and boot argument builder. |
public/roms/ |
Default directory for system firmware (ROM download target). |
public/wasm/ |
MAME WASM Core. Contains mame.wasm.gz and its loader script. |
public/samples/ |
Audio Samples. e.g., floppy drive mechanical sounds (floppy/*.wav). |
public/resources/ |
UI Resources. Includes machine icons, logos, and UI assets. |
- Original macOS version developer: Kelvin Sherlock
- Web Port Developers: anomixer + Antigravity
- WASM Core: Powered by emularity-engine and custom MAME builds.
Disclaimer: AmpleWeb is an independent open-source project and is not affiliated with, authorized, maintained, or endorsed by Apple Inc. or any other respective companies mentioned. All product and company names are trademarksโข or registeredยฎ trademarks of their respective holders.

