Hartii Biome docs

Games

Hartii Games

Hartii Games is a neon-dark, eleven-game skill arcade at hartiigames.com. Free play is always available, and a daily challenge opens every day. Ranked play is designed to stake a small USD-priced amount (paid in QUAI) into a per-game, on-chain prize pool. The pool contracts exist, but no game takes a paid entry in 1.19.0. A sibling read-only dashboard, Biome, aggregates live numbers from Games plus the other Hartii products.

The games

Eleven games are on the roster, in the order the lobby grid shows them.

GameIdGenre
Hex Breakerhex-breakerBrick Breaker
Gravity Flipgravity-flipOne-Button Runner
Orbit Lockorbit-lockOrbital Dodge
Pulse Snakepulse-snakeModern Snake
Shatter Stackshatter-stackFalling Blocks
Nova Stormnova-stormBullet-Hell Survival
Flux Hopflux-hopAuto-Platformer
Neon Driftneon-driftLane Drifter
Alien Siegealien-siegeAlien Shooter
Piano Keyspiano-keysRhythm / Piano
Blade Pongblade-pongSolo Pong

One list in the code, apps/hub/src/games-registry.js, feeds the lobby, Boards, the SEO pages and Biome. Every count the site prints, such as "eleven", is derived from it. The server keeps a matching list (ACTIVE_GAME_IDS in functions/api/_lib/gameRoster.js), and a test fails if the two differ.

What changed in 1.19.0

  • Alien Siege and Piano Keys are back, on rules v2 (Season 2). Their 1.18.0 rules are kept byte for byte as rules v1 (Season 1), so every old replay still verifies. Neither game has a prize-pool contract, so both are free play and daily only.
  • Hash Wars is removed from the roster. It has no tile, no page and no sitemap entry, and its client code is not in the bundle. /games/hash-wars and everything under it answers 301 to the lobby (apps/hub/public/_redirects). A #/play/hash-wars link falls back to the lobby. An old replay link, #/watch/<run>, shows "This game is offline for now." instead of playing. Its simulations, its season entry and the server-side replay check stay as an archive, so old runs still verify.

Architecture

npm workspaces, one repo (hartii-games):

  • apps/hub: the site itself. Vanilla JS + Canvas 2D, no framework. src/main.js is the hub shell and src/games-registry.js is the one list of games. Each game lives at games/<name>/{game.js,sim.js} behind a shared games/_shared/shell.js contract between the hub and the game code.
  • apps/biome — a separate static site + three tiny read-only Functions (functions/api/chain.js, ecosystem.js, prices.js), deployed on its own (hartii-biome Cloudflare Pages project) at hartiibiome.com. It holds no wallet-signing or money logic of its own — that stays on hartiigames.com.
  • packages/engine — deterministic core: seeded RNG, replay record/verify. Determinism is a hard product invariant here: the same {seed, input log} must reproduce the same score everywhere, so a server-side replay can verify a client's claimed score without trusting the client.
  • packages/arcade-sdk: wallet + chain interaction. Its src/hbome.js reads the HBOME balance and holds the Shop's checkout call, which stays unused until an HBOME marketplace is configured.
  • workers/settlement — score verification and payout math for the monthly settlement job.
  • contracts/ — Hardhat project: one prize-pool contract per game, plus a small token/sale/ cosmetics/marketplace stack.
  • functions/ — Cloudflare Pages Functions (api/) backing the hub.

Live URLs

Hub (games, ranked play, profile)hartiigames.com
Public API basehttps://hartiigames.com/api/
Biome (read-only ecosystem dashboard)hartiibiome.com

The lobby

