• CLIENT WORK
  • IN DEVELOPMENT & TESTING

IVPITER: a community website and 5v5 league platform

A community website and real-time league platform for an Italian VALORANT community, built from the client's approved design.

Client
IVPITER, an Italian VALORANT community (named with permission)
Role
Built the site and league platform from the client's approved design
Status
In development and testing
Platform
Web
Links
None

The problem

IVPITER ran its community and its in-house 5v5 league mostly on Discord, through a bot. It needed a real website (roster, news, staff, careers, sponsors and contact), and the league itself (queue, check-in, captains' draft, map veto, results, ratings and moderation) had to move onto the site. The community has no game API key of its own, so verified identities and match results had to come from a partner service through a privacy-preserving contract.

What I built

I built a Next.js / React / TypeScript site with plain CSS Modules from the community's approved desktop and mobile design boards. The public side covers the community, news, events, roster, staff, job applications, sponsors and contact. Forms are protected against spam and post to the staff's Discord channels. In the league app, players sign in with Discord, link a verified game account through vStats Connect, and queue alone or in a party of up to three. Each match room moves through check-in, a captains' duel, a snake draft, map veto and side choice, with live updates in the browser. Results are fetched automatically and feed a skill rating. Staff get an admin panel for seasons, matches and moderation.

Highlights

  1. API CONTRACT

    Privacy-first partner sign-in.

    Both sides of the OAuth 2.0 contract with vStats Connect: authorization code flow with mandatory PKCE, single-use codes that expire in 60 seconds, no refresh tokens, and pairwise identifiers. The community site never receives a player's vStats account ID, email or raw game ID.

  2. ENGINE

    A tested league engine.

    About 28 server-side modules cover the queue, parties, check-in, draft, veto, substitutes, reports, seasons and automatic result checks, with their own test files.

  3. RATING

    Calibrated skill ratings.

    An OpenSkill rating tuned with a simulator and checked against historical results. It caps the change per match and uses a separate display scale, so stored ratings never need migrating.

  4. REAL-TIME

    Live match rooms.

    Server-Sent Events with a snapshot on connect, batched updates, heartbeats, and a limit on open streams per user.

  5. SECURITY

    Careful sessions.

    Random session tokens in HttpOnly cookies, with only their hash stored; same-origin server actions; rate-limited forms; and a token-authenticated bridge to the community's Discord bot.

  6. DELIVERY

    From design to code to deploy.

    Desktop boards were matched at 1440px and mobile boards at phone width, with a screenshot script for comparing pages against the designs. Deploys build the new release side by side while the old one keeps serving, with a health check, automatic rollback and the last 5 releases kept.

How it works

Linking a game account through vStats ConnectSequence between the player, the community site and vStats Connect: authorize with a PKCE challenge, player consent, a single-use code, a server-side exchange with the verifier, and a pairwise ID with verified account data in return, with no email and no internal ID. The list below describes each step.PlayerCommunity sitevStats Connect1Link game account2authorize + PKCE challenge3consentsingle-use code4server exchange + verifier5pairwise ID + verified accountno email, no internal IDLinking a game account through vStats ConnectSequence between the player, the community site and vStats Connect: authorize with a PKCE challenge, player consent, a single-use code, a server-side exchange with the verifier, and a pairwise ID with verified account data in return, with no email and no internal ID. The list below describes each step.PlayerCommunitysitevStatsConnect1Link game account2authorize +PKCE challenge3consentsingle-use code4server exchange+ verifier5pairwise ID +verified accountno email, no internal ID
  1. The player clicks "Link game account" on the community site.
  2. The site sends them to vStats Connect with a PKCE challenge.
  3. The player approves; vStats Connect returns a single-use code.
  4. The site exchanges the code and its PKCE verifier on the server.
  5. vStats Connect returns a pairwise identifier and verified account data, never the player's email or internal ID.

Stack

  • Next.js 16
  • React 19
  • TypeScript
  • CSS Modules
  • Drizzle ORM
  • PostgreSQL
  • Vitest
  • OpenSkill
  • three.js
  • Server-Sent Events
  • OAuth 2.0 + PKCE
  • Discord OAuth & webhooks
  • Caddy + pm2 on a VPS

By the numbers

  • 64test files
  • ~620test cases
  • 33pages + 16 API handlers
  • 30database tables
  • 27migrations
  • 44design boards implemented

Outcome

A complete community site and league platform, now in development and testing with the community. The site is in Italian; the league interface is in Italian and English.

Need something like this? Get a free quote.

Get a free quote

VALORANT and Riot Games are trademarks of Riot Games, Inc. This project is not affiliated with or endorsed by Riot Games.