Last updated 28 August 2026
This is a scoreboard for people who play mahjong together. It is not a product with a funnel, and it does not make money from anybody's data. This page says exactly what is kept, why, and how to get rid of it.
No email address. No analytics. No advertising. No third-party trackers. One cookie, and it only says you are signed in. You can delete your account from Settings, and it takes your rooms with it.
A username, and a way to prove it is yours. There is no email field anywhere in the database, which has one real consequence worth saying out loud: nobody can reset a forgotten password for you. If it is lost, the account is lost.
If you sign in with a password, the password itself is never stored. What is kept is a PBKDF2-SHA256 hash with 100,000 iterations and a random per-account salt, which cannot be turned back into the password. Use a password you do not use elsewhere anyway.
Optional, and it changes almost nothing about what is stored here. We ask
Google for one thing: openid, the scope that answers "is this
the same person as last time". Not your email, not your name, not your
photo, not your contacts. Google is not told anything about you in return;
it learns only that you signed in to this app, which it would learn anyway.
What is kept is the stable identifier Google uses for you, an opaque number next to your account here. That is the whole record. Because we never ask for your email address, there is still no email column for one to go in, and the paragraph above stays true.
Connecting Google to an account you already have is done from Settings, and is the right way round: signing in with Google first would make a second, empty account, and the rooms you are in would still belong to the first one. Disconnecting is not offered, because for an account created through Google it is the only way in and removing it would lock you out of your own rooms.
Optional, and there is a drawn face for everybody who does not set one. If you do, the picture never leaves your device as the file you chose: the app crops it to a square, shrinks it to 512 pixels and re-encodes it as WebP first, which is also what removes the time and the place the photograph was taken. Only that copy is uploaded, to a private R2 bucket.
It is not public and has no shared link. It is shown to you, to the people you are friends with, and to the people you share a room with, and to nobody else. Change it or remove it at any time from your profile, and removing it deletes the stored image rather than hiding it.
A private scanner pilot lets a super moderator attach a photograph of a winning hand after consent is explicitly confirmed. The frame should contain the tiles, not people's faces. The app accepts only a cropped WebP copy, limited to 5 MB, and refuses EXIF, location and other embedded metadata.
A super moderator can also record which tiles are in the photograph and what the hand was counted for, so the picture has something to be read against. That is a list of tile names and scoring reasons, and nothing about the people at the table.
The photograph is not public and has no shared link. Only a super moderator can upload, view, approve or delete it. Unapproved photographs are deleted after 90 days. A photograph explicitly approved for scanner training is kept until it is manually deleted, unless the account that uploaded it is deleted. Ask the person running this instance to have one removed.
A room is visible to the people in it, and to nobody else. Joining takes a code that somebody in the room reads out. Within a room, everyone sees the roster, the games, the leaderboard and each other's profile pictures; one person (the master) is the one who records hands.
Nothing is public. There are no shared links, no search, and no way to browse rooms you are not in.
One, called sid. It holds a random session token, not your
name and not your password, and it is set HttpOnly,
Secure and SameSite=Lax, so scripts cannot read it
and other sites cannot send it. It lasts 30 days, and signing out deletes
it on both ends.
There are no analytics or advertising cookies, because there are no analytics or advertising.
The game in progress is saved in your browser's local storage, along with a cache of the rooms and lists you have looked at. That is what lets the app keep working at a table with no signal. That is the point of the design, not an optimisation. None of it leaves your device except as the hands you record, and deleting your account clears all of it.
A failed sign-in records the username tried and the IP address it came from, so repeated guessing can be slowed down. Rows older than the counting window are deleted automatically, and signing in successfully clears yours. Account creation is counted the same way, per address, to stop a script minting accounts.
If the app throws an error in your browser, it sends a report so it can be fixed. That report is the error message, the stack trace, which page you were on, and your browser's user-agent string, plus your username if you are signed in, so a report can be matched to a "it did something odd on Friday". It does not include room names, player names, scores, or anything you typed.
Reports go into the server log and nothing else. There is no third-party error service, and nothing is sold or shared. The same fault is reported once per visit, so a bug that repeats does not repeat the report.
On Cloudflare: Workers for the application, D1 for the database, and two private R2 buckets, one for profile pictures and one for pilot hand photographs. Cloudflare processes it on our behalf and stores it in their network; they do not use it for anything of their own. Traffic is encrypted in transit.
Rooms and their games are kept until somebody deletes them, because a leaderboard that quietly forgot last winter would be worse than useless. Sessions expire after 30 days. Invite codes expire after seven, or when the master replaces them. A profile picture is kept until you replace it or remove it. Unapproved pilot photographs expire after 90 days; approved training photographs remain until they are manually deleted.
Settings → Account → Delete my account. It asks you to type your username, because it cannot be undone. What happens:
There is no download button. Everything about you is already on screen in the app (your rooms, your games, every hand) and this is a small app run by people you know, so: ask, and it will be exported by hand.
If what is stored changes, this page changes with it and the date at the top moves. Keeping anything genuinely new will be asked for rather than assumed.
Message whoever invited you to the room, or the person who runs this instance. It is a small app run by people you know.