Skip to content

Latest commit

 

History

History
331 lines (269 loc) · 10.6 KB

File metadata and controls

331 lines (269 loc) · 10.6 KB

vRacer Rendering Simplification Plan

🎯 Objective

Transform vRacer from a real-time rendered game with complex animation systems to a simplified, event-driven turn-based game that maintains visual quality while reducing complexity and resource usage.

📊 Current State Analysis

Over-Engineered Components:

  • Animation System: 353 lines (src/animations.ts)
  • Performance Monitoring: 337 lines (src/performance.ts)
  • 60 FPS Animation Loop: Continuous rendering in main.ts
  • Complex Layering: Multi-layer transparency system in game.ts
  • Particle Systems: Real-time particle physics for visual effects

Resource Impact:

  • CPU Usage: Continuous 60 FPS rendering loop
  • Battery Drain: Unnecessary for turn-based gameplay
  • Code Complexity: ~700+ lines of animation/performance code
  • Maintenance Overhead: Multiple systems to debug and maintain

🗺️ Simplification Roadmap

Phase 1: Disable Animation System 🔧

Goal: Test game without animations to validate functionality Impact: Immediate performance improvement, no code removal yet Risk Level: Low (easily reversible)

Actions:

  1. Set animations: false in feature flags
  2. Test all game functionality
  3. Measure performance improvement
  4. Document any visual regressions

Success Criteria:

  • ✅ All gameplay mechanics work correctly
  • ✅ No JavaScript errors in console
  • ✅ Mouse interactions still responsive
  • ✅ Game state changes render correctly

Phase 2: Remove Animation Loop

Goal: Replace continuous rendering with event-driven rendering Impact: Eliminate 60 FPS loop, major resource savings Risk Level: Medium (requires careful event handling)

Actions:

  1. Remove animationLoop() function from main.ts
  2. Replace with render() calls on specific events:
    • Player moves (mouse click, keyboard input)
    • UI state changes (toggles, hover)
    • Game state updates (new game, reset)
  3. Update mouse hover handling to trigger renders
  4. Test responsiveness of all interactions

Implementation Details:

// REMOVE: Continuous animation loop
// if (isFeatureEnabled('animations')) {
//   animationLoop()
// }

// REPLACE WITH: Event-driven rendering
function renderOnEvent() {
  render()
}

// Call renderOnEvent() on:
// - canvas click events
// - mouse move (for hover effects)  
// - keyboard inputs
// - toggle changes
// - game state updates

Success Criteria:

  • ✅ Game renders immediately on user interaction
  • ✅ Hover effects still work smoothly
  • ✅ No visual lag or missing updates
  • ✅ CPU usage drops significantly when idle

Phase 3: Simplify Performance Monitoring 📈

Goal: Replace complex performance system with minimal debug info Impact: Remove 300+ lines of performance tracking code Risk Level: Low (debug feature, not core gameplay)

Actions:

  1. Create minimal performance tracker (10-20 lines)
  2. Keep only basic render time logging for debug mode
  3. Remove frame time arrays, FPS calculations, memory tracking
  4. Update HUD to show simplified debug info

Replacement Implementation:

// Minimal performance tracking
class SimplePerformanceTracker {
  private renderStart = 0
  
  startRender() {
    if (isFeatureEnabled('debugMode')) {
      this.renderStart = performance.now()
    }
  }
  
  endRender() {
    if (isFeatureEnabled('debugMode') && this.renderStart > 0) {
      const renderTime = performance.now() - this.renderStart
      console.log(`Render time: ${renderTime.toFixed(2)}ms`)
    }
  }
}

Success Criteria:

  • ✅ Debug mode still shows basic render info
  • ✅ No performance tracking overhead in production
  • ✅ Bundle size reduced significantly

Phase 4: Remove Animation System Files 🗑️

Goal: Delete animation system code and dependencies Impact: Remove 350+ lines, clean up imports Risk Level: Low (already disabled and tested)

Actions:

  1. Delete src/animations.ts
  2. Remove animation imports from main.ts and game.ts
  3. Remove animation manager references in draw function
  4. Update TypeScript types if needed
  5. Clean up any animation-related feature flags

File Changes:

  • DELETE: src/animations.ts
  • UPDATE: src/main.ts (remove imports, animation references)
  • UPDATE: src/game.ts (remove particle rendering)
  • UPDATE: src/features.ts (remove animations flag)

Success Criteria:

  • ✅ TypeScript compiles without errors
  • ✅ No animation-related imports or references
  • ✅ Game functions identically to Phase 1 testing

Phase 5: Simplify Draw Function 🎨

Goal: Reduce complexity in rendering layers and effects Impact: Cleaner, more maintainable rendering code Risk Level: Medium (core rendering logic)

Actions:

  1. Simplify LayerManager opacity system
  2. Remove unnecessary layering complexity
  3. Streamline canvas drawing operations
  4. Keep essential visual elements:
    • Track boundaries and surface
    • Car positions with colors
    • Move candidates
    • Basic hover effects
    • Grid and coordinates

Simplification Targets:

