Portfolio  /  Product  /  2027

Oliver
Seifert

Business Economics and Psychology at UCLA. I founded BetRoyale, a real-money skill-wagering platform, and took it 0 → 1 alone: strategy, spec, design, experiments, fraud rules, and growth.

Oliver Seifert Los Angeles, CA
1,000+
users in the first month
6,000+
matches played
$10k
deposited by real users
35/50
US states cleared
1.9%
CTR on paid social
01  /  Case study

BetRoyale

Two Clash Royale players each post a wager. They get matched, add each other in game, and play a friendly 1v1. Supercell's official API reads the battle log and settles the match automatically. Winner credited, loser debited, money through PayPal. No screenshots, no disputes, no trusting a stranger.

My role

Founder and sole operator. I wrote the vision and the spec, designed every screen and the design system, researched the legal constraints, designed the fraud rules, ran acquisition, and built the QA harness. I directed engineering with AI as the implementation layer and made every tradeoff call myself.

Timeline

Build: concept to live product, solo, while carrying a full course load.
Live: May to June 2026.
Wind-down: I shut it down after identifying a dependency risk tied to a third-party API partner's terms of service. That was a judgment call, not a failure to keep it running.

The shape of the problem

Clash Royale has a huge competitive player base and no sanctioned way to play for money. The blockers weren't technical. They were trust (who confirms who won), liquidity (an empty queue kills the product), and law (skill wagering is legal in some states and not others).

The first decision, which everything hangs off

Skill competition, not gambling

In gambling, chance decides the outcome. Here it's decided by how well you play a game with a ranked ladder and a pro scene. You aren't betting on someone else's match, you're staking your own performance. Legally and psychologically those are different products.

That call set the legal exposure, the addressable market, the brand, and the wording of every button. It also banned casino visuals and any outcome-promise language from the marketing.

Market scoping and the model

I made the market smaller on purpose

I sorted all 50 states into permitted, prohibited, and ambiguous, then treated ambiguous as prohibited. That cost me 15 states including New York, Texas, Illinois, and Pennsylvania, four of the biggest player pools in the country.

Revenue is a fixed take rate on every settled pool, not on losses. So revenue scales with match volume, which pointed the whole roadmap at one thing: more matches per dollar deposited.
02  /  Decisions

Six calls I had to make

Building isn't the interesting part. Choosing what not to build, and knowing what it would cost if you chose wrong, is.

01

Killed automated matchmaking and replaced it with an order book

Problem
Trophy-based automated matchmaking is the obvious design. It's also the wrong one at launch. With a small player pool it either pairs a 7,000-trophy player against a 3,000-trophy player, or it leaves people waiting in a silent queue. Both kill the session.
Decision
I threw out automated pairing and built a peer-to-peer challenge board, closer to a live order book than a matchmaker. Player A posts a wager. Every online player sees it with A's trophy count, league, and record. Anyone can hit Challenge, and A confirms before the match locks.
Why
Three problems, one mechanic. Players self-select fair matchups because they see who they're accepting. No algorithmic mismatches at low volume. And a visible board with real names and trophy counts makes a thin queue feel alive instead of empty.
Tradeoff
Slower time-to-match than an automated system would be at scale, and it needs both players actively looking. I accepted that. Cold start was the real risk, not throughput.
02

Two currencies, so nobody has to pay to find out if they like it

Problem
A real-money product has a brutal first-run problem. To experience the core loop you have to trust an unknown site with your money before you've seen it work once. Most people won't.
Decision
Two currencies with a hard wall between them. Coins are free, 1,000 at signup. Balance is real USD through PayPal. Coins convert into balance at a fixed rate, so free play accumulates real value slowly, but balance never converts back.
Why
A new player can run the whole loop, queue, match, add opponent, play, get settled by the API, see the payout, without spending a cent. The product proves itself before it asks for money, and the compliance friction never touches the fun part.
Guardrail
Currency clarity became a non-negotiable design rule. Coins and balance never share a component, a color, or a number format. Blurring them is the fastest way to turn a skill product into a deceptive one.
03

