# 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 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.