Silly steam backlog random game chooser
  • Elixir 98.1%
  • CSS 0.7%
  • JavaScript 0.5%
  • HTML 0.4%
  • Dockerfile 0.3%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Jeremy Knope b638df39bb
All checks were successful
CI / test (push) Successful in 36s
chore: 2.0.3
2026-08-01 17:39:22 -04:00
.claude feat: xbox support, library & playtime & roulette 2026-07-30 14:19:17 -04:00
.forgejo/workflows ci: fix CI by using less ancient debian 2026-07-14 14:34:26 -04:00
assets Buddy Roulette: multi-user Steam backlog roulette 2026-07-14 09:11:32 -04:00
config feat: review in played modal - fixes #16 2026-07-31 09:59:34 -04:00
docs chore: docs for psn/xbox investigation 2026-07-15 16:16:06 -04:00
lib fix: allow removing of steam users who haven't logged in 2026-08-01 17:39:13 -04:00
priv fix: allow removing of steam users who haven't logged in 2026-08-01 17:39:13 -04:00
rel/overlays/bin Add Dockerfile, release tooling, and CI build workflow 2026-07-14 10:05:04 -04:00
test fix: allow removing of steam users who haven't logged in 2026-08-01 17:39:13 -04:00
.dockerignore Add Dockerfile, release tooling, and CI build workflow 2026-07-14 10:05:04 -04:00
.formatter.exs Buddy Roulette: multi-user Steam backlog roulette 2026-07-14 09:11:32 -04:00
.gitignore Buddy Roulette: multi-user Steam backlog roulette 2026-07-14 09:11:32 -04:00
AGENTS.md Buddy Roulette: multi-user Steam backlog roulette 2026-07-14 09:11:32 -04:00
airlock.toml feat: xbox support, library & playtime & roulette 2026-07-30 14:19:17 -04:00
Dockerfile ci: fix CI by using less ancient debian 2026-07-14 14:34:26 -04:00
mise.toml chore: mise task for release 2026-07-15 10:23:16 -04:00
mix.exs chore: 2.0.3 2026-08-01 17:39:22 -04:00
mix.lock fix: performance improvements, cache libraries in db & avoid hammering 2026-07-14 16:04:52 -04:00
README.md feat: wishlist comparisons 2026-07-15 09:17:56 -04:00

Buddy Roulette 🎲

Compare Steam libraries, find the games everyone owns but nobody has really played, and let fate pick your group's next game night. Works solo too — load a single library to roulette your own backlog.

A Phoenix LiveView app grown out of the single-file backlog-roulette.html experiment. Because all Steam API calls happen server-side, no CORS proxies are involved.

How it works

  1. Add Steam profiles to the roster (SteamID64, custom URL name, or a full profile link — vanity names are resolved and persona names/avatars fetched automatically).
  2. Select one or more profiles — one loads that player's own backlog, two or more compares their libraries.
  3. Use the playtime slider to keep only games nobody in the group has played past the cutoff.
  4. Optionally require macOS support, SteamOS/Linux support, and/or full controller support (any combination). Platform data comes from the Steam store's appdetails endpoint and is cached in the database, since that endpoint is rate-limited and only answers one app per request.
  5. Spin the roulette.

Each profile's game details must be public (Steam → Edit Profile → Privacy Settings → Game details).

Wishlists

The Wishlists page compares the roster's Steam wishlists the same way: pick profiles, see the combined wishlist with current store prices and sale discounts, filter to games on sale / on everyone's wishlist / under a price cap, sort by discount, price, name, or recency, and let fate suggest the group's next purchase. Wishlists and prices are cached in the database and refreshed automatically a few times a day (a private wishlist just shows up empty — wishlist visibility follows the same Steam privacy settings).

Setup

Requires Elixir 1.20 on Erlang/OTP 29 — exact versions are pinned in mise.toml, so with mise installed the right toolchain activates automatically.

You need a Steam Web API key — get a free one at steamcommunity.com/dev/apikey. One key works for looking up anyone's public library.

mix setup
STEAM_API_KEY=yourkeyhere ALLOWED_STEAM_IDS=76561198000000001,76561198000000002 mix phx.server

Now visit localhost:4000.

Profiles are stored in a local SQLite database; the API key is only read from the STEAM_API_KEY environment variable (see config/runtime.exs).

Authentication

The app is invite-only: visitors sign in through Steam (OpenID via Überauth), and only SteamID64s listed in the ALLOWED_STEAM_IDS environment variable (comma-separated) may enter. When it's unset, nobody can sign in. The allow list is re-checked on every request, so removing an id locks that account out immediately. The same STEAM_API_KEY is used to fetch the signed-in player's persona name and avatar.

Tests

mix test

Tests stub the Steam API via Req.Test — nothing hits the network.

Deployment

Pushes to main build and push a container image via the Forgejo workflow in .forgejo/workflows/build.yml. The Dockerfile builds a standard Phoenix release that runs pending migrations on boot (bin/migrate && bin/server) and listens on PORT (default 4000).

The container needs:

  • SECRET_KEY_BASE — generate with mix phx.gen.secret
  • STEAM_API_KEY and ALLOWED_STEAM_IDS — see above
  • PHX_HOST — the public hostname
  • DATABASE_PATH — the SQLite file, on a persistent volume; single-writer, so run exactly one replica (e.g. a Recreate deployment strategy)