Skip to content

Crash and performance reports

The game reports to Sentry, the same account as the race server’s error alerts (Server operations), in a project of its own: org stackly-at (EU data region), projects neon-drag-game and neon-drag-server. Sentry stores no IP addresses (an org setting) and mails high-priority issues. Only our own builds report: the iOS and Android apps and the game on nitrolegend.com, never a portal or Playables build. Only production builds report, and only with VITE_SENTRY_DSN set (sops puts it in every shell), so npm run dev and npm run shot stay silent. nix develop .#emulator adds an Android emulator for checks without a phone; the native crash check ran on it (2026-11-13).

  • Errors: every uncaught JavaScript error and rejected promise, with the stack trace. The apps (@sentry/capacitor) also catch native crashes and hangs on Android and iOS. Play Console vitals and Xcode Organizer show Android crashes, ANRs and iOS crashes as well, without our SDK.
  • Performance, as Sentry metrics (boot/perfReport.ts):
Metric When Meaning
boot.ms once per launch page start until the Preloader is done and the first screen starts
scene.load_ms every scene start from the scene’s start to its create: its preload plus building it
memory.textures_mb, memory.audio_mb every scene start the same estimate as npm run shot prints (core/memoryEstimate.ts)
memory.js_heap_mb every scene start the JS heap, only where the WebView exposes it (Chromium, so Android)
race.fps_avg, race.fps_low1, race.frame_max_ms end of each race from every frame the Race scene ran, paused frames left out

Every report and metric carries target, platform, os, device (maker and model from @capacitor/device) and memory_gb (the browser’s rough device memory, 0 where unknown), so numbers split per phone. These are the numbers the graphics quality setting and the lazy-loading plan need from real phones. The release is <package.json version>+<commit count> (vite/sentry.mjs), the commit count being the Android versionCode.

No account, player id, nickname or advertising id is attached. The privacy policy section “Crash and performance reports” says so; change it with the code.

Settings, Display card, Share data, shared with the game statistics: on by default (legitimate interest, privacy policy section 9), stored in localStorage (core/crashReportSetting.ts), not in the save. Off stops sending at once (beforeSend and beforeSendMetric drop everything); Sentry itself only starts when the switch is on.

In Sentry: Issues for errors (grouped, with the release and device), Explore, Metrics for the performance numbers (p50 to p99 per attribute, for example race.fps_low1 grouped by device). The free Developer plan keeps 30 days and sends alerts by mail.

With SENTRY_AUTH_TOKEN set, npm run build and the native builds make hidden source maps, upload them to Sentry for the release and delete them again, so no build ships them. Without the token the build is as before and stack traces show minified code. For readable native iOS crashes, Sentry also needs the app’s dSYM files (not set up yet).

Make a production build (or drop the import.meta.env.PROD check in boot/crashReports.ts for the test) and point VITE_SENTRY_DSN at a local server that answers POST /api/<id>/envelope/ with CORS headers (for example http://key@localhost:9876/1), run the game and read the envelopes: one event item per error, trace_metric items for the numbers.