CODEXARENA
◢ docs // v1.0

CODEX ARENA // docs

// Everything you need to understand how CODEX ARENA pulls Codex Pets from the wild, scores them, matches them, and throws them into the arena. No magic. Just deterministic math and a tiny authoritative server tick.

00 //

Overview

CODEX ARENA is a four-layer stack:

  1. 1 Ingest — a scheduled job mirrors the public codex-pet-share feed into our database every ~10 minutes.
  2. 2 Derive — a pure function (computeStats) turns each pet's public metadata into four 1-99 battle stats.
  3. 3 Account — signing in spins up an in-app Solana wallet, drops 5 free starter pets in your collection, and starts tracking your points/wins.
  4. 4 Codex Arena — rooms run a host-authoritative simulation and sync state to everyone via Supabase Realtime broadcast.
01 //

Data source

Every pet on CODEX ARENA originates from codex-pet-share, the public community archive of pets hatched inside the Codex desktop app (shipped by OpenAI in May 2026). We do not generate new pets — we mirror what's already public.

Sync interval~10 minutes
TransportHTTPS pull, signed snapshot
De-dup keypet.id (stable)
Retentionindefinite, append-only
PIInone — owner display name only
⚠ noteCODEX ARENA is unofficial and not affiliated with OpenAI. We never modify sprite data or owner names.
02 //

Sprite format

Codex Pets ship as a single PNG spritesheet. CODEX ARENA reads the metadata header and renders any frame on the fly via CSSbackground-position animation — no canvas, no JS tweens.

Layout9 rows × up to 8 columns
Rows (animations)idle · waving · running · running-right · jumping · waiting · failed · review · happy
Cell sizevariable per pet (typ. 64–96 px)
FPS8 (uniform)
Loopalways (except failed → freezes last frame)

The renderer (PetSprite) is dumb on purpose: it sets CSS variables and lets the browser composite. That's how 100+ pets can animate on the same page without dropping a frame.

03 //

Stat engine

Every pet has four stats in 1..99: PWR, SPD, DEF, STA. They are 100% deterministic — the same pet always yields the same numbers. No DB writes, no RNG.

◇ Inputs

likeCountpopularity → punch
downloadCountbattle-tested → defense
viewCountendurance of attention → stamina
displayName.lengthshorter = snappier → speed
pet.id (FNV-1a hash)deterministic ±10 jitter per stat

◇ Formulas

// diminishing-returns curve, 0..1
curve(n, k) = 1 - 1 / (1 + n / k)

// per-stat jitter from FNV-1a hash of (id + seed), in ±10
jitter(seed) = (hash01(id + seed) - 0.5) * 20

power   = clamp(20 + curve(likes,     8) * 75 + jitter("p"))
speed   = clamp(25 + (1 - min(name,24)/24) * 60 + salt*20 + jitter("s"))
defense = clamp(20 + curve(downloads, 6) * 70 + jitter("d"))
stamina = clamp(20 + curve(views,    40) * 75 + jitter("e"))

overall = round((power + speed + defense + stamina) / 4)

◇ Why diminishing returns?

Without a curve, a pet with 9000 likes would crush a pet with 90 likes by 100×. The curve() function squashes huge counts into the top of the 0-1 range, so a pet with 8 likes still gets ~50 % of max PWR, and a pet with 800 likes gets ~99 %. The k constants (8, 6, 40) calibrate each stat's "how much is enough" threshold.

◆ infoStats live in src/lib/pet-stats.ts. The function is pure — feel free to fork the math, just don't expect your fork to match official CODEX ARENA battles.
04 //

Account & starter pets

Most of CODEX ARENA is browseable without an account, but to create rooms, submit pets, claim starters, or buy from the shop you need to sign in at /auth (email + password, or Google). The same account follows you across the site and is the owner of your pets, points, and in-app wallet.

Sign-inemail + password or Google OAuth
First logincreates wallet + grants 5 free starter pets
Starter petsreal entries from the archive (never placeholders)
Backfillif your collection is empty on a later visit, starters are re-granted
Profile/profile shows pets, total power, points, wins, SOL
◆ infoStarter pets roll a rarity from common · common · common · uncommon · rare — so most are common, but you can get lucky on day one.
05 //

Wallet (SOL)

Every account gets an in-app Solana wallet generated server-side on first login. The keypair is encrypted at rest and only used to pay for actions inside CODEX ARENA — there is no external signing flow, no browser extension required.

NetworkSolana mainnet-beta
Addressshown on /wallet, with a deposit QR code
Balance sourcelive RPC query (cached briefly)
Spendingcurrently the shop only — 0.02 SOL per pet
Withdrawalsnot exposed in the UI yet
⚠ noteDon't deposit more than you're willing to spend on pets. The wallet is a fun in-app feature, not a custody product.
06 //

Shop & rarities

The shop at /shop mints a random pet straight into your collection. Payment is debited from your in-app wallet — no external wallet popup.

Price0.02 SOL per pet
Poolthe live archive (same pets you see in /gallery)
Rarity rollweighted: common · uncommon · rare · epic
Stat boostcommon +0 · uncommon +8 · rare +15 · epic +30
Ownershipstored on your profile, usable in any room

The boost is added to the pet's derived stats when it shows up in your collection — so a rare Goku hits harder than the same Goku in the public archive.

07 //

Rooms

There is no automatic matchmaker. You either create a room or join one from the lobby at /play. Rooms are stored in the database so anyone with the code (or browsing public rooms) can drop in.

  1. 1 Sign in and pick a pet from your collection.
  2. 2 Hit Create public room (listed in the lobby) or Create private room (code-only).
  3. 3 Share the 4-char room code (e.g. R7K2) — friends join via the lobby or by pasting it.
  4. 4 The room creator becomes the host and runs the authoritative simulation for everyone in the room.
  5. 5 Round starts when the host launches it. Last pet standing wins; the winner gets points credited to their profile.
◆ infoNo CPU bot fill, no Elo, no MMR. If a room only has one player, it's a one-pet sandbox until someone else joins.
08 //

Codex Arena engine

The arena runs a fixed-step host-authoritative loop. The host client steps physics, resolves combat, and broadcasts snapshots; other clients send inputs and render the latest snapshot.

Tick rate~30 Hz
Arenafixed 16:9 plane, no scroll
PhysicsAABB collision + gravity, no rotation
Combatmelee on overlap, knockback ∝ attacker PWR
HP scalingderived from DEF
Move speedderived from SPD
Jump impulsederived from SPD
Attack cooldownshorter at high SPD
Recoverypassive HP regen scaled by STA
Win conditionlast pet alive, or top HP at time-up
◆ infoAll four stats matter. A glass-cannon (high PWR / low DEF) wins short trades; a tank (high DEF / STA) wins attrition.
10 //

Ranks

The leaderboard at /leaderboard (linked as ranks in the header) sorts every account by total points, with wins shown alongside.

Pointsearned by winning rounds
Winscount of rounds you finished in 1st place
Tie-breakwins, then most-recent activity
Resetnever — it's a lifetime board
11 //

FAQ

Do I need an account to play?

To browse the archive and read docs, no. To create rooms, claim starter pets, submit a pet, or buy from the shop, yes — sign in at /auth.

Where do my starter pets come from?

They are 5 random real entries from the archive, picked the first time you sign in. They roll a rarity (mostly common, sometimes uncommon or rare) which adds a flat stat boost.

What is the in-app wallet for?

It pays for shop purchases (0.02 SOL per pet). It's a real Solana mainnet wallet generated for your account; the address and a deposit QR live on /wallet.

Can I submit my own pet?

Yes — sign in and head to /submit, then paste the pet's codex-pet-share URL. After a quick review it appears in the archive and is playable in the arena.

Why does my pet have weird stats?

Stats are derived from public engagement (likes, views, downloads) and the pet's id/name. A brand-new pet starts low and climbs as it gathers attention. Pets bought from the shop also get a flat rarity boost.

Are stats ever recalculated?

Yes — stats are computed on read. Whenever the underlying counts change in the next sync, the stats update automatically.

How does ranking work?

Win a round in the arena, get points. The /leaderboard page sorts everyone by total points. There is no MMR or season reset.

end of transmission // /docs v1.0