100 lines
5.1 KiB
Markdown
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
|