Doozer Games' second game, built only from what Doozer knows about real places near a town, and the TV home that lets a room move between games. How a question stays true and fair, and what the data taught.
v2.2.681 (Oct 26 2026). The rooms and relay under it: Doozer Games rooms and relay.
includes/doozer-tv-home.php): a splash once per visit, then"What are we playing?" with a tile per game. The room is open from the first second, so people join while the room decides. The remote's arrows and OK choose, or any phone taps a game (pick). The TV then opens /tv/<game>, a real navigation, so Back (the app walks its history) returns to the menu and Back again leaves.
is on, so the code never changes between games. Players come along by themselves: the new page does not know them, answers their next message with who, they rejoin, and the welcome says which game this is (game: menu | zen | trivia | four | reversi). Before navigating, the TV tells phones {t: 'game'} so they show "Opening Town Trivia" instead of a stale screen.
assets/js/doozer-tv-room.js(players, colors, nickname dedupe, away and leave, the code card, the remote as a local player) and includes/doozer-tv-chrome.php (the same glass, card and version stamp as Zen). Zen keeps its own room code, tied to its gardens.
includes/doozer-pad.php): the menu tiles, the Zen touchpad, orTown Trivia's screens, chosen by the welcome.
Choose a town (a phone searches the cities table or taps "Use where I am", which only finds the nearest town and is not kept; the remote picks from towns Doozer knows well; the last town comes back first), then Start. Ten questions, 20 seconds each, four answers, locked in on tap. A right answer scores 500 plus up to 500 for speed. The reveal marks the answer, shows each option's fact (reviews, stars, miles, kind), a sentence and the source, and the phone links to the place's Doozer page. The final ranks everyone; play again (new questions, same town) or change town. Scores live only in the room. The remote is a player too (arrows choose, OK locks in).
includes/doozer-trivia.php)No model writes a question. Five kinds, each a comparison the data can settle: most Google reviews, highest rated, which kind of place, which street, closest to a landmark.
domains row; the reveal links there), open(OPERATIONAL), reviewed. elks.club (retired) and vague kinds (organization, lodging, nonprofit) are out. Two places sharing a name (two of a chain) are both out: an option must be unambiguous.
and 30+ reviews each; closest needs 0.7x the next distance.
primary_niche alone. GOTCHA (found inthe first live round): "Upstate produce" was filed as self-storage because Google lists storage before market and grocery_store; the reveal would have said so. Now a kind counts only when Google's types agree, and a place Google files in two families sits out of kind questions.
wrong answers come from another family and carry none of the target family's types.
(Cibo e Vino Ristorante is a restaurant; "Discount Liquors" for liquor store is a giveaway). For pharmacy the name is required: Google files dollar stores as pharmacies, and locals know.
landmarks or answers (a single point inside a forest is not "where it is").
ix_latlng) and kept six hours in the tempdir; a round is deterministic for its seed and costs no query.
Data is served at doozer.games/trivia/towns (?q=, ?near=lat,lng, ?popular=1) and /trivia/round?town=&seed=. GOTCHA: never under /api/ on any host: index.php claims every /api path for its own API before a domain's routes run.
A 1-on-1 game sits on the winner-stays rule instead: Winner stays.
A new game is a TV page at /tv/<game> using DZRoom.start({game}), a tile in doozer-tv-home.php, a screen in the phone page keyed by welcome.game, and any new phone intent added to both relay allowlists (grPhoneMsg in includes/games-relay.php and phoneMsg in the Worker). Until the allowlist ships, the live relay silently drops the new message (it did for pick, Oct 26).
Related: Doozer Games and Doozer Shop, Niche Matching and Discovery, The Observed World.