QuaiAxe docs

QuaiAxe

Arena

The Arena is a match of three players. Every match is run by an online match server, which simulates the fight and decides the result. Your browser only sends your controls. Weekly-pool and Instant matches are on this site. Practice against two bots is available on the Arena page and on hartiigames.com.

Practice

  • Practice is you against two bots, starts at once, and needs no wallet.
  • There are no free online matches. Online matches are paid and run only on this site: the Weekly pool is ranked by week, while Instant settles each match on its own. Practice never reaches a ranked result or a prize.

Two modes

The Arena page has a mode switch. Both modes use the same three lobbies and the same match.

InstantWeekly pool
Entry5,000 / 15,000 / 40,000 QAXE5,000 / 15,000 / 40,000 QAXE
ContractQaxeInstantArenaQaxeArenaPot
Who is paidThe winner of the match claims 2.7x the entry (90% of the three entries). QuaiAxe gets 9% and Hartii 1%.The top ten of the week, paid by QuaiAxe in QAXE
StandingsNone: each match settles on its ownWeekly, best single match counts
Unmatched ticketRefund after 24 hoursNever expires; no refunds

Lobbies

LobbyEntry
L15,000 QAXE
L215,000 QAXE
L340,000 QAXE

In the Weekly pool each lobby is its own weekly competition. Every entry and every prize is paid in QAXE.

Instant

  • You enter one lobby in QAXE and play a three-player match.
  • The winner presses Claim 2.7x your entry. The contract pays 90% of the three entries to the winner, 9% to QuaiAxe and 1% to Hartii. Losers receive nothing back.
  • My unclaimed wins lists wins that are still waiting to be claimed. The page looks them up with every unresolved ticket secret this browser holds, with no wallet signature. It sends bounded batches of 12 and merges the answers; completed ticket history is capped, unresolved tickets are not.
  • My open tickets shows tickets that have not been used. If a ticket is still unsettled 24 hours after entry, its payer can press Refund.
  • Instant has no weekly standings. The winner's claim is signed by the match server, and the contract checks that signature, so only a real result can be claimed.

Weekly pool

The Weekly pool works as before: your best single match of the week sets your rank, and QuaiAxe pays the top ten from its own wallet. See Prizes.

How to enter a match

  1. Pick a mode and a lobby: L1, L2 or L3.
  2. Confirm that you are 18 or older and eligible. There is a checkbox. No birth date is collected.
  3. Connect your wallet. The page only uses the Cyprus-1 network.
  4. Confirm the wallet prompts. There is no message signing.
    • With the QAXE in your wallet: at most two prompts. Approve (skipped when your allowance already covers the lobby; the amount is exact, never unlimited) and enter.
    • With a QUAI buy-in: three prompts. Buy, approve, enter. The page quotes the QAXE curve (0x004Bc407903A51506bcF0b1aB423958c5991c237) and HartiiSwap (router 0x006B3450cca780066A3A8aA8b508103d25315Ea4), buys exactly the QAXE you need on whichever needs less QUAI, with slippage protection.
    • Immediately before every actual wallet method, the page rechecks the same provider connection, Cyprus-1 chain 9 and the originally selected Cyprus account. If any changed after an estimate, earlier prompt or receipt wait, that next request is not made. Transaction objects still omit chainId.
  5. Your entry counts after one block. You do not wait for more confirmations.
  6. The page opens an animated waiting lobby while the chain confirms: the steps, the block height, the seconds elapsed, the players waiting and a Quaiscan link. When your ticket is ready it joins the queue by itself.

Your ticket secret

Each entry makes a random 32-byte ticket secret in your browser. The entry carries keccak256(secret) as its nonce, and the match server proves the ticket is yours by checking the secret you send when you join. The page stores the secret in your browser before the first wallet prompt. It never leaves your browser except to join a match. Back it up: the Instant page has a Back up secret button that copies the ticket as text. Without the secret, an Instant ticket cannot win a claim, and clearing your browser data loses it. Tickets made before 1.22.0 still join with the older signed message.

If the wallet returns no hash

Some wallets close or fail after a request without returning a transaction hash. The page does not guess and does not send twice. It stores the wallet's nonce, balances and the expected effect before each request, plus the exact sender, target, calldata and native value, then reads the chain: "Checking the chain...". A hash-less buy always stays on the manual hold, because a byte-identical buy in another tab cannot be distinguished from the original request. For approval and entry, the flow continues only after it finds that exact request at the snapshotted paying nonce (or a later nonce if another tab used the first) and reads that transaction's receipt. An unrelated incoming QAXE transfer, allowance change or stale nonce reply never clears the hold. Clear and re-check is the player's explicit override; the page does not decide that nothing was sent on its own.

