Three Prompts: Doom Test
Three Prompts: Doom Test

Introduction
Doom, released in 1993, revolutionized the gaming industry with its fast-paced first-person shooter gameplay and immersive 3D environments. In this project, we've created a modern web-based Doom clone using React and Three.js, all guided by just three AI prompts. The result is a functional first-person shooter with core Doom mechanics: player movement, weapon systems, enemy AI, and a classic HUD interface.
What makes this project particularly interesting is how quickly a complex 3D game can be built using modern web technologies and AI assistance. The entire game runs in the browser, demonstrating the power of Three.js for 3D rendering and React for UI management.
The Three Prompts
Here are the exact prompts that were used to create this project:
Prompt 1
@projects/doom-test Make a doom clone in this project. /execute
Prompt 2
Continue
Prompt 3
Now make the enemies move and track the player. Don't make any breaking changes. /execute
Technologies Used
- React 19.1.0: For building the UI components and managing game state
- Three.js: Powers the 3D rendering, camera controls, raycasting, and physics
- Vite: Fast build tool and development server
- CSS: Custom styling for the game UI and HUD elements
Key Features and Functionality
1. Game Engine Architecture
The core of the game is built around a modular architecture with several key systems:
- GameEngine: Manages the Three.js scene, camera, renderer, controls, and animation loop
- WeaponSystem: Handles weapon switching, firing mechanics, and hit detection
- EnemySystem: Controls enemy spawning, AI behavior, and interactions with the player
- Game Component: Integrates all systems and manages the React lifecycle
This modular approach allows each system to be developed and tested independently, making the codebase more maintainable.
2. First-Person Movement and Controls
The game features classic DOOM-style movement using WASD or arrow keys, with mouse look controls:
- Forward/backward/strafe movement
- Mouse-based camera rotation
- Jumping mechanics with gravity
- Pointer lock for immersive first-person control
3. Weapon System
The weapon system includes multiple weapons with different characteristics:
- Pistol: Fast firing rate with moderate damage
- Shotgun: Slower firing rate with higher damage
- Weapon Switching: Press 1 or 2 to switch between weapons
- Ammo Management: Limited ammunition that can be tracked in the UI
- Visual Effects: Muzzle flash and impact effects when firing
4. Enemy AI and Behavior
Enemies in the game exhibit different behaviors based on their state and proximity to the player:
- Patrol State: Enemies move between patrol points when not engaged
- Chase State: Enemies actively pursue the player when detected
- Attack State: Enemies attack the player when in close range
- Line of Sight Detection: Enemies only chase when they can "see" the player
- Memory: Enemies continue chasing briefly after losing sight of the player
5. Game UI and HUD
The game features a classic Doom-style heads-up display:
- Health indicator
- Ammo counter
- Current weapon display
- Enemy counter
- Crosshair for aiming
- Start screen with instructions
Implementation Details
Enemy Movement and Tracking
One of the most interesting aspects of the implementation is the enemy AI system. Enemies have multiple states (patrol, chase, attack, dead) and transition between them based on various factors:
// Update enemy state based on distance to player and visibility
if (distanceToPlayer < 2) {
enemy.userData.state = 'attack';
} else if (distanceToPlayer < enemy.userData.sightRange && canSeePlayer) {
enemy.userData.state = 'chase';
enemy.userData.lastStateChange = now;
} else if (previousState === 'chase' && now - enemy.userData.lastStateChange < 3000) {
// Keep chasing for a bit after losing sight of player
enemy.userData.state = 'chase';
} else {
enemy.userData.state = 'patrol';
}
The patrol system assigns random patrol points to each enemy, creating more dynamic and unpredictable movement patterns:
// Assign random patrol points for this enemy
const patrolPointIndices = [];
const numPatrolPoints = Math.floor(Math.random() * 3) + 2; // 2-4 patrol points
while (patrolPointIndices.length < numPatrolPoints) {
const randomIndex = Math.floor(Math.random() * this.patrolPoints.length);
if (!patrolPointIndices.includes(randomIndex)) {
patrolPointIndices.push(randomIndex);
}
}
Weapon System and Hit Detection
The weapon system uses Three.js raycasting to detect hits on enemies:
// Cast ray for hit detection
this.raycaster.setFromCamera(new THREE.Vector2(0, 0), this.camera);
const intersects = this.raycaster.intersectObjects(this.scene.children, true);
// Handle hits
if (intersects.length > 0) {
const hit = intersects[0];
// If we hit an enemy
if (hit.object.userData.isEnemy) {
hit.object.userData.takeDamage(weapon.damage);
}
// Create impact effect
this.createImpactEffect(hit.point);
}
System Registration for Updates
The game engine uses a registration system to update all game systems each frame:
// Update all registered systems
for (const system of this.systems) {
if (system && typeof system.update === 'function') {
system.update(delta);
}
}
This approach allows for easy extension of the game with new systems without modifying the core game loop.
Challenges and Solutions
Challenge 1: Enemy Movement AI
Challenge: Creating enemies that move naturally and track the player without getting stuck or behaving erratically.
Solution: Implemented a state machine for enemy behavior with patrol, chase, and attack states. Added line-of-sight detection using raycasting and a "memory" system so enemies continue chasing briefly after losing sight of the player. This creates more realistic and engaging enemy behavior.
Challenge 2: Weapon System Integration
Challenge: Creating a weapon system that feels responsive and integrates with the 3D environment.
Solution: Used Three.js raycasting for precise hit detection and added visual feedback (muzzle flash, impact effects) to make weapons feel impactful. Implemented weapon switching and ammo management systems to add depth to gameplay.
Challenge 3: Performance Optimization
Challenge: Ensuring smooth performance with multiple enemies and systems running simultaneously.
Solution: Created a modular system architecture where each component only updates what's necessary. Used efficient Three.js techniques like object pooling for projectiles and effects, and implemented distance-based culling for enemies far from the player.
Conclusion
This Doom clone project demonstrates how modern web technologies can be used to create engaging 3D games directly in the browser. Using just React and Three.js, we've implemented core FPS mechanics including movement, weapons, enemy AI, and a classic HUD interface.
What's particularly impressive is that this entire implementation was guided by just three AI prompts, showcasing the power of AI assistance in game development. The modular architecture makes it easy to extend with new features like additional weapons, enemy types, levels, or even multiplayer functionality.
While this is a simplified version of Doom, it captures the essence of what made the original game so groundbreaking - fast-paced first-person action with enemies that actively hunt the player through 3D environments.