Backend REST API built with Spring Boot for a Unity Tower Defense game.
This backend handles user authentication, JWT security, password hashing, and per-account player progress.
Each player has their own unlocked levels and stars earned for every level.
- User registration
- User login
- JWT authentication
- BCrypt password hashing
- Per-user player progress
- Level unlock system
- Star saving system
- Reset progress endpoint
- Input validation
- Global exception handling
- MySQL database integration
- Unity client integration
- Java
- Spring Boot
- Spring Security
- Spring Data JPA
- MySQL
- JWT
- BCrypt
- Maven
After a player registers or logs in, the backend returns a JWT token.
The Unity client stores this token locally and sends it with every protected request using the Authorization header:
Authorization: Bearer <token>The backend validates the token, identifies the current user, and loads or updates only that user's progress.
The backend uses three main entities:
Stores account information.
| Field | Description |
|---|---|
| id | User ID |
| username | Unique username |
| password | BCrypt hashed password |
Stores the general progress of a player.
| Field | Description |
|---|---|
| id | Progress ID |
| maxLevelUnlocked | Highest unlocked level |
| user | The user that owns this progress |
Stores the stars earned by a player on each level.
| Field | Description |
|---|---|
| id | Level progress ID |
| levelNumber | Level number |
| starUnlocked | Stars earned on that level |
| user | The user that owns this level progress |
POST /api/auth/register{
"username": "cosmin",
"password": "1234"
}{
"token": "jwt_token_here"
}When a new user registers, the backend automatically creates:
- a player progress entry with
maxLevelUnlocked = 1 - 10 level progress entries
- all levels with
0stars
POST /api/auth/login{
"username": "cosmin",
"password": "1234"
}{
"token": "jwt_token_here"
}All player progress endpoints require a valid JWT token.
Example header:
Authorization: Bearer <token>GET /api/player/progress{
"maxLevelUnlocked": 2,
"levels": [
{
"levelNumber": 1,
"stars": 3
},
{
"levelNumber": 2,
"stars": 0
},
{
"levelNumber": 3,
"stars": 0
}
]
}The Unity client uses this endpoint after login or auto-login to load the player's progress.
PUT /api/player/levels/{levelNumber}Example:
PUT /api/player/levels/1{
"stars": 3
}levelNumbermust be between1and10starsmust be between1and3- locked levels cannot be updated
- stars can only improve, they do not decrease
- completing the current max unlocked level unlocks the next level
- max level cannot go above level
10
Example:
If the player has:
{
"maxLevelUnlocked": 1
}and completes level 1, the backend updates the progress to:
{
"maxLevelUnlocked": 2
}POST /api/player/progress/resetThis resets only the currently authenticated user's progress.
It sets:
maxLevelUnlocked = 1
all level stars = 0
{
"maxLevelUnlocked": 1,
"levels": [
{
"levelNumber": 1,
"stars": 0
},
{
"levelNumber": 2,
"stars": 0
},
{
"levelNumber": 3,
"stars": 0
}
]
}Usernames must:
- be between
3and20characters - contain only letters, numbers and underscore
- not contain spaces
Valid examples:
cosmin
cosmin123
cosmin_boss
Invalid examples:
cosmin boss
cosmin-boss
cosmin@boss
Passwords must:
- be between
4and30characters - not contain spaces
Valid examples:
1234
password123
my_password
Invalid examples:
123 4
password
password
{
"message": "Username already exists"
}{
"message": "Invalid username or password"
}{
"message": "Level is locked"
}{
"message": "Invalid level"
}{
"username": "Username can only contain letters, numbers and underscore"
}POST /api/auth/registerThe backend returns a JWT token.
The Unity client stores the token in PlayerPrefs.
GET /api/player/progressThe backend returns the player's unlocked levels and stars.
PUT /api/player/levels/1Request body:
{
"stars": 3
}The backend saves the result and unlocks the next level if needed.
The Unity client updates its local GameSession.Progress with the backend response.
Example application.properties:
spring.application.name=tower-defense-progress-api
spring.datasource.url=jdbc:mysql://localhost:3306/tower_defense_db
spring.datasource.username=root
spring.datasource.password=your_password
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
jwt.secret=your_secret_key_must_be_long_enoughDo not expose real production database passwords or JWT secrets in a public repository.
Clone the repository:
git clone <repository-url>
cd tower-defense-progress-apiRun the project with Maven:
mvn spring-boot:runOr build the project:
mvn clean packageThen run the generated .jar file:
java -jar target/tower-defense-progress-api-0.0.1-SNAPSHOT.jarBy default, the API runs on:
http://localhost:8080
The Unity client connects to the backend using:
http://localhost:8080After login or register, Unity stores the JWT token and loads the player's progress:
GET /api/player/progressWhen a level is completed, Unity sends:
PUT /api/player/levels/{levelNumber}When the player resets progress, Unity sends:
POST /api/player/progress/resetFor a real release, the backend must be hosted online because localhost only works on the developer's machine.
This backend is currently intended for local development and testing with the Unity client.
The full system includes:
Unity Client
↓
Spring Boot REST API
↓
Spring Security + JWT
↓
MySQL Database
Current version includes:
- complete account system
- JWT login and register
- password hashing with BCrypt
- per-user progress
- level unlocking
- star saving
- reset progress
- Unity integration
- auto-login support on the Unity side
- sign out support on the Unity side
This backend is ready for local development and testing with the Unity Tower Defense client.