Instant Claim and Refund use the same exact-transaction rule. Before the wallet opens, the browser saves the pending nonce, block and exact request bytes. If no hash comes back, a retry first checks the ticket: only explicit Settled or Refunded state ends the action; a missing/not-yet-visible ticket does not. Otherwise the page can recover the exact claim/refund transaction and its own receipt. If proof is still unavailable, that win or ticket row changes to Clear and re-check. Pressing it is an explicit override for that one nested hold only; it preserves the signed claim and ticket secret.

Your ticket is good for one match in its lobby. It waits in the queue until three players are in. A ranked match prefers three different IP addresses, so one person cannot fill a match with their own wallets while others wait. Players who share an IP address (the same Wi-Fi or mobile carrier) are seated together once each of them has waited 20 seconds (SAME_IP_GRACE_MS). One wallet never takes two seats. In the Weekly pool a ticket never expires and there are no refunds; if a match cannot start, its tickets go back to paid and wait again.

Queue behaviour (1.23.1 and 1.23.2)

  • The queue keeps going on its own. While three or more players wait, the match server checks every 5 seconds, so a group sharing one network is seated as soon as the 20 second wait ends.
  • The waiting number is live. "N of 3 players waiting" follows the server's count whenever someone joins or leaves, the same figure /lobbies reports.
  • A lost queue connection rejoins by itself (up to 5 tries, same ticket) on Pooled and Instant. When a phone tab returns to the foreground or the network comes back, the page pings the queue at once and replaces a socket that does not answer. A queued connection that stays silent for 180 seconds is dropped.
  • Few players online. The waiting lobby shows "N more players needed" and a Copy invite link button that opens the same lobby on /arena/?lobby=.... No bots are added to paid matches.
  • A ticket stuck as matched is healed. If a match that no longer exists left your paid ticket marked as matched, it is released when you join and you are queued. A ticket whose match is still being played answers ticket_in_match.
  • A match server problem keeps your seat. The server sends a notice (storage_unavailable or match_unavailable), pauses pairing 10 seconds and retries. Only six failures in a row end the wait with an error.
  • Instant tickets near the limit. An Instant ticket that reaches 5 minutes before its 6 hour join limit is dropped from the queue with ticket_stale; it stays refundable on chain after 24 hours.

Instant security and recovery (1.23.5–1.23.7)

  • A match is not playable until its replay and claim index is durable. The match room may be created first, but no player receives a room token until the three tickets and match id are stored. If that write fails, all three seats and secrets stay queued, the page shows storage_unavailable, and the tokenless room expires by itself.
  • The chain monitor never jumps over an old backlog. Its five-minute cron reads the next contiguous range of at most 5,000 blocks and advances only to that range's end after alerts are delivered. A larger backlog is caught up across later runs.
  • Claim discovery lasts as long as the signed claim. Match ids are stored in bounded per-wallet UTC-hour buckets for the Match Durable Object's 48-hour claim lifetime. The Worker still reads the older 20-match format during the upgrade. Secret-proved lookups use at most 12 proofs per request; the older wallet-signed recovery route pages at most 12 candidates at a time.
  • The browser keeps unresolved tickets. The 60-ticket cap now applies only to completed history. Continued play no longer evicts an open ticket's entry key, nonce or secret before it is claimed or refunded. Clearing browser storage can still destroy these local records, so the copyable backup remains important.

Player names

Arena names are Hartii usernames when you have claimed one. A wallet linked to a username shows as that name plus a number, for example ibo_1, ibo1 or ibo+1 (Games/Biome 1.44.0). Without a claimed or linked name, the page shows the short wallet. Link a wallet on your Biome profile; the standings API returns the name in each row's name field.

Lobby popup

Every page on quaiaxe.com except the tracker, and every page on hartiigames.com, shows a small popup when someone is waiting in a lobby, for example "1 player in Arena L1 · 5,000 QAXE — Join". Join opens the Arena with that lobby selected. The counts come from the public lobbies feed. When the feed cannot answer, the popup shows nothing.

Watching live matches

Anyone can watch a running match on quaiaxe.com (added in QuaiAxe 1.23.0). Watching is free, needs no wallet and cannot change a match.

  • Live now. The Arena page has a Live now list: one card per running match with the lobby, the three names, how long ago it started, the number of watchers and a Watch button. The list refreshes every 5 seconds while the tab is visible. With no running match it says so and links to the lobbies.
  • 2 second delay. Spectators see a match about 2 seconds after it happened, so nothing a spectator does or says can help a player. The view shows a LIVE badge with the delay.
  • Cameras. Action follows the closest fight, 1 / 2 / 3 follow one fighter, Overview shows the whole arena. Keys: 1, 2, 3 follow a fighter, 0 overview, A action, B broadcast mode, Esc leave. The view also has a scoreboard, a kill feed, and an end screen with the final placements and Next live match.
  • Broadcast mode. Add ?broadcast=1 (or press B) for a clean 16:9 view with the page chrome hidden, meant for screen recording.
  • Deep link. /arena/?watch=<matchId> opens a match directly (/tr/arena/?watch=<matchId> in Turkish). A match that is over or not live says so.
  • Limits. At most 50 watchers per match and 3 watch connections per IP address per match.
  • Nothing private is shown. Spectators never receive the seed, player tokens, ticket secrets, entry ids, claims or wallets. Names are the same labels the players see. Spectating covers Weekly pool and Instant matches alike.

