Three Prompts: Doom Test

AI Assistant

Three Prompts: Doom Test

Doom clone game demo

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.

Links