- The voting thumbs are twice the size. They are tapped on a phone, quickly, in the gap between questions — so they are sized to be hit rather than to be tidy. The tap target around each one is larger again, because a target the same size as its glyph is one you miss.
- The tally grew with them. A small number beside a large thumb reads as a mistake rather than as a count.
DiddlySquawk player
The phone and browser app: join a room by code, pick an avatar, answer questions.
- The category list is centred. It was also 800 pixels tall inside a space that already had a size of its own, so on any phone shorter than that it ran off the bottom — and something running off the bottom cannot be centred in anything. A short list now sits in the middle and a long one still scrolls.
- The clock waits three seconds before it appears. A number ticking in the corner from the instant a question goes up is the thing you watch instead of the question. It keeps counting while it is out of sight, though — the service is timing the question either way, and a clock that says twenty when seventeen are left is worse than no clock at all.
- And it is three-quarters see-through. It still goes yellow and pulses under five seconds, which is when a clock has something worth saying.
- Clearing the room code now puts the button back to "Join Room". It used to clear the code and leave the button reading "Change avatar" — offering to change your animal in a room the screen no longer showed you being in.
- And it actually leaves the room. Flipping the button back without telling the service would be the same contradiction from the other side: the television would still show you sitting there and still wait for your answers, while this screen offered to join somewhere. Clearing the code is now the way out, and says so when you are in a room.
- The clear button is twice the size. It is a target you reach for on a phone, mid-game, usually in a hurry.
-
Two browser tabs were one player. Opening the player a
second time took the first one's place instead of joining beside it. The
session id was kept in secure storage, which on the web is localStorage
— and localStorage belongs to the browser, not to the tab. So the second
tab read the first one's id, asked the service to restore that session,
and got it. The id is now kept in
sessionStorage: one per tab, and it still survives a reload, which is what the restore is actually for here. Two different browsers were never affected. - "The game was terminated by player: " ended at the colon. The host is a television and has never typed a name, so there was nothing to put after it — and the host is not a player anyway. The message now reads "The host ended the game", or names the player when it was one.
- The category list never appeared. The service sends "the game is starting" and the list of categories in the same breath. The app moves to the game screen on the first, so the part that shows the list was still being built when the list arrived — and a message goes only to whatever is listening at that instant. It was dropped every time, on every game.
- What changed. The app now holds on to the last message for the handful of things that describe a state rather than an event, and hands them over to a screen that arrives late. Only state: "these are the categories" is still true a second later, where "somebody answered" is not, and replaying that would be worse than missing it.
- Removed a read that was one server change away from breaking every game. The countdown handler bound the opening tagline as a value that could not be absent, on a line whose only use had been commented out for as long as it existed. The service stopped sending that tagline — it was old copy, and it was overwriting the host screen's instructions — and this would have thrown the moment it did.
- Tapping the rooster goes back to the site — what people already try with a product's own logo.
- It asks first if that would abandon something. Mid-game it says the others will carry on without you; in a room it names the room. Leaving tells the room on the way out, so the television stops showing an avatar for somebody who has gone. Navigating away is not undoable, and doing it silently for a mistaken tap would be a poor trade for a shortcut.
- It says so when the room disappears. A room can close under a player — an admin shuts it down, the host leaves, it goes idle — and the app carried on showing a lobby it was no longer part of. A notice now names the reason and offers the two useful answers.
- Try again counts down from fifteen and retries on its own, so a room that comes back is rejoined without anybody watching the screen. A retry that fails says why and starts the clock again rather than leaving a dead dialog up.
- Try another room clears the code, puts the cursor back in it and turns the button back into Join Room.
- An ✕ beside the room code clears it and focuses it — faster than four backspaces when somebody reads the number out wrong.
- It notices when the service goes away. A red band across the top says so and keeps saying so until the connection is back. Before this the socket dropped silently: the app carried on looking healthy, and a question could be answered into nothing with a small corner icon as the only clue.
-
The app is called Diddly Squawk. Flutter writes its
MaterialApp.titleinto the browser tab, so the tab has read Flutter Demo whateverweb/index.htmlsaid. It is also the name Android shows in the task switcher. - The app icon — the rooster in the tractor tyre — now sits in the top bar beside the name, so the player carries the same mark as the home screen and the tab.
- Thumbs up or down on the question just asked. The bar appears when the question closes, not while it is open: a verdict cast before the answers have been read is not a verdict, and a thumb beside a running clock is one more thing to hit by accident. Tapping the thumb you already chose takes the vote back.
- The running tally comes from the service, so what you see is the room's count rather than your own guess at it — and a vote the service refuses puts the thumb back rather than leaving it looking cast.
- A tap on a disconnected socket no longer crashes. Sending before the first connection, or after one dropped, threw a LateInitializationError out of whichever widget called it. It is a no-op now.
- The vote row could overflow on a narrow phone — the prompt and the two thumbs together are wider than a 320pt screen. The prompt shortens instead.
-
The real app icon, everywhere. Generated from
icon/app.png: browser tab, the two web icon sizes, and separate maskable versions inset to 78% on the artwork's own cream — Android crops those to whatever shape the launcher likes, and edge-to-edge art loses the rooster's comb to the crop. The web icons had been the stock Flutter ones since 2022. -
The manifest called the app
game79with the description “A new Flutter project”, so anyone installing it to a home screen got that. It now names the game and uses its colours. - The version badge is legible. It was pale text on the app's white background — invisible, the same mistake as the top banner.
-
--dart-define=DS_SERVICEforces a specific backend, which is what makesflutter run -d chromeusable: the dev server hands the page a random localhost port, and the web build otherwise infers the service from the page's own URL. -
flutter_launcher_iconsupgraded to 0.14.4 — 0.11.0 no longer compiles on the current SDK.
- The character row can be dragged with a mouse. Flutter deliberately leaves the mouse out of the devices allowed to drag a scrollable on desktop and the web, on the reasoning that desktop users scroll with a wheel. For a horizontal strip that is exactly backwards — most mice have no horizontal wheel — so the row looked scrollable, scrolled by touch, and would not budge when grabbed and pulled. It now accepts mouse, trackpad, touch and stylus alike.
- It also rubber-bands rather than sitting rigid, so it is obvious the row is a thing you can move even on a wide screen where every character already fits.
- The button is called Change avatar, and the change now reaches the screen everyone is looking at. The app had been sending it correctly all along; the message the service broadcast did not say which player it replaced, so no host could apply it.
- The confirmation is written from what the service echoes back rather than from what was asked for — so it says the name and animal the rest of the room has actually been told about, and a refused change (somebody already is that animal) still reads as a refusal.
- Confetti when you get one right, and a line under it saying where you have been sent — the sunny meadow, the hayloft, or the pig pen if you got it wrong or ran out of time. The service decides; the app only celebrates.
- The character picker is a line-up now. It was a one-at-a-time pager showing the current animal and half of the next one hanging off the edge — and nothing at all to the left of the first. You can now see the row, scroll it and tap the one you want.
- Joining keeps you where you are. It used to push you to a different screen; now it says which room you are in and who you are playing as, and leaves the name box and the animals right there, so you can still change your mind while everyone else arrives.
- The name field's icon no longer swallows the field, and messages in the top banner are legible — they were white text on a white background, so every confirmation rendered as an empty coloured strip.
-
Restored the socket listener. The previous build sent
messages and never read any: the connect rewrite in 2.1.0+1 removed
channel.stream.listenalong with some duplicated lines beside it. The app asked for a session and never learned it had one, so it never joined a room — and because every later screen is pushed in response to a message, the category vote and the questions never appeared either. Three separate-looking faults, one missing line. -
The web build talks to whoever served it. It keyed off
“is this a web build” and so always dialled
api.liquidsteam.com, even when served from a service on the local network — joining a room on the wrong machine, finding nothing, and saying nothing. It now derives the service from the page's own URL. - You no longer have to type a name to join. An empty name box meant an empty username, which the service refuses outright. Every character already has a name — Enzo, Dutchess, Maui — and that is now used unless you type your own.
- Joining says so. Tapping the button acknowledges immediately, and a confirmation names the room and the character you are playing as. Once you are in, the button becomes Change character, which is the thing still worth changing.
-
Served at diddly.liquidsteam.com/play/, behind the
product landing page. A QR code scanned off a television arrives as
/?room=4821and is redirected here with the code already filled in. -
No more service worker. Built with
--pwa-strategy=none. While this app was served at the origin root it registered a worker with scope/, which then intercepted every path on the host — including the host page — and served stale content to anyone who had visited before the paths were rearranged. Offline caching buys a page opened once from a QR code almost nothing, and cost exactly that. The landing and host pages now also unregister any leftover root-scope worker, so an affected browser heals on its next visit. -
The build number is shown small in the bottom-right corner, read from
the
version.jsonthatflutter buildwrites — so what the page claims and what was built are the same thing. -
Numbering changed. This app was date-stamped
(
2026.8.23+1); it now shares amajor.minor.patchline with the diddlysquawk service, so a client and the service it was built for carry the same number.
-
Talks to the new diddlysquawk service. The app now
connects straight to
wss://api.liquidsteam.com/ms/diddlysquawk/socket. The old two-step — asklb.diddlysquawk.comfor an endpoint, then connect to whatever it named — is gone, along withhelpers/loadBalancer.dart. That hostname stopped resolving some time ago, so no shipped build could connect at all. - Connects on startup rather than when the Join button is pressed, so the socket is already up by the time somebody has finished typing a four-digit code.
-
The QR code works.
getRoom()read the page URL withUri.dataFromString, which wraps a string in adata:URI instead of parsing it — so the room in?room=4821was never found and a guest who scanned the code still had to type the number. -
The web build loads again.
index.htmlused_flutter.loader.loadEntrypoint(), removed from Flutter after 3.22; on a current toolchain that produces a blank page and no error. Replaced withflutter_bootstrap.js, plus a loading message so a phone on mobile data shows something while the engine starts. - Keeps the connection alive. Pings every four minutes. The gateway closes an idle proxied socket after an hour, and a player waiting in a lobby sends nothing at all in that time.
-
Stopped sending
session_laston connect — an action no server has ever implemented. Session restore is handled bysession_restore, which the socket layer already sent. -
google_fontsupgraded to 6.3.3; 6.1.0 fails to compile on the current SDK with a constant-evaluation error.
Version numbering
major.minor.patch+build, shared with the diddlysquawk
service so a client and its backend carry the same number. Earlier
releases used a date (2023.11.26+1) and are left as they
were. The build after + increments for a bug fix.