Tic Tac Toe Party is a modern, real-time multiplayer mobile game built with Flutter and Firebase. It features a stunning "Neon Dark Mode" glassmorphism UI, instant room creation, live scoreboards, and seamless rematch capabilities.
- Real-Time Gameplay: Instant move synchronization using Cloud Firestore.
- Multiplayer Rooms: Create a private room and share the 4-digit code to play with friends anywhere.
- Modern UI: Sleek, dark-themed interface with neon accents and glassmorphism effects.
- Live Scoreboard: Tracks wins (X vs O) persistently throughout the session.
- Smart Rematch: "Play Again" feature that automatically swaps players (X becomes O) for fair play.
- Rejoin Ability: Accidentally closed the app? Re-enter the room code to reclaim your spot.
- Player Status: Detects when opponents join or disconnect.
| Home Screen | Game Room | Win State |
|---|---|---|
![]() |
![]() |
![]() |
(Note: Add your actual screenshots to a screenshots folder in your repo)
| Layer | Technology |
|---|---|
| Framework | Flutter |
| Language | Dart |
| Backend | Firebase Cloud Firestore |
| State Management | GetX |
| Icons | Flutter Launcher Icons |
Make sure you have the following installed:
- Flutter SDK
- Git
- VS Code or Android Studio
git clone https://github.com/JhaSourav07/ticTakToe.git
cd tictaktoeflutter pub getFollow the full Firebase setup guide below, then run:
flutter runThis app uses Firebase Firestore for real-time multiplayer functionality. You must connect the project to your own Firebase project before running the app.
- Go to the Firebase Console
- Click Add Project
- Name it
TicTacToeParty(or any name you prefer) - (Optional) Disable Google Analytics
- Click Create Project
- In the Firebase dashboard, click the Android icon (🤖)
- Find your Android Package Name by opening
android/app/build.gradleand locating:applicationId "com.example.tictactoe" - Paste that value into Firebase and click Register App
- Download
google-services.jsonand move it to:android/app/google-services.json
- In the Firebase dashboard, click Add App → iOS
- Find your iOS Bundle ID by opening
ios/Runner.xcodeproj/project.pbxprojand searching forPRODUCT_BUNDLE_IDENTIFIER - Paste that value into Firebase and click Register App
- Download
GoogleService-Info.plistand move it to:ios/Runner/GoogleService-Info.plist
- In the Firebase Console, go to Build → Firestore Database
- Click Create Database
- Choose a location (e.g.,
nam5 (us-central)) - Select Start in Test Mode
⚠️ Test Mode allows public read/write access for 30 days. For production, you must configure authentication and secure Firestore rules.
- In the Firebase Console, go to Authentication → Sign-in method
- Enable Anonymous sign-in
In the Firebase Console, go to Firestore Database → Rules and replace the content with:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /rooms/{roomId} {
function isSignedIn() {
return request.auth != null;
}
function myUid() {
return request.auth.uid;
}
function isPlayer() {
return resource.data.player1Id == myUid() || resource.data.player2Id == myUid();
}
allow read: if isSignedIn() && (
isPlayer() ||
resource.data.player1Id == '' ||
resource.data.player2Id == ''
);
allow create: if isSignedIn() &&
request.resource.data.player1Id == myUid() &&
request.resource.data.player2Id == '' &&
request.resource.data.turn == myUid() &&
request.resource.data.board.size() == 9;
allow update: if isSignedIn() && (
(
request.writeFields().hasOnly(['player1Id', 'player1Name']) &&
resource.data.player1Id == '' &&
request.resource.data.player1Id == myUid()
) ||
(
request.writeFields().hasOnly(['player2Id', 'player2Name']) &&
resource.data.player2Id == '' &&
request.resource.data.player2Id == myUid()
) ||
(
request.writeFields().hasOnly(['player1Id']) &&
resource.data.player1Id == myUid() &&
request.resource.data.player1Id == myUid()
) ||
(
request.writeFields().hasOnly(['player2Id']) &&
resource.data.player2Id == myUid() &&
request.resource.data.player2Id == myUid()
) ||
(
request.writeFields().hasOnly(['player1Id']) &&
resource.data.player1Id == myUid() &&
request.resource.data.player1Id == ''
) ||
(
request.writeFields().hasOnly(['player2Id']) &&
resource.data.player2Id == myUid() &&
request.resource.data.player2Id == ''
) ||
(
request.writeFields().hasOnly(['board', 'turn']) &&
resource.data.turn == myUid() &&
(resource.data.player1Id == myUid() ? resource.data.player2Id : resource.data.player1Id) != '' &&
request.resource.data.turn == (
resource.data.player1Id == myUid()
? resource.data.player2Id
: resource.data.player1Id
)
) ||
(
request.writeFields().hasOnly(['winner', 'isGameActive', 'player1Score', 'player2Score', 'winningLine']) &&
isPlayer()
) ||
(
request.writeFields().hasOnly(['board', 'turn', 'winner', 'isGameActive', 'winningLine']) &&
isPlayer() &&
request.resource.data.player1Id == resource.data.player1Id &&
request.resource.data.player2Id == resource.data.player2Id
)
);
}
}
}Contributions are welcome! 🎉
- Fork the repository
- Create a new branch:
git checkout -b feature/your-feature-name
- Make your changes and commit:
git commit -m "Add: short description of your feature" - Push to your branch:
git push origin feature/your-feature-name
- Open a Pull Request
- Improve UI/UX
- Add sound effects
- Add player authentication
- Improve Firestore security rules
- Add game history
- Add leaderboard support
- Write tests
If you find a bug or have a feature request:
- Open an Issue
- Clearly describe the problem
- Include screenshots if applicable
- Provide steps to reproduce
Thank you for contributing and helping improve TicTacToe Party ❤️


