mirror of
https://github.com/tiennm99/vngeoguessr.git
synced 2026-10-18 12:14:40 +00:00
b7f8879fe07f3e9117a29f249767bc8235bb941a
Every panorama now carries the district it falls in, so a guess can be attributed to a leaf rather than only to a province. The assignment runs against the indexes already on disk: districts are a property of a panorama, not a separate dataset, and re-fetching per district would multiply a ~2,800-tile build against Mapillary's 50,000/day cap for bytes we already hold. The district is stored as an integer offset into a per-province districts array rather than as a code string, which costs about five bytes an entry instead of twelve. Across 424,617 entries that is the difference between the 2.85 MB the data actually grew and something closer to five. Coverage is judged on distinct places, not on raw counts. The index is thinned at 33m, so a count overstates how many different places a district offers by roughly thirty times -- a district can hold hundreds of panoramas and still be one street seen from many angles. Playability therefore needs both a panorama floor, which exists because the Mapillary lookup retries three times with a different candidate, and a floor on distinct ~1.1km cells. Sixty-four of the sixty-seven regions clear it. The three that do not are one of each kind the coverage note describes: Cu Chi has no boundary, while Cam Le and Hoa Vang have no street imagery at all. A point that falls in a sliver between two simplified outlines is placed in the nearest district by distance to the outline itself. Ranking by bounding-box centre instead was measured putting points up to six kilometres inside the wrong district, because a compact district's centre can beat a sprawling neighbour whose edge is metres away. The stranded tally is recorded per province and the build refuses to write above two percent, since that is the signal that the leaf simplification tolerance has opened gaps along shared borders. It currently sits at 0.05 percent, worst case forty-six metres. fetchCityPanorama now reports the district of the attempt that succeeded. Each retry draws a fresh candidate, potentially from a different district, so carrying the first one forward would credit the wrong place. An exhausted pool returns a failure rather than escaping as a 500. Panorama arrays handed out at runtime are frozen. They are process-global and cached for the life of the server, and an in-place sort on the shared district array had already once repointed every panorama at the wrong district. Nothing is wired to scoring yet: the resolved district is computed and returned but not stored on the session. That lands with the leaderboard fan-out.
VNGeoGuessr
A GeoGuessr clone focused on Vietnamese locations with accurate boundary detection and anti-cheat security. Play geolocation guessing games across 5 Vietnamese locations using real street-level imagery.
🎮 Features
- 5 Vietnamese Locations: Ha Noi, Da Nang, Ho Chi Minh, Da Lat, Duc Hoa (Long An)
- 360° Street View: Mapillary panoramic images with PhotoSphere viewer
- Anti-Cheat Security: Server-side session management prevents cheating
- Distance-Based Scoring: 0-5 point system based on accuracy
- Persistent Leaderboards: Redis-powered top 200 player rankings
- Accurate Boundaries: Nominatim API + Turf.js for precise city detection
📚 Documentation
For detailed information about this project, see the documentation in /docs/:
- Project Overview - Project summary and key characteristics
- Features - Complete feature list and game mechanics
- Tech Stack - Technology stack and dependencies
- Development Guidelines - Development setup and coding standards
- Game Flow - Complete gameplay flow documentation
- Project Structure - Codebase organization and architecture
🚀 Getting Started
Prerequisites
- Node.js 18+
- npm 11+
- Redis server (for leaderboards)
Development
# Install dependencies
npm install
# Start development server
npm run dev
# Build for production
npm run build
# Start production server
npm start
# Run linting
npm run lint
Open http://localhost:3000 to play the game.
🏗️ Built With
- Frontend: Next.js 15 + React 19 + Tailwind CSS 4
- Street View: Mapillary API + PhotoSphere Viewer
- Maps: Leaflet + OpenStreetMap
- Geographic Data: Nominatim API + Turf.js
- Storage: Redis (leaderboards) + In-memory sessions
- UI Components: shadcn/ui
🎯 How to Play
- Enter your username
- Select a Vietnamese location
- View the 360° street panorama
- Place your guess on the map
- Earn points based on accuracy (closer = more points)
- Compete for the top 200 leaderboard spots!
📋 Development Notes
- JavaScript Only: No TypeScript files
- Individual Parameters: Functions use separate parameters, not object destructuring
- Server-Side Security: Game coordinates never sent to client
- Session Management: Automatic cleanup after 30 minutes
🤝 Contributing
This project follows specific development guidelines. Please read the Development Guidelines before contributing.
Description
GeoGuessr clone for Vietnamese locations — Mapillary panoramas, Turf.js boundaries, Upstash REST leaderboards
Readme
Apache-2.0
14 MiB
0 Stars
1 Watchers
0 Forks
Languages
JavaScript
98.2%
CSS
1.8%