Skip to content

codewreaker/football-simulator

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

21 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๐ŸŽฎ Football Simulator

A fully-featured 11v11 football (soccer) simulation game built with TypeScript, React, and Canvas. Initially generated by Claude, and then tweaked to work well.

Enhancement Summary

๐ŸŒŸ Overview

Football Simulator is a modern web-based football game that demonstrates:

  • Pure TypeScript Game Engine - A completely decoupled game engine with zero React dependencies
  • Intelligent Decisions - Intelligent player behavior including possession, passing, and tactical positioning
  • Realistic Physics - Ball friction, collision detection, and impulse-based responses
  • Clean Architecture - Modular design following SOLID principles and separation of concerns

The game features two 11-player teams (home in red, away in blue) with a 4-3-3 formation, automatic goal detection, and real-time score tracking. Simply hit play to watch AI-controlled players battle it out!

๐Ÿš€ Quick Start

Prerequisites

  • Node.js 16+
  • pnpm (or npm/yarn)

Installation & Running

# Install dependencies
pnpm install

# Start development server
pnpm dev
# Opens at http://localhost:5173/

# Build for production
pnpm build

# Run linter
pnpm lint

๐ŸŽฎ Game Features

Player & Teams

  • 11 vs 11 Players - Full football teams with realistic formations
  • 4-3-3 Formation - Goalkeeper, 4 defenders, 3 midfielders, 3 forwards per team
  • Role-Based AI - Each player has a specific role affecting their behavior:
    • Goalkeeper: Tracks ball vertically, makes long passes
    • Defender: Intercepts passes, positions defensively
    • Midfielder: Balances defense and attack, supports play
    • Forward: Aggressive positioning, finishing opportunities

Gameplay Mechanics

  • Ball Possession - Realistic possession system based on proximity
  • Intelligent Passing - AI players make forward passes to teammates
  • Dribbling - Players can dribble forward when in possession
  • Collision Physics - Physical interactions between players
  • Goal Detection - Automatic scoring when ball crosses the goal line
  • Score Tracking - Real-time score display for both teams

Controls

  • Play/Pause - Toggle game simulation
  • Reset Game - Reset to initial state
  • Score Display - Real-time match score

๐Ÿ“ Project Structure

src/
โ”œโ”€โ”€ App.tsx                 # React UI component
โ””โ”€โ”€ engine/                 # Pure TypeScript Game Engine
    โ”œโ”€โ”€ GameEngine.ts       # Main orchestrator (60 FPS game loop)
    โ”œโ”€โ”€ index.ts           # Public API exports
    โ”œโ”€โ”€ entities/
    โ”‚   โ”œโ”€โ”€ Ball.ts        # Ball physics and behavior
    โ”‚   โ””โ”€โ”€ Player.ts      # Player AI and physics
    โ”œโ”€โ”€ math/
    โ”‚   โ””โ”€โ”€ Vector.ts      # 2D vector math utilities
    โ”œโ”€โ”€ renderer/
    โ”‚   โ””โ”€โ”€ Renderer.ts    # Canvas drawing operations
    โ””โ”€โ”€ physics/
        โ””โ”€โ”€ Physics.ts     # Collision detection & response

๐Ÿ—๏ธ Architecture

Clean Separation of Concerns

The game is built with a strict separation between the game engine (pure TypeScript) and the UI layer (React).

Game Engine (Pure TypeScript) - No React Dependencies

// src/engine/GameEngine.ts
export class GameEngine {
  // Game state
  getState(): GameState
  
  // Lifecycle
  start(): void
  stop(): void
  togglePause(): void
  resetGame(): void
  
  // Callbacks
  onStateChange(callback: (state: GameState) => void): void
}

React Integration - UI Only

// src/App.tsx
function App() {
  const [gameState, setGameState] = useState<GameState>({
    score: { home: 0, away: 0 },
    paused: false,
  });

  useEffect(() => {
    const engine = new GameEngine(canvas);
    engine.onStateChange(setGameState);
    engine.start();
    return () => engine.destroy();
  }, []);

  // Render UI and canvas
}

Module Responsibilities

