Files
vngeoguessr/docs/features.md
T
tiennm99 1c62e3e1dd perf(mapillary): race dart-throw windows concurrently
Each Mapillary window query costs ~1-5s and most windows hold no
panoramas, so throwing them one at a time made /api/new-game wait for
the sum of every miss. Measured in production: median 17.8s, max 90.5s
over 18 samples.

Throw 8 windows per round instead, race them with Promise.any and abort
the losers once one yields panoramas. Wall time becomes one round-trip
in the common case. Same 20-window budget, same per-city delta, same
401 short-circuit.

After the change, over 10 samples: median 5.6s, max 20.3s.
2026-08-29 14:27:42 +07:00

2.6 KiB

Game Features

Location Coverage

  • 5 Vietnamese Locations: Ha Noi, Da Nang, Ho Chi Minh, Da Lat, Duc Hoa (Long An)
  • Bbox-based Location Generation: Pre-defined city bounding boxes for accurate area targeting
  • Random Location Selection: Server-side random coordinate generation within city boundaries

Street View System

  • Mapillary Integration: Panoramic street-level images via Mapillary API
  • Dart-throw Strategy: Pick random points in city bbox, query small fixed-size sub-bboxes, 8 raced concurrently per round, re-roll on empty/error (20 windows max)
  • Per-city Optimization: Delta tuned per city to balance coverage and Mapillary query cost
    • Ha Noi: 0.003° (~333m square)
    • Ho Chi Minh, Da Lat, Da Nang, Duc Hoa: 0.005° (~556m square)
  • Panoramic Image Priority: Filters for is_pano=true images (limit 3 per query)
  • Thumbnail Display: Uses thumb_original_url for image display

Interactive Maps

  • Leaflet Integration: OpenStreetMap-based interactive mapping
  • Click-to-Place: Intuitive guess marker placement

Anti-Cheat Security

  • Redis Session Management: Target coordinates stored server-side in Redis
  • UUID Session IDs: Unique session identifiers using uuid v4
  • 30-minute Expiry: Automatic Redis session cleanup for security
  • Server-side Calculations: All distance and scoring computed server-side using Turf.js
  • Session Cleanup: Automatic session deletion after guess submission

Scoring System

Distance-based points (0-5 scale):

  • 0-50m: 5 points
  • 50m-100m: 4 points
  • 100m-200m: 3 points
  • 200m-500m: 2 points
  • 500m-1km: 1 point
  • 1km+: 0 points

Leaderboards

  • Triple-Leaderboard System: Score leaderboards (accumulated points) + Distance leaderboards (best distances)
  • Score Leaderboards: Separate accumulated score leaderboards for each city plus global Vietnam
  • Distance Leaderboards: Best distance records for each city plus global Vietnam (multiple entries per user)
  • Redis Sorted Sets: Persistent leaderboard data using Redis ZADD/ZRANGE
  • Top 200 Entries: Maximum entry limit with automatic trimming per leaderboard
  • Accumulated Scoring: All scores are added to both city and global score totals simultaneously
  • Distance Records: Each game creates a new distance record entry (users can have multiple positions)
  • Persistent Storage: No expiration on leaderboard data
  • Real-time Ranking: Dynamic rank calculation for all leaderboard types
  • Triple Updates: Each game updates score leaderboards AND distance leaderboards (city + global)