Welcome to the Organism Simulation API documentation. This guide provides comprehensive information about the project's architecture, APIs, and development practices.
- Getting Started
- Architecture Overview
- Core APIs
- Development Tools
- Testing Guide
- Performance Guidelines
- Contributing
- Node.js 18+
- npm 9+
- Modern web browser with Canvas support
# Clone the repository
git clone <repository-url>
cd simulation
# Install dependencies
npm install
# Start development server
npm run dev
# Run tests
npm test
# Run E2E tests
npm run test:e2e
# Generate coverage report
npm run test:coveragesrc/
├── core/ # Core simulation logic
├── dev/ # Development tools
├── features/ # Game features (achievements, challenges, etc.)
├── models/ # Data models and types
├── services/ # Business logic services
├── types/ # TypeScript type definitions
├── ui/ # User interface components
└── utils/ # Utility functions and helpers
The Organism Simulation follows a modular, service-oriented architecture with clear separation of concerns:
- Organism - Individual organisms in the simulation
- OrganismSimulation - Main simulation engine
- Services - Business logic (AchievementService, StatisticsService, etc.)
- UI Components - Reusable interface elements
- Development Tools - Debug mode, console, profiler
- Service Layer Pattern - Business logic separation
- Component Pattern - Reusable UI elements
- Observer Pattern - Event-driven communication
- Singleton Pattern - Global state management
- Factory Pattern - Object creation
The Organism class represents individual organisms in the simulation.
constructor(x: number, y: number, type: OrganismType)x: number- Initial X position on canvasy: number- Initial Y position on canvastype: OrganismType- Organism type definition
// Update organism state
update(deltaTime: number, canvasWidth: number, canvasHeight: number): void
// Check if organism should reproduce
shouldReproduce(): boolean
// Check if organism should die
shouldDie(): boolean
// Render organism on canvas
render(ctx: CanvasRenderingContext2D): voidx: number // Current X position
y: number // Current Y position
age: number // Current age in simulation time
type: OrganismType // Type definition
reproduced: boolean // Whether organism has reproducedDefines the characteristics of organism types.
interface OrganismType {
name: string // Display name
color: string // Render color
growthRate: number // Reproduction rate
deathRate: number // Death rate
maxAge: number // Maximum lifespan
size: number // Render size
description: string // Description text
}Main simulation engine that manages organisms, rendering, and game state with performance optimizations.
constructor(canvas: HTMLCanvasElement, initialOrganismType: OrganismType)Parameters:
canvas- HTML canvas element for renderinginitialOrganismType- Initial organism type for placement
Example:
const canvas = document.getElementById('canvas') as HTMLCanvasElement;
const simulation = new OrganismSimulation(canvas, ORGANISM_TYPES.bacteria);// Simulation control
start(): void // Start the simulation
pause(): void // Pause the simulation
reset(): void // Reset to initial state
clear(): void // Clear all organisms
// Configuration
setSpeed(speed: number): void // Set simulation speed (1-10)
setOrganismType(type: OrganismType): void // Set organism type for placement
setMaxPopulation(limit: number): void // Set population limit (1-5000)
// State access
getStats(): SimulationStats // Get current simulation statistics
getOrganismTypeById(id: string): OrganismType | null // Get organism type by ID// Algorithm optimizations
setOptimizationsEnabled(enabled: boolean): void // Enable/disable optimizations
toggleSoAOptimization(enable: boolean): void // Toggle Structure of Arrays
getAlgorithmPerformanceStats(): PerformanceStats // Get performance statistics
// Memory management
getMemoryStats(): MemoryStats // Get memory usage statistics// Environmental factors
updateEnvironmentalFactors(factors: Partial<EnvironmentalFactors>): void
getEnvironmentalFactors(): EnvironmentalFactors
getPopulationPrediction(): PopulationPrediction | nullinterface SimulationStats {
population: number; // Current population count
generation: number; // Current generation number
isRunning: boolean; // Whether simulation is running
placementMode: boolean; // Whether in placement mode
}// Basic simulation setup
const canvas = document.getElementById('canvas') as HTMLCanvasElement;
const simulation = new OrganismSimulation(canvas, ORGANISM_TYPES.bacteria);
// Configure simulation
simulation.setSpeed(5);
simulation.setMaxPopulation(200);
// Enable performance optimizations
simulation.setOptimizationsEnabled(true);
simulation.toggleSoAOptimization(true);
// Start simulation
simulation.start();
// Monitor statistics
setInterval(() => {
const stats = simulation.getStats();
console.log(`Population: ${stats.population}, Generation: ${stats.generation}`);
}, 1000);
// Get performance data
const perfStats = simulation.getAlgorithmPerformanceStats();
console.log('Performance stats:', perfStats);
// Get memory usage
const memStats = simulation.getMemoryStats();
console.log('Memory usage:', memStats);Manages achievements and unlockables.
class AchievementService {
checkAchievements(statistics: SimulationStatistics): Achievement[]
unlockAchievement(id: string): void
getUnlockedAchievements(): Achievement[]
}Tracks and manages simulation statistics.
class StatisticsService {
updateStatistics(organisms: Organism[]): void
getStatistics(): SimulationStatistics
reset(): void
}High-level simulation management.
class SimulationService {
createSimulation(config: SimulationConfig): OrganismSimulation
saveSimulation(): SimulationData
loadSimulation(data: SimulationData): void
}Activate with Ctrl+Shift+D or programmatically:
import { DebugMode } from './dev/debugMode';
const debug = DebugMode.getInstance();
debug.enable(); // Show debug panel
debug.updateInfo({ fps: 60, organismCount: 100 });Activate with `Ctrl+`` (backtick):
import { DeveloperConsole } from './dev/developerConsole';
const console = DeveloperConsole.getInstance();
console.show();
console.registerCommand({
name: 'custom',
description: 'Custom command',
usage: 'custom [args]',
execute: (args) => 'Command executed'
});help- Show available commandsclear- Clear console outputdebug [on|off]- Toggle debug modeperformance- Show performance infoprofile [start|stop]- Performance profilinglocalStorage [get|set|remove|clear]- Manage storage
import { PerformanceProfiler } from './dev/performanceProfiler';
const profiler = PerformanceProfiler.getInstance();
const sessionId = profiler.startProfiling(10000); // 10 seconds
// ... do work ...
const session = profiler.stopProfiling();
console.log(session.recommendations);Located in test/ directory. Use Vitest framework.
# Run all tests
npm test
# Run with UI
npm run test:ui
# Run specific test file
npm test organism.test.ts
# Generate coverage
npm run test:coverageLocated in e2e/ directory. Use Playwright framework.
# Run E2E tests
npm run test:e2e
# Run with UI
npm run test:e2e:ui
# Run specific browser
npx playwright test --project=chromiumLocated in test/performance/ directory.
# Run performance benchmarks
npm run test:performance# Run visual tests
npm run test:visual
# Update baselines
npx playwright test --config playwright.visual.config.ts --update-snapshotsimport { describe, it, expect } from 'vitest';
import { Organism } from '../src/core/organism';
import { ORGANISM_TYPES } from '../src/models/organismTypes';
describe('Organism', () => {
it('should create organism with correct properties', () => {
const organism = new Organism(100, 200, ORGANISM_TYPES.bacteria);
expect(organism.x).toBe(100);
expect(organism.y).toBe(200);
expect(organism.type).toBe(ORGANISM_TYPES.bacteria);
expect(organism.age).toBe(0);
});
});import { test, expect } from '@playwright/test';
test('should start simulation', async ({ page }) => {
await page.goto('/');
await page.click('#start-btn');
// Verify simulation is running
await expect(page.locator('#pause-btn')).toBeVisible();
});- 60 FPS - Maintain smooth animation
- < 16ms - Frame time budget
- < 100MB - Memory usage limit
- < 80% - GC pressure threshold
class OrganismPool {
private pool: Organism[] = [];
acquire(x: number, y: number, type: OrganismType): Organism {
if (this.pool.length > 0) {
const organism = this.pool.pop()!;
organism.reset(x, y, type);
return organism;
}
return new Organism(x, y, type);
}
release(organism: Organism): void {
this.pool.push(organism);
}
}class QuadTree {
insert(organism: Organism): void { /* ... */ }
query(bounds: Rectangle): Organism[] { /* ... */ }
}class CanvasManager {
private dirtyRegions: Rectangle[] = [];
markDirty(region: Rectangle): void {
this.dirtyRegions.push(region);
}
render(): void {
this.dirtyRegions.forEach(region => {
this.renderRegion(region);
});
this.dirtyRegions.length = 0;
}
}// Track frame rate
const profiler = PerformanceProfiler.getInstance();
profiler.trackFrame(); // Call each frame
// Monitor memory
profiler.updateInfo({
memoryUsage: (performance as any).memory?.usedJSHeapSize || 0
});import { ErrorHandler, ErrorSeverity } from './utils/system/errorHandler';
try {
// Risky operation
} catch (error) {
ErrorHandler.getInstance().handleError(
error,
ErrorSeverity.HIGH,
'Operation Context'
);
}LOW- Minor issues, logged onlyMEDIUM- Noticeable issues, user notificationHIGH- Significant problems, error recoveryCRITICAL- Fatal errors, application halt
import { GameStateManager } from './utils/game/gameStateManager';
const gameState = GameStateManager.getInstance();
// Subscribe to state changes
gameState.subscribe('organisms', (organisms) => {
console.log('Organisms updated:', organisms.length);
});
// Update state
gameState.setState('organisms', newOrganisms);import { BaseComponent } from './ui/components/BaseComponent';
class CustomComponent extends BaseComponent<HTMLDivElement> {
protected createElement(): HTMLDivElement {
const element = document.createElement('div');
element.className = 'custom-component';
return element;
}
protected setupEventListeners(): void {
this.element.addEventListener('click', this.handleClick.bind(this));
}
private handleClick(): void {
this.emit('clicked');
}
}const component = new CustomComponent();
component.on('clicked', () => console.log('Clicked!'));
component.mount(document.body);import { ObjectPool } from './utils/memory/objectPool';
const organismPool = new ObjectPool(() => new Organism(0, 0, ORGANISM_TYPES.bacteria));
// Acquire from pool
const organism = organismPool.acquire();
// Release back to pool
organismPool.release(organism);import { MemoryMonitor } from './utils/memory/memoryMonitor';
const monitor = MemoryMonitor.getInstance();
monitor.startMonitoring();
monitor.on('memoryWarning', (usage) => {
console.warn('High memory usage:', usage);
});interface SimulationConfig {
maxOrganisms: number;
updateInterval: number;
canvasWidth: number;
canvasHeight: number;
initialOrganismCount: number;
enableDebugMode: boolean;
}# Development mode
VITE_DEV_MODE=true
# Debug level
VITE_DEBUG_LEVEL=info
# Performance monitoring
VITE_ENABLE_PROFILING=true- Fork the repository
- Create feature branch:
git checkout -b feature/amazing-feature - Make changes following coding standards
- Add tests for new functionality
- Ensure all tests pass:
npm test - Update documentation as needed
- Submit pull request
- Use TypeScript strict mode
- Follow ESLint configuration
- Write comprehensive tests (90%+ coverage)
- Document public APIs with JSDoc
- Use semantic commit messages
- Ensure CI passes
- Update README if needed
- Add tests for new features
- Update CHANGELOG.md
- Request review from maintainers
Complete API reference is available in the generated TypeDoc documentation:
# Generate API docs
npm run docs
# View docs
open docs/index.html- Check organism count - reduce if > 1000
- Enable debug mode to monitor FPS
- Use performance profiler to identify bottlenecks
- Consider enabling object pooling
- Monitor memory usage with dev tools
- Check for unreleased event listeners
- Verify object pools are releasing properly
- Use memory profiler to track allocations
- Verify canvas element exists
- Check canvas dimensions
- Ensure proper context cleanup
- Monitor canvas operation count
// In browser console
window.debug.enable(); // Enable debug mode
window.profiler.start(); // Start profiling
window.simulation.getStats(); // Get current statsThis project is licensed under the MIT License - see the LICENSE file for details.
- Create an issue for bug reports
- Start a discussion for questions
- Check existing documentation first
- Provide minimal reproduction examples