The home page is a compact mobile-game lobby. The code is apps/hub/index.html and apps/hub/src/main.js, with no framework.

  • Top bar. A slim bar with the wordmark (it goes back to the lobby), the QUAI price (wide screens only), the HBOME balance chip and the wallet button. The HBOME chip appears only when a wallet is connected. It shows the balance from GET /api/token/hbome/:wallet, and the whole chip links to the HBOME page on HartiiLabs.
  • Today's daily row. A countdown to 00:00 UTC, when the shared daily seed changes. An "S2 live" chip shows while every game on the roster is on the same season. A counter shows how many of today's dailies this browser has played, such as "3/11", and the daily streak when the wallet has one. The played marks live in this browser's local storage.
  • Game tiles. One button per game, each with a small live preview. The previews share one animation loop at about 30 frames a second, only paint tiles that are on screen, and stop while the tab is hidden. With reduced motion on, each tile is a still frame. The grid has 3 columns, 4 from 720 pixels wide and 6 from 1000 pixels, inside a column no wider than 1100 pixels.
  • Navigation. Four destinations: Play, Boards, Shop and Me. Under 900 pixels wide they are a dock fixed to the bottom of the screen. From 900 pixels they are a tab row in the top bar. Me opens a sheet. The other three change the route.
  • Mode sheet. Tapping a tile opens a sheet (a bottom sheet at 720 pixels and under) with the game's name, its genre and season, a short description and three buttons: Play free, Daily challenge and Leaderboard. Ranked never appears there. It could only show for a game in the paidGames list from GET /api/config, and that list is empty.
  • Boards. Four tabs: Monthly, Free, Daily and Activity. Ranked tabs appear only while paid play is on for at least one game.
  • Footer. One line of links: Transparency, Terms, Privacy and Docs. Studio is no longer linked from the lobby.

The cinema hero, the scrolling ticker, the QuaiAxe event banner and burn counter, the HARTII chip and its buy window, and the dailies strip are gone from the home page. The monthly leaders moved to Boards, and the token champions moved to the Shop.

The hub routes on the URL hash:

HashShows
#/The lobby
#/play/<id>A game
#/watch/<runId>A replay
#/leaderboardsBoards
#/shopThe Shop

One launch, one game. Setting location.hash already fires hashchange, which routes. Until 1.18.0 the Play free, Daily and stake flows then called the router a second time, so every launch mounted its game twice. The first copy kept its game loop, music and key listeners running under the second, and a daily could start as a free run. A single helper, goPlay(id), now navigates once. See Versions.

The Shop and HBOME