// SIMPLIFY: Complex layering system
// Remove excessive transparency layers
// Keep only essential visual hierarchy:
// 1. Background (paper + grid)
// 2. Track (surface + borders)  
// 3. Game elements (cars, trails, candidates)
// 4. UI feedback (hover, selection)

Success Criteria:

  • ✅ Visual quality maintained
  • ✅ All game elements clearly visible
  • ✅ Simplified code structure
  • ✅ Faster rendering performance

Phase 6: Replace Visual Effects

Goal: Simple static replacements for dynamic effects Impact: Maintain visual feedback without complexity Risk Level: Low (purely cosmetic)

Actions:

  1. Replace particle explosions with simple color changes
  2. Replace celebration effects with static success indicators
  3. Add simple visual feedback for crashes/wins
  4. Ensure accessibility of visual cues

Simple Effect Replacements:

// Instead of particle explosion:
function showCrashEffect(pos: Vec, ctx: CanvasRenderingContext2D, g: number) {
  // Simple red flash or X mark
  ctx.fillStyle = '#ff4444'
  ctx.fillRect(pos.x * g - 5, pos.y * g - 5, 10, 10)
}

// Instead of celebration particles:
function showWinEffect(pos: Vec, ctx: CanvasRenderingContext2D, g: number) {
  // Simple checkmark or star
  ctx.fillStyle = '#44ff44' 
  // Draw checkmark shape
}

📋 Implementation Checklist

Pre-Implementation:

  • Backup current codebase
  • Run full test suite to establish baseline
  • Document current performance metrics
  • Create feature branch for simplification work

Phase 1 - Disable Animations:

  • Update animations: false in src/features.ts
  • Test game functionality comprehensively
  • Measure performance impact
  • Document any issues or regressions

Phase 2 - Event-Driven Rendering:

  • Remove animationLoop() from src/main.ts
  • Add render() calls to event handlers
  • Update mouse move handler for hover effects
  • Test all interaction responsiveness
  • Verify CPU usage improvement

Phase 3 - Simplify Performance:

  • Create SimplePerformanceTracker class
  • Replace complex performance system
  • Update HUD debug display
  • Test debug mode functionality

Phase 4 - Remove Animation Files:

  • Delete src/animations.ts
  • Remove animation imports and references
  • Clean up TypeScript compilation
  • Update feature flags
  • Verify no broken dependencies

Phase 5 - Simplify Rendering:

  • Streamline draw() function in src/game.ts
  • Simplify LayerManager complexity
  • Remove unnecessary transparency layers
  • Maintain visual quality standards

Phase 6 - Replace Effects:

  • Implement simple crash feedback
  • Add basic win/success indicators
  • Test visual accessibility
  • Ensure all feedback is clear

Final Validation:

  • Full functionality test
  • Performance comparison (before/after)
  • Code review for cleanup opportunities
  • Update documentation and README
  • Bundle size analysis

📈 Expected Benefits

Performance Improvements:

  • CPU Usage: 90%+ reduction when game is idle
  • Battery Life: Significant improvement on mobile devices
  • Memory Usage: Lower baseline memory consumption
  • Startup Time: Faster initial load with smaller bundle

Code Quality:

  • Lines of Code: ~700 line reduction (20% smaller codebase)
  • Complexity: Fewer interdependent systems
  • Maintainability: Simpler debugging and feature development
  • Bundle Size: Smaller JavaScript payload

Development Experience:

  • Build Time: Faster TypeScript compilation
  • Debug Experience: Less noise in performance monitoring
  • Feature Development: Cleaner architecture for new features
  • Bug Fixing: Fewer systems to consider during debugging

🔍 Testing Strategy

Regression Testing:

  1. Core Gameplay: All turn-based mechanics
  2. Multi-car Support: Player switching, collisions
  3. UI Interactions: Mouse clicks, keyboard shortcuts
  4. Visual Quality: Track rendering, car display
  5. Feature Flags: All toggleable features work
  6. Mobile Responsiveness: Touch interactions, layout

Performance Testing:

  1. Resource Usage: CPU, memory monitoring
  2. Responsiveness: Input lag measurements
  3. Battery Impact: Mobile device power consumption
  4. Bundle Analysis: JavaScript size comparison

User Experience Testing:

  1. Visual Feedback: Clear game state communication
  2. Interaction Smoothness: No perceived lag
  3. Accessibility: Visual cues remain clear
  4. Error Handling: Graceful degradation

🚨 Risk Mitigation

Rollback Plan:

  • Git branch with all changes for easy revert
  • Feature flag toggles for gradual rollout
  • Performance baseline documentation for comparison

Testing Gates:

Each phase requires sign-off before proceeding:

  • Functionality verification
  • Performance validation
  • Visual quality approval
  • User experience confirmation

Monitoring:

  • Console error tracking during development
  • User feedback collection after deployment
  • Performance metric comparison

🚀 Ready to Begin

This plan provides a systematic approach to simplifying vRacer's rendering system while maintaining game quality and minimizing risk. Each phase builds on the previous one, allowing for validation and course correction along the way.

Next Step: Phase 1 implementation - disabling animations and testing functionality.