Skip to content

The backend and the data

One service holds all of Kacky's truth: the backend, a .NET / ASP.NET Core app (src/KackyGG.Api). Everything a player sees — a record, a rank, whether a server is live — is a value the backend decided and stored. Nothing else gets to be the authority.

What it stores

The backend keeps the core things in a PostgreSQL database, through EF Core. The handful of entities you actually need to know:

  • Event — one edition's batch of maps, with its type, start, and end.
  • Map — a single Kacky map. Its real identity is the map's UID, not its number (numbers aren't unique across families).
  • Player — someone who plays in-game, optionally linked to a website account.
  • Finish — every completion. One row per time crossed.
  • Record — a player's best online time on a map in an event.

How they hang together:

Event ─* EventMap *─ Map        (an event's maps)
Map   ─* Finish   *─ Player     (every completion)
Map   ─* Record   *─ Player     (best online time per event)

Finish and Record look similar and aren't — that split is the thing people trip on, and Records vs Finishes owns the full story.

How it serves everything

The backend talks to the world three ways:

  • REST — the website and admin panel read and write over a normal HTTP API.
  • SignalR — live pushes (server status, updates) so the site doesn't have to keep asking.
  • Redis Streams — it consumes what the in-game controllers report and writes it to the database.

The frontends don't hand-write their API code. They generate it from the backend's OpenAPI spec, so when the backend's shape changes, the clients regenerate to match — they can't quietly drift out of sync.

Where the rules live

Rank cutoffs, what counts toward which edition, which times are trustworthy — that logic lives in the backend, in one place, not scattered across each client. A client asks; the backend answers with the one true version. That's the whole point of a single source of truth: there's no second opinion to disagree with.