The Shop (#/shop) sells cosmetic skins, and they never change gameplay. The site uses HBOME (HartiiBiomeInc) as the Hartii token. Its facts are in the contract map. The Shop prices skins in HBOME only. The old Games HARTII token has no purchase path on the site.

  • Champions are free. HRT, QUAIBOSS and QAXE are built-in skins. Wearing one needs no wallet and is remembered in the browser.
  • Skins come from GET /api/cosmetics/catalog. A wallet that owns a skin can equip it. Equipping is a signed message, not a transaction.
  • Prices are in HBOME. Each sellable rarity has a US dollar list price, and the HBOME amount is meant to come from that price and an HBOME/USD quote. No quote source exists yet, so the HBOME amount shows as a dash next to the dollar price. The catalog's own price field is the old HARTII price, and the Shop never reads it.
  • Buy is disabled. The Shop says "HBOME checkout opens soon". Buy turns on only when GET /api/token/config returns an hbome.marketplace address (set from the HBOME_MARKETPLACE setting) and the skin has a listing there. No marketplace address is configured today.
  • Earned exclusives stay earn-only. A skin of the Exclusive rarity (today the Champion Crown) is never priced or sold. Its tile says "Earn only" and its button says "Not for sale". A wallet that owns one can still equip it.
  • Market tab. Lists the existing player listings. Players can no longer buy from them or list new ones. A seller can still cancel their own listing.

Data flow

Free play: a game's sim.js runs entirely client-side against a shared daily seed; the score is posted to /api/play/track and lands on a KV-backed leaderboard. No chain interaction.

Ranked play (see contracts and api for exact mechanics). Paid entry is off in 1.19.0, and no game takes it. This is the designed flow, not something a player can do today:

  1. Client requests a price quote for a stake tier, pays it as a plain QUAI transaction straight to that game's MonthlyGamePayouts pool contract (enterRanked() or a bare transfer).
  2. Client calls POST /api/ranked/enter with the tx hash; the API verifies the transaction on-chain (destination, sender, value within a tolerance band of the tier's USD quote at the current QUAI price) and, if it checks out, issues a fresh deterministic run seed.
  3. Client plays the run against that seed and calls POST /api/ranked/submit with the recorded input log and claimed score; the server replays the run itself with the same seed and compares scores — a mismatch is rejected, never trusted from the client.
  4. Once a month, the owner (a manually-signed, non-automated wallet) reviews the off-chain verified leaderboard and calls setMonthlyWinState() on each game's pool contract to allocate the prize split as per-winner claimable balances.
  5. Winners pull their own payout with claimPayout() — the contract never pushes funds to anyone, so no single winner's misbehaving address can block the others' payouts.

Biome: its three Functions simply re-fetch and cache public data from Games, Gallery and Labs (and MEXC/the Quai RPC directly) server-side and re-serve it — it originates nothing.

Seasons

Since 1.18.0, free and daily leaderboards are kept per season. A season is one version of a game's rules, called its rules version. Scores set under different rules never share a board.

  • Season 1, classic rules. Every score set under the classic rules stays on this board, unchanged. It is the archive.
  • Season 2, current rules (rules v2). All eleven games on the roster run rules v2. Nine moved in 1.18.0: Hex Breaker, Blade Pong, Pulse Snake, Shatter Stack, Nova Storm, Neon Drift, Flux Hop, Gravity Flip and Orbit Lock. Alien Siege and Piano Keys joined in 1.19.0. New free runs, Play Again and the daily challenge use these rules and post to the Season 2 boards, which start with no scores. What changed in each game is listed in Play Hartii Games.
  • Season 3, Alien Siege only (rules v3, since 1.23.0). The ship fires only while you hold Space, the mouse button or a finger on the screen; before, it fired on its own. Alien Siege's free runs and daily challenge use rules v3 and post to the Season 3 boards. Its Season 1 and Season 2 boards stay as archives. See Play Hartii Games.
  • Hash Wars left the roster in 1.19.0. Its one season is rules v2, and its old boards stay readable through the API as an archive. The site no longer offers its practice rules (v3 to v5), which never had a leaderboard.

The server reads the season from the run's seed (<kind>-<game>-v<N>-…; a seed with no -v<N>- token uses the game's classic rules) and replays the run under those rules before the score counts. Ranked seeds carry no version token, so ranked entry stays on each game's classic rules. Paid ranked entry is separate from seasons and is currently switched off (see Live contracts).

Where the switcher is. Tap a game's tile and choose Leaderboard, or open Boards and tap a game's card on the Free or Daily tab. In the board, buttons above the scores switch season: S1 · archive and S2 · now. The board opens on the current season. A game with one season shows no switcher. Ten roster games have two seasons, and Alien Siege has three (S3 · now). Over HTTP the same choice is the season parameter of GET /api/leaderboard/:game; see Seasons in the API.

Live contracts (Quai mainnet, Cyprus-1)

Addresses read from wrangler.toml/contracts/deployed.json, confirmed live via quai_getCode.

Prize pools — one MonthlyGamePayouts deployment per game:

All ten were confirmed live (non-empty quai_getCode) when this table was written, and 1.19.0 changes no contract. No game takes a ranked entry in 1.19.0. The list of paid games (PAID_GAME_IDS in functions/api/_lib/gameRoster.js) is empty, GET /api/config reports paidGames: [], and GET /api/pools has no pool to show. The global switch (PAID_PLAY_ENABLED) is "false" in wrangler.toml, so POST /api/ranked/enter and POST /api/ranked/prepare answer 503 first. With the switch on they would answer 403 for every gameId, because the list is empty. Free play is unaffected.

There are ten pools for eleven games. Alien Siege and Piano Keys never had a pool. Hash Wars was the only paid game, and it left the roster in 1.19.0. Its pool stays deployed and stays in the settlement list, so an unsettled period can never be stranded. Prizes that were already settled can still be claimed from the Me sheet.

Legacy HARTII and cosmetics contracts:

ContractAddressRole
HartiiToken0x00356B9bc20Ea80C654D77655Da53ca07547c216Fixed-supply ERC-20 from the original Games economy (legacy). The Shop does not sell or price skins in it. The Hartii token is HBOME, see the contract map
HartiiSale0x00483bE6EAaA8015130b216e06d8f70723dF822DLegacy QUAI → HARTII sale at an admin-set rate. The site no longer links to it
HartiiCosmetics0x007fDe17CbA1Fe1750906F08f64fEf44195702eAERC-1155 cosmetics, won as tournament editions. Its own buy still takes HARTII (legacy); the Shop prices skins in HBOME
HartiiMarketplace (cosmetics)0x0034D51cc6162E27bCfDce5E276d92Eb563bb73CLegacy peer-to-peer resale of cosmetics, priced in HARTII. The site only lets a seller cancel a listing

All four were confirmed live when this table was written, and 1.19.0 changes none of them. Cosmetics never affect gameplay, a product rule stated directly in the repo's AGENTS.md.

Since 1.19.0 the site has no HARTII purchase path. There is no buy-HARTII button and no HARTII balance chip. A skin cannot be bought with HARTII. Nothing can be bought or listed on the HARTII market, though a seller can still cancel a listing. The HARTII-burn display name and the paid daily retry are gone from the page too. Skins are priced in HBOME instead (see The Shop and HBOME). The server still records HARTII play-reward entries, but no rewards contract is deployed (GET /api/claimable/:wallet returns rewards: null), so nothing can be claimed and the Me sheet's Claim button does not show.

See contracts for the full MonthlyGamePayouts interface and trust model, and api / integrate for the HTTP surface and code examples.

Biome

hartiibiome.com is a small, separate, read-only static site (apps/biome) that shows live cross-product numbers — QUAI/USD price, chain stats, and an "ecosystem" summary that fans out to Games, Gallery and Labs' own public endpoints server-side. Its wrangler.toml states its scope directly: "Biome serves its own three read-only Functions. Wallet signing/pinning remains on hartiigames.com; do not inherit Games money configuration or bindings here." That line is about Biome's own Functions (still three, still read-only) — it has no contracts and no write endpoints of its own, see api for its routes. The HartiiBiome Analytics page (1.22.0) adds GET /api/analytics, GET /api/analytics/traffic and the page-counting beacon POST /api/t, which is switched off until the project turns counting on. Four pages on the site are a separate layer: HPAY (formerly PayLink), the Hartii Airdrop (beta), the Hartii OTC Link and the Hartii Claim (beta) sign transactions directly from the visitor's own wallet straight to a mainnet contract, with no Biome backend involved in the send at all.

Biome's arcade room and its Hartii Games product page list the same eleven games as the hub, in the same order. A Biome test imports the hub's roster and fails the build if the two differ. Biome's Hartii Games product page and its product summaries no longer mention ranked play or prize pools, because no game takes a paid entry.

Games2.0.0 money safety hold

Wallet-associated free submissions now require consent over the exact replay. Durable D1 accounting atomically enforces replay uniqueness and twenty five-HARTII grants per UTC day. These grants remain held until a reviewed clean UTC cutover with all legacy writers retired. Anonymous no-wallet practice remains available and earns no wallet grant.

Studio mint/create APIs and clients are temporarily held before burns, minting or artwork side effects while actual minted-token artwork identity is repaired. Existing vouchers and immutable contracts are not revoked by this producer hold. The stricter free API and held Studio writes are a major compatibility change.

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.