A full-stack application for uploading, playing, and managing Scratch games (exported as HTML from TurboWarp) with user authentication, leaderboards, and MinIO bucket management.
- Spring Boot 3.5.10 - Java framework
- H2 Database - File-based persistent database
- MinIO - Object storage for game files
- Lombok - Reduce boilerplate code
- Maven - Build tool
- React 19 with TypeScript
- Vite - Build tool
- Axios - HTTP client
- Tailwind CSS - Utility-first CSS framework
- React Router DOM - Client-side routing
✅ User Authentication
- Register new accounts
- Login/logout functionality
- User session persistence
✅ Game Management
- Upload HTML games (from TurboWarp/Scratch)
- Store files in MinIO object storage
- Save game metadata in H2 database
- Play games in iframe
✅ Leaderboard System
- Track user scores
- Display top 10 players
- Show games played count
- Automatic score updates
✅ MinIO Bucket Management
- List all buckets
- Create new buckets
- Delete buckets
- View objects in buckets
- Delete objects
- Real-time bucket monitoring
✅ Persistent Data
- File-based H2 database (survives restarts)
- User data preserved
- Game history maintained
demogame/
├── be/ # Spring Boot backend
│ ├── src/main/java/com/example/be/
│ │ ├── config/
│ │ │ └── MinioConfig.java
│ │ ├── controller/
│ │ │ ├── GameController.java
│ │ │ ├── AuthController.java
│ │ │ └── MinioController.java
│ │ ├── entity/
│ │ │ ├── Game.java
│ │ │ ├── User.java
│ │ │ └── PlayHistory.java
│ │ ├── repository/
│ │ │ ├── GameRepository.java
│ │ │ ├── UserRepository.java
│ │ │ └── PlayHistoryRepository.java
│ │ ├── dto/
│ │ │ ├── LoginRequest.java
│ │ │ ├── RegisterRequest.java
│ │ │ ├── AuthResponse.java
│ │ │ ├── LeaderboardEntry.java
│ │ │ ├── BucketInfo.java
│ │ │ └── ObjectInfo.java
│ │ └── BeApplication.java
│ └── src/main/resources/
│ └── application.properties
├── fe/ # React frontend
│ └── src/
│ ├── components/
│ │ ├── Auth.tsx
│ │ ├── GameList.tsx
│ │ ├── Leaderboard.tsx
│ │ └── BucketManager.tsx
│ ├── App.tsx
│ ├── main.tsx
│ └── index.css
└── docker-compose.yml # MinIO setup
cd /home/hoang/Desktop/demogame
docker-compose up -dThis will start MinIO on:
- API: http://localhost:9000
- Console: http://localhost:9001 (login: minioadmin/minioadmin)
cd be
./mvnw spring-boot:runBackend will run on: http://localhost:8080
Available endpoints:
Auth API:
POST /api/auth/register- Register new userPOST /api/auth/login- User loginGET /api/auth/leaderboard- Get top 10 playersGET /api/auth/user/{username}- Get user profile
Game API:
GET /api/games- List all gamesGET /api/games/{id}- Get game detailPOST /api/games/upload- Upload new gamePOST /api/games/{id}/play- Track play history (with score & duration)
MinIO Management API:
GET /api/minio/buckets- List all bucketsPOST /api/minio/buckets- Create bucketDELETE /api/minio/buckets/{name}- Delete bucketGET /api/minio/buckets/{name}/objects- List objects in bucketDELETE /api/minio/buckets/{name}/objects/{object}- Delete objectGET /api/minio/buckets/{name}/exists- Check if bucket exists
Database Console:
GET /h2-console- H2 database console
cd fe
npm install # First time only
npm run devFrontend will run on: http://localhost:5173
- Open http://localhost:5173
- Register a new account or login
- Your session will be saved in localStorage
- Click "➕ Upload Game"
- Export your Scratch project as HTML from TurboWarp
- Fill in title and description
- Select the HTML file
- Click "Upload Game"
- Browse available games on the home page
- Click "▶ Play Now" on any game card
- The game will load in full screen
- A random score is automatically generated for demo
- Your play history is tracked for the leaderboard
curl -X POST http://localhost:8080/api/auth/register \
-H "Content-Type: application/json" \
-d '{"username":"player1","password":"pass123","email":"player1@example.com"}'curl -X POST http://localhost:8080/api/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"player1","password":"pass123"}'curl http://localhost:8080/api/auth/leaderboardcurl -X POST http://localhost:8080/api/games/upload \
-F "file=@game.html" \
-F "title=My Game" \
-F "desc=A fun game"curl http://localhost:8080/api/gamescurl -X POST "http://localhost:8080/api/games/1/play?userId=player1&score=500&duration=120"- Server port:
8080 - H2 database: File-based at
./data/gamedb(persistent) - MinIO:
localhost:9000 - Bucket name:
scratch-games - Max file size:
50MB
- API URL:
http://localhost:8080/api/* - Tailwind CSS for styling
- React Router for navigation
✅ Upload HTML games (from TurboWarp/Scratch)
✅ Store files in MinIO object storage
✅ Save game metadata in persistent H2 database
✅ User registration and login
✅ Session management with localStorage
✅ List all games with beautiful cards
✅ Play games in full-screen iframe
✅ Track play history with scores
✅ Real-time leaderboard (top 10 players)
✅ MinIO bucket management interface
✅ Create, delete, and view buckets
✅ View and delete objects in buckets
✅ CORS enabled for frontend
✅ Public bucket policy for direct file access
✅ Responsive design with Tailwind CSS
✅ Client-side routing with React Router
✅ Data persists across application restarts
curl http://localhost:8080/api/games
### Track Play
```bash
curl -X POST "http://localhost:8080/api/games/1/play?userId=user_123"
- Server port:
8080 - H2 database: in-memory
- MinIO:
localhost:9000 - Bucket name:
scratch-games - Max file size:
50MB
- API URL:
http://localhost:8080/api/games - Fake user ID: randomly generated on page load
- Check if Docker is running:
docker ps - Restart MinIO:
docker-compose restart - Verify MinIO is accessible: http://localhost:9000
- Check if MinIO is running
- Verify application.properties settings
- Check console logs for errors
- Ensure
data/directory has write permissions
- Verify backend is running on port 8080
- Check browser console for CORS errors
- Clear localStorage:
localStorage.clear() - Reinstall dependencies:
npm install
- Database files are stored in
be/data/ - To reset database, delete the
data/directory - Console URL:
jdbc:h2:file:./data/gamedb
- H2 database is now file-based - data persists across restarts
- Database files stored in
be/data/directory - Use persistent database (PostgreSQL/MySQL) for production
- MinIO data is persisted in Docker volume
- Games are publicly accessible once uploaded
- Authentication is basic - use proper JWT/OAuth for production
- Passwords are not hashed - implement BCrypt for production
- Random scores are generated for demo purposes
- Leaderboard updates in real-time based on play tracking
- Verify backend is running on port 8080
- Check browser console for CORS errors
- Ensure axios is installed:
npm install axios
- H2 database is in-memory, data resets on restart
- Use persistent database (PostgreSQL/MySQL) for production
- MinIO data is persisted in Docker volume
- Games are publicly accessible once uploaded
- No authentication/authorization implemented (demo only)
MIT