Files
spacetris/supabe_integrate.md
2025-12-21 21:17:58 +01:00

214 lines
3.8 KiB
Markdown

# Spacetris — Supabase Highscore Integration
## VS Code Copilot AI Agent Prompt
You are integrating Supabase highscores into a native C++ SDL3 game called **Spacetris**.
This is a REST-only integration using Supabase PostgREST.
Do NOT use any Supabase JS SDKs.
---
## 1. Goal
Implement a highscore backend using Supabase for these game modes:
- classic
- challenge
- cooperate
- versus
Highscores must be:
- Submitted asynchronously on game over
- Fetched asynchronously for leaderboard screens
- Non-blocking (never stall render loop)
- Offline-safe (fail silently)
---
## 2. Supabase Configuration
The following constants are provided at build time:
```cpp
const std::string SUPABASE_URL = "https://xzxpmvyamjvtxpwnjpad.supabase.co";
const std::string SUPABASE_ANON_KEY = "sb_publishable_GqQx844xYDizO9-ytlBXfA_MVT6N7yA";
````
All requests go to:
```
{SUPABASE_URL}/rest/v1/highscores
```
---
## 3. Database Schema (Already Exists)
The Supabase table `highscores` has the following fields:
* score (integer)
* lines (integer)
* level (integer)
* time_sec (integer)
* name (string)
* game_type ("classic", "versus", "cooperate", "challenge")
* timestamp (integer, UNIX epoch seconds)
---
## 4. Data Model in C++
Create a struct matching the database schema:
```cpp
struct HighscoreEntry {
int score;
int lines;
int level;
int timeSec;
std::string name;
std::string gameType;
int timestamp;
};
```
---
## 5. HTTP Layer Requirements
* Use **libcurl**
* Use **JSON** (nlohmann::json or equivalent)
* All network calls must run in a worker thread
* Never block the SDL main loop
Required HTTP headers:
```
apikey: SUPABASE_ANON_KEY
Authorization: Bearer SUPABASE_ANON_KEY
Content-Type: application/json
```
---
## 6. Submit Highscore (POST)
Implement:
```cpp
void SubmitHighscoreAsync(const HighscoreEntry& entry);
```
Behavior:
* Convert entry to JSON
* POST to `/rest/v1/highscores`
* On failure:
* Log error
* Do NOT crash
* Optionally store JSON locally for retry
Example JSON payload:
```json
{
"score": 123456,
"lines": 240,
"level": 37,
"time_sec": 1820,
"name": "P1 & P2",
"game_type": "cooperate",
"timestamp": 1710000000
}
```
---
## 7. Fetch Leaderboard (GET)
Implement:
```cpp
std::vector<HighscoreEntry> FetchHighscores(
const std::string& gameType,
int limit
);
```
REST query examples:
Classic:
```
?game_type=eq.classic&order=score.desc&limit=20
```
Challenge:
```
?game_type=eq.challenge&order=level.desc,time_sec.asc&limit=20
```
Cooperate:
```
?game_type=eq.cooperate&order=score.desc&limit=20
```
---
## 8. Threading Model
* Use `std::thread` or a simple job queue
* Network calls must not run on the render thread
* Use mutex or lock-free queue to pass results back to UI
---
## 9. Error Handling Rules
* If Supabase is unreachable:
* Game continues normally
* Leaderboard screen shows "Offline"
* Never block gameplay
* Never show raw network errors to player
---
## 10. Security Constraints
* API key is public (acceptable for highscores)
* Obfuscate key in binary if possible
* Do NOT trust client-side data (future server validation planned)
---
## 11. File Structure Suggestion
```
/network
supabase_client.h
supabase_client.cpp
/highscores
highscore_submit.cpp
highscore_fetch.cpp
```
---
## 12. Acceptance Criteria
* Highscores are submitted after game over
* Leaderboards load without blocking gameplay
* Works for all four game types
* Offline mode does not crash or freeze
* Code is clean, modular, and SDL3-safe
---
## 13. Summary for the Agent
Integrate Supabase highscores into Spacetris using REST calls from C++ with libcurl. Use async submission and fetching. Support classic, challenge, cooperate, and versus modes. Ensure non-blocking behavior and graceful offline handling.