BeamNG.Earth
A 1:1 scale streamed Earth for BeamNG.drive: real elevation and satellite imagery, floating origin, LOD streaming from a companion server
Archipelago Alerts is a simple tool for tracking Archipelago multiworld games. It consists of a Python backend service and a native Android application designed to send push notifications for key in-g
GamesPython · KotlinGitHub @wrjones104OnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Archipelago Alerts is a simple tool for tracking Archipelago multiworld games. It consists of a Python backend service and a native Android application designed to send push notifications for key in-game events for players you choose to follow.
Taken from the repository README
Loading the full README. The saved excerpt is shown below.
Archipelago Alerts (formerly AP Tracker) is a tracking and notification service for Archipelago Multiworld games. It polls the rooms you follow and pushes a notification to your phone the moment something you care about happens — so you can play an async multiworld without babysitting a tracker page.
The project is a monorepo containing a Python backend (Flask API + background poller) and a native Android app (Kotlin / Jetpack Compose).
📱 Google Play · 📦 APK downloads (GitHub Releases) · 💬 Discord threadRead the full README ↗Archipelago Alerts (formerly AP Tracker) is a tracking and notification service for Archipelago Multiworld games. It polls the rooms you follow and pushes a notification to your phone the moment something you care about happens — so you can play an async multiworld without babysitting a tracker page.
The project is a monorepo containing a Python backend (Flask API + background poller) and a native Android app (Kotlin / Jetpack Compose).
📱 Google Play · 📦 APK downloads (GitHub Releases) · 💬 Discord thread
Tracking
Notifications
Milestones
History and widgets
Integrations and account
/delete-account.backend/ Python service
app/
routes/ Domain REST blueprints (auth, user, rooms, slots,
thresholds, templates, history, game, whats_new)
services/ Poller engine and workers (poller, threshold, notification,
cheese, datapackage, filtering, retention, redis)
data/ changelog.json — single source of truth for versions
models.py SQLAlchemy models and composite indexes
poller.py Poller supervisor / room setup engine
db_migrations.py Runs Alembic on startup for Postgres deployments
tests/ unittest suite (run in CI)
run.py API + poller in one process (local dev)
run_api_only.py API container entrypoint
run_poller_only.py Poller container entrypoint
android/ Kotlin / Jetpack Compose app
app/src/main/java/com/jones/aptracker/
network/ Retrofit API, DTOs, DAOs, token/session management
database/ Room database, migrations, milestone cache
repository/ Data layer, history sync manager and worker
ui/ Compose screens and ViewModels
widget/ Glance home screen widgets
alembic/ Database migrations
scripts/ generate_changelog.py
Further reading: architecture.md for system design, Redis pub/sub events, composite indexes, and container topology; LLM.md for a component-by-component overview and the project's gotchas; backend/SECURITY.md for the security model.
Backend (Python 3.11+)
immediate_poll pub/sub bus and datapackage name caching.Android app (Kotlin)
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txt
pip install -r backend/requirements.txt
backend/requirements.txt is what the container installs (it adds psycopg2-binary and redis); the root file is the local and CI environment.
Generate a service account private key in your Firebase project settings and save the JSON as service-account-key.json in backend/. Override the path with FIREBASE_KEY_FILE_ANDROID if you keep it elsewhere. An iOS key (service-account-key-ios.json, or FIREBASE_KEY_FILE_IOS) is optional — the backend initializes a second Firebase app only if the file exists.
Create backend/.env:
# Database — omit entirely to fall back to a local SQLite file
DATABASE_URL=postgresql://ap_user:ap_password@localhost:5432/ap_tracker_dev
REDIS_URL=redis://localhost:6379/0
# Flask
FLASK_ENV=development # development | uat | production
SECRET_KEY=change-me # JWT signing key
LOG_LEVEL=DEBUG # optional override
# Discord OAuth
DISCORD_CLIENT_ID=your-client-id
DISCORD_CLIENT_SECRET=your-client-secret
DISCORD_REDIRECT_URI=http://localhost:5000/web/callback
# Encryption key for stored Cheese Tracker API keys (Fernet key)
ENCRYPTION_KEY=your-fernet-key
# Optional
CHEESE_BASE_URL=https://cheesetrackers.theincrediblewheelofchee.se
The dev compose file brings up PostgreSQL 15 and Redis 7, plus API and poller containers with the app package bind-mounted so backend edits do not need a rebuild:
docker-compose -f docker-compose.dev.yml up -d
To run only the datastores and keep the Python process local, start just the postgres and redis services and point DATABASE_URL at localhost:5432.
PostgreSQL: migrations run automatically on startup — every entrypoint goes through create_app(), which takes an advisory lock and upgrades to head. To apply them by hand instead:
alembic upgrade heads
SQLite: no migrations. Tables are created directly from the models on startup.
python backend/run.py
This serves the API on http://0.0.0.0:5000 and runs the poller in the same process. The containers split these into run_api_only.py and run_poller_only.py.
Each test module owns its own engine and database, so modules must run in separate processes:
PYTHONPATH=backend:. python -m unittest backend.tests.test_cheese_sync -v
$env:PYTHONPATH="backend;."; python -m unittest backend.tests.test_cheese_sync -v
CI (backend-tests.yml) runs every module in backend/tests/ this way on pushes to main and on PRs touching the backend, and also verifies the changelog is in sync.
Open the android/ folder in Android Studio.
Add google-services.json from your Firebase project's Android app settings to android/app/.
Create android/app/local.properties. Secrets are read from here by build.gradle.kts and are never committed:
DISCORD_CLIENT_ID=your-discord-client-id
# Your machine's LAN IP, so a physical device can reach your local backend.
# Defaults to http://10.0.2.2:5000/ (the emulator's host loopback) if omitted.
DEV_API_BASE_URL=http://192.168.1.100:5000/
# Required only when building those flavors — the build fails without them.
UAT_API_BASE_URL=https://uat.example.com/
PROD_API_BASE_URL=https://prod.example.com/
Pick a build variant and run. Flavors are dev, uat, and prod; each installs under its own application id suffix, so they coexist on one device.
| Build type | Purpose |
|---|---|
debug | Everyday development. |
release | Minified and shrunk, signed for distribution. |
minified | The release R8 pipeline, but debuggable and debug-signed — use it to catch missing keep rules before they reach the Play Store. |
Use devDebug for normal local work against your own backend.
The app and the backend are versioned independently. backend/app/data/changelog.json is the single source of truth — it holds two newest-first arrays, app_releases and server_releases. The CHANGELOG.md files, the landing page version badges, and GET /api/whats_new are all derived from it.
To cut a release:
Prepend an entry to the relevant array in changelog.json.
For an Android release, bump versionName and versionCode in android/app/build.gradle.kts to match.
Regenerate the markdown:
python scripts/generate_changelog.py
Commit. scripts/generate_changelog.py --check runs in CI and fails if the markdown is stale or if the gradle versionName disagrees with the newest app_releases entry.
Do not hand-edit android/CHANGELOG.md or backend/CHANGELOG.md — they are generated.
Licensed under the Apache License 2.0.