Football strategy without a live opponent requirement.
The game is asynchronous: the active player spends Energy, and the opponent is represented by the latest saved squad from a real wallet.
Game loop
Design principles
Owned NFTs matter. Eligibility and squad strength are based on real on-chain NFT ownership and real metadata attributes.
Strategy stays readable. The player makes meaningful decisions by choosing six NFTs and assigning them to roles, without being forced into a complex tactics screen.
Randomness creates tension. Stronger squads should win more often, not every time.
The game does not alter the NFT. Levels and XP are stored inside RollTheBall only.
Six NFTs become six football roles.
Every NFT can technically fill any role, but the formula rewards correct placement. A defender-like NFT used as a striker should not be optimal.
Required formation
| Role | Count | Primary value |
|---|---|---|
| Goalkeeper | 1 | Goalkeeping, stability, last-line defense |
| Defender | 2 | Defense, tackles, interceptions |
| Midfielder | 2 | Passing, control, pressing, possession |
| Striker | 1 | Accuracy, finishing, headers |
Metadata used
Role fit
Each selected NFT receives a role-fit multiplier from 0.90 to 1.10. The multiplier is based on how well the NFT's actual attributes match the assigned football position. This keeps the game strategic without adding a tactics burden.
The first scoring model.
These formulas are designed as version 0.1: transparent enough for partners, adjustable before production.
Normalize raw NFT values
Base stats are expected in low integer ranges, max stats near 0-100, perks as small decimals, and Alpha Score as a larger integer.
Base(stat) = clamp(stat / 25, 0, 1) * 100 Max(maxStat) = clamp(maxStat / 100, 0, 1) * 100 Perk(perk) = clamp(perk / 0.25, 0, 1) * 100 Alpha(alpha) = clamp((alpha - 250) / 450, 0, 1) * 100
NFT skill ratings
Attack = 0.50*Base(Accuracy) + 0.20*Max(MaxAccuracy)
+ 0.20*Perk(PrecisionShot) + 0.10*Perk(HardHeader)
Playmaking = 0.45*Base(Passing) + 0.20*Base(Control)
+ 0.15*Max(MaxPassing) + 0.10*Perk(FlankPass)
+ 0.10*Perk(ProtectiveHolding)
Defending = 0.45*Base(Defense) + 0.15*Max(MaxDefense)
+ 0.15*Perk(HardTackle) + 0.15*Perk(PassInterception)
+ 0.10*Perk(DefensiveAwareness)Goalkeeping and stability
Goalkeeping = 0.35*Base(Defense) + 0.20*Perk(GoldenGloves)
+ 0.15*Perk(GoalieResistance) + 0.15*Perk(LastStandDefense)
+ 0.10*Perk(GoalieLongBall) + 0.05*Base(Control)
Stability = 0.45*Base(Control) + 0.25*Alpha(AlphaScore)
+ 0.15*average(MaxAccuracy, MaxPassing, MaxDefense, MaxControl)
+ 0.15*RoleFitTeam ratings
AttackRating = 0.62*Striker.Attack + 0.19*Mid1.Playmaking + 0.19*Mid2.Playmaking
MidfieldRating = 0.42*Mid1.Playmaking + 0.42*Mid2.Playmaking
+ 0.08*Def1.Defending + 0.08*Def2.Defending
DefenseRating = 0.34*GK.Goalkeeping + 0.28*Def1.Defending
+ 0.28*Def2.Defending + 0.05*Mid1.Defending + 0.05*Mid2.Defending
Spirit = average(all six Alpha ratings) * 0.60 + average(all six Stability) * 0.40Mini-match simulation
For each of 7 mini-matches:
PossessionDuel = My(MidfieldRating*0.55 + Spirit*0.20 + random(0..25))
- Opp(MidfieldRating*0.55 + Spirit*0.20 + random(0..25))
Chances = 2 + bonusFrom(PossessionDuel) // usually 2-4 chances
For each chance:
ChanceQuality = My(AttackRating*0.58 + MidfieldRating*0.22 + Spirit*0.08 + random(0..20))
- Opp(DefenseRating*0.62 + Spirit*0.08 + random(0..20))
If ChanceQuality > threshold:
Shot = My(AttackRating*0.65 + Striker.Stability*0.15 + random(0..25))
- Opp(GK.Goalkeeping*0.68 + Opp.Spirit*0.10 + random(0..25))
If Shot > goalThreshold: goal += 1Final winner
MiniMatchPoints = win*3 + draw*1 GoalScore = goalsFor - goalsAgainst FinalScore = MiniMatchPoints + clamp(GoalScore, -4, 4) * 0.35 Winner = higher FinalScore
Balance target
A clearly stronger squad should win most Play sessions, but not all of them. Initial target: a squad rated 10% stronger should win about 60-65% of sessions; 20% stronger should win about 72-78%.
Progression is local to the game, not written to the NFT.
Max level is 10. Leveling should feel difficult, and ownership history must be wallet-specific.
Level table
| Level | Total XP required | Estimated sessions per monkey* |
|---|---|---|
| 1 | 0 | 0 |
| 2 | 120 | 18-24 |
| 3 | 330 | 48-66 |
| 4 | 720 | 100-144 |
| 5 | 1,350 | 185-270 |
| 6 | 2,300 | 315-460 |
| 7 | 3,700 | 500-740 |
| 8 | 5,700 | 770-1,140 |
| 9 | 8,500 | 1,150-1,700 |
| 10 | 12,500 | 1,700-2,500 |
*Estimate assumes 5-8 XP per Play session for a monkey that is included in the active squad.
XP earnings
The cap prevents farming loops from accelerating progression beyond the intended curve.
Wallet-specific ownership memory
RollTheBall stores levels using the pair Wallet Address + NFT Mint. If an NFT moves to a new wallet, it starts at Level 1 for that new wallet. If it later returns to a wallet where it had previous progress, that wallet's previous level is restored. The NFT itself is never modified.
StoredProgressKey = hash(walletAddress + nftMint) VisibleLevel(wallet, mint) = progressTable[StoredProgressKey]
Rewards should favor the active player without excluding passive winners.
The active player spends Energy, so the active side receives a larger reward coefficient. The ghost side can still earn when it wins.
Reward formula
BaseResult = win ? 10 : draw ? 4 : 1 GoalBonus = min(goalsFor, 5) * 0.8 UnderdogBonus = opponentRating > myRating ? min((opponentRating-myRating)/10, 4) : 0 ActiveMultiplier = 1.00 GhostMultiplier = 0.75 RTD = (BaseResult + GoalBonus + UnderdogBonus) * SideMultiplier
Example rewards
| Outcome | Active player | Ghost opponent |
|---|---|---|
| Active wins | 10-18 RTD | 0-2 RTD |
| Draw | 4-8 RTD | 3-6 RTD |
| Ghost wins | 1-4 RTD | 7-14 RTD |
Near-term utility
Tournament entry, seasonal league registration, limited training actions, and marketplace-style RTD offers for NFTs.
Anti-inflation controls
Energy limits, reward caps, tournament sinks, optional entry fees, and tuning by season.
Future market layer
Players may offer RTD for NFTs, creating game-native demand around role fit, levels, and squad needs.
Transparent rules before production starts.
This page is intentionally written as a shared agreement document for partners, not as marketing copy.
Eligibility and fairness
- Only wallets holding at least six eligible NFTs can play for RTD.
- Matchmaking targets squads with comparable Team Power and recent performance.
- The same opponent should not be repeated too frequently.
- Saved ghost squads allow gameplay without both players being online.
- Formula changes should be versioned by season.
Non-custodial boundaries
- The game reads public wallet ownership and metadata.
- The game does not request seed phrases or private keys.
- The game does not mutate NFT metadata.
- XP, levels, Energy, and RTD accounting are stored in RollTheBall systems.
- Wallet signatures, if added, should be limited to login verification.
Open parameters before build approval
| Parameter | Draft value | Reason |
|---|---|---|
| Energy interval | 1 per 8 hours | Creates three natural play windows per day. |
| Mini-matches per Play | 7 | Enough variance and narrative without a long session. |
| Max level | 10 | Simple progression ceiling. |
| Level curve | Very slow | Levels become meaningful and cannot be rushed quickly. |
| Entry requirement | 6 eligible NFTs | Keeps the game centered on owned NFT squads. |
| Initial visual scope | Text/data-first | Core value is strategy, ownership, and simulation logic. |