shellquest
Version:
Terminal-based procedurally generated dungeon crawler
216 lines (169 loc) • 5.65 kB
Markdown
# Lighting System Integration Guide
This document describes how to integrate the lighting system into the game.
## Files Created
1. `LightingSystem.ts` - Core lighting engine with light sources and flicker
2. `DungeonLighting.ts` - High-level API for dungeon torch management
3. `LightingRenderer.ts` - Applies lighting to the rendered output
4. `index.ts` - Main exports
## Required Changes
### 1. DungeonLevel.ts - Add getGrid() method
Add this method at the end of the DungeonLevel class:
```typescript
/**
* Get the internal grid for lighting system torch placement
*/
getGrid(): TileGrid {
return this.grid;
}
```
### 2. ZombieAttackGame.ts - Full Integration
#### Add imports at the top:
```typescript
import {DungeonLighting} from './lighting/DungeonLighting.ts';
import {applyLighting} from './lighting/LightingRenderer.ts';
```
#### Add class properties:
```typescript
// Lighting system for dungeon levels
private dungeonLighting: DungeonLighting | null = null;
private lightingEnabled: boolean = true;
```
#### Add initialization in initializeSync() after setting player spawn:
```typescript
// Initialize lighting system for dungeon
if (this.level instanceof DungeonLevel) {
this.initializeLighting(player);
}
```
#### Add the initializeLighting method:
```typescript
private initializeLighting(player: Player): void {
if (!(this.level instanceof DungeonLevel)) return;
// Create the lighting system
this.dungeonLighting = new DungeonLighting({
ambientLight: 0.08, // Very dark in unlit areas
maxBrightness: 1.0,
falloffExponent: 1.5,
});
// Get the dungeon grid for torch placement
const grid = this.level.getGrid();
if (grid) {
// Place wall torches throughout the dungeon
const seed = this.hashString('default_torches');
this.dungeonLighting.placeTorches(grid, MAP_WIDTH, MAP_HEIGHT, seed, {
minSpacing: 8,
frequency: 0.15,
maxTorches: 60,
preferCorridors: true,
});
}
// Initialize player's torch
this.dungeonLighting.initializePlayerTorch(
player.x + TILE_SIZE / 2,
player.y + TILE_SIZE / 2,
);
console.log(`Lighting initialized: ${this.dungeonLighting.getStats().torches} torches placed`);
}
private hashString(str: string): number {
let hash = 0;
for (let i = 0; i < str.length; i++) {
const char = str.charCodeAt(i);
hash = (hash << 5) - hash + char;
hash = hash & hash;
}
return Math.abs(hash);
}
```
#### Update the update() method:
```typescript
private update(deltaTime: number): void {
// Update all entities
for (const entity of this.level.getEntities()) {
entity.update(deltaTime, this.level, this.collisionSystem);
this.collisionSystem.updateEntity(entity);
}
// Update camera
this.camera.update(this.level.player.x, this.level.player.y);
// Update lighting system (handles flicker animation)
if (this.dungeonLighting && this.lightingEnabled) {
this.dungeonLighting.update(deltaTime);
// Update player torch position to follow player
this.dungeonLighting.updatePlayerTorch(
this.level.player.x + TILE_SIZE / 2,
this.level.player.y + TILE_SIZE / 2,
);
}
}
```
#### Add lighting toggle to setupInput() (optional):
```typescript
case 'l':
// Toggle lighting with 'L' key
this.lightingEnabled = !this.lightingEnabled;
console.log(`Lighting ${this.lightingEnabled ? 'enabled' : 'disabled'}`);
break;
```
#### Add applyLightingEffect() call at the end of render():
```typescript
render(): void {
// ... existing render code ...
// Apply lighting after all layers are rendered
this.applyLightingEffect();
}
private applyLightingEffect(): void {
if (!this.dungeonLighting || !this.lightingEnabled) return;
// Compute light map for current viewport
const lightMap = this.dungeonLighting.computeLightMap(
this.mainCanvas.width,
this.mainCanvas.height,
this.camera.x,
this.camera.y,
);
// Apply lighting to the main canvas
applyLighting(this.mainCanvas, lightMap, true);
}
```
## Configuration Options
### Lighting System Config
```typescript
{
ambientLight: 0.08, // Base visibility in darkness (0-1)
maxBrightness: 1.0, // Maximum brightness cap
falloffExponent: 1.5, // How sharply light fades (higher = sharper)
}
```
### Torch Placement Config
```typescript
{
minSpacing: 8, // Minimum tiles between torches
frequency: 0.15, // Probability of placing torch
maxTorches: 60, // Maximum torches per level
preferCorridors: true, // Place more torches in corridors
}
```
### Torch Light Config (in LightingSystem.ts)
```typescript
TORCH_LIGHT_CONFIG = {
radius: 6, // Light radius in tiles
intensity: 0.95, // Base brightness
color: {r: 255, g: 200, b: 100}, // Warm orange
flicker: true,
flickerSpeed: 2.5, // How fast the flicker
flickerIntensity: 0.15, // How much light varies
};
PLAYER_TORCH_CONFIG = {
radius: 5,
intensity: 0.85,
color: {r: 255, g: 220, b: 150}, // Slightly cooler
flicker: true,
flickerSpeed: 3.0,
flickerIntensity: 0.12,
};
```
## Performance Notes
- Light map is computed only for visible viewport
- Each frame updates flicker values using Perlin noise
- Typical performance: 60fps with ~50 visible lights
- Light map is cached and invalidated on camera movement
## Keyboard Controls
- `L` - Toggle lighting on/off (if implemented)