A browser-based port of Diablo enhanced with AI-driven procedural content generation, dynamic narratives, and adaptive NPC behavior.
Play the original version: https://d07RiV.github.io/diabloweb/
This fork transforms the static Diablo experience into a living, AI-driven game with:
Instead of the same dungeon layouts, the AI generates unique 40x40 tile dungeons with:
- Procedurally generated room layouts based on level theme
- Guaranteed connectivity between entrance and exit
- Dynamic monster spawn point placement
- Theme-aware generation (Cathedral, Catacombs, Caves, Hell)
NPCs now respond contextually based on your progress:
- Deckard Cain references bosses you've defeated
- Ogden comments on your wounds after battle
- Griswold offers advice based on your class
- Story context is maintained across sessions
Create entirely new Diablo experiences:
- Campaign Templates: Classic Descent, Under Siege, Spreading Corruption, Sacred Relics
- Procedural Storylines: AI-generated narrative arcs with progression gates
- World Building: Multiple dungeon levels, overworld maps, and boss lairs
- Progression System: Kill bosses to unlock new areas
AI can generate new monsters and characters:
- Sprite Generation: Pass requirements (size, description) to generate new sprites
- Browser-side Resizing: Automatic conversion to game-compatible formats
- CL2/CEL Conversion: AI images converted to Diablo's 256-color palette
Instead of real-time AI control (too many API calls), the system:
- Places enemies at design time based on difficulty
- Controls spawn locations and enemy types per area
- Creates boss encounters with appropriate minions
- Gates progression via required boss kills
Full client-side storage with IndexedDB:
- Save Games: Persist campaigns and progress locally
- Export Campaigns: Share AI-generated campaigns as JSON files
- Import Campaigns: Load campaigns created on other machines
- Cross-Browser: Works on any modern browser
# Install dependencies
npm install
# Start development server
npm start
# Open http://localhost:3000The Neural Augmentation system works in two modes:
- Mock Mode (No API key): Uses built-in procedural generation
- AI Mode: Uses your preferred AI provider for enhanced content
On first launch, you'll see a configuration panel to set up your AI provider.
| Provider | Text Generation | Image Generation | Setup |
|---|---|---|---|
| OpenRouter | All models | Via compatible endpoints | Recommended - access to 100+ models |
| OpenAI | GPT-4, GPT-3.5 | DALL-E 3 | Direct API key |
| Google Gemini | Gemini Pro/Ultra | Imagen | Google AI API key |
| Anthropic | Claude 3 | - | Direct API key |
| Local (Ollama) | Any local model | - | No API key needed |
# For OpenRouter (recommended)
REACT_APP_AI_PROVIDER=openrouter
REACT_APP_OPENROUTER_API_KEY=sk-or-...
# For OpenAI
REACT_APP_AI_PROVIDER=openai
REACT_APP_OPENAI_API_KEY=sk-...
# For Gemini
REACT_APP_AI_PROVIDER=gemini
REACT_APP_GEMINI_API_KEY=...
# For local models
REACT_APP_AI_PROVIDER=local
REACT_APP_LOCAL_ENDPOINT=http://localhost:11434src/neural/
├── config.js # Multi-provider configuration
├── index.js # Main entry point
├── NeuralInterop.js # WASM <-> JS bridge
├── LevelGenerator.js # AI dungeon generation
├── NarrativeEngine.js # Dynamic dialogue & quests
├── CommanderAI.js # Tactical NPC behavior (reference)
├── EnemyPlacement.js # Design-time enemy spawning
├── CampaignGenerator.js # AI storyline & mission creation
├── WorldBuilder.js # Level & area construction
├── GameStorage.js # IndexedDB persistence & export
├── AssetPipeline.js # AI asset generation + resizing
├── AIConfigPanel.js # Provider configuration UI
├── CampaignManager.js # Campaign management UI
├── AIConfigPanel.scss # Provider UI styles
├── CampaignManager.scss # Campaign UI styles
└── providers/ # AI provider implementations
└── index.js # OpenRouter, OpenAI, Gemini, Anthropic, Local
| Module | Purpose |
|---|---|
| NeuralInterop | Bridges JavaScript AI systems with the WASM game engine |
| LevelGenerator | Generates 40x40 dungeon grids with A* pathfinding validation |
| NarrativeEngine | Maintains story context and generates contextual dialogue |
| EnemyPlacement | Places enemies at design time based on difficulty |
| CampaignGenerator | Creates storylines, missions, and progression gates |
| WorldBuilder | Constructs worlds with levels, areas, and transitions |
| GameStorage | IndexedDB storage with export/import functionality |
| AssetPipeline | Converts AI images to CL2 format with browser resizing |
| CampaignManager | React UI for creating/loading/exporting campaigns |
The system uses simple, compatible prompt patterns:
// Level Generation - expects JSON output
"Generate a 40x40 dungeon grid as JSON..."
// Dialogue - simple text completion
"You are Deckard Cain. The player just defeated the Butcher..."
// Tactics - expects JSON decisions
"Analyze this tactical situation and provide orders as JSON..."Compatibility Matrix:
| Feature | OpenRouter | OpenAI | Gemini | Claude | Llama/Local |
|---|---|---|---|---|---|
| Dungeon Generation | Full | Full | Full | Full | Full |
| NPC Dialogue | Full | Full | Full | Full | Full |
| Quest Generation | Full | Full | Full | Full | Full |
| Tactical AI | Full | Full | Full | Full | Partial* |
| Image Generation | Via models | DALL-E | Imagen | - | Stable Diffusion |
*Smaller local models may produce less coherent tactical decisions
OpenRouter is recommended because:
- Access to 100+ models from one API key
- Automatic fallback if a model is unavailable
- Pay-per-use with no monthly minimums
- Model comparison to find best price/quality
On first launch (or via Settings), you can configure:
- AI Provider: OpenRouter, OpenAI, Gemini, Anthropic, or Local
- API Key: Your provider's API key
- Text Model: Which model to use for text generation
- Image Model: Which model to use for asset generation (optional)
- Feature Toggles: Enable/disable individual AI features
Settings are stored in browser localStorage.
// The AI receives constraints and generates layouts
const level = await levelGenerator.generate(DTYPE_CATHEDRAL, depth);
// Returns:
{
grid: [[0,1,1,...], ...], // 40x40 tile array
rooms: [{x, y, width, height}, ...],
entities: [{type: 'MONSTER_SPAWN', x, y, count}, ...]
}Tile Types:
0Floor - walkable area1Wall - impassable2Door - connecting rooms3Stairs Up - level entrance4Stairs Down - level exit
// Context is automatically tracked
narrativeEngine.recordEvent('BOSS_DEFEATED', { boss: 'BUTCHER' });
// Dialogue reflects context
const dialogue = await narrativeEngine.generateDialogue('OGDEN');
// "Thank the Light! You've slain that butcher! The town sleeps easier..."// Generate a new campaign
const campaign = await neuralAugmentation.generateCampaign('CLASSIC', {
customTheme: 'Ancient Egyptian tombs',
});
// Campaign structure
{
id: 'campaign_123',
name: 'The Darkness Returns',
acts: [
{
name: 'Act 1: Desecrated Halls',
theme: 'Cathedral',
levels: [...],
boss: { name: 'The Defiler', type: 'SKELETON_KING' },
unlockCondition: null,
},
// ... more acts
],
quests: [...],
}Campaign Templates:
CLASSIC: Traditional 4-act dungeon descentSIEGE: Defend Tristram from waves (3 acts)CORRUPTION: Time-limited cleansing missionsQUEST: Collect sacred relics across 5 acts
// Generate enemy placements for an area
const placements = await enemyPlacement.generatePlacements({
name: 'Cathedral Level 2',
difficulty: 3,
spawnPoints: [
{ x: 10, y: 15, template: 'PATROL' },
{ x: 25, y: 20, template: 'AMBUSH' },
],
bossArea: {
x: 20, y: 5,
bossType: 'SKELETON_KING',
progressionGate: 'cathedral_level_3',
},
});
// Returns array of enemy spawns
[
{ x: 10, y: 15, enemyType: 'SKELETON', difficulty: 2 },
{ x: 20, y: 5, enemyType: 'SKELETON_KING', isBoss: true, progressionGate: '...' },
// ...
]// Save current game
await GameStorage.saveGameState(campaign, world, progress);
// List saved campaigns
const saved = await GameStorage.getSavedCampaigns();
// Export to file
await GameStorage.exporter.exportToFile(campaignId);
// Downloads: diablo-campaign-the-darkness-returns-1699999999.json
// Import from file
const campaign = await GameStorage.importer.importFromFile(file);# Unit tests for neural modules
npm run test:neural
# Integration tests (requires browser)
npm run test:integration
# All tests
npm run test:all# Build container
npm run docker:build
# Development with hot reload
npm run docker:dev
# Run tests in container
npm run docker:testnpm run buildThis project can be deployed to GitHub Pages for free hosting. There are two methods:
The repository includes a GitHub Actions workflow that automatically deploys when you push to main.
-
Fork or clone this repository
-
Enable GitHub Pages in your repository settings:
- Go to Settings > Pages
- Under "Build and deployment", select "GitHub Actions"
-
Push to main branch:
git push origin main
The workflow will automatically build and deploy your site.
-
Access your site at:
https://[your-username].github.io/[repo-name]/
If you prefer manual control over deployments:
-
Install gh-pages:
npm install
-
Build and deploy:
npm run deploy:manual
This builds the project and pushes to the
gh-pagesbranch. -
Configure GitHub Pages:
- Go to Settings > Pages
- Under "Build and deployment", select "Deploy from a branch"
- Choose
gh-pagesbranch and/ (root)folder
- All features work on GitHub Pages - The Neural Augmentation system uses client-side storage (IndexedDB) and API calls are made directly from the browser
- API Keys - When you configure an AI provider, your API key is stored in localStorage on your browser only
- Game Files - The shareware
spawn.mpqis included; for the full game, users need to provide their ownDIABDAT.MPQ - Custom Domain - You can configure a custom domain in Settings > Pages
This project is based on:
- devilution: https://github.com/diasurgical/devilution
- diabloweb: https://github.com/d07RiV/diabloweb
The original WebAssembly compilation removes all native dependencies and exposes a minimal JavaScript interface, allowing the game to run entirely in the browser.
- Shareware: Included
spawn.mpqallows playing the demo - Full Game: Requires
DIABDAT.MPQfrom GoG
The Neural Interop Layer provides bidirectional communication:
// Initialize with WASM module
neuralInterop.initialize(wasmModule);
// Read game state
const state = neuralInterop.extractGameState();
// Inject AI decisions
neuralInterop.injectCommand('MOVE_MONSTER', { monsterId, targetX, targetY });- Pointers are refreshed after WASM memory growth
- LRU caching prevents memory bloat
- Automatic cleanup of dead entities
When no API key is configured, the system falls back to:
- MockLevelGenerator: Procedural room-based generation
- MockDialogueGenerator: Pre-written thematic dialogue
- MockCommanderAI: Simple distance-based tactics
This ensures the game remains fully playable offline.
- Fork the repository
- Create a feature branch
- Run tests:
npm run test:all - Submit a pull request
Based on the original Diablo decompilation project. See devilution for license details.
- AI-driven procedural level generation
- Dynamic NPC dialogue with context
- Campaign generation system
- World building with progression gates
- Smart enemy placement (design-time)
- Save/Export/Import campaigns
- Multi-provider AI support
- Browser-side image resizing
- IndexedDB persistence
- Full game loop integration with campaigns
- Custom character sprite generation UI
- GitHub Pages deployment support
- Procedural item generation with AI descriptions
- AI-generated monster variants
- Overworld exploration areas
- Multiplayer with campaign sharing
- Voice synthesis for NPC dialogue
- Campaign rating and sharing platform