Skip to content
FLICKED Docs

Project

Roadmap & decisions

Where FLICKED is going, why it looks the way it does, and the decisions behind it, each with what it costs.

What this project has to work with#

Worth stating plainly, because it explains most of the decisions below.

People

One person

Part time, learning some parts of the stack while building them.

Hardware

One VPS

No second machine to test failover on, and no fleet of idle CS2 servers.

Budget

None for infrastructure

Anything that only works when servers are left running is out of reach.

Code that has never run against the thing it manages is not finished code, it is a guess. A server pool can be tested properly on one machine, with a single real CS2 server proving the end-to-end path. Where real capacity is needed, it comes from the people who already have it: server owners run CS2 servers anyway, and FLICKED coordinates them.

Where it is#

As of 27 September 2026

The whole path works end to end, on a real server, with real people: two players signed in through Steam, queued, accepted, voted a map, and CS2 connected them itself. The match finished and the result was written to Postgres.

ShippedWhat it means
Real dataNews, leaderboard and history come from Postgres. Migrations apply on startup, so upgrading is replacing a binary
AccountsSteam sign-in, with the session token held in Rust and never handed to the webview
Server poolServers registered in the dashboard, RCON passwords encrypted, claims with FOR UPDATE SKIP LOCKED, leases, offline detection
MatchesWidening rating windows, accept and map-vote phases, RCON start, and waiting for the map to change before handing out the address
Results and ratingReported over an authenticated endpoint, applied once per match. See Rating
PartiesQueueing with friends, drafted onto the same team. See Matchmaking & parties
Short-handed matchesOpt-in 4v4 or 3v3 after twenty seconds for small communities, always even
NewsAdmins write posts in the dashboard; every launcher reads the one feed
Dashboard and guidesServer pool and news pages, and deployment guides for Windows and Linux

Known gaps#

Things that are wrong or missing today, written down so they are not rediscovered. A good place to start contributing.

  • Declining a match does not requeue anyone. Only the twenty-second timeout path does. With parties it also costs a party its place in the queue.
  • A cancelled Wingman match requeues its players into Competitive. The mode is not stored on the match.
  • Wingman is disabled in the launcher. The backend supports it; there is no Wingman server in the pool to send it to.
  • No live updates. Friends, parties and the queue are polled. A push channel would replace the transport without changing what the screens read.
  • No presence. Whether a friend is online, in menus or in a match belongs with that push channel.
  • Demos are recorded but not linked to a match anywhere a player can reach.
  • A stuck match needs SQL. There is no admin action to cancel one, and a player can leave the queue but not a match.
  • Seeded demo players share the leaderboard with real ones on any instance that ran the migrations.
  • The live instance runs over plain HTTP, deliberately, for testing among friends. See Security.

Planned#

Roughly in order.

A FLICKED plugin, built on MatchZy

Not a better plugin: one that answers to one backend. Per-match admin control from the dashboard, moderation while a match is live, and stats shaped the way FLICKED stores them. MatchZy is MIT licensed, so the route is to fork it, keep what works, and credit it properly. Nothing starts until the current arrangement is genuinely the limiting factor.

Bans

First a ban on the Steam account, which is simple and enough for the usual case; later a hardware ban. This is moderation, not anti-cheat: it removes people an admin decided to remove and detects nothing. A hardware ban means collecting identifiers from players' machines, which players deserve to be told about plainly. It raises the cost of coming back; it does not prevent it.

Party codes

A short code the leader can share, for when an invite is the wrong shape: a Discord call, a friend not on your list yet. The groundwork is done; a code is one column and one endpoint.

Not planned#

  • Anti-cheat. See the decision below.
  • Creating or hosting CS2 servers. Not ruled out forever, but not planned.
  • Mobile apps, a web launcher, tournaments and brackets. Maybe one day. Not promised.

Decisions#

Why things are the way they are, newest first. Each entry is what was decided, why, and what it costs.

2026-09-20 · Server owners bring the servers#

Decided: FLICKED keeps a pool of CS2 servers that owners register themselves. It claims one for a match and releases it afterwards. It does not create, host or destroy servers.

Why: orchestration is an infrastructure product on its own: containers on demand, ports, capacity, cleaning up dead servers. None of it is about CS2. It is also not testable here: orchestration is judged on what happens when a machine dies mid-match or ten matches start at once, and with one VPS none of that could be tried, only hoped for.

What it costs: self-hosters run their own CS2 servers, which is normal for community tooling. The door stays open: provisioning would just be another way a row lands in the pool table, and matchmaking would never notice.

2026-09-20 · MatchZy first, a custom plugin later#

Decided: use MatchZy to run matches instead of writing a plugin first.

Why: it already does match configs, knife rounds, pauses, demo recording and event webhooks. Writing that again would take months and produce something worse. The backend only needs two endpoints.

What it costs: a dependency on MatchZy's config and event format. It is open source and C#, so it can be read, and forked if it stops fitting.

2026-09-20 · No anti-cheat#

Decided: drop the planned C++ anti-cheat.

Why: anti-cheat is specialist and adversarial, and doing it badly is worse than not doing it, because it promises a protection that is not real. The people it is up against work full time on getting past it.

What it costs: cheating is left to the server owner, using community anti-cheat. Honest silence beats a badge nobody should rely on.

2026-09-19 · PostgreSQL in Docker, not XAMPP's MySQL#

Decided: PostgreSQL, run through docker compose.

Why: the leaderboard is a ranking query, and Postgres has window functions and FOR UPDATE SKIP LOCKED for handing out servers without two matches claiming the same one. EF Core's Npgsql provider is the best supported. Self-hosting should be one command rather than a list of installers.

What it costs: Docker Desktop and WSL2 have to be installed before anything runs locally.

2026-09-19 · C# for the backend#

Decided: ASP.NET Core, over Go.

Why: the CS2 side is already C#. CounterStrikeSharp and MatchZy are C#, so a future plugin will be too, and one language means one set of match and player models. SignalR covers live updates later, and EF Core gives self-hosters real migrations.

What it costs: a heavier runtime than Go: containers around 100 MB rather than 20 MB, and higher idle memory on a small VPS.

Rust and Tauri for the launcher#

Decided: Tauri with a React and TypeScript UI, over Electron.

Why: players keep the launcher open while they queue, so it has to be light. Tauri uses the system webview instead of shipping a browser: a download of a few megabytes instead of a hundred. Its native side matters too: the session token can live in Rust and never enter the webview.

What it costs: Rust is the least familiar language in the project, so that side is slower to write, and Tauri's ecosystem is smaller than Electron's.

Writing a new decision#

Keep it short, and be honest about the cost. A decision with no trade-off usually means the trade-off has not been found yet.

docs/ROADMAP.md
## YYYY-MM-DD · Short title

**Decided:** what was chosen.

**Why:** the reason, in plain words.

**What it costs:** what is given up, or who has to do more work because of it.
Esc
↑↓ navigate ↵ open