Skip to content

Retro-style 18-hole browser minigolf game - React + TypeScript

License

Notifications You must be signed in to change notification settings

mguttmann/minigolf-2000

Repository files navigation

Minigolf 2000

A retro-style 18-hole browser minigolf game built with React and TypeScript.

Play now: https://mguttmann.github.io/minigolf-2000/

Minigolf 2000 License


Features

  • 18 unique holes with progressive difficulty
    • Easy (Holes 1-6): Simple layouts for beginners
    • Medium (Holes 7-12): More complex with obstacles
    • Hard (Holes 13-18): Challenging precision courses
  • Realistic physics - velocity, friction, bouncing
  • Obstacles - walls, sand traps, water hazards, bumpers
  • Touch & mouse controls - drag to aim, release to shoot
  • Score tracking - par comparison, hole-in-one detection
  • Sound effects - synthesized audio, no external files
  • Fully responsive - works on desktop and mobile

How to Play

  1. Click/tap near the ball to start aiming
  2. Drag away from the ball to set direction and power
  3. Release to shoot
  4. Get the ball in the hole in as few strokes as possible!

Scoring

Score Meaning
Hole in One 1 stroke on any hole
Albatross 3 under par
Eagle 2 under par
Birdie 1 under par
Par Expected strokes
Bogey 1 over par
Double Bogey 2 over par

Tech Stack

  • React 18 - UI framework
  • TypeScript - Type safety
  • Vite - Build tool
  • Tailwind CSS - Styling
  • HTML5 Canvas - Game rendering
  • Web Audio API - Sound effects

Development

Prerequisites

  • Bun (or Node.js 18+)

Setup

# Clone the repository
git clone https://github.com/mguttmann/minigolf-2000.git
cd minigolf-2000

# Install dependencies
bun install

# Start development server
bun run dev

Scripts

Command Description
bun run dev Start dev server at localhost:5173
bun run build Build for production
bun run preview Preview production build
bun run lint Run ESLint

Project Structure

src/
├── components/
│   ├── GameCanvas.tsx    # Main game canvas with rendering
│   └── HUD.tsx           # UI overlays (score, menus)
├── game/
│   ├── GameContext.tsx   # React context for game state
│   ├── physics.ts        # Physics engine (collision, movement)
│   ├── courses.ts        # 18 hole definitions
│   └── sounds.ts         # Web Audio synthesizer
├── types/
│   └── game.ts           # TypeScript interfaces
├── App.tsx               # Main app component
└── main.tsx              # Entry point

Course Data

Courses are defined in src/game/courses.ts. Each course has:

interface Course {
  id: number
  name: string
  par: number
  ballStart: Vector2D
  hole: Hole
  walls: Wall[]
  obstacles: Obstacle[]  // sand, water, bumper
  bounds: { width: number, height: number }
}

Add or modify courses by editing this file.


Physics Constants

Tweak gameplay in src/types/game.ts:

export const PHYSICS = {
  FRICTION: 0.985,        // Ball slowdown per frame
  MIN_VELOCITY: 0.1,      // Speed to stop
  MAX_POWER: 15,          // Maximum shot power
  POWER_MULTIPLIER: 0.30, // Shot strength
  BOUNCE_DAMPING: 0.7,    // Energy loss on bounce
  SAND_FRICTION: 0.95,    // Extra friction in sand
}

Deployment

The game auto-deploys to GitHub Pages on every push to master.

Workflow: .github/workflows/deploy.yml


License

MIT License - feel free to use, modify, and distribute.


Credits

Built with React, TypeScript, and retro vibes.

Play the game: https://mguttmann.github.io/minigolf-2000/

About

Retro-style 18-hole browser minigolf game - React + TypeScript

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages