Arena player progression: XP/level cap (5), feature unwrapping, onboarding UX #299
Labels
No labels
agent:fix_bugfix
agent:fix_conflicts
agent:fix_security
agent:gap_analysis
agent:implement
agent:open_issues
agents
agent:security_audit
agent:verify
area
timecurve
arena
arena-v2
audit
block:feature_review
block:security
bug
contracts
design
devops
docs
documentation
enhancement
epic
feature
frontend
indexer
low priority
megaeth
operations
ops
performance
QA
qa checklist
referrals
removal
security
smart-contracts
tech-debt
testing
time-arena
timecurve
visual-qa
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
code/yieldomega#299
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Introduce player progression as a primary Arena pillar: cap levels at 5, gate podium mechanics behind level unlocks (“unwrapping”), surface XP/level prominently in the UX, and tune first-buy onboarding so two starter buys teach the loop and reach level 2.
Parent epic: #238. Related: #250 (XP math), #265 (buy-path XP), #268 (first-buy CRED), #256 (unified
/arena).Current codebase
Onchain (
TimeArena)ArenaXp.sol: charm maps to 1–10 XP per buy; level thresholdsmin(20 + (L-1)*5, 100); uncapped level via_cachedLevel+xpTowardNext(#265)._finishBuyextends all four podium deadlines (_extendOtherPodiumTimers), updates Time Booster totals, Defended Streak, WarBow BP, and may plant/cancel flags — no per-player gating today.plantWarBowFlag; buys from a new leader cancel pending flags immediately (_maybePlantWarBowFlag).FIRST_BUY_CRED_BONUS = 150e18scheduled inepochFixedCredBonus[lastBuyEpoch+1](#268); not tuned for “second buy free + level 2” onboarding.level(user),xp(user),xpToNextLevel(user).Frontend
WalletProfileXpSection); not a primary/arenahero element.arenaBuyProjectedEffects.ts) assumes full mechanics (timer, streak, WarBow BP, flags) for every connected wallet.Indexer
level/xp(#255); nounlocked_featuresorfeature_tutorial_seenpersistence yet.Product spec
docs/product/arena-v2.mddocuments uncapped XP and all-four-podium buy side effects.Why this is needed
New players currently land in a fully unlocked arena: one buy moves four independent timers, WarBow scoring, streak logic, and flag PvP simultaneously. XP/level is a secondary stat buried in the wallet modal.
Progressive unwrapping teaches mechanics one podium at a time, reduces early cognitive load, and makes leveling a core retention loop. Capping at level 5 gives a clear mastery arc. First-buy CRED tuning ensures the onboarding path is self-funding through level 2 without whale assumptions.
Note: Prize DOUB routing to all podiums regardless of unlock state is specified in the companion issue (100% epoch-weighted podium funding). This issue covers player-scoped buy effects and UX only.
Constraints & guardrails
TimeArena(not UI-only). Indexer/frontend are derived.featureTutorialSeen, etc.) must be append-only for upgrade safety.lastBuyEpochroll must not reset level,xpTowardNext, or lifetimexp(#250).applyXpGain; max 5 level-ups per buy (#265).MAX_PLAYER_LEVEL = 5; XP may still accrue but level stops at 5 (define overflow behavior: bank XP vs discard — recommend bank for future cap raises).buyWithCredparticipates in XP/level and first-buy bonus per #268; level gates apply equally.Level unlock matrix
plantWarBowFlag; buys can cancel/replace pending flagsUntil level 5: player buys must not cancel or replace
warbowPendingFlagOwner(other players still can).Locked UI copy:
Locked until Level {N}+ lock icon on gated controls/sections.Mechanic popover: On first unlock (or help
?button), show a modal/popover explaining that feature’s rules (reuse play-skill copy where possible:skills/play-active-time-arena,skills/play-time-arena-warbow).First-buy onboarding (tune constants)
Goal: First buy ever (per wallet,
buyCount == 0before increment) grants enough bonus CRED to afford a second buy at the same CHARM, plus ~10% headroom, and two buys at the recommended starter CHARM yield ≥ 20 XP (level 2 threshold).Current: fixed
150 CRED(#268).Recommended direction:
0.99e18or product-chosen default on/arena).FIRST_BUY_CRED_BONUS(or formula:credBurn(firstBuyCharm) * 1.10) so claimable CRED covers secondbuyWithCredat same charm + 10%.xpForCharm(starter) * 2 >= xpToAdvance(1)(20 XP); adjust starter charm hint or bonus XP event if needed (prefer charm/CRED tuning over special-case XP grants).verify-cred-buy-anvil.shand invariants §268.Relevant files
TimeArena.sol,ArenaXp.sol,ArenaPodiumTimerConfig.solTimeArena.t.sol,ArenaXp.t.solArenaSimplePage.tsx,ArenaSections.tsx,ArenaTimerChips.tsx,ArenaWarbowHeroPanel.tsx,arenaBuyProjectedEffects.ts,arenaXpMath.ts,WalletProfileModalSections.tsxarena_wallet_stats.rs,api_arena.rsarena-v2.md,arena-views.md,invariants-and-business-logic.mdverify-cred-buy-anvil.sh,verify-wallet-profile-anvil.sh,e2e-anvil.shRecommended solution direction
Contracts
MAX_PLAYER_LEVEL = 5inArenaXp; clamp inapplyXpGain/levelview.function _playerLevel(address) internal viewand branch_finishBuy:_trackLastBuyer(always)._extendOtherPodiumTimersfor cat 1 only (not all secondary podiums at once)._processDefendedStreak._applyBuyWarBowBp._maybePlantWarBowFlag.warbowSteal/warbowActivateGuard/warbowRevengeat level ≥ 4.LevelUp/FeatureUnlockedevents for indexer + UX (optionalXpGainedenrichment).FIRST_BUY_CRED_BONUSper onboarding math.Frontend
/arena(level badge, progress bar to next level, XP gained on buy toast).FeatureMechanicModal— localStorage or indexer-backed “seen” + first-unlock trigger.level).Indexer
level,xp_toward_next, optionalunlocked_levelon wallet stats.POSTnot needed — persist tutorial seen client-side unless cross-device required.Acceptance criteria
levelcapped at 5 onchain and mirrored in frontend/indexer.Locked until Level N./arenaview without opening wallet profile.buyWithCredrespects same gates and XP cap.INV-ARENA-PROGRESSION-*rows.buyCountwallets: define migration (grandfather full unlock at level 5 ifbuyCount > 0or recompute level from XP — product decision, document in issue/MR).Test plan (functional paths)
forge test --match-contract ArenaXp+ newTimeArenalevel-cap testsforge test --match-test test_level_*_gates_timersinTimeArena.t.solforge test --match-test test_level_*_warbowbash scripts/verify-cred-buy-anvil.sh(extend assertions)npm run typecheck && npm run lint && npm testarena.spec.ts/anvil-arena-*.spec.tsarenaBuyProjectedEffects.test.tscases per levelcargo test+verify-wallet-profile-anvil.shbash scripts/e2e-anvil.sh(mock wallet; level state via Anvil impersonation / pre-seeded buys)Test plan (attack / abuse / edge vectors)
buy(plantWarBowFlag=true)at level < 5test_level4_buy_plant_flag_revertsTimeArena: level(or equivalent)_finishBuybuyCount/ first-buy keyed to address; no reset on hard-resetbuyWithCredstill levels; no double-dip on DOUB routingnonReentrantpreservedlevelfor tx building_disableInitializersVerification criteria (merge gate)
cd contracts && forge testcd indexer && cargo clippy --all-targets -- -D warnings && cargo testcd frontend && npm run typecheck && npm run lint && npm testbash scripts/verify-cred-buy-anvil.shbash scripts/verify-wallet-profile-anvil.shbash scripts/check-doc-anchors.shbash scripts/e2e-anvil.shmarked as related to #238
marked as related to #300
mentioned in commit
71dc5a157bmentioned in merge request !441
mentioned in commit
a49b3dfb21mentioned in commit
377e3a881fmentioned in issue #304
mentioned in merge request !460
mentioned in commit
9d384bf7f1mentioned in merge request !475
mentioned in commit
6dda90975bmentioned in merge request !479
mentioned in issue #331
mentioned in merge request !504