Module Responsibility
GameEngine.ts Game state, loop coordination, system integration
Ball.ts Ball physics, friction, collision, goal detection
Player.ts Player AI, movement, possession, passing logic
Vector.ts 2D vector math operations and utilities
Renderer.ts Canvas rendering: pitch, players, ball
Physics.ts Player collision detection and impulse response

Dependency Graph

App.tsx
  โ””โ†’ GameEngine
      โ”œโ†’ Ball
      โ”‚  โ””โ†’ Vector
      โ”œโ†’ Player[]
      โ”‚  โ”œโ†’ Vector
      โ”‚  โ””โ†’ Ball
      โ”œโ†’ Renderer
      โ”‚  โ”œโ†’ Ball
      โ”‚  โ””โ†’ Player
      โ””โ†’ Physics
         โ””โ†’ Player

โœ… Zero circular dependencies โœ… No React in game engine โœ… 100% TypeScript typed

๐Ÿง  AI System

Decision Making

The AI system uses role-specific logic to determine player behavior:

Possession Logic

  • Players with the ball (within 20px radius) gain possession
  • Possession holders either pass or dribble based on timers
  • Goalkeepers hold longer than outfield players

Passing

  • Players prefer forward passes to teammates
  • Falls back to any available teammate if no forward options
  • Pass power calculated based on distance

Off-Ball Positioning

  • Goalkeepers track the ball vertically at their goal
  • Outfield players chase the ball if closest and it's slow
  • Players return to formation when ball is far away
  • Players provide support play near ball position

Role-Specific Behaviors

Role Possession Speed Acceleration Positioning
Goalkeeper Hold 20 frames 1.5 0.25 Track ball vertically
Defender Dribble 40 frames 2.0 0.35 Defensive shape
Midfielder Dribble 40 frames 2.3 0.40 Balance defense/attack
Forward Dribble 40 frames 2.5 0.45 Aggressive positioning

โš™๏ธ Physics

Ball Physics

  • Velocity & Friction: 0.97x friction per frame (3% energy loss)
  • Bounce Damping: 0.7x energy on wall collisions
  • Stop Threshold: Velocity < 0.05 treated as zero
  • Size: 6px radius

