Files
fragalytics/README.md
T
2026-04-20 18:15:08 +00:00

100 lines
5.1 KiB
Markdown

# Fragalytics MVP
Fragalytics is a self-hosted MVP for Counter-Strike 2 demo analysis and highlight generation built in C# on ASP.NET Core. You upload `.dem` files manually, the app stores them, parses them in a background worker, scores highlight moments with explainable rules, persists the results in a local JSON-backed store, and creates clip job records for future rendering.
## Why this C# stack
- Web app: ASP.NET Core Razor Pages. It keeps the UI simple, local, and maintainable without adding a separate frontend build.
- Background work: `BackgroundService`. Good enough for a single-node MVP and easy to replace later with a queue worker.
- Persistence: file-backed JSON store. It avoids external package dependencies in this environment while still giving durable local storage and a clean repository boundary.
- Parsing: parser adapter abstraction. The app can run today with the sample adapter and can be pointed at an external parser process later.
- Scoring: explicit service layer with versioned rules and explainable output.
## What is implemented
- Manual `.dem` upload
- Background demo parsing
- Persistent storage
- Models for demos, matches, rounds, players, events, highlights, scoring profiles, and clip jobs
- Explainable highlight scoring
- Highlight tags: `multikill`, `headshot`, `opening_kill`, `clutch`, `1vX`, `wallbang`, `smoke_kill`, `round_win`
- Clip job records with `start_tick`, `end_tick`, `status`, `renderer`, and payload
- Web UI for demos, match details, highlights, and clip jobs
- Rescoring when scoring rules change
- Parser adapter abstraction
- Future render-worker abstraction
- Docker setup
- Tests for scoring and basic ingest flow
## Run locally
```bash
DOTNET_CLI_HOME=/tmp/dotnet-home DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 dotnet run --project src/Fragalytics.Web
```
Open `http://localhost:5000` or the URL printed by ASP.NET Core.
## Run the render worker
The render worker is a separate process:
```bash
DOTNET_CLI_HOME=/tmp/dotnet-home DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 dotnet run --project src/Fragalytics.RenderWorker
```
Right now it uses the `sample-copy` backend. That backend does not render from a `.dem`; it claims pending clip jobs and attaches a configured sample `.mp4` or `.webm` file so the end-to-end worker flow is in place.
## Docker
```bash
docker compose up --build
```
Open `http://localhost:8080`.
## Configuration
Main settings live in [appsettings.json](/home/hz/source/fragalytics/src/Fragalytics.Web/appsettings.json).
- `Fragalytics:DataDirectory`: persistent app state root
- `Fragalytics:UploadDirectory`: uploaded demo path
- `Fragalytics:WorkerPollSeconds`: polling interval for the hosted worker
- `Fragalytics:Parser:Mode`: `sample` or `external`
- `Fragalytics:Parser:ExternalCommand`: executable for a real parser sidecar
- `Fragalytics:Parser:ExternalArguments`: argument template, with `{demoPath}` placeholder
- `Fragalytics:RenderWorker:Backend`: render backend name, currently `sample-copy`
- `Fragalytics:RenderWorker:SampleClipPath`: source media file used by the stub backend
- `Fragalytics:RenderWorker:TempDirectory`: worker scratch directory
- `Fragalytics:RenderWorker:PollSeconds`: clip-job polling interval
## Scoring
Scoring rules live in [scoring-rules.json](/home/hz/source/fragalytics/src/Fragalytics.Web/scoring-rules.json). Change the weights or threshold, then use `Rescore All Matches` from the home page. The app stores a hashed scoring version on each highlight so rule changes are traceable.
## Rendering Roadmap
The app can now play uploaded clip files, but it still does not render video directly from CS2 demos. The step-by-step implementation plan for real demo-to-video rendering is documented in [docs/rendering-from-cs2-demo.md](/home/hz/source/fragalytics/docs/rendering-from-cs2-demo.md).
## Assumptions
- This MVP is kill-centric. It does not yet score utility-only, positioning-only, or movement-only moments.
- The default parser is the deterministic sample adapter so the app is runnable offline and testable in this environment.
- Real CS2 parsing is expected to come from an external parser process wired through `IDemoParserAdapter`. That keeps the ASP.NET Core app stable even if the parsing implementation changes.
- The persistent store is intentionally simple for a local MVP. If this moves beyond single-node use, replace the store with SQLite or Postgres behind the same service boundary.
- Rendering is intentionally not implemented. Clip jobs are created as durable work intents for a future render worker.
Current status: the separate render-worker scaffold exists, but the only backend today is a stub that copies a known video file instead of driving CS2.
## Tests
```bash
DOTNET_CLI_HOME=/tmp/dotnet-home DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 dotnet run --project tests/Fragalytics.Web.Tests
```
## Extension path
- Replace the JSON store with SQLite or Postgres
- Move background processing into a separate worker process
- Add a real parser sidecar that emits the normalized `ParsedDemo` JSON contract
- Replace the `sample-copy` render backend with real CS2-driven capture
- Add richer event ingestion and rule editing in the UI