The brief
An arcade that works on a plane, in a car, and across a table from another person. Offline first, tiny, and playable with someone nearby without either phone touching the internet.
How it is built
A plain activity and a WebView in Java, with no library dependencies at all. No support libraries, no Play Services, nothing that has to resolve from a network at build time. The arcade itself is an HTML and canvas bundle inside the APK: one engine file carrying the registry, router, lifecycle, scores and sound, then one file per game. The 80 menu icons are hand drawn line glyphs, because an icon font would have been larger than the games.
The whole thing is about 224 KB installed.
Nearby play without permissions
Discovery over mDNS through the system service, then a direct TCP socket between the two phones carrying newline delimited JSON. Install time network access only, so there is no runtime permission prompt, no pairing screen and no account.
Two duel shapes cover all 80 games: a move relay for the 21 turn based games, and a score race that deals both phones an identical board and races the results.
The trick that made 80 games multiplayer
While a duel is running, the engine replaces the random number generator with a seeded one. Every game becomes deterministic, both phones generate the same board, and not one of the 80 games needed to know that duels exist.
Testing without two phones
The link layer falls back to a browser channel between two tabs when there is no Android bridge underneath it. That is how every duel path was verified: turn relay, score races, seeded boards, live score sync and the win and lose settle.
Honest limits
All 80 games mount and play with no console errors, and every duel path passes in the two tab harness. The discovery and socket layer has not run on two real handsets yet. That is the first thing to check before this is put in front of anyone.