Every promise on this page is something the build refuses to break.
Open Games is free, has no purchases, contacts no third party, and keeps working when the network does not. Those are the reasons to fund it, so each one is a check the build runs — and this page is that build’s output, not a description of it. The numbers below were measured by the same commands anyone can run on the repository.
- pass
The games contact nobody. No font CDN, no analytics, no ad call.
325 built files scanned, 0 third-party request(s) found.
Checked by check:network, on the BUILT bundles - a dependency can emit a request the source never shows.
An <a href> to the project’s own repository is not counted: it fetches nothing until a reader chooses to follow it. Counting those would have reported 13 violations where the honest number is zero.
- pass
The games cannot take money. There is no purchase path to hide.
325 built files scanned, 0 payment integration(s) found.
Checked by check:payments, matching processor hosts and SDK call shapes rather than payment words.
The word “purchase” appears 40 times in these bundles and every one is gameplay - Arena Champions is a MOBA with an in-match item shop. A gate matching words would report 40 violations against an honest zero, so it matches integrations instead.
- pass
Every asset a game loads comes from the game itself.
234 asset paths across 7 games, 0 missing or cross-origin.
Checked by check:selfhosted, resolving every asset path a bundle names against what shipped.
- pass
The games stay small enough for a metered connection, and cannot quietly grow.
First wait 163.5–394.9 KB; full download 343.8–1660.1 KB.
Checked by check:budget, gzipped bytes per game per asset class against committed ceilings.
Game First wait Full download champs 163.5 KB 1660.1 KB gridfall 342.5 KB 343.8 KB kingshot 379 KB 1383.5 KB lastwar 387.1 KB 1326.5 KB ringout 343.4 KB 344.6 KB whiteout 394.9 KB 1213.4 KB wirework 366.8 KB 781.5 KB The audio figure counts both shipped formats though a browser downloads only one, so it overstates what a player pays. A ceiling that over-counts fails safe.
- pass
A game that has been opened once keeps working with no network.
window.__GAME__ present, game.isRunning true, TitleScene active, and the real menu rendered - not the browser's error page. Games probed: whiteout, wirework.
Checked by a real browser driven over the DevTools protocol with the network denied, not an assertion. Re-runnable with scripts/lib/offline-probe.py.
Not measured: kingshot, lastwar and champs have generated workers from the same script but were not probed; only whiteout and wirework were.
Not measured: Deep offline play - reaching a scene whose sprites were never fetched while online. Those are runtime-cached on first use, so an asset never touched while online is still unavailable offline by design.
Not measured: The probe is a maintainer tool, not part of `npm run build`: it needs a live browser, so the build gates the precondition (check:selfhosted) rather than the boot.
Known and not yet done
Subsetting the Korean webfonts to the glyphs actually used.
Measured per glyph, which cancels out how much Korean a game happens to show: champs 484 distinct Korean characters in 1068.7 KB (2261 B/glyph), lastwar 393 in 544.7 KB (1419), kingshot 331 in 492.9 KB (1525), against whiteout 421 in 74.6 KB (182). So champs carries 12.5x, kingshot 8.4x and lastwar 7.8x what whiteout pays for the same job.
No subsetter is available on this host and installing one is not the agent's to do. Checked and absent: pyftsubset, hb-subset, fonttools, woff2_compress and sfnt2woff on PATH; fontTools in system python; any font-parsing package in node_modules. python brotli IS present, but that is woff2 compression only and cannot rebuild a glyph table.
Needs: Approval to install a font toolchain - python3 fonttools with brotli (giving pyftsubset), or the harfbuzz hb-subset binary. `node scripts/font-glyphs.mjs` then prints the exact command per font.
Funding
- server cost
- Zero. The games are static files; multiplayer is peer-to-peer or local-network, so there is no backend to run.
- what is asked for
- Sponsorship and portal revenue share, so the games can stay free with no purchases and no advertising.
- what is not taken
- In-app purchases, advertising, telemetry, and any third-party runtime request.
- terms
- Not settled. Talk to us rather than reading a number here that nobody has agreed.