2 Troubleshooting
Emily edited this page 2026-11-05 15:06:35 +01:00

Troubleshooting

The app does not start or build

  • Run flutter doctor -v and resolve missing platform toolchains.
  • Run flutter clean and flutter pub get after switching Flutter versions.
  • Confirm Flutter 3.47+ / Dart 3.13+.

Android build fails

  • Use JDK 17, not a newer unsupported JDK.
  • Set JAVA_HOME, ANDROID_HOME and the build-tools path:
export JAVA_HOME="$HOME/jdk-17/Contents/Home"
export ANDROID_HOME="$HOME/android-sdk"
export PATH="$JAVA_HOME/bin:$ANDROID_HOME/platform-tools:$ANDROID_HOME/build-tools/36.0.0:$PATH"
  • aapt and apksigner are not on PATH by default; the build-tools directory must be added explicitly.
  • If release signing fails, check android/key.properties and the keystore path.

Android install fails

  • The APK must be signed with the same key as the installed version. Uninstall the old app only if you accept losing local data.
  • Enable installation from unknown sources.
  • Check the minimum SDK: Android 7.0 (API 24) or newer.

iOS build or install fails

  • The published IPA is unsigned. Re-sign it with your own identity.
  • Universal Links and password-manager credentials require a signed build and the correct Team ID.
  • Free Apple IDs expire after seven days.
  • Build on macOS with Xcode 27+.

macOS says the app is damaged or cannot be opened

The build is ad-hoc signed, not notarized. Use System Settings → Privacy & Security → Open Anyway, or remove quarantine:

xattr -dr com.apple.quarantine "/Applications/Universal Gaming.app"

Web build is blank or routes 404

  • Serve build/web/ over HTTP(S), not by opening index.html directly.
  • Configure an SPA fallback so unknown paths return index.html.
  • The app uses path-based URLs; a host that only serves / will break /account and deep links.
  • Clear the service worker/site data after deploying a new version.
  • Check that version.json and latest.json are reachable.

Account server connection fails

  • Tap Test connection in Account settings.
  • Check that the URL uses the correct scheme and has no trailing path.
  • A plain http:// server works but shows a warning; use HTTPS in production.
  • If the app was built with UNIVERSAL_GAMING_API_URL, the runtime Account server setting can still override it.
  • Check CORS on the backend if using the web build. CORS_ORIGINS must include the exact web origin.

Account exists but e-mail stays “Not confirmed”

  • The server needs EMAIL_CONFIRMATION_ENABLED=true, SMTP_HOST and SMTP_FROM.
  • Open the confirmation link from the e-mail.
  • The label refreshes when Account settings opens or the app resumes; pull-to-refresh or reopen the screen if needed.
  • If the server has no SMTP, confirmation is unavailable but the account still works.

Password reset e-mail never arrives

  • Password reset only works for accounts with an assigned and confirmed e-mail.
  • The server must have SMTP configured.
  • The endpoint always returns success to prevent account enumeration, so a missing mail does not necessarily mean an error.
  • Reset links expire after 30 minutes by default (PASSWORD_RESET_TTL_MINUTES).

Competitive leaderboard is empty or falls back to Local

  • Viewing is public, but the server must have LEADERBOARD_ENABLED=true.
  • If the server is unreachable, the app falls back to the on-device board.
  • Submitting requires a signed-in account.
  • The Local switch intentionally prevents uploads.
  • Scores are client-reported; the server validates bounds and ranking but not actual gameplay.

Discord Rich Presence does not appear

Check all of these:

  1. You are on macOS, Windows or Linux. Mobile and web do not support it.
  2. The build included --dart-define=DISCORD_CLIENT_ID=....
  3. Discord is running on the same machine.
  4. Settings → Integrations → Discord Rich Presence is enabled.
  5. A game is open; the hub itself does not publish a presence.
  6. On macOS, the build must not be sandboxed. The project disables the App Sandbox for this reason.
  7. Restart Discord and the game after changing the client ID.

Connection failures are intentionally silent. The app retries later and never blocks gameplay.

Save backups are missing or fail

  • Save backups need backend 1.5.0 or newer. An older server answers 404 and the card shows This server does not support save backups.
  • The server operator can disable the feature with SAVE_BACKUP_ENABLED=false; the card then reports that save backups are disabled.
  • You must be signed in. Back up now and Restore are only shown on the Account screen for an active session; an expired session reports Sign in again to use save backups.
  • Back up now with no saved games uploads nothing and explains that there is nothing to back up yet.
  • A single save larger than 32 kB is rejected by the server.
  • Restore replaces the saved games on this device. It does not touch statistics, settings or the local leaderboard.
  • Failed or offline backups never remove local saves; the game you are playing is unaffected.

Tests hang

Run the suite serially:

flutter test --concurrency=1

Parallel widget tests can exhaust resources on some machines.

Old release artifacts are still shown

  • Check version.json on the web host.
  • Clear browser cache and service worker data.
  • Verify the container is running the new image tag:
docker compose ps
  • Check that the reverse proxy is not caching index.html or version.json aggressively.

Checksums do not match

Download the artifact again from the same release. SHA256SUMS.txt is generated from the exact uploaded files; a partial download or an older file with the same name will fail verification.