Welcome to the Organism Simulation project! This guide will help you get up and running as a developer on this project.
- Prerequisites
- Quick Start
- CLI Tools Authentication
- Project Structure
- Development Workflow
- Architecture Overview
- Common Development Tasks
- Testing Guide
- Performance Optimization
- Troubleshooting
- Contributing Guidelines
Before you begin, ensure you have the following installed:
- Node.js (v18 or higher)
- npm (v9 or higher)
- Git (for version control)
- VS Code (recommended IDE)
- TypeScript and JavaScript Language Features
- ESLint
- Prettier
- Live Server
- GitLens
- Thunder Client (for API testing)
# Clone the repository
git clone <repository-url>
cd simulation
# Install dependencies
npm install
# Start development server
npm run devOpen your browser to http://localhost:5173 and you should see the organism simulation running.
# Run unit tests
npm test
# Run tests with coverage
npm run test:coverage
# Run end-to-end tests
npm run test:e2eThis project uses several CLI tools that require authentication for full functionality:
- Wrangler CLI - Cloudflare Pages deployment
- Snyk CLI - Security vulnerability scanning
- GitHub CLI - Repository management (optional)
For detailed authentication instructions, see CLI Authentication Guide.
# Authenticate with Cloudflare
wrangler login
# Authenticate with Snyk
snyk auth
# Authenticate with GitHub (optional)
gh auth loginsrc/
├── core/ # Core simulation logic
│ ├── organism.ts # Individual organism behavior
│ ├── simulation.ts # Main simulation engine
│ └── constants.ts # Configuration constants
├── models/ # Data models and types
│ ├── organismTypes.ts # Different organism configurations
│ └── unlockables.ts # Unlockable content
├── services/ # Business logic layer
│ ├── AchievementService.ts
│ ├── SimulationService.ts
│ └── StatisticsService.ts
├── ui/ # User interface components
│ ├── components/ # Reusable UI components
│ └── domHelpers.ts # DOM manipulation utilities
├── utils/ # Utility functions
│ ├── algorithms/ # Performance optimization algorithms
│ ├── canvas/ # Canvas rendering utilities
│ ├── memory/ # Memory management
│ └── system/ # System utilities (logging, error handling)
├── features/ # Game features
│ ├── achievements/ # Achievement system
│ ├── challenges/ # Challenge system
│ └── powerups/ # Power-up mechanics
├── dev/ # Development tools
│ ├── debugMode.ts # Debug mode functionality
│ └── performanceProfiler.ts # Performance profiling
└── types/ # TypeScript type definitions
# Create a new feature branch
git checkout -b feature/my-new-feature
# Make your changes
# ... code changes ...
# Run tests to ensure nothing broke
npm test
# Check type safety
npm run type-check
# Build the project
npm run buildWe use TypeScript with strict type checking. Follow these conventions:
- Use PascalCase for classes and interfaces
- Use camelCase for variables and functions
- Use UPPER_SNAKE_CASE for constants
- Always provide type annotations for public APIs
- Use JSDoc comments for classes and public methods
# Before committing
npm run lint # Check code style
npm test # Run tests
npm run build # Ensure build works
# Commit with descriptive messages
git add .
git commit -m "feat: add organism reproduction algorithm"
# Push changes
git push origin feature/my-new-feature-
Organism Class (
src/core/organism.ts)- Represents individual organisms
- Handles movement, reproduction, and death
- Optimized for performance with object pooling
-
OrganismSimulation Class (
src/core/simulation.ts)- Main simulation engine
- Manages organism lifecycle
- Handles rendering and user interactions
- Implements performance optimizations
-
Services Layer (
src/services/)- AchievementService: Manages achievement system
- SimulationService: Business logic for simulation
- StatisticsService: Handles statistics calculation
-
UI Components (
src/ui/components/)- Reusable interface elements
- Event-driven communication
- Separation of concerns
- Service Layer Pattern: Business logic separation
- Object Pool Pattern: Memory optimization
- Observer Pattern: Event-driven updates
- Singleton Pattern: Global state management
- Factory Pattern: Organism creation
- Define the organism type in
src/models/organismTypes.ts:
export const NEW_ORGANISM: OrganismType = {
id: 'new-organism',
name: 'New Organism',
color: '#FF5733',
size: 5,
growthRate: 0.02,
deathRate: 0.01,
maxAge: 100,
reproductionAge: 20,
reproductionRate: 0.05,
icon: '🧬'
};- Add to organism types array in the same file
- Update UI to include the new organism in dropdowns
- Write tests for the new organism type
- Create component file in
src/ui/components/:
// src/ui/components/MyComponent.ts
export class MyComponent {
private element: HTMLElement;
constructor(container: HTMLElement) {
this.element = this.createElement();
container.appendChild(this.element);
}
private createElement(): HTMLElement {
const element = document.createElement('div');
element.className = 'my-component';
element.innerHTML = `
<h3>My Component</h3>
<p>Component content</p>
`;
return element;
}
public update(data: any): void {
// Update component with new data
}
public destroy(): void {
this.element.remove();
}
}- Add styles in
src/ui/style.css - Export from index in
src/ui/components/index.ts - Write tests for the component
- Identify bottlenecks using the built-in profiler:
import { perf } from '../utils/system/logger';
// Start timing
perf.startTiming('my-operation');
// Your code here
doExpensiveOperation();
// End timing
const duration = perf.endTiming('my-operation', 'Description');- Implement optimizations in
src/utils/algorithms/ - Add configuration in
src/core/constants.ts - Write performance tests in
test/performance/
- Create feature directory in
src/features/ - Implement feature logic with proper interfaces
- Add to main simulation class
- Create UI controls if needed
- Write comprehensive tests
- Update documentation
We use Vitest for unit testing with jsdom for DOM testing.
// Example test file
import { describe, it, expect, beforeEach } from 'vitest';
import { Organism } from '../src/core/organism';
describe('Organism', () => {
let organism: Organism;
beforeEach(() => {
organism = new Organism(100, 100, BACTERIA);
});
it('should initialize with correct properties', () => {
expect(organism.x).toBe(100);
expect(organism.y).toBe(100);
expect(organism.age).toBe(0);
});
it('should update position correctly', () => {
const initialX = organism.x;
organism.update(1, 800, 600);
expect(organism.x).not.toBe(initialX);
});
});We use Playwright for E2E testing:
// e2e/simulation.spec.ts
import { test, expect } from '@playwright/test';
test('should start simulation', async ({ page }) => {
await page.goto('/');
await page.click('[data-testid="start-button"]');
await expect(page.locator('[data-testid="population-count"]')).toContainText('5');
});// test/performance/benchmark.test.ts
import { describe, it, expect } from 'vitest';
import { OrganismSimulation } from '../src/core/simulation';
describe('Performance Benchmarks', () => {
it('should handle 1000 organisms under 16ms', async () => {
const canvas = document.createElement('canvas');
const simulation = new OrganismSimulation(canvas, BACTERIA);
// Add 1000 organisms
for (let i = 0; i < 1000; i++) {
simulation.addOrganism(Math.random() * 800, Math.random() * 600);
}
const startTime = performance.now();
simulation.update(16.67); // One frame at 60fps
const endTime = performance.now();
expect(endTime - startTime).toBeLessThan(16);
});
});- Object Pooling: Reuse organism instances
- Structure of Arrays: Cache-friendly data layout
- Memory Monitoring: Track memory usage
- Garbage Collection: Minimize allocation/deallocation
- Canvas Layers: Separate background and organisms
- Batch Drawing: Group similar operations
- Dirty Rectangle: Only redraw changed areas
- Level of Detail: Reduce detail at high populations
- Spatial Partitioning: Efficient collision detection
- Batch Processing: Process organisms in groups
- Web Workers: Offload heavy calculations
- Predictive Algorithms: Population forecasting
-
Canvas not rendering
- Check canvas element exists in DOM
- Verify 2D context is available
- Ensure proper canvas sizing
-
Performance issues
- Enable algorithm optimizations
- Reduce population limits
- Check for memory leaks
-
Type errors
- Run
npm run type-check - Check TypeScript configuration
- Verify import paths
- Run
-
Tests failing
- Clear test cache:
npm run test:clear-cache - Check for browser compatibility
- Verify mock setup
- Clear test cache:
Enable debug mode for detailed logging:
import { enableDebugMode } from '../dev/debugMode';
enableDebugMode({
showFPS: true,
showMemoryUsage: true,
enableConsole: true,
logLevel: 'debug'
});Use the built-in profiler:
import { performanceProfiler } from '../dev/performanceProfiler';
performanceProfiler.startProfiling();
// Run your code
const results = performanceProfiler.getResults();
console.log(results);- Fork the repository and create a feature branch
- Follow code style guidelines and use TypeScript
- Write tests for new features and bug fixes
- Update documentation for API changes
- Ensure all tests pass before submitting
- Write clear commit messages following conventional commits
- Submit a pull request with detailed description
- Automated checks must pass (tests, linting, type checking)
- Code review by at least one maintainer
- Manual testing of new features
- Documentation review for completeness
- Performance impact assessment
- Version bump following semantic versioning
- Update changelog with new features and fixes
- Create release notes with migration guides
- Deploy to staging for final testing
- Deploy to production after approval
Now that you've completed the setup:
- Explore the codebase - Start with
src/main.tsandsrc/core/simulation.ts - Run the tests - Understand how components work together
- Make a small change - Try adding a new organism type or UI feature
- Read the API documentation - Understand the public interfaces
- Check out the examples - See how features are implemented
Welcome to the team! If you have any questions, don't hesitate to reach out to the maintainers.