Player Physics

  • Collision Damping: 0.3x energy in player collisions
  • Friction: 0.88x per frame (12% deceleration)
  • Size: 15px radius
  • Mass: 2 units (vs ball's 1)

Collision Detection

  • Impulse-based collision response
  • Elastic collisions between players
  • Automatic boundary constraints
  • Distance-based pass detection

๐Ÿ“Š Code Quality

Build Status

  • โœ… TypeScript Compilation: PASS
  • โœ… Vite Build: SUCCESS
  • โœ… Compiler Errors: 0
  • โœ… Compiler Warnings: 0

Code Organization

  • โœ… 7 modular TypeScript files (~785 lines total)
  • โœ… 100% type coverage
  • โœ… No circular dependencies
  • โœ… No unused imports or variables
  • โœ… SOLID principles followed

Before vs After Refactoring

Aspect Before After
Files 1 monolithic 7 focused
Lines 400+ mixed 785 organized
React coupling Heavy None in engine
Type safety Partial 100%
Reusability Limited Full
Testability Difficult Easy

๐Ÿ”ง Developer Guide

Using the Game Engine

import { GameEngine } from './engine/GameEngine';
import type { GameState } from './engine/GameEngine';

const canvasEl = document.getElementById('game') as HTMLCanvasElement;
const engine = new GameEngine(canvasEl);

// Listen to state changes
engine.onStateChange((newState: GameState) => {
  console.log(`Score: ${newState.score.home} - ${newState.score.away}`);
  console.log(`Paused: ${newState.paused}`);
});

// Control the game
engine.start();
engine.togglePause();
engine.resetGame();
engine.stop();

Game Loop (60 FPS)

Each frame:

  1. Update Ball - Apply velocity, friction, detect goals
  2. Update Players - AI decisions, movement, possession
  3. Collision Detection - Resolve player-player collisions
  4. Render - Draw pitch, players, and ball

Team Formation (4-3-3)

Home Team (Red) - Attacks Right    Away Team (Blue) - Attacks Left

        GK                               GK
    LB  LCB RCB RB              LB  LCB RCB RB
    LM   CM   RM                LM   CM   RM
    LW   ST   RW                LW   ST   RW

Extending the Game

To add new features:

  1. Ball Behavior: Modify src/engine/entities/Ball.ts
  2. Player AI: Modify src/engine/entities/Player.ts
  3. Rendering: Modify src/engine/renderer/Renderer.ts
  4. Physics: Modify src/engine/physics/Physics.ts
  5. Coordination: Modify src/engine/GameEngine.ts

Example: Adding stamina system

// In Player.ts
export class Player {
  stamina: number = 100;
  
  update(ball: Ball, players: Player[]) {
    // ... existing code ...
    
    // Recovery when not in possession
    if (!this.hasPossession) {
      this.stamina = Math.min(100, this.stamina + 0.5);
    } else {
      this.stamina = Math.max(0, this.stamina - 1);
    }
    
    // Reduce speed when tired
    const speedMultiplier = this.stamina < 20 ? 0.8 : 1.0;
    this.maxSpeed *= speedMultiplier;
  }
}

๐ŸŽฏ Game Logic Details

Team Formations & Starting Positions

The game uses a classic 4-3-3 formation with 11 players per team:

  • 1 Goalkeeper - Maintains defensive position
  • 4 Defenders - Left back, 2 center backs, right back
  • 3 Midfielders - Left, center, right
  • 3 Forwards - Left wing, striker, right wing

Scoring System

Goals are automatically detected when:

  • Ball crosses goal line (X < 30 or X > 870)
  • Ball is within goal area (Y between 140-460)
  • Ball has been hit by a player

Possession Mechanics

A player has possession when:

  • Ball is within 20px radius of player
  • No opponent is closer to the ball
  • Ball is traveling slow enough

๐Ÿš€ Performance

  • Frame Rate: 60 FPS target
  • Entities: 22 players + 1 ball = 23 total
  • Collisions: Nยฒ detection (optimizable for larger games)
  • Memory: ~5-10MB runtime
  • Canvas Size: 900x600px

๐Ÿ“š Game Concepts

Vector Math

The game uses 2D vector math for all physics:

const velocity = new Vector(5, 10);
const friction = velocity.mult(0.97);
const normalized = velocity.normalize();
const magnitude = velocity.mag();

Impulse-Based Physics

Collisions use impulse-based responses:

  • Calculate relative velocity
  • Apply counter-impulse to both bodies
  • Dampen energy loss (0.3x for players)

AI Decision Tree

Each player evaluates:

  1. Do I have possession?
  2. Is the ball moving fast? (Chase if < 3 m/s)
  3. Am I in formation? (Return if far away)
  4. Can I support play? (Position near ball)

๐Ÿ”ฎ Future Enhancements

The clean architecture makes it easy to add:

  • Advanced AI: Tactics system, pressing strategies, formations
  • Player Stats: Individual attributes (pace, passing, shooting)
  • Animations: Smooth transitions, celebration animations
  • Match Events: Yellow/red cards, fouls, injuries
  • Replay System: Record and replay match highlights
  • Multiplayer: Network play or local hot-seat mode
  • UI Dashboard: Team selection, player management, statistics
  • Sound Effects: Goal sounds, crowd noise, commentary
  • Different Game Modes: Tournament, career, custom matches

๐Ÿ“– Additional Documentation

  • REFACTORING_SUMMARY.md - Detailed breakdown of all changes
  • REFACTORING_COMPLETE.md - Complete refactoring checklist
  • DEVELOPER_GUIDE.md - Comprehensive development guide
  • COMPLETION_CHECKLIST.md - All requirements verified

๐Ÿ“ License

See LICENSE file for details.

๐Ÿค Contributing

The modular architecture makes it easy to contribute:

  1. Pick a module to enhance
  2. Review its type definitions
  3. Implement your feature
  4. Test in the game
  5. Ensure no circular dependencies

Happy coding! โšฝ

About

A Football Sim Generated from Claude

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages