# stoopkid713/stoop architecture

> Architecture diagram of the GitHub repository stoopkid713/stoop, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-21). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/stoopkid713/stoop
- Repository: https://github.com/stoopkid713/stoop

## Overview

1. **System shape**
   - STOOP is a **local desktop log analyzer** plus a **remote party-sync service**.
   - The local app reads Throne & Liberty combat logs from disk, computes stats, and renders the UI.
   - The remote service is only for **shared Party DPS** state, invites, and board synchronization.

2. **Primary data source boundary**
   - The only game input is the **Detailed Combat Log** written by T&L to `%LOCALAPPDATA%/TL/Saved/CombatLogs`.
   - The app does **not** inject into the game, hook graphics, or read game memory; everything starts from log files on disk.

3. **Local ingestion pipeline**
   - `backend/log_watcher.py` monitors the log file.
   - `backend/combat_log_parser.py` converts raw log lines into structured combat events.
   - `backend/encounter_scan.py` and `backend/encounter_boundary.py` decide where fights start/end.
   - `backend/combat_stats.py`, `backend/party_state.py`, and related modules aggregate damage, crit/heavy rates, party membership, and encounter summaries.

4. **Local application runtime**
   - `backend/main.py` is the desktop app entry point and orchestration layer.
   - `backend/dps_meter_server.py` provides the local server/API that the UI talks to.
   - `backend/hotkey.py`, `backend/debug.py`, and `backend/party_state.py` support interaction, resets, and diagnostic flows.
   - `backend/persistence.py` manages the app’s JSON state files.

5. **Local persistent state**
   - User and combat data are stored as JSON in the app data folder.
   - Key persisted artifacts include `config.json`, `encounters.json`, `saved_runs.json`, `skill_settings.json`, `weapon_config.json`, `default_target_assignments.json`, and `dungeons.json`.
   - This persistence layer is the boundary between transient combat events and long-lived build/run history.

6. **Frontend/UI layer**
   - The main UI is a browser-based frontend built from `index.html`, `party_render.js`, and modules under `src/js/`.
   - Those modules cover party display, encounter editing, run building, saved runs, skill/rotation analysis, target assignment, and drill-down views.
   - The frontend is the presentation layer; it consumes data from the local backend and reflects persisted state.

7. **Overlay subsystem**
   - `overlay/src-tauri` is a separate **Tauri/Rust** app that provides the in-game overlay window.
   - Its architectural role is distinct from the main UI: a transparent, click-through overlay that displays the live party board over the game.
   - The overlay is a separate process/window boundary, not part of the game client.

8. **Party DPS remote service**
   - `workers/party` is the cloud backend for shared party functionality, deployed as a **Cloudflare Worker**.
   - It handles party/dashboard synchronization, invite codes/links, analytics, feedback, and game-data endpoints.
   - Local clients push or fetch party state through this service so multiple players can contribute to one shared scoreboard.

9. **Build/data-refresh tooling**
   - `backend/build.py` packages the desktop app with **PyInstaller** and optional **Inno Setup** installer creation.
   - `backend/tools/refresh_game_data.py` and the worker-side game-data code support refreshing metadata used by the UI and analysis.
   - Repo-level JSON fixtures and samples are used to validate parsing and encounter behavior.

10. **Testing architecture**
   - Backend logic is covered by Python unit tests in `backend/tests/`.
   - UI behavior is covered by browser tests in `tests/frontend/`.
   - Party-service behavior is covered by worker tests in `workers/party/test/`.
   - End-to-end robustness is exercised by battery scenarios in `tests/battery/`, which simulate multi-client, overlay, race, reconnect, and adversarial conditions.

11. **Key end-to-end flows**
   - **Solo analysis flow:** log file → watcher/parser → encounter/stats aggregation → persistence → local UI.
   - **Party flow:** each player’s local app parses their own logs → stats are merged/synchronized via the worker → shared board is shown locally and in the overlay.
   - **Review flow:** persisted encounters/runs are reopened in the UI for drill-down, comparison, and build analysis.

12. **Operational boundaries**
   - GitHub Actions handles CI and release packaging.
   - The cloud worker is the only remote runtime involved in product features; everything else is local desktop processing.
   - The repo is therefore a **multi-runtime desktop system**: Python backend, browser UI, Rust overlay, and serverless party infrastructure.

