- Sign Up/Login - Create an account using email or Google sign-in
- Choose Your Opponent - Select from available AI models (Gemini, GPT-oss, NVIDIA)
- Start Match - Click "Start New Game" to begin your battle
- Click a piece to see all legal moves highlighted
- 🟢 Green dots = Empty squares you can move to
- 🟢 Green rings = Enemy pieces you can capture
- 🟡 Yellow highlight = Your selected piece
- Click destination to execute the move
- Invalid moves are blocked with helpful notifications
- Press ESC to deselect a piece
- ⚔️ AI Commentary - Get real-time insights from your AI opponent
- 🤖 AutoPilot Mode - Let AI play on your behalf and watch two AIs battle
- 🤝 Draw Offers - Propose a draw after 10 moves (AI may accept or decline)
- 📊 Live Stats - Track your wins, losses, and draws
- 📜 Move History - Review all moves made during the game
- 3 free matches per day to manage API costs
- Limit resets at midnight UTC
- Stats are tracked across all matches
- ✅ Legal Move Validation - All chess rules enforced via chess.js
- ✅ Check Detection - King pulses red when in check
- ✅ Draw Conditions - Stalemate, insufficient material, threefold repetition, 50-move rule (15 for Gemini)
- ✅ Captured Pieces - Displayed in player bars
- ✅ Last Move Highlight - Visual feedback for previous move
- 🧠 MasterGemi (Gemini) - Google's Gemini 2.0 Flash - Strategic and confident
- 💬 ChampGPT (GPT-oss) - OpenAI GPT-4o-mini via OpenRouter - Tactical and aggressive
- ⚡ NemoTron (NVIDIA) - NVIDIA's chess AI - Powerful and analytical
- 🎭 Coming Soon - Claude, LLaMA, Mistral, DeepSeek
- 🎨 Neo-Brutalist UI - Bold, modern design inspired by Chess.com
- 🌓 Dark Mode - Automatic theme switching
- 📱 Responsive Design - Optimized for desktop (1024px+)
- 🔔 Toast Notifications - Clear feedback for all actions
- ⚡ Smooth Animations - Polished UI interactions
- 🔐 Authentication - Email/password + Google OAuth
- 📈 Stats Tracking - Comprehensive game history
- 💾 Match Storage - All games saved to Firestore
- 🎯 Daily Limits - Fair play system with rate limiting
- React 18 - Modern UI library
- React Router 6 - Client-side routing
- Tailwind CSS 3 - Utility-first styling
- chess.js - Chess logic and validation
- Firebase SDK v10 - Authentication & database
- Firebase Authentication - User management
- Cloud Firestore - NoSQL database
- Firebase Cloud Functions - Serverless API
- Google Gemini API - AI opponent
- OpenRouter API - Multi-model AI access
- Vercel - Frontend hosting
- Firebase Hosting - Alternative hosting
- GitHub Actions - CI/CD ready
- Node.js 18+ installed
- Firebase account
- Gemini API key (Get it here)
- OpenRouter API key (optional, Get it here)
# Clone the repository
git clone https://github.com/yourusername/lmc-arena.git
cd lmc-arena
# Install dependencies
npm install
# Install Firebase Functions dependencies
cd functions
npm install
cd ..- Create
.envfile in the root directory:
# Firebase Configuration
REACT_APP_FIREBASE_API_KEY=your_api_key
REACT_APP_FIREBASE_AUTH_DOMAIN=your_project.firebaseapp.com
REACT_APP_FIREBASE_PROJECT_ID=your_project_id
REACT_APP_FIREBASE_STORAGE_BUCKET=your_project.appspot.com
REACT_APP_FIREBASE_MESSAGING_SENDER_ID=your_sender_id
REACT_APP_FIREBASE_APP_ID=your_app_id
# AI API Keys
REACT_APP_GEMINI_API_KEY=your_gemini_api_key
REACT_APP_OPENROUTER_API_KEY=your_openrouter_api_key- Firebase Setup
# Login to Firebase
firebase login
# Initialize project
firebase use --add
# Deploy Firestore rules
firebase deploy --only firestore:rules
# Configure Functions environment
firebase functions:config:set gemini.api_key="your_gemini_key"
# Deploy Cloud Functions
firebase deploy --only functions- Enable Firebase Services
- Go to Firebase Console
- Authentication → Enable Email/Password and Google providers
- Firestore Database → Create database in production mode
- Authorized domains → Add your deployment domain
# Start development server
npm startVisit http://localhost:3000
# Create optimized build
npm run build
# Deploy to Firebase Hosting (optional)
firebase deploy --only hosting
# Or deploy to Vercel
vercellmc-arena/
├── public/
│ ├── index.html
│ ├── gemini-logo.svg
│ ├── gpt-logo-light.svg
│ ├── gpt-logo-dark.svg
│ └── nvidia-logo.svg
├── src/
│ ├── components/
│ │ ├── ChessBoard.jsx # Chess board with move logic
│ │ ├── Square.jsx # Individual chess square
│ │ ├── PlayerBar.jsx # Player info and captured pieces
│ │ ├── MoveHistory.jsx # Move list sidebar
│ │ ├── SidePanel.jsx # Controls and AI commentary
│ │ ├── Navbar.jsx # Top navigation bar
│ │ ├── Toast.jsx # Notification system
│ │ ├── GameOverModal.jsx # End game results
│ │ ├── LimitReachedModal.jsx # Daily limit warning
│ │ └── ProtectedRoute.jsx # Auth route guard
│ ├── pages/
│ │ ├── Login.jsx # Login/Register page
│ │ ├── Home.jsx # Landing page
│ │ └── Game.jsx # Main game page
│ ├── services/
│ │ ├── authService.js # Authentication functions
│ │ └── gameService.js # Game logic and AI calls
│ ├── context/
│ │ └── AuthContext.jsx # Global auth state
│ ├── config/
│ │ └── firebase.js # Firebase initialization
│ ├── utils/ # Helper functions
│ ├── assets/ # Images and icons
│ ├── App.jsx # Main app component
│ ├── index.css # Global styles
│ └── index.js # App entry point
├── functions/
│ ├── index.js # Cloud Functions
│ └── package.json # Function dependencies
├── .env # Environment variables (gitignored)
├── .env.example # Environment template
├── firebase.json # Firebase configuration
├── firestore.rules # Firestore security rules
├── firestore.indexes.json # Database indexes
├── vercel.json # Vercel deployment config
└── package.json # Project dependencies
- All moves validated by
chess.jslibrary - White (player) always moves first
- AI plays as black
- Checkmate, stalemate, and all draw conditions detected
- Stalemate - Player has no legal moves but isn't in check
- Insufficient Material - Not enough pieces to checkmate
- Threefold Repetition - Same position occurs three times
- 50-Move Rule - 50 moves without capture or pawn move (15 for Gemini to save API costs)
- Mutual Agreement - Players agree to a draw
// Get AI's next move
firebase.functions().httpsCallable('getGeminiMove')({
fen: 'position-string',
lastMove: 'e4'
})
// Returns: { move: 'Nf6', commentary: 'Developing the knight', wasInvalid: false }// Check user's remaining matches
firebase.functions().httpsCallable('checkDailyLimit')()
// Returns: { canPlay: true, matchesLeft: 2 }// Start a new match (increments counter)
firebase.functions().httpsCallable('incrementMatchCount')()// Save completed match
firebase.functions().httpsCallable('saveMatchResult')({
result: 'win', // 'win', 'loss', or 'draw'
moves: ['e4', 'e5', 'Nf3', ...],
finalFen: 'final-position-string'
})/* Light Mode */
--background: #FFFFFF
--surface: #F5F5F5
--text-primary: #1A1A1A
--accent: #4CAF50
/* Dark Mode */
--dark-background: #1A1A1A
--dark-surface: #262626
--dark-text-primary: #FFFFFF
--dark-accent: #66BB6A
/* Chess Board */
--light-square: #EBECD0
--dark-square: #739552
--highlight: #BACA2B- Headings: Inter Bold
- Body: Inter Regular
- Code/Stats: IBM Plex Mono
- All API keys stored in
.env(gitignored) - Never commit sensitive credentials
- Use environment variables in Vercel/Firebase
// Users can only read/write their own data
match /users/{userId} {
allow read, write: if request.auth != null && request.auth.uid == userId;
}
// Matches are user-specific
match /matches/{matchId} {
allow read: if request.auth != null && resource.data.userId == request.auth.uid;
allow create: if request.auth != null && request.resource.data.userId == request.auth.uid;
}- All functions require authentication
- Rate limiting via daily match counter
- Input validation on all parameters
{
"userId": "firebase-uid",
"username": "player123",
"email": "player@example.com",
"photoURL": "https://...",
"createdAt": "timestamp",
"stats": {
"wins": 0,
"losses": 0,
"draws": 0,
"totalGames": 0
}
}{
"userId": "firebase-uid",
"result": "win",
"playedAt": "timestamp",
"moves": ["e4", "e5", "Nf3", ...],
"finalFen": "position-string"
}{
"userId": "firebase-uid",
"date": "2025-12-29",
"matchesPlayed": 1,
"lastUpdated": "timestamp"
}- Solution: Add all environment variables in Vercel Dashboard → Settings → Environment Variables
- Redeploy after adding variables
# Increase timeout in functions/index.js
exports.getGeminiMove = functions
.runWith({ timeoutSeconds: 60 })
.https.onCall(...)- Solution: This is a harmless warning. Add to
.gitignore:
GENERATE_SOURCEMAP=false
- Check Gemini API usage in Google AI Studio
- Upgrade to paid tier or reduce daily match limit
# Clear cache and rebuild
rm -rf node_modules package-lock.json build
npm install
npm run build- Push to GitHub
git add .
git commit -m "Initial commit"
git push origin main- Import to Vercel
- Go to vercel.com
- Click "Import Project"
- Select your GitHub repository
- Add environment variables from
.env - Deploy!
# Build the app
npm run build
# Deploy
firebase deploy --only hostingThis project is licensed under the MIT License - see the LICENSE file for details.
- Chess Engine: chess.js
- AI Models: Google Gemini, OpenAI (via OpenRouter), NVIDIA
- Backend: Firebase
- Design Inspiration: Chess.com
- Icons: Google Material Icons
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the project
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
Your Name - @yourusername
Project Link: https://github.com/yourusername/lmc-arena
Live Demo: https://lmc-arena.vercel.app
Made with ❤️ and ♟️
⭐ Star this repo if you found it helpful!
gemimaster/
├── src/
│ ├── components/
│ │ ├── ChessBoard.jsx # Main board with legal moves
│ │ ├── Square.jsx # Individual square
│ │ ├── PlayerBar.jsx # Player info bar
│ │ ├── MoveHistory.jsx # Move list panel
│ │ ├── SidePanel.jsx # Right panel
│ │ ├── Navbar.jsx # Top navigation
│ │ ├── Toast.jsx # Notifications
│ │ ├── GameOverModal.jsx # End game modal
│ │ ├── LimitReachedModal.jsx # Daily limit modal
│ │ └── ProtectedRoute.jsx # Auth guard
│ ├── pages/
│ │ ├── Login.jsx # Login/Register
│ │ └── Game.jsx # Main game page
│ ├── services/
│ │ ├── authService.js # Auth functions
│ │ └── gameService.js # Game functions
│ ├── context/
│ │ └── AuthContext.jsx # Auth state
│ ├── config/
│ │ └── firebase.js # Firebase config
│ ├── App.jsx # Main app
│ └── index.js # Entry point
├── functions/
│ ├── index.js # Cloud Functions
│ └── package.json # Function dependencies
├── .env # Environment variables (secured)
├── firebase.json # Firebase config
└── firestore.rules # Security rules
---
<div align="center">
**Made with ❤️ and ♟️**
⭐ Star this repo if you found it helpful!
</div>