DEV Community

Cover image for I built a rank platform that starts where Steam achievements end
Voland
Voland

Posted on

I built a rank platform that starts where Steam achievements end

I have loved video games my entire life.
My way of honoring a game was always the same: get 100%.
Every achievement. Every collectible. Every secret.
But after the last achievement popped one day, I felt something
I didn't expect. Emptiness. The game was over. Nowhere left to go.
I looked around. I had done something genuinely hard.
But where could I show it? Nobody cared about a Steam profile screenshot.
So I asked: what if 100% is not the end of a game, but only the beginning?
That question became Pantheon HDS.

How it works
You connect Steam. You get an automatic rank based on your achievement
completion. Then you earn higher ranks by completing community-created
challenges, verified by real judges through anonymous blind voting.

Bronze -> Silver -> Gold   (achievement-based, automatic)
              |
   Complete community challenges
   Verified by real judges
              |
Platinum -> Diamond -> Master -> Grandmaster
              |
           Legend
    Community vote only. Forever.
No money. No algorithms. Just skill.
Enter fullscreen mode Exit fullscreen mode

How it's built

React 19 + TypeScript 5, Vite, TanStack Query v5.
Backend is Supabase: PostgreSQL with RLS on every table,
Edge Functions on Deno for server-side logic.
Deployed on Vercel. Auth is Steam OpenID only.
No passwords. No emails. Steam is already the source of truth
for achievement data, so it made sense to use it for identity too.

Design decisions

Anonymous blind voting.
Judges are assigned randomly. They don't see the player's name.
The player doesn't know who's judging.
No social pressure, no favoritism. Verdicts stay honest.

JWT with server-side revocation.
Tokens live in localStorage. On logout, the token is killed
via an Edge Function. Leaked token after logout is useless.

const handleLogout = () => {
  const token = JSON.parse(
    localStorage.getItem('pantheon_user') ?? '{}'
  )?.token;
  if (token) revokeToken(token); // fire and forget
  localStorage.removeItem('pantheon_user');
  navigate('/');
};
Enter fullscreen mode Exit fullscreen mode

One file owns all rank data.
Tier strings, colors, ordering — all in constants/ranks.ts.
Nothing hardcoded elsewhere. Refactoring rank logic
never turns into grep-and-pray.

export const RANK_TIERS = [
  'Legend', 'Grandmaster', 'Master',
  'Diamond', 'Platinum', 'Gold',
  'Silver III', 'Silver II', 'Silver I',
  'Bronze III', 'Bronze II', 'Bronze I',
] as const;

export type RankTier = typeof RANK_TIERS[number];
Enter fullscreen mode Exit fullscreen mode

Lazy loading gated pages.
Dashboard, Admin, JudgePanel are lazy-loaded.
Visitors who never log in don't pay for that code.

const Dashboard  = lazy(() => import('./components/pages/Dashboard'));
const Admin      = lazy(() => import('./components/pages/Admin'));
const JudgePanel = lazy(() => import('./components/pages/JudgePanel'));

Enter fullscreen mode Exit fullscreen mode

What's live

  • Steam OpenID auth
  • Automatic rank assignment via Steam API
  • Challenge submission and judge voting
  • Anonymous blind voting
  • Admin panel
  • Public profiles at /u/username
  • Playwright E2E + Vitest unit tests

What we will never do

  • Sell ranks for money
  • Use AI to verify Legend rank. Humans only, always.
  • Sell the platform without a community vote

These are the three principles. They don't change.

It's open source

GitHub: https://github.com/pantheon-hds/core
Live: https://pantheonhds.com

If you've ever gotten 100% in a game and wondered "now what?" —
this was built for you.

Top comments (0)