Run DOOM inside KiCad's PCB editor using real PCB traces and component footprints as the rendering medium. Features triple-mode rendering: SDL window, Python wireframe renderer, and KiCad PCB visualization.
🎮 Triple-Mode Rendering
- SDL window for standard gameplay
- Python wireframe renderer for reference visualization
- KiCad PCB traces and footprints for technical demonstration
🔧 Real PCB Components
- Walls rendered as copper traces (wireframe edges)
- Entities rendered as actual PCB footprints:
- SOT-23 (3-pin) for collectibles (health, ammo, keys)
- SOIC-8 (8-pin) for decorations (barrels, bodies, props)
- QFP-64 (64-pin) for enemies (zombies, demons, player)
⚡ Performance Optimized
- Vector extraction (200-500x faster than pixel rendering)
- Object pooling (pre-allocated PCB elements)
- 10-25 FPS in KiCad, 60+ FPS in standalone renderer
🎯 Electrically Authentic
- Real copper traces on F.Cu/B.Cu layers
- Industry-standard component packages
- Connected to shared net (could be fabricated!)
# Python dependencies
pip3 install pygame # For standalone renderer
# SDL2 (for dual-output mode)
brew install sdl2 # macOS
sudo apt install libsdl2-dev # Linuxcd doom/source
./build.shThis will:
- Clone doomgeneric if needed
- Apply KiDoom patches (entity type extraction)
- Build the DOOM binary
- Download shareware WAD file
# Terminal 1: Start Python wireframe renderer
./run_standalone_renderer.py
# Terminal 2: Launch DOOM with vectors
./run_doom.sh dual -w 1 1 # E1M1 with SDL + vectorsYou'll see:
- SDL window (top-left) - Full DOOM graphics for gameplay
- Python window (top-right) - Wireframe visualization
# Install plugin
ln -s $(pwd)/kicad_doom_plugin ~/.kicad/scripting/plugins/kidoomThen in KiCad:
- Open PCBnew
- Create/open a PCB (A4 landscape recommended)
- Tools → External Plugins → KiDoom - DOOM on PCB
Watch as DOOM appears on your PCB with:
- Blue copper traces for walls (thickness = depth)
- Real component footprints for entities
- Vias for projectiles
Instead of scanning 64,000 pixels, we extract vectors directly from DOOM's internal arrays:
// Extract from DOOM's rendering pipeline
drawsegs[] → Wall segments (already 3D-projected!)
vissprites[] → Entity positions with scale
vissprite.mobjtype → Real entity type (MT_SHOTGUY, MT_BARREL, etc.)Performance: 200-500x faster than pixel buffer scanning
Custom DOOM patches extract real entity types:
// Patch to r_defs.h
typedef struct vissprite_s {
lighttable_t* colormap;
int mobjtype; // NEW: Captures MT_* enum during R_ProjectSprite()
int mobjflags;
} vissprite_t;Python categorizes 150+ entity types:
MT_PLAYER → CATEGORY_ENEMY → QFP-64 footprint
MT_MISC11 → CATEGORY_COLLECTIBLE → SOT-23 footprint (medikit)
MT_BARREL → CATEGORY_DECORATION → SOIC-8 footprint| DOOM Element | PCB Element | Example |
|---|---|---|
| Wall | 4x PCB_TRACK (wireframe box) | Blue traces, thick=close |
| Enemy | FOOTPRINT (QFP-64) | Shotgun Guy, Cyberdemon |
| Collectible | FOOTPRINT (SOT-23) | Health pack, ammo clip |
| Decoration | FOOTPRINT (SOIC-8) | Barrel, dead body |
| Projectile | PCB_VIA | Bullet, fireball |
| HUD | PCB_TEXT | Health/ammo counters |
KiDoom/
├── run_doom.sh # Main DOOM launcher
├── run_standalone_renderer.py # Wireframe renderer launcher
├── CLAUDE.md # AI assistant instructions
├── README.md # This file
│
├── kicad_doom_plugin/ # KiCad plugin (install to ~/.kicad/)
│ ├── doom_plugin_action.py # Main plugin entry point
│ ├── pcb_renderer.py # Wireframe + footprint rendering
│ ├── entity_types.py # 150+ entity categorization
│ ├── doom_bridge.py # Socket communication
│ ├── object_pool.py # Pre-allocated PCB objects
│ └── coordinate_transform.py # DOOM pixels → KiCad nanometers
│
├── doom/ # DOOM engine
│ ├── doomgeneric_kicad # Compiled binary (dual-mode)
│ ├── doom1.wad # Shareware game data
│ └── source/
│ ├── doomgeneric_kicad_dual_v2.c # Vector extraction
│ ├── doom_socket.c # Socket client
│ └── build.sh # Automated build
│
├── src/
│ └── standalone_renderer.py # Pygame wireframe renderer
│
└── logs/docs/ # Development documentation
├── 22_*_KICAD_WIREFRAME_PLAN.md
├── 23_*_KICAD_PLUGIN_INTEGRATION.md
└── 24_*_FOOTPRINT_ENTITIES_COMPLETE.md
- WASD - Move (forward/back/strafe)
- Arrow keys - Turn left/right
- Ctrl - Fire weapon
- Space / E - Use / Open doors
- 1-7 - Select weapon
- ESC - Menu / Quit
| Environment | FPS | Notes |
|---|---|---|
| Standalone Renderer | 60+ | pygame is very fast |
| KiCad (M1 MacBook Pro) | 15-25 | PCB refresh overhead |
| KiCad (i7 + RTX 3050 Ti) | 18-28 | GPU-accelerated |
| KiCad (older hardware) | 8-15 | Still playable! |
Bottleneck: KiCad's PCB refresh, not DOOM or communication
For best performance in KiCad, disable these before running:
- View → Show Grid: OFF (saves 5-10%)
- View → Ratsnest: OFF (saves 20-30%)
- Preferences → PCB Editor → Display Options:
- Clearance outlines: OFF
- Pad/Via holes: Do not show
- Preferences → Common → Graphics:
- Antialiasing: Fast or Disabled
- Rendering engine: Accelerated
Custom patches to doomgeneric source capture entity types:
// r_defs.h - Add mobjtype field
int mobjtype; // Stores MT_PLAYER, MT_SHOTGUY, etc.
// r_things.c - Capture during sprite projection
vis->mobjtype = thing->type;See doom/source/patches/vissprite_mobjtype.patch for details.
KiCad crashes when modifying PCB objects from background threads on macOS.
Solution:
- Socket server and DOOM run in background
- Monitor thread watches process health
- All PCB operations on main thread via wx.Timer
- Clean shutdown without KiCad crash
- DOOM: 320×200 pixels, (0,0) top-left, Y down
- KiCad: nanometers, Y down on screen (same direction!)
- Scaling: 1 DOOM pixel = 0.5mm = 500,000 nm
- Centering: A4 landscape center (148.5mm, 105mm)
No Y-axis flip needed - both systems use screen-space coordinates.
See logs/docs/ for chronological documentation:
- Phase 1-5: Initial implementation (socket, renderer, plugin)
- macOS Threading: Crash fixes (V1, V2, V3 iterations)
- Standalone Renderer: Pygame wireframe visualization
- Vector Extraction: Direct access to DOOM internals
- Wireframe Rendering: Edge-based wall rendering
- Triple-Mode Integration: SDL + Python + KiCad
- Entity Type Extraction: DOOM source patches for real types
- Footprint System: Category-based component rendering
Standalone Renderer Test:
./run_standalone_renderer.py # Terminal 1
./run_doom.sh dual -w 1 1 # Terminal 2KiCad Smiley Test:
export KIDOOM_TEST_MODE=true
# Then run plugin in KiCadFull Integration:
# Install plugin, open KiCad PCBnew
# Tools → External Plugins → KiDoom- KiCad Performance: PCB refresh is inherently slow (10-25 FPS)
- macOS Threading: wx.Timer must stay on main thread
- Footprint Loading: Initial load ~10-50ms per footprint type
- Socket Timing: Must create socket before launching DOOM
All major issues have been solved. See CLAUDE.md for technical details.
┌─────────────┐ ┌──────────────┐
│ DOOM Engine │ Unix Socket │ KiCad Plugin │
│ (C/SDL) │ ─────────────→ │ (Python) │
│ │ JSON Vectors │ │
└─────────────┘ └──────────────┘
│ │
├─ SDL Window (gameplay) ├─ PCB Traces (walls)
├─ Vector Extraction ├─ Footprints (entities)
└─ Entity Types (MT_*) └─ Vias (projectiles)
│
↓
┌──────────────────┐
│ Python Renderer │
│ (Pygame/Ref) │
└──────────────────┘
| Entity | Type | Category | PCB Component | Visual |
|---|---|---|---|---|
| Player | MT_PLAYER (0) | Enemy | LQFP-64 | 64-pin complex IC |
| Shotgun Guy | MT_SHOTGUY (2) | Enemy | LQFP-64 | 64-pin complex IC |
| Imp | MT_TROOP (11) | Enemy | LQFP-64 | 64-pin complex IC |
| Medikit | MT_MISC11 (38) | Collectible | SOT-23 | 3-pin small package |
| Ammo Clip | MT_CLIP (52) | Collectible | SOT-23 | 3-pin small package |
| Barrel | MT_BARREL (68) | Decoration | SOIC-8 | 8-pin flat package |
| Dead Body | MT_MISC53 (95) | Decoration | SOIC-8 | 8-pin flat package |
Visual Hierarchy: Package complexity = Gameplay importance! 🎯
Python:
- pygame (standalone renderer)
- pynput (optional, keyboard capture)
C/Build:
- GCC or Clang
- SDL2 development libraries
- make, pkg-config
KiCad:
- KiCad 7 or 8 (Python scripting support)
- Standard footprint libraries included
See LICENSE file.
DOOM Engine: Based on doomgeneric by ozkl Original DOOM: id Software (1993) KiCad: Open source PCB design software
ScopeDoom - DOOM rendered on an oscilloscope in XY mode, inspired by KiDoom's vector extraction approach. Some original development code remains in this repo under scopedoom/.
- id Software - Original DOOM (1993)
- ozkl - doomgeneric framework
- KiCad Project - Open source PCB design tools
- Community - Testing and feedback
✨ First DOOM port using real PCB components as the rendering medium 🏆 Entity system with semantic component selection 🎨 Triple-mode rendering for different use cases ⚡ Vector extraction 200-500x faster than pixel scanning 🔧 Electrically authentic PCB design (could be fabricated!)
Status: Fully working with triple-mode rendering and footprint-based entities!
For technical details and development guidance, see CLAUDE.md.

