For the complete documentation index, see llms.txt. This page is also available as Markdown.

Penalty Shootout

Pick your spot, beat the keeper, bank the win streak. Every goal compounds your multiplier, every dive is a fresh Chainlink VRF draw, and you decide when to walk away. Fully onchain.

How it works

Overtime Penalty Shootout is a streak game: one stake, as many kicks as you dare.

  1. You pick a difficulty (Amateur, Pro or World Class), choose where to aim, and take the first kick. Placing the bet and taking the first kick happen in one transaction

  2. The contract requests a random word from Chainlink VRF. The keeper's dive is derived from it: randomWord % zones, one zone out of the difficulty's total

  3. If the keeper dives anywhere other than where you aimed, it's a goal and your running multiplier grows by the difficulty's factor. If the keeper dives to your zone, it's a save: the run ends and the stake is lost

  4. After every goal you choose again: take another kick (at any difficulty) or cash out to take stake × current multiplier

  5. The run continues until you cash out, the keeper saves, or no difficulty fits under the multiplier cap

Where you aim does not change your odds. The keeper covers exactly one zone, chosen uniformly at random, so your chance of scoring is simply the open zones over the total. Your aim is written to the contract in the same transaction that requests the randomness, before the random word exists, so neither your shot nor the keeper's dive can react to the other.


Difficulty levels

Each difficulty narrows the goal. The keeper always covers one zone.

Difficulty
Goal zones
Open zones
Chance to score
Multiplier per goal (2% edge)

Amateur

5

4

80% (4 in 5)

1.225×

Pro

3

2

66.7% (2 in 3)

1.47×

World Class

2

1

50% (1 in 2)

1.96×

You can switch difficulty between kicks. Bank a few Amateur goals and finish at World Class, or open big and play it safe once the multiplier is worth protecting. The game is fixed for the whole run; only the difficulty and your aim change from kick to kick.


The multiplier

Every goal multiplies your running total by the difficulty's factor:

That's the entire pricing model. It makes chance to score × factor = 1 − houseEdge for every difficulty, so each kick carries exactly the same house edge whichever one you pick. At the default 2% edge that's 1.225×, 1.47× and 1.96×. Players never supply odds: a kick is a difficulty and an aim, and the contract looks the odds up and derives the factor itself.

Goals compound:

Goals in a row
Amateur
Pro
World Class

1

1.225×

1.47×

1.96×

2

1.50×

2.16×

3.84×

3

1.84×

3.18×

7.53×

4

2.25×

4.67×

14.76×

5

2.76×

6.86×

28.93×

6

3.38×

10.09×

56.69×

Most before cap

22 goals, 86.89×

11 goals, 69.26×

6 goals, 56.69×

Mixing difficulties gets closer to the cap: the highest reachable multiplier is about 99×.

Because the edge applies to every kick, it compounds across a run. A run you cash out after n goals returns 0.98ⁿ of the stake on average at the 2% edge (about 90.4% after 5 goals, whatever the difficulty). The harder difficulties reach a given multiplier in fewer kicks, so they pay less total edge getting there, in exchange for a much bigger chance of an early save.

The cap. The default multiplier cap is 100×. A kick whose factor would push the multiplier past the cap is rejected, not trimmed: payouts are never silently truncated. Near the cap only the difficulties that still fit are playable (playableTiers), and once none fit, the only move left is to cash out. The house edge and the cap are both snapshotted when you place the bet, so a later parameter change can never alter a run that's already live.


Cashing out

This is the whole game. After any goal your multiplier is locked in as long as you stop. The moment you kick again, you're risking the entire accumulated amount on the next dive.

  • Cash out → you receive stake × current multiplier, the run resolves, done

  • Kick again → a goal grows the multiplier; a save loses everything

There is no partial cash out and no insurance. Reaching the cap does not cash out for you either: winnings are paid only in the cash out transaction, never inside the VRF callback.

Before each kick, the contract checks that the treasury can cover what that kick would owe if you score. If it can't, the kick is rejected before any randomness is requested, and your run stays exactly where it was, cashable at its current multiplier.

Runs don't expire. If a run sits idle after a goal for longer than the core's cancelTimeout, the resolver can settle it for you with adminCashout, which pays exactly what a cash out would: stake × current multiplier. It cannot pay less.


Limits

Parameter
Value

Minimum bet

3 USD (configurable per game via core)

Maximum bet

Bounded by max profit: stake × (cap − 1) ≤ maxProfitUsd. At a 2,000 USD max profit and the 100× cap, about ~ 20 USD

House edge

2% per kick

Multiplier per goal

1.225× / 1.47× / 1.96× at 2% edge

Multiplier cap

100× default, snapshotted per bet

Max kicks per run

200

Push

None: every kick is a goal or a save

Idle run

Resolver may settle it after cancelTimeout at the full stake × current multiplier

Cancellation

Admin/resolver only, intended for a stalled VRF request; refunds original stake, forfeits accumulated multiplier

If the game is paused while you're mid-run, Cash Out is available again as soon as it's unpaused. The resolver's adminCashout is not pause-gated and still pays the full multiplier.

Supported collaterals: USDC, WETH, $OVER. Free bets supported via the isFreeBet flag on placeBet. On a lost real-money run, the referrer's share is paid automatically in the transaction that settles the save.


User guide

1. Open Penalty Shootout

Select Penalty Shootout from the casino lobby. Set your stake and collateral.

2. Pick a difficulty

Choose Amateur, Pro or World Class. The panel shows the payout on a first goal.

3. Aim and shoot

Pick your spot and hit Take the Kick. This places the bet and takes the first kick in a single transaction.

4. Goal or save

When the VRF callback arrives, the keeper dives. Goal: your multiplier ticks up and it's your turn again. Save: the run is over.

5. Shoot again or cash out

Keep the difficulty or change it, and kick again to push the multiplier higher. Or hit Cash Out to bank stake × multiplier.

6. Resolution

Cashing out, or a save, resolves the bet. Your full run is stored onchain and shown in your history: the difficulty of every kick, its factor, where the keeper dived, the result, and your multiplier after each one.


Onchain reference

Penalty Shootout runs on StreakGame, a streak engine on the shared CasinoCoreV2 treasury. Games on the engine are registered modes, each with a fixed set of difficulty tiers validated when they're published. Read getModes() for the live list.

Action
Call

Start a run (bet + first kick)

placeBet(collateral, amount, referrer, modeId, tierIdx, choice, isFreeBet)

Next kick

playRound(betId, tierIdx, choice)

Cash out

cashout(betId)

Difficulties still playable

playableTiers(betId)

Kick-by-kick history

getBetRounds(betId)

Factor for a difficulty

factorForTierE18(modeId, tierIdx)

Penalty Shootout is modeId = 1. tierIdx: 0 Amateur, 1 Pro, 2 World Class. choice is the zone you aim at, from 0 to zones − 1.


Why this matters

A streak game is the easiest game in a casino to rig. The whole product is the question of whether to shoot one more time, and on a centralized site nothing stops the server from making the keeper a little better at reading you exactly when your multiplier gets big. You'd never see it happen.

On Overtime, the keeper can't read you. Each dive comes from a fresh Chainlink VRF request that doesn't exist until your aim is committed onchain. The odds are zones you can count, the factor is a published formula, the house edge is a public variable locked into your bet when you place it, and every kick of every run is reconstructable from the chain. The only thing deciding whether you score is the dive. Which is the entire point.

Last updated