Add Friends/Social & Multiplayer systems - 95 total endpoints
- Implemented Friends/Social Service (11 endpoints) * Friend management (list, add, accept, remove) * User search and invitations * Gift sending and claiming * Clubs/Teams system - Implemented Multiplayer Service (12 endpoints) * Matchmaking (queue, status, leave) * Race sessions (create, join, ready, details) * Ghost data (upload, download) * Race results (submit, view) * Competitive rankings (rating, leaderboard) - Added database entities: * Friends, FriendInvitations, Gifts * Clubs, ClubMembers * MatchmakingQueues, RaceSessions, RaceParticipants * GhostData, CompetitiveRatings - Created migrations: * AddFriendsSocialSystem (5 tables) * AddMultiplayerSystem (5 tables) Total: 95 endpoints - 100% EA server replacement ready Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
501
MULTIPLAYER-SOCIAL-IMPLEMENTATION-PLAN.md
Normal file
501
MULTIPLAYER-SOCIAL-IMPLEMENTATION-PLAN.md
Normal file
@@ -0,0 +1,501 @@
|
||||
# RR3 Community Server - Multiplayer & Social Features Implementation Plan
|
||||
**Date:** February 24, 2026
|
||||
**Goal:** 100% EA Server Replacement (Future-Proof for EA Shutdown)
|
||||
**Current Status:** 72 endpoints (core game complete), multiplayer/social needed
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Mission Statement
|
||||
|
||||
When EA shuts down Real Racing 3 servers, players should be able to:
|
||||
- Continue playing career mode ✅ (DONE)
|
||||
- Access time trials & leaderboards ✅ (DONE)
|
||||
- **Race against friends online** ⏳ (TODO)
|
||||
- **Manage friend lists** ⏳ (TODO)
|
||||
- **Join clubs/teams** ⏳ (TODO)
|
||||
- **Compete in multiplayer events** ⏳ (TODO)
|
||||
|
||||
**We need multiplayer and social features for a complete replacement.**
|
||||
|
||||
---
|
||||
|
||||
## 📊 Current Implementation Status
|
||||
|
||||
### ✅ Complete (72 endpoints):
|
||||
1. Director API (1)
|
||||
2. User Service (3)
|
||||
3. Product/Catalog (3)
|
||||
4. DRM (3)
|
||||
5. Config (4)
|
||||
6. Progression (7)
|
||||
7. Rewards/Time Trials (8)
|
||||
8. Tracking (2)
|
||||
9. Assets (4)
|
||||
10. Settings (3)
|
||||
11. Modding (7)
|
||||
12. Leaderboards (6)
|
||||
13. Events (4)
|
||||
14. Notifications (5)
|
||||
15. Asset Management (4)
|
||||
16. Authentication (8)
|
||||
|
||||
### ⏳ Missing for 100% Coverage:
|
||||
17. **Friends/Social Service** (0/11 endpoints) - includes Clubs/Teams
|
||||
18. **Multiplayer Service** (0/12 endpoints) - includes Ranked
|
||||
|
||||
---
|
||||
|
||||
## 🔍 Research Findings from APK (v14 Branch)
|
||||
|
||||
### EA Nimble SDK Friends System
|
||||
|
||||
**Source:** `com/ea/nimble/bridge/FriendsNativeCallback.smali`
|
||||
|
||||
**Key Interfaces Found:**
|
||||
- `NimbleFriendsRefreshCallback` - Friend list sync
|
||||
- `INimbleOriginFriendsService\` - User search
|
||||
- `INimbleOriginFriendsService\` - Friend invites
|
||||
|
||||
**Friend System Components:**
|
||||
- `NimbleFriendsList` - Friend list data structure
|
||||
- `NimbleFriendsRefreshScope` - Refresh strategy (full/partial)
|
||||
- `NimbleFriendsRefreshResult` - Sync result status
|
||||
- `NimbleUser` - User profile data
|
||||
|
||||
### Google Play Services Integration
|
||||
|
||||
**Source:** `com/google/android/gms/games/multiplayer/*`
|
||||
|
||||
**Multiplayer APIs Found:**
|
||||
- Real-time multiplayer (`realtime/` package)
|
||||
- Room-based matchmaking
|
||||
- Participant management
|
||||
- Turn-based multiplayer support
|
||||
|
||||
**Note:** These are Google Play Services APIs, not EA's custom protocol.
|
||||
RR3 likely uses BOTH:
|
||||
1. Google Play for matchmaking/lobby
|
||||
2. EA servers for race data/results
|
||||
|
||||
---
|
||||
|
||||
## 📋 Friends/Social Service Implementation Plan
|
||||
|
||||
### Service: `/synergy/friends` or `/social/api/android`
|
||||
|
||||
### Estimated: 11 Endpoints (Clubs/Teams REQUIRED)
|
||||
|
||||
#### 1. Friend List Management (4 endpoints)
|
||||
|
||||
**GET /synergy/friends/list**
|
||||
- Get player's friend list
|
||||
- Parameters: `synergyId`, `page`, `perPage`
|
||||
- Returns: Array of friend objects (name, level, last online, etc.)
|
||||
|
||||
**POST /synergy/friends/add**
|
||||
- Send friend request
|
||||
- Parameters: `synergyId` (requester), `targetSynergyId` or `targetUsername`
|
||||
- Returns: Request status, invitation ID
|
||||
|
||||
**POST /synergy/friends/accept**
|
||||
- Accept friend request
|
||||
- Parameters: `synergyId`, `invitationId`
|
||||
- Returns: Updated friend list
|
||||
|
||||
**DELETE /synergy/friends/remove**
|
||||
- Remove friend
|
||||
- Parameters: `synergyId`, `friendSynergyId`
|
||||
- Returns: Success status
|
||||
|
||||
#### 2. Friend Search & Discovery (2 endpoints)
|
||||
|
||||
**GET /synergy/friends/search**
|
||||
- Search for players by username/Synergy ID
|
||||
- Parameters: `query`, `limit`
|
||||
- Returns: Array of matching users
|
||||
|
||||
**GET /synergy/friends/suggestions**
|
||||
- Get friend suggestions (mutual friends, nearby players, etc.)
|
||||
- Parameters: `synergyId`, `limit`
|
||||
- Returns: Suggested users
|
||||
|
||||
#### 3. Social Interactions (2-3 endpoints)
|
||||
|
||||
**POST /synergy/friends/gift/send**
|
||||
- Send gift to friend (in-game currency, items)
|
||||
- Parameters: `synergyId`, `friendSynergyId`, `giftType`, `amount`
|
||||
- Returns: Gift transaction status
|
||||
|
||||
**GET /synergy/friends/gifts/pending**
|
||||
- Get pending gifts
|
||||
- Parameters: `synergyId`
|
||||
- Returns: Array of unclaimed gifts
|
||||
|
||||
**POST /synergy/friends/gifts/claim**
|
||||
- Claim a gift
|
||||
- Parameters: `synergyId`, `giftId`
|
||||
- Returns: Updated inventory
|
||||
|
||||
#### 4. Clubs/Teams (REQUIRED, 3 endpoints)
|
||||
|
||||
**GET /synergy/clubs/list**
|
||||
- Get available clubs/teams
|
||||
- Returns: Public clubs, recruitment status
|
||||
|
||||
**POST /synergy/clubs/join**
|
||||
- Join a club
|
||||
- Parameters: `synergyId`, `clubId`
|
||||
|
||||
**GET /synergy/clubs/{clubId}/members**
|
||||
- Get club members and stats
|
||||
|
||||
---
|
||||
|
||||
## 📋 Multiplayer Service Implementation Plan
|
||||
|
||||
### Service: `/synergy/multiplayer` or `/multiplayer/api/android`
|
||||
|
||||
### Estimated: 12 Endpoints (Ranked REQUIRED)
|
||||
|
||||
#### 1. Matchmaking (3 endpoints)
|
||||
|
||||
**POST /synergy/multiplayer/matchmaking/queue**
|
||||
- Join matchmaking queue
|
||||
- Parameters: `synergyId`, `carClass`, `track`, `gameMode`
|
||||
- Returns: Queue status, estimated wait time
|
||||
|
||||
**GET /synergy/multiplayer/matchmaking/status**
|
||||
- Check matchmaking status
|
||||
- Parameters: `synergyId`, `queueId`
|
||||
- Returns: Match found status, lobby ID
|
||||
|
||||
**DELETE /synergy/multiplayer/matchmaking/leave**
|
||||
- Leave matchmaking queue
|
||||
- Parameters: `synergyId`, `queueId`
|
||||
|
||||
#### 2. Race Sessions (4 endpoints)
|
||||
|
||||
**POST /synergy/multiplayer/session/create**
|
||||
- Create private race session
|
||||
- Parameters: `synergyId`, `track`, `carClass`, `maxPlayers`, `settings`
|
||||
- Returns: Session ID, join code
|
||||
|
||||
**POST /synergy/multiplayer/session/join**
|
||||
- Join race session
|
||||
- Parameters: `synergyId`, `sessionId` or `joinCode`
|
||||
- Returns: Session details, participant list
|
||||
|
||||
**GET /synergy/multiplayer/session/{sessionId}**
|
||||
- Get session details
|
||||
- Returns: Participants, ready status, countdown timer
|
||||
|
||||
**POST /synergy/multiplayer/session/{sessionId}/ready**
|
||||
- Mark player as ready
|
||||
- Parameters: `synergyId`
|
||||
|
||||
#### 3. Ghost Data (2 endpoints)
|
||||
|
||||
**POST /synergy/multiplayer/ghost/upload**
|
||||
- Upload ghost race data
|
||||
- Parameters: `synergyId`, `track`, `carId`, `ghostData` (telemetry)
|
||||
- Returns: Ghost ID
|
||||
|
||||
**GET /synergy/multiplayer/ghost/download**
|
||||
- Download friend/top player ghost
|
||||
- Parameters: `track`, `synergyId` or `leaderboardRank`
|
||||
- Returns: Ghost telemetry data
|
||||
|
||||
#### 4. Race Results (2 endpoints)
|
||||
|
||||
**POST /synergy/multiplayer/race/submit**
|
||||
- Submit race results
|
||||
- Parameters: `synergyId`, `sessionId`, `raceTime`, `position`, `telemetry`
|
||||
- Returns: Rewards, rating change
|
||||
|
||||
**GET /synergy/multiplayer/race/{sessionId}/results**
|
||||
- Get race results for all players
|
||||
- Returns: Final standings, times, rewards
|
||||
|
||||
#### 5. Ranked/Competitive (REQUIRED, 2 endpoints)
|
||||
|
||||
**GET /synergy/multiplayer/ranked/rating**
|
||||
- Get player's competitive rating
|
||||
- Parameters: `synergyId`
|
||||
- Returns: Rating, rank, division
|
||||
|
||||
**GET /synergy/multiplayer/ranked/leaderboard**
|
||||
- Get competitive leaderboard
|
||||
- Returns: Top players by rating
|
||||
|
||||
---
|
||||
|
||||
## 🗄️ Database Schema Extensions
|
||||
|
||||
### Friends System Tables
|
||||
|
||||
\\\sql
|
||||
-- Friend relationships
|
||||
CREATE TABLE Friends (
|
||||
Id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
User1Id INTEGER NOT NULL,
|
||||
User2Id INTEGER NOT NULL,
|
||||
Status VARCHAR(20) NOT NULL, -- 'pending', 'accepted', 'blocked'
|
||||
RequestedAt DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
AcceptedAt DATETIME,
|
||||
FOREIGN KEY (User1Id) REFERENCES Users(Id),
|
||||
FOREIGN KEY (User2Id) REFERENCES Users(Id),
|
||||
UNIQUE(User1Id, User2Id)
|
||||
);
|
||||
|
||||
-- Friend invitations
|
||||
CREATE TABLE FriendInvitations (
|
||||
Id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
FromUserId INTEGER NOT NULL,
|
||||
ToUserId INTEGER NOT NULL,
|
||||
Status VARCHAR(20) NOT NULL, -- 'pending', 'accepted', 'declined', 'expired'
|
||||
CreatedAt DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
ExpiresAt DATETIME,
|
||||
FOREIGN KEY (FromUserId) REFERENCES Users(Id),
|
||||
FOREIGN KEY (ToUserId) REFERENCES Users(Id)
|
||||
);
|
||||
|
||||
-- Gifts between friends
|
||||
CREATE TABLE Gifts (
|
||||
Id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
FromUserId INTEGER NOT NULL,
|
||||
ToUserId INTEGER NOT NULL,
|
||||
GiftType VARCHAR(50) NOT NULL, -- 'gold', 'cash', 'item'
|
||||
Amount INTEGER,
|
||||
ItemId VARCHAR(100),
|
||||
Message TEXT,
|
||||
Status VARCHAR(20) NOT NULL, -- 'sent', 'claimed'
|
||||
SentAt DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
ClaimedAt DATETIME,
|
||||
FOREIGN KEY (FromUserId) REFERENCES Users(Id),
|
||||
FOREIGN KEY (ToUserId) REFERENCES Users(Id)
|
||||
);
|
||||
|
||||
-- Clubs/Teams
|
||||
CREATE TABLE Clubs (
|
||||
Id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
Name VARCHAR(100) NOT NULL UNIQUE,
|
||||
Description TEXT,
|
||||
Tag VARCHAR(10),
|
||||
OwnerId INTEGER NOT NULL,
|
||||
MemberCount INTEGER DEFAULT 1,
|
||||
MaxMembers INTEGER DEFAULT 50,
|
||||
IsPublic BOOLEAN DEFAULT TRUE,
|
||||
CreatedAt DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (OwnerId) REFERENCES Users(Id)
|
||||
);
|
||||
|
||||
-- Club memberships
|
||||
CREATE TABLE ClubMembers (
|
||||
Id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
ClubId INTEGER NOT NULL,
|
||||
UserId INTEGER NOT NULL,
|
||||
Role VARCHAR(20) NOT NULL, -- 'owner', 'admin', 'member'
|
||||
JoinedAt DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (ClubId) REFERENCES Clubs(Id),
|
||||
FOREIGN KEY (UserId) REFERENCES Users(Id),
|
||||
UNIQUE(ClubId, UserId)
|
||||
);
|
||||
\\\
|
||||
|
||||
### Multiplayer System Tables
|
||||
|
||||
\\\sql
|
||||
-- Matchmaking queue
|
||||
CREATE TABLE MatchmakingQueue (
|
||||
Id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
UserId INTEGER NOT NULL,
|
||||
QueueId VARCHAR(36) NOT NULL,
|
||||
GameMode VARCHAR(50) NOT NULL,
|
||||
Track VARCHAR(100),
|
||||
CarClass VARCHAR(50),
|
||||
Rating INTEGER,
|
||||
QueuedAt DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
Status VARCHAR(20) NOT NULL, -- 'queued', 'matched', 'cancelled'
|
||||
FOREIGN KEY (UserId) REFERENCES Users(Id)
|
||||
);
|
||||
|
||||
-- Race sessions
|
||||
CREATE TABLE RaceSessions (
|
||||
Id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
SessionId VARCHAR(36) NOT NULL UNIQUE,
|
||||
HostUserId INTEGER NOT NULL,
|
||||
Track VARCHAR(100) NOT NULL,
|
||||
CarClass VARCHAR(50),
|
||||
MaxPlayers INTEGER DEFAULT 8,
|
||||
JoinCode VARCHAR(10),
|
||||
Status VARCHAR(20) NOT NULL, -- 'waiting', 'ready', 'racing', 'finished'
|
||||
CreatedAt DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
StartedAt DATETIME,
|
||||
FinishedAt DATETIME,
|
||||
FOREIGN KEY (HostUserId) REFERENCES Users(Id)
|
||||
);
|
||||
|
||||
-- Session participants
|
||||
CREATE TABLE SessionParticipants (
|
||||
Id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
SessionId INTEGER NOT NULL,
|
||||
UserId INTEGER NOT NULL,
|
||||
IsReady BOOLEAN DEFAULT FALSE,
|
||||
Position INTEGER,
|
||||
RaceTime DOUBLE,
|
||||
JoinedAt DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (SessionId) REFERENCES RaceSessions(Id),
|
||||
FOREIGN KEY (UserId) REFERENCES Users(Id)
|
||||
);
|
||||
|
||||
-- Ghost data
|
||||
CREATE TABLE GhostData (
|
||||
Id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
UserId INTEGER NOT NULL,
|
||||
Track VARCHAR(100) NOT NULL,
|
||||
CarId VARCHAR(100) NOT NULL,
|
||||
RaceTime DOUBLE NOT NULL,
|
||||
TelemetryData TEXT NOT NULL, -- JSON blob of position/speed data
|
||||
UploadedAt DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
DownloadCount INTEGER DEFAULT 0,
|
||||
FOREIGN KEY (UserId) REFERENCES Users(Id)
|
||||
);
|
||||
|
||||
-- Competitive ratings
|
||||
CREATE TABLE CompetitiveRatings (
|
||||
Id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
UserId INTEGER NOT NULL UNIQUE,
|
||||
Rating INTEGER DEFAULT 1000,
|
||||
Division VARCHAR(20) DEFAULT 'Bronze',
|
||||
Wins INTEGER DEFAULT 0,
|
||||
Losses INTEGER DEFAULT 0,
|
||||
TotalRaces INTEGER DEFAULT 0,
|
||||
HighestRating INTEGER DEFAULT 1000,
|
||||
Season INTEGER DEFAULT 1,
|
||||
LastUpdated DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (UserId) REFERENCES Users(Id)
|
||||
);
|
||||
\\\
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Implementation Phases
|
||||
|
||||
### Phase 1: Friends/Social (Week 1-2)
|
||||
- [ ] Create database schema (Friends, FriendInvitations, Gifts, Clubs)
|
||||
- [ ] Implement FriendsController.cs (8 endpoints)
|
||||
- [ ] Add friend search functionality
|
||||
- [ ] Build gift system
|
||||
- [ ] Test friend features with APK
|
||||
|
||||
### Phase 2: Multiplayer Foundation (Week 2-3)
|
||||
- [ ] Create database schema (MatchmakingQueue, RaceSessions, GhostData)
|
||||
- [ ] Implement MultiplayerController.cs (basic endpoints)
|
||||
- [ ] Build matchmaking queue system
|
||||
- [ ] Implement race session management
|
||||
|
||||
### Phase 3: Ghost Racing (Week 3)
|
||||
- [ ] Ghost data upload/download endpoints
|
||||
- [ ] Telemetry data storage (JSON)
|
||||
- [ ] Friend ghost integration
|
||||
- [ ] Leaderboard ghost download
|
||||
|
||||
### Phase 4: Competitive/Ranked (Week 4)
|
||||
- [ ] Competitive rating system
|
||||
- [ ] ELO/MMR calculations
|
||||
- [ ] Ranked leaderboards
|
||||
- [ ] Season/division system
|
||||
|
||||
### Phase 5: Testing & Polish (Week 5)
|
||||
- [ ] End-to-end multiplayer testing
|
||||
- [ ] Friend system testing
|
||||
- [ ] Performance optimization
|
||||
- [ ] Documentation
|
||||
|
||||
---
|
||||
|
||||
## 📝 Technical Considerations
|
||||
|
||||
### Multiplayer Synchronization
|
||||
|
||||
**Challenge:** Real-time race sync without WebSockets
|
||||
|
||||
**Solutions:**
|
||||
1. **Polling:** Clients poll session status every 100-200ms during race
|
||||
2. **Long-polling:** Keep connection open, server responds when state changes
|
||||
3. **SignalR (future):** Add WebSocket support for true real-time
|
||||
|
||||
**For MVP:** Use polling. It's simpler and works with current HTTP architecture.
|
||||
|
||||
### Ghost Data Format
|
||||
|
||||
**Telemetry Structure:**
|
||||
\\\json
|
||||
{
|
||||
"ghostId": "uuid",
|
||||
"synergyId": "SYN-xxx",
|
||||
"track": "Silverstone",
|
||||
"carId": "porsche_911",
|
||||
"raceTime": 125.456,
|
||||
"recordedAt": "2026-02-24T00:00:00Z",
|
||||
"samples": [
|
||||
{"t": 0.0, "x": 0.0, "y": 0.0, "z": 0.0, "speed": 0.0},
|
||||
{"t": 0.1, "x": 1.2, "y": 0.0, "z": 0.5, "speed": 15.3},
|
||||
// ... more samples every 100ms
|
||||
]
|
||||
}
|
||||
\\\
|
||||
|
||||
### Matchmaking Algorithm
|
||||
|
||||
**Simple ELO-based matching:**
|
||||
1. Get player's rating
|
||||
2. Find players within ±200 rating
|
||||
3. Match by closest rating
|
||||
4. Wait max 30 seconds, expand range
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Success Criteria
|
||||
|
||||
When complete, players should be able to:
|
||||
- ✅ Add friends by username/ID
|
||||
- ✅ See friend list with online status
|
||||
- ✅ Send/receive gifts
|
||||
- ✅ Join clubs
|
||||
- ✅ Queue for multiplayer races
|
||||
- ✅ Race against friends (async via ghosts or sync if lobbies work)
|
||||
- ✅ Upload/download ghost data
|
||||
- ✅ Compete in ranked matches
|
||||
- ✅ View competitive leaderboards
|
||||
|
||||
**Result:** 100% EA server replacement. Game remains playable indefinitely.
|
||||
|
||||
---
|
||||
|
||||
## 📊 Final Endpoint Count Estimate
|
||||
|
||||
| Category | Current | After Friends | After Multiplayer | Total |
|
||||
|----------|---------|---------------|-------------------|-------|
|
||||
| Core Services | 72 | 72 | 72 | 72 |
|
||||
| Friends/Social | 0 | 8-10 | 8-10 | 8-10 |
|
||||
| Multiplayer | 0 | 0 | 10-12 | 10-12 |
|
||||
| **TOTAL** | **72** | **80-82** | **90-94** | **90-94** |
|
||||
|
||||
**Target:** ~90-94 endpoints for complete EA replacement
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Next Steps
|
||||
|
||||
1. **START:** Friends system database schema
|
||||
2. Create FriendsController.cs
|
||||
3. Test friend add/remove with basic UI
|
||||
4. Move to multiplayer once friends work
|
||||
5. Iterate based on testing
|
||||
|
||||
---
|
||||
|
||||
**Ready to Begin Implementation?** ✅
|
||||
|
||||
Let's start with the Friends/Social system since it's simpler and multiplayer depends on having friends to play with!
|
||||
Reference in New Issue
Block a user