Spectator API

Public and read-only, on the match server https://quaiaxe-arena.hartii.workers.dev.

GET /live returns the running matches (cached for 3 seconds):

json
{ "asOf": "<ISO time>",
  "matches": [ { "matchId": "<64 hex>", "queue": "t50", "label": "L2",
                 "mode": "pooled", "players": ["name", "name", "name"],
                 "startedAt": "<ISO time>", "tick": 0, "spectators": 0 } ] }

matches: null means the list is unknown right now (it is never a made-up empty list). mode is pooled or instant. No entry id, token, seed, wallet or IP appears in it.

wss://quaiaxe-arena.hartii.workers.dev/watch/<matchId> is a read-only WebSocket (browser origin allow-list applies). It is refused before the upgrade with 404 not_live (waiting, finished or unknown match) or 429 spectators_full / too_many_connections. Frames, server to client:

FrameContent
{type:"spectate", matchId, queue, mode, players, tickRate:60, snapEvery:3, engine, delayMs, spectators}First frame: public facts only
{type:"snap", tick, state}The engine snapshot, every 3rd tick, delivered delayMs (2000) late
{type:"end", matchId, ticks, logDigest, results:[{slot, label, placement, kills, damage, survivedTicks, hpLeft, score}]}Final result, then the socket closes (1000)
{type:"error", code}A cap tripped inside the socket; the socket closes (4429)

The client may send only {"type":"ping"} (answered with {"type":"pong"}). Any other frame closes the socket (4405) and never reaches the match.

How to win

  • A match is three fighters. Each fighter is scored at the end of the match:
    • Placement: 1st = 1,000 points, 2nd = 500, 3rd = 0.
    • 200 points per kill.
    • Damage dealt, in points.
    • One point per whole second survived.
  • Your weekly ranking is your best single match score in that week. Playing more matches does not add up; only your best one counts.
  • Ties go to the wallet whose best match ended earlier.
  • A week runs from UTC Monday 00:00 for seven days. The standings are final 10 minutes after the week ends.

The live standings come from the Arena API, which the Arena home on hartiigames.com reads.

Where the money goes

  • All Arena money is QAXE. Players hold QAXE, or buy it with QUAI when they enter. The entry amount is paid in QAXE to QaxeArenaPot.
  • The pot pays QuaiAxe and Hartii. Each time the pot holds 200,000 QAXE or more, it pays 99% to the QuaiAxe wallet and 1% to Hartii, both in QAXE. Anyone can trigger that payout once the pot is at 200,000 QAXE. QuaiAxe or Hartii can trigger it for any balance.
  • QuaiAxe pays the prizes in QAXE. The contract does not pay prizes.
  • The recipients, the 1% fee and the 200,000 QAXE threshold are fixed in the contract. There is no owner, no admin withdrawal, no pause and no way to change them.
  • Native QUAI sent to the contract is refused. Only an enter call counts as an entry.

The retired QUAI pot, QuaiAxeEntryPot (0x00192b4027C644A0F651A2586B62A6be5EF090B6), took no entries and is no longer used. See contract reference.

Details, functions and events: contract reference (QaxeArenaPot).

Prizes

QuaiAxe pays the weekly prizes in QAXE from its own wallet. The contract does not pay prizes.

  • 90% of each lobby's weekly entries go to the top ten:
RankShare of the week's entries
130%
218%
312%
49%
57%
65%
73.5%
82.5%
91.5%
101.5%
  • Of the rest, 1% of every entry is Hartii's fee (paid by the pot) and QuaiAxe keeps about 9% after paying the prizes.

The Arena API returns each lobby's entry count in QAXE, its prize pool in QAXE and the top ten.

Fairness rules

  • The server runs every match. Clients send only inputs. The server runs the same deterministic engine that the page uses and writes the results. Results cannot be edited from the browser.
  • Each seat is one ticket. One ticket is used for one match, and a ticket can produce one result.
  • Disconnects do not cancel a result. A player who disconnects keeps standing in the match, and the match completes and counts.
  • Practice does not count. Practice never reaches the weekly standings or the prizes.
  • The 1% fee, the 99% split and the threshold are fixed in the contract.
Quai Network mainnet · chain 9 · Cyprus-1. Figures marked "read on" a date were read from the chain that day; re-read before relying on them.