Geoguessr Self-Hosted Reimplementation

API
API Endpoints
GET /
Returns 200 and {
"version": string,
"status": string
}
POST /score
Accepts {
"point1": {
"lat": number,
"lng": number
},
"point2": {
"lat": number,
"lng": number
}
}
Returns 400 or 200 and {
"score": number,
"distance": number
}
PUT /game
Accepts {
"timer": number,
"rounds": number,
"onlyAmerica": boolean (default: false)
}
Returns 200 and {
"gameId": string
}
GET /game/{ID}/config
Returns 404 vs 200 and {
"timer": number,
"rounds": number,
"onlyAmerica": boolean,
}
GET /game/{ID}/coords
Returns 404 vs 200 and {
"1": {
"lat": number,
"lng": number,
}, ...
}
GET /game/{ID}/players
Returns 404 vs 200 and {
"players": [
{
"name": string,
"currentRound": string || null,
"totalScore": number,
"guesses": {
"1": {
"lat": number,
"lng": number,
"score": number || null,
"timeRemaining": number
}, ...
}
}, ...
]
}
GET /game/{ID}/linked
Returns 404 vs 200 and {
"linkedGame": string || null
}
POST /game/{ID}/linked
Accepts {
"linkedGame": string
}
Returns (401, 404) vs 201
POST /game/{ID}/join
Accepts {
"playerName": string
}
Returns (401, 404, 409) vs 201 and {
"playerId": string
}
GET /game/{ID}/current
Header Authorization: Player string
Returns (400, 404) vs 200 and {
"currentRound": string || null,
"coord": {
"lat": number,
"lng": number,
} || null,
"timer": number
}
POST /game/{ID}/guesses/{round}
Header Authorization: Player string
Accepts {
"timeRemaining": number,
"lat": number,
"lng": number
} OR {
"timeout": boolean
}
Returns (400, 401, 404, 409) vs 201 and {
"score": number,
"totalScore": number,
"distance": number || null
}
Next Steps
- Asynchronously generate locations, allowing game creation to appear faster
- Improve error handling in UI
- Override google controls in streetview, make custom divs
- Modify scoring to linear interp in the middle
- Alternative game mode: Single timer across all rounds
- Timestamps/hashes in info responses so checks can be faster