Took the identity check off deposits and moved every gate to cashout

Problem
The default here is to verify identity before letting anyone put money in. It's the safe-feeling choice. It also puts a document upload in front of the highest-intent moment in the funnel.
Decision
I asked where the fraud actually is. Money coming in is low risk. Chargeback and laundering exposure lives on the way out. So I stripped friction from deposit and stacked every gate on cashout: identity verification, tax info, a 7-day account age minimum, one cashout per 24 hours, a $500 rolling weekly cap, and an automatic block on any account with a chargeback.
Why
Same total risk coverage, applied where the risk is. Friction at the money-in moment costs conversion. Friction at the money-out moment costs almost nothing, because by then the user is motivated and has already had a good experience.
04

Every result is API-settled. No screenshots, ever.

Problem
Every informal wagering community solves "who won" the same way: post a screenshot, argue in Discord, wait for a mod. It doesn't scale, and it produces a support queue that is 100% angry people.
Decision
Results come from Supercell's API reading the battle log, with no manual override path anywhere in the product. I wrote it into the Golden Rules so I couldn't talk myself out of it later under support pressure.
Why
A manual override is a backdoor. The moment one exists, every disputed match becomes a negotiation, and the platform's neutrality is the only thing it's really selling. Removing my own ability to intervene was the feature.
Cost
The API lags about 30 seconds behind a finished match and I can't shrink that. So I treated it as expectation management instead of latency: a status line saying the platform is actively reading the battle log. Silence reads as broken. Narrated waiting reads as careful.
05

Switched payment processors mid-build

Situation
I built the money flow on Stripe first, then moved deposits, payouts, and account linking to PayPal and ripped the Stripe references out of the product and the legal pages.
Criteria
Four things: appetite for a regulated real-money skill product, payout reliability to individuals, whether the brand read as trustworthy to a 16-to-24 audience, and integration cost. PayPal won on trust and payouts, the two that mattered here.
Bonus
It produced a UX win I hadn't planned for. Because deposit links a PayPal account, the cashout screen pre-fills that same account as the destination. Nearly everyone deposits before withdrawing, so withdrawal became a one-tap confirm for almost every user.
Lesson
Rework I chose early was much cheaper than infrastructure I'd have been stuck with. Two weeks of sunk integration work isn't a reason to keep the wrong vendor.
Shipped

What it looked like

BetRoyale matchmaking queue showing open challenges with opponent stats
Queue: the challenge boardCurrency toggle, preset entry tiers, and the live payout above the button. Below, open challenges with each player's tag, trophy count, league badge, and record, so you know exactly who you're accepting.
BetRoyale deposit modal with keypad and quick-pick amounts
Deposit: fewest taps possibleQuick-pick chips for common amounts, a keypad for anything else, and the credited total shown large before the player commits. No identity check stands in front of this screen, by design.
BetRoyale cash out modal showing a readiness checklist of remaining requirements
Cash out: show the gates, don't spring themEvery fraud and compliance gate lives here, so the screen shows a live checklist of what's still blocking a withdrawal and the current value of each. Nobody hits an unexplained wall.
BetRoyale mobile queue screen
MobileThe product lives on a phone next to the game itself, so it ships as an installable PWA. Entry presets, the live payout, and one primary action, all inside thumb reach.
03  /  Analytics & experimentation

The bet-sizing experiment

The clearest analytical problem I had, and the one where the incentives were least obvious. This is the experiment design I wrote, unedited in substance.

The observation

Watching the match and wager tables in SQL, a pattern showed up: a chunk of depositors were staking a large share of their balance on their first real-money match, winning or losing once, and leaving. Deposit, one big match, cash out or churn.

That's terrible for a business whose revenue is a take rate on match volume. A player who makes twenty $1 wagers is worth far more than one who makes a single $20 wager, and they usually have a better time.

The hypothesis