Main entry points: [`index.html`](https://github.com/stoopkid713/stoop/blob/main/index.html) (Main UI), [`workers/party/src/index.js`](https://github.com/stoopkid713/stoop/blob/main/workers/party/src/index.js) (Party worker), [`backend/main.py`](https://github.com/stoopkid713/stoop/blob/main/backend/main.py) (App entry), [`backend/dps_meter_server.py`](https://github.com/stoopkid713/stoop/blob/main/backend/dps_meter_server.py) (Local API)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_local_backend["Local backend"]
  node_backend_main["App entry<br/>python orchestrator<br/>[main.py]"]
  node_backend_log_watcher["Log watcher<br/>file tailer<br/>[log_watcher.py]"]
  node_backend_parser["Parser"]
  node_backend_encounter_scan["Encounter scan<br/>fight detector<br/>[encounter_scan.py]"]
  node_backend_combat_stats["Combat stats<br/>aggregation<br/>[combat_stats.py]"]
  node_backend_party_state["Party state<br/>state model<br/>[party_state.py]"]
  node_backend_persistence["Persistence<br/>json store<br/>[persistence.py]"]
  node_backend_server["Local API<br/>http server"]
end

subgraph group_frontend["Frontend UI"]
  node_frontend_html["Main UI<br/>web app<br/>[index.html]"]
  node_frontend_party["Party view<br/>ui module<br/>[party.js]"]
  node_frontend_run_builder["Run builder<br/>ui module<br/>[run-builder.js]"]
  node_frontend_targets["Targets<br/>ui module<br/>[targets-assign.js]"]
end

subgraph group_overlay["Overlay"]
  node_overlay_main["Overlay app<br/>tauri window<br/>[main.rs]"]
end

subgraph group_cloud_worker["Cloud worker"]
  node_worker_index["Party worker<br/>cloudflare worker<br/>[index.js]"]
  node_worker_dashboard["Dashboard sync<br/>sync service<br/>[dashboard.js]"]
  node_worker_gamedata["Game data<br/>metadata service<br/>[gamedata.js]"]
end

subgraph group_tests["Tests"]
  node_tests_battery["Battery tests<br/>e2e scenarios<br/>[runner.js]"]
  node_tests_frontend["Frontend tests<br/>browser tests<br/>[harness.js]"]
  node_tests_worker["Worker tests"]
end

subgraph group_tooling["Tooling"]
  node_tool_build["Build packager<br/>packaging<br/>[build.py]"]
  node_tool_refresh["Data refresh<br/>refresh tool"]
end

node_backend_main -->|"watches"| node_backend_log_watcher
node_backend_log_watcher -->|"raw lines"| node_backend_parser
node_backend_parser -->|"events"| node_backend_encounter_scan
node_backend_encounter_scan -->|"segments"| node_backend_combat_stats
node_backend_combat_stats -->|"summaries"| node_backend_party_state
node_backend_party_state -->|"save/load"| node_backend_persistence
node_backend_main -->|"serves"| node_backend_server
node_backend_server -->|"data"| node_frontend_html
node_frontend_html -->|"loads"| node_frontend_party
node_frontend_html -->|"loads"| node_frontend_run_builder
node_frontend_html -->|"loads"| node_frontend_targets
node_backend_server -->|"overlay feed"| node_overlay_main
node_backend_party_state -->|"syncs"| node_worker_index
node_worker_index -->|"routes"| node_worker_dashboard
node_worker_index -->|"serves"| node_worker_gamedata
node_backend_main -.->|"packages"| node_tool_build
node_backend_main -.->|"refreshes"| node_tool_refresh
node_tests_battery -.->|"exercises"| node_backend_server
node_tests_battery -.->|"exercises"| node_worker_index
node_tests_frontend -.->|"verifies"| node_frontend_html
node_tests_worker -.->|"verifies"| node_worker_index
node_tool_refresh -.->|"feeds"| node_worker_gamedata

click node_backend_main "https://github.com/stoopkid713/stoop/blob/main/backend/main.py"
click node_backend_log_watcher "https://github.com/stoopkid713/stoop/blob/main/backend/log_watcher.py"
click node_backend_parser "https://github.com/stoopkid713/stoop/blob/main/backend/combat_log_parser.py"
click node_backend_encounter_scan "https://github.com/stoopkid713/stoop/blob/main/backend/encounter_scan.py"
click node_backend_combat_stats "https://github.com/stoopkid713/stoop/blob/main/backend/combat_stats.py"
click node_backend_party_state "https://github.com/stoopkid713/stoop/blob/main/backend/party_state.py"
click node_backend_persistence "https://github.com/stoopkid713/stoop/blob/main/backend/persistence.py"
click node_backend_server "https://github.com/stoopkid713/stoop/blob/main/backend/dps_meter_server.py"
click node_frontend_html "https://github.com/stoopkid713/stoop/blob/main/index.html"
click node_frontend_party "https://github.com/stoopkid713/stoop/blob/main/src/js/party.js"
click node_frontend_run_builder "https://github.com/stoopkid713/stoop/blob/main/src/js/run-builder.js"
click node_frontend_targets "https://github.com/stoopkid713/stoop/blob/main/src/js/targets-assign.js"
click node_overlay_main "https://github.com/stoopkid713/stoop/blob/main/overlay/src-tauri/src/main.rs"
click node_worker_index "https://github.com/stoopkid713/stoop/blob/main/workers/party/src/index.js"
click node_worker_dashboard "https://github.com/stoopkid713/stoop/blob/main/workers/party/src/dashboard.js"
click node_worker_gamedata "https://github.com/stoopkid713/stoop/blob/main/workers/party/src/gamedata.js"
click node_tool_build "https://github.com/stoopkid713/stoop/blob/main/backend/build.py"
click node_tool_refresh "https://github.com/stoopkid713/stoop/blob/main/backend/tools/refresh_game_data.py"
click node_tests_battery "https://github.com/stoopkid713/stoop/blob/main/tests/battery/runner.js"
click node_tests_frontend "https://github.com/stoopkid713/stoop/blob/main/tests/frontend/harness.js"
click node_tests_worker "https://github.com/stoopkid713/stoop/blob/main/workers/party/test/dashboard_analytics.test.mjs"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_backend_main,node_backend_log_watcher,node_backend_parser,node_backend_encounter_scan,node_backend_combat_stats,node_backend_party_state,node_backend_persistence,node_backend_server toneBlue
class node_frontend_html,node_frontend_party,node_frontend_run_builder,node_frontend_targets toneAmber
class node_overlay_main toneMint
class node_worker_index,node_worker_dashboard,node_worker_gamedata toneRose
class node_tests_battery,node_tests_frontend,node_tests_worker toneIndigo
class node_tool_build,node_tool_refresh toneTeal
```

## Components

### Local backend

Python desktop runtime that ingests logs, computes stats, persists state, and serves the local API.

- [App entry](https://github.com/stoopkid713/stoop/blob/main/backend/main.py): python orchestrator · Desktop application entry point and orchestration layer. · `backend/main.py`
- [Log watcher](https://github.com/stoopkid713/stoop/blob/main/backend/log_watcher.py): file tailer · Monitors the combat log file on disk. · `backend/log_watcher.py`
- [Parser](https://github.com/stoopkid713/stoop/blob/main/backend/combat_log_parser.py): event parser · Converts raw combat log lines into structured events. · `backend/combat_log_parser.py`
- [Encounter scan](https://github.com/stoopkid713/stoop/blob/main/backend/encounter_scan.py): fight detector · Detects encounter boundaries and fight segmentation. · `backend/encounter_scan.py`
- [Combat stats](https://github.com/stoopkid713/stoop/blob/main/backend/combat_stats.py): aggregation · Aggregates damage, crit rates, summaries, and related encounter metrics. · `backend/combat_stats.py`
- [Party state](https://github.com/stoopkid713/stoop/blob/main/backend/party_state.py): state model · Tracks party membership, encounter state, and shared DPS board data. · `backend/party_state.py`
- [Persistence](https://github.com/stoopkid713/stoop/blob/main/backend/persistence.py): json store · Reads and writes the app's persisted JSON state files. · `backend/persistence.py`
- [Local API](https://github.com/stoopkid713/stoop/blob/main/backend/dps_meter_server.py): http server · Local server/API used by the UI and overlay-facing flows. · `backend/dps_meter_server.py`

### Frontend UI

Browser-based presentation layer for party, encounters, runs, and analysis views.

- [Main UI](https://github.com/stoopkid713/stoop/blob/main/index.html): web app · Browser-based frontend shell for the desktop application. · `index.html`
- [Party view](https://github.com/stoopkid713/stoop/blob/main/src/js/party.js): ui module · Party board and live combat presentation logic. · `src/js/party.js`
- [Run builder](https://github.com/stoopkid713/stoop/blob/main/src/js/run-builder.js): ui module · Builds, edits, and compares saved runs and encounter views. · `src/js/run-builder.js`
- [Targets](https://github.com/stoopkid713/stoop/blob/main/src/js/targets-assign.js): ui module · Target assignment and analysis views for encounters and rotations. · `src/js/targets-assign.js`

### Overlay

Separate Tauri/Rust overlay window for in-game party board display.

- [Overlay app](https://github.com/stoopkid713/stoop/blob/main/overlay/src-tauri/src/main.rs): tauri window · Transparent, click-through overlay window for shared party display. · `overlay/src-tauri/src/main.rs`

### Cloud worker

Remote party-sync service and game-data endpoints deployed as a Cloudflare Worker.

- [Party worker](https://github.com/stoopkid713/stoop/blob/main/workers/party/src/index.js): cloudflare worker · Remote sync entry point for party/dashboard functionality. · `workers/party/src/index.js`
- [Dashboard sync](https://github.com/stoopkid713/stoop/blob/main/workers/party/src/dashboard.js): sync service · Handles invite, party board, and dashboard synchronization logic. · `workers/party/src/dashboard.js`
- [Game data](https://github.com/stoopkid713/stoop/blob/main/workers/party/src/gamedata.js): metadata service · Serves game-data and analytics endpoints used by the UI and sync service. · `workers/party/src/gamedata.js`

### Tests

Backend, frontend, worker, and end-to-end validation suites.

- [Battery tests](https://github.com/stoopkid713/stoop/blob/main/tests/battery/runner.js): e2e scenarios · Multi-client, overlay, race, reconnect, and adversarial end-to-end scenarios. · `tests/battery/runner.js`
- [Frontend tests](https://github.com/stoopkid713/stoop/blob/main/tests/frontend/harness.js): browser tests · Browser-based UI behavior and capture tests. · `tests/frontend/harness.js`
- [Worker tests](https://github.com/stoopkid713/stoop/blob/main/workers/party/test/dashboard_analytics.test.mjs): worker tests · Cloud worker behavior and dashboard analytics validation. · `workers/party/test/dashboard_analytics.test.mjs`

### Tooling

Packaging and data-refresh utilities.

- [Build packager](https://github.com/stoopkid713/stoop/blob/main/backend/build.py): packaging · Packages the desktop app with PyInstaller and installer tooling. · `backend/build.py`
- [Data refresh](https://github.com/stoopkid713/stoop/blob/main/backend/tools/refresh_game_data.py): refresh tool · Refreshes game metadata used by the app and worker. · `backend/tools/refresh_game_data.py`

## Connections

- App entry → Log watcher: watches · Starts log monitoring for the on-disk combat log.
- Log watcher → Parser: raw lines · Feeds raw log lines into structured parsing.
- Parser → Encounter scan: events · Parsed combat events are scanned for fight boundaries.
- Encounter scan → Combat stats: segments · Encounter segments are aggregated into combat stats.
- Combat stats → Party state: summaries · Computed encounter and party summaries update shared state.
- Party state → Persistence: save/load · Long-lived party, run, and configuration state is persisted.
- App entry → Local API: serves · Orchestrates the local API consumed by the UI.
- Local API → Main UI: data · UI reads state and live updates from the local server.
- Main UI → Party view: loads · Main shell loads the party board presentation module.
- Main UI → Run builder: loads · Main shell loads run editing and comparison views.
- Main UI → Targets: loads · Main shell loads target assignment and analysis views.
- Local API → Overlay app: overlay feed · Overlay consumes live board state from the local runtime.
- Party state → Party worker: syncs · Local party state is pushed to or fetched from the remote sync service.
- Party worker → Dashboard sync: routes · Routes party and dashboard synchronization requests.
- Party worker → Game data: serves · Exposes analytics and game-data endpoints.
- App entry → Build packager: packages · Desktop app is packaged through the build pipeline.
- App entry → Data refresh: refreshes · Build/runtime tooling refreshes metadata used by analysis.
- Battery tests → Local API: exercises · End-to-end scenarios drive the local backend and sync flows.
- Battery tests → Party worker: exercises · Battery scenarios validate party-sync behavior against the worker.
- Frontend tests → Main UI: verifies · Browser tests verify UI behavior and rendering.
- Worker tests → Party worker: verifies · Worker tests validate cloud sync behavior.
- Data refresh → Game data: feeds · Metadata refresh tooling supports worker game-data endpoints.
