Development¶
This page is Developer Documentation. It collects operational notes and local workflow details for maintainers.
Dependencies¶
Install runtime dependencies:
pip install -r requirements.txt
Install development + documentation tooling:
pip install -r requirements-dev.txt
Quality checks¶
Run the full local validation suite (lint, types, tests):
./scripts/checks
If you want checks available in your virtualenv's PATH, create a symlink:
ln -sf ../../scripts/checks .venv/bin/checks
Testing¶
Testing conventions, markers, and running instructions are documented on the dedicated Testing page.
See: Testing
Production Snapshot (Local)¶
Use the refresh script to pull a read-only production snapshot into your local database and prune to a single player:
.venv/bin/python scripts/refresh_staging_db.py --player-display-name mahbam42
The script reads .env by default and expects PROD_READONLY_DATABASE_URL and LOCAL_DATABASE_URL to be set. After restoring the snapshot it also runs local Django migrations against LOCAL_DATABASE_URL so newer local tables remain available even when the production dump comes from an older schema. For the manual workflow and grant setup, see archive/stagingDB.md.
Local Django entry points now also read .env automatically. If DATABASE_URL in .env points at the same local Postgres database as LOCAL_DATABASE_URL, python manage.py runserver will read the refreshed snapshot without needing a manual export DATABASE_URL=....
Repository docs in MkDocs¶
MkDocs includes repo-root GitHub Markdown files (for example, CHANGELOG.md and
CONTRIBUTING.md) via mkdocs-gen-files instead of symlinks.
To add another repo document:
- Add the filename to
REPO_FILESinscripts/mkdocs_gen_repo_docs.py. - Add a matching entry under the
Projectsection inmkdocs.yml.
Guided Walkthrough testing note: if the walkthrough does not appear in demo mode, clear local storage keys tts_walkthrough_dismissed and tts_walkthrough_completed_at via DevTools → Application → Local Storage for the current site.
Migrations¶
If Django reports conflicting migrations (multiple leaf nodes in an app), create a merge migration and commit it.
python manage.py makemigrations --merge
python manage.py migrate
Chart configuration¶
The Charts dashboard is driven by declarative ChartConfig entries and a central MetricSeries registry.
- Metric keys and capabilities are declared in
analysis/series_registry.py. - Built-in charts are declared in
core/charting/configs.pyand validated at import time. core/charting/validator.pyenforces strict rules so future Chart Builder output fails fast with clear errors.
Derived formulas¶
- Formulas may use numeric constants, metric-key identifiers, unary
+/-, and binary+ - * /only. - All identifiers must be registered metric keys and must also appear in the chart’s
metric_series. derived.x_axismust match the referenced metrics’ time index (time→timestamp,wave_number→wave_number).
Comparisons¶
- Comparison modes other than
noneare only allowed whencategory="comparison". by_tierandby_presetrequire every metric series to support that dimension.by_entityrequirescomparison.entitiesand exactly one entity filter enabled (uw,guardian, orbot).
Explore summaries¶
- Farming efficiency by tier compares each tier to the nearest available tier when building deltas and plateau checks, while still warning about missing tiers.
Explore query templates¶
- Explore query templates are stored in the database and managed through Django Admin.
- Templates are global, not player-scoped.
- Explore only lists templates where
is_active=True, ordered alphabetically by name. - Templates are copied into the editor and remain editable before the player runs or saves them.
- Seed migrations only create missing built-in templates and do not overwrite later admin edits.
- Seeded templates currently include
Farming Efficiency by Tier,Guardian Chip Performance, andReroll Shards Earned.
Event window helpers¶
- Shared Event-window calculations live in
analysis/event_windows.py. - Use the shared helper instead of duplicating the Event anchor date in dashboard-specific code paths.
Time semantics¶
- Real time comes from the Battle Report’s “Real Time” field and is used for per-hour rates such as coins/real hour.
- In-game timing (cooldowns and durations) is shown in seconds and is sourced from the external wiki tables.
- Accelerated time can make real-world time diverge from in-game seconds (for example, due to speed effects); dashboards must label units explicitly.
- Wiki-derived timing values are treated as reference data and may be inaccurate or drift over time.
Attributions¶
- Per-hour resource metrics (cells/hour, reroll shards/hour) requested by u/BoxersOrCaseBriefs.
Multi-player scoping¶
Phase 8 introduces first-class multi-player support.
- Every player-owned or mutable row is linked to
Player, andPlayeris a 1:1 extension of the Django auth user. - Views must derive the Player from
request.userand must not accept aplayer_idfrom the client. - Queryset filtering is mandatory for correctness and isolation; permissions are not a substitute for filtering.
- Admin pages must scope querysets to
player__user=request.userfor non-superusers and must assignplayerautomatically on create.
Security notes¶
- Post actions that accept
nextmust validate the URL before redirecting. Usecore.redirects.safe_redirectfor any redirect derived from user input. - AJAX error payloads should avoid raw exception details and return a user-safe message in production.
- The documentation toolchain pulls in Pygments transitively. In this repo it is used for trusted, repo-authored docs only, not player input. If docs rendering is ever exposed to untrusted content, run that highlighting/build step with a timeout and process isolation.