Skip to content
FLICKED Docs

Getting started

Configuration

Every setting the backend reads, what it defaults to, and what breaks when it is wrong. Most deployment problems are one of three addresses.

Where settings come from#

The API is a standard ASP.NET Core app, so any setting can come from appsettings.json, the environment, or the command line. On top of that it reads a .env file: it looks in the content root and up to two parent folders, and uses the first one it finds.

  • Next to the binary in production, for example C:\flicked\api\.env or /opt/flicked/api/.env.
  • backend/.env in development, found by walking up from the project.
  • Environment variables win. A key already set in the environment is skipped when .env is read. In the environment, write : as __, for example Api__PublicUrl.

The three addresses#

Nearly every deployment problem is one of these being wrong, and each fails quietly rather than loudly. Each is read by a different program on a different machine, which is why none of them can be localhost in production.

graph LR
    browser["A friend's browser"] -->|"Steam:PublicUrl"| api["Flicked.Api :5165"]
    launcher["Launcher"] -->|"FLICKED_API, compiled in"| api
    cs2["CS2 server + MatchZy"] -->|"Api:PublicUrl"| api
    api -->|"RCON"| cs2

Who reads which address

SettingRead byIf it is wrong
Steam:PublicUrlA player's browser, signing inSign-in sends them back to their own PC
Api:PublicUrlThe CS2 server, fetching a match configThe server fetches nothing and stays on its old map, with no error anywhere
FLICKED_APIThe launcher, compiled in at build timeThe launcher looks for FLICKED on the player's own machine

Backend reference#

Network and URLs#

KeyDefaultWhat it does
Steam:PublicUrlrequiredThis API as a browser reaches it. Steam redirects back here after sign-in. Sign-in throws if it is missing; development sets it to http://localhost:5165
Api:PublicUrlfalls back to FLICKED_API_PUBLIC_URL, then Steam:PublicUrlThis API as a CS2 server reaches it. Sent to the server over RCON as the config URL and the event endpoint
Dashboard:Urlhttp://localhost:3000Where the dashboard runs. Added to CORS by name, and used for the dashboard's sign-in redirect. Alias FLICKED_DASHBOARD_URL
urlslocalhost onlyThe interfaces Kestrel listens on. Use http://0.0.0.0:5165 to be reachable directly, or http://127.0.0.1:5165 behind a proxy

Identity and secrets#

KeyDefaultWhat it does
STEAM_API_KEYnoneReads names and avatars from Steam. Free from steamcommunity.com/dev/apikey. Alias Steam:ApiKey
FLICKED_ADMIN_STEAM_IDSnobodyComma-separated SteamID64s allowed into the dashboard. Checked on the server on every request. Alias Admin:SteamIds
DataProtection:KeyPath<content root>/keysThe folder holding the keys that encrypt stored RCON passwords. Alias FLICKED_KEY_PATH. Back it up

Database#

KeyDefaultWhat it does
ConnectionStrings:FlickedrequiredThe Npgsql connection string. Development points it at the Docker database
Database:AutoMigratetrueApply EF Core migrations on startup, so a self-hoster upgrades by replacing a binary. Set to false to run migrations yourself

Matchmaking#

KeyDefaultWhat it does
Matchmaking:CompetitivePlayers10Players in a full Competitive match. Set to 2 to test with one other person
Matchmaking:WingmanPlayers4Players in a full Wingman match
Matchmaking:MinCompetitivePlayerssame as fullThe smallest Competitive match worth starting when nobody else turns up. Equal to the full size means off
Matchmaking:MinWingmanPlayerssame as fullThe same, for Wingman
Matchmaking:ShortHandedAfterSeconds20How long the longest-waiting party waits before a short match is tried

Short-handed matches

For a small community that cannot reliably find ten people, set a minimum and the matchmaker will, after the wait, form a 4v4 or 3v3 out of whoever is queueing, largest first. A full match is always tried first, so a short match is never formed around players who could have had a real one.

.env
Matchmaking:MinCompetitivePlayers=6
Matchmaking:MinWingmanPlayers=2
Matchmaking:ShortHandedAfterSeconds=20
  • Matches are always even. A minimum of 5 or 7 is read as 6 or 8, and nine people waiting become one 4v4 plus one player still in the queue. 5v4 is not a match worth starting.
  • A party can still be too big. Party size is capped at half a full match. A five-stack on an instance with a minimum of 6 can only ever play a full 5v5, because six seats split 3-3 and a party is never split.

Build-time settings#

These are baked into a build. Changing them means rebuilding and redistributing.

VariableUsed byWhat it does
FLICKED_APILauncherThe API address, compiled into both the Rust side and the webview so they cannot disagree. Unset means http://localhost:5165
NEXT_PUBLIC_API_URLDashboardThe API address the dashboard calls

Dashboard runtime#

VariableTypical valueWhy
PORT3000The port the standalone Next.js server listens on
HOSTNAME0.0.0.0 or 127.0.0.1Next binds to localhost otherwise. Use loopback behind a proxy

A complete example#

A production .env for a single VPS serving plain HTTP. For HTTPS behind Caddy, see Deploy on Linux.

C:\flicked\api\.env
ConnectionStrings:Flicked=Host=localhost;Port=5432;Database=flicked;Username=flicked;Password=<db-password>

# This machine as the outside world sees it. Never localhost.
Steam:PublicUrl=http://<vps-address>:5165
Api:PublicUrl=http://<vps-address>:5165
Dashboard:Url=http://<vps-address>:3000

# Listen on every interface, not just localhost.
urls=http://0.0.0.0:5165

STEAM_API_KEY=<your-steam-web-api-key>
FLICKED_ADMIN_STEAM_IDS=<your-steamid64>
DataProtection:KeyPath=C:\flicked\keys
Esc
↑↓ navigate ↵ open