Anchoring the default wager chips to a share of the player's actual balance, adding a confirm step above 25% of balance, and framing stakes as "% of balance / rounds left" would cut the median wager-to-balance ratio by about 25%, concentrated in new and casual players, with no drop in deposits or revenue.

I pre-registered the direction and the kill signal before running it, so I couldn't rationalize a bad result afterward.

Design
AssignmentUser-level, deterministic 50/50 hash on user ID. Not per match, so no one sees both versions.
CohortNew signups only. Bet-sizing habits form on first exposure, and changing the UI under existing users adds noise plus a support spike.
TreatmentThree nudges shipped together: balance-scaled default chip, confirm step above 25% of balance, percent-of-balance framing.
PopulationReal-money matches only. Free-coin matches are a guardrail, not a primary metric.
StoppingFixed N up front, roughly 300 depositors per arm with at least one balance wager. No peeking and stopping.
Metric tree

Primary. Median wager-to-balance ratio per arm. Median rather than mean, because the ratio distribution is right-skewed by a handful of large players.

Secondary. Matches per dollar deposited. Mean real-money matches per depositor. Share of depositors who withdraw after two or fewer matches, the hit-and-run rate.

Guardrails. Deposit conversion must not fall. Revenue per user must not fall. Self-exclusion and deposit-limit hits must not rise.

Significance. Mann-Whitney U on the primary, because the ratio isn't normally distributed. Two-proportion z-test on conversion. Threshold p < 0.05, with guardrails weighted conservatively: a revenue dip that isn't significant is still a yellow flag.

The measurement query I wrote against my own database
-- PRIMARY: median wager-to-balance ratio on real-money matches, by arm
SELECT
  e.metadata->>'arm'                                           AS arm,
  count(*)                                                     AS wagers,
  count(DISTINCT e.user_id)                                    AS users,
  round(percentile_cont(0.5) WITHIN GROUP (
        ORDER BY (e.metadata->>'ratio')::numeric)::numeric, 4) AS median_ratio,
  round(avg((e.metadata->>'wagerCents')::numeric)/100.0, 2)    AS mean_wager_usd
FROM user_events e
WHERE e.name = 'wager_placed' AND e.metadata->>'currency' = 'balance'
GROUP BY 1 ORDER BY 1;
The instrumentation gap I had to close first

The schema didn't store the player's balance at the moment of the bet, which is exactly what the primary metric needs. Reconstructing it afterward from settlement records would have been guesswork.

So before launching I added one event, wager_placed, emitted when a wager locks and before settlement, carrying the arm, the stake, the balance at that instant, and the precomputed ratio. No schema migration needed, because the events table already stored JSON metadata.

The lesson that stuck: you can't measure a behavior you didn't instrument. Deciding what to log is a product decision, and it has to happen before you need the number.
Risks I wrote down in advance
  • Large players barely move. Expect the effect in new and casual users, so segment the read by lifetime deposit size or the signal drowns.
  • Novelty decay. A confirm step is annoying at first and then normal. Read the final seven days separately.
  • Cannibalization. The whole point is more matches at smaller size, so total volume holds or grows. Watch total balance wagered per user, not just per-match size.
Shipping the three nudges produced a 24% lift in repeat play. Worth noting the design above is more rigorous than what a one-month-old platform could fully power, and I'd rather defend the design than overclaim the read.
Stack: PostgreSQL queried directly, Google Analytics 4 for the acquisition funnel, and an internal admin dashboard with a funnel chart, an event table, and user lookup.
04  /  User flow

Mapping every path a player can take

Before building the onboarding and match loop, I mapped the entire journey in FigJam: every screen, every branch, every place a player can fail a check and what happens to them when they do. It's a big board, so it's embedded live. Pan and zoom it here, no Figma account needed.

scroll to pan  ·  pinch or ctrl-scroll to zoom Open in Figma →
Why I mapped it first

A real-money product has more failure states than happy paths. A player can be in an ineligible state, unverified, missing a player tag, missing a friend link, short on balance, mid-match, or blocked from cashing out. Each one needs a defined destination. Drawing it was the only way to find the dead ends before users did.

What the branches encode

The decision diamonds are the compliance and readiness gates: age and state eligibility, email verification, identity verification for deposits, tax info for cashouts. The flow makes it visible that every gate sits on the money path and none of them stand between a new player and their first match.

What it changed

Mapping it surfaced the contextual next-step card. Once you can see every state a player can be stuck in, the obvious fix is a single component that always names the one action that unblocks them, instead of a profile page full of incomplete fields.

05  /  Product requirements

The PRD

The document the product was built from. Below is the part that shows the thinking: what I decided not to do, and what would have told me I was wrong.

BetRoyale, Product Requirements Document
OLIVER SEIFERT  ·  v1  ·  4 PAGES
Download PDF ↓

Non-Goals

  • Betting on other people's matches. Users stake their own performance only. Wagering on a third party's outcome is a different legal product and is explicitly out of scope.
  • Other games. Clash Royale only for v1. The settlement mechanism depends on a public match-history API, and generalizing it before the model is proven adds risk without adding learning.
  • Tournaments and brackets. Higher operational cost, and they don't test the core question, which is whether players will stake money on a 1v1 they'd have played anyway.
  • A public leaderboard at launch. Its value comes from player density, so shipping it into a thin player base advertises emptiness.

Success Metrics

MetricWhy it mattersTarget
Signup to first matchTests whether free coins actually remove the trust barrierUnder 3 min, 60%+ play once
Deposit conversionWhether free play converts into real stakes20% of signups
Weekly wagers per depositing userThe revenue driver, since the fee is per settled poolGrows week over week
Settlement dispute rateValidates the whole API-settlement premiseNear zero

Key Risks, abridged

RiskSeverityMitigation
Platform dependencyCriticalSettlement runs entirely on a third-party API governed by terms the platform doesn't control. Get the platform relationship settled before scaling spend, not after. This risk was underweighted in practice.
Cold startHighA wagering marketplace with nobody in it has zero value to the first user. Peer-to-peer challenge board over automated matchmaking, free starter coins, community partnerships for concentrated early liquidity.
Tilt and problem playMediumUnresolved as of v1. Any retention mechanic aimed at losing players must clear a responsible-gaming bar first, and none proposed so far does. Deliberately left open rather than shipped badly.

Open Questions

  • What is the right fee percentage? It needs to fund the business without making the expected value of playing obviously negative for a good player, which would break the core pitch.
  • Does the double-or-nothing rematch loop increase healthy repeat play, or does it primarily catch losing players? This needs measurement before it gets promoted in the interface.
The full PRD also covers the problem statement and competitive framing (Triumph and UMG Gaming), target users, the core flow, and requirements across onboarding, currency, matchmaking, settlement, money movement, and integrity.
06  /  About

Where the two majors meet

I'm a junior at UCLA, double majoring in Business Economics and Psychology, graduating in 2028. The combination isn't an accident. Economics gives me the incentive model and the analytical toolkit. Psychology tells me why people don't behave the way the incentive model says they should. Product sits exactly in that gap.

Alongside BetRoyale I've worked on financial reporting and KPI dashboards at Lambda Chi Alpha Headquarters, financial management consulting through UCLA's AY Consulting, and I'm joining a UCLA research team on Designing Better AI Tutors.

I'm looking for a Summer 2027 internship in product management, product strategy, analytics, or growth. I'm most useful somewhere I can own a problem end to end rather than a slice of one.

Toolkit

Analysis
SQL, R, econometrics, A/B testing and experiment design, Google Analytics 4, Excel

Product
PRDs and specs, Jira, roadmapping, QA design, competitive and legal research

Design
Figma and FigJam, design systems, mobile-first interface design, PWA patterns

Technical
REST API integration, relational and vector databases, RAG pipelines, PostgreSQL