Privacy · plainly
You can play this game without an account, and nothing on this page changes that. An account exists for exactly one thing: it reserves your handle so nobody else can wear it, and it carries a rating once you duel somebody else who is signed in. It buys nothing else — no profile, no synced settings, nothing that follows you off this site.
the short version
You can play without an account and nothing is asked of you at all. If you want one, there are two ways to make it and you choose: your device's own passkey — a fingerprint, a face, a PIN, whatever your browser offers, where what reaches the server is a public key and a signature — or an email address and a password, where the address is kept and the password never is. That is the whole of what is asked for. There is no name, no date of birth, no phone number and no profile of any kind, and the address is used for one thing: getting you back into your account. It is never shown to another player, never sold, and never used to write to you about anything else. (One other page on this site asks for an address: the sponsorship form, which is a company writing to us rather than a player signing up. It has a section of its own below.)
Almost everything below is either in your own browser, where you can clear it yourself, or one row you can delete from inside the game. The one exception is the match tape, which the server writes while a match runs and throws away after ninety days.
on your device
Ordinary localStorage, on the site's own origin. It never leaves the browser
except where the table says so, it is not shared with anybody, and clearing site data removes
all of it. No advertising cookie is set and none is read; the analytics library described
below keeps an id of its own here too, and a development build keeps one more (a table of
tuning values) that never leaves the browser either.
| Key | What it is |
|---|---|
| railmid.handle | The name you chose, or the fact that you declined to choose one. It is sent to the server so the other seat can see who they are playing. |
| railmid.session | A random string that signs you back in on your next visit, if you made an account. Signing out or deleting your account puts it down. |
| railmid.best | The best round trip this browser has ever measured, used to decide whether a freshly opened socket is good enough to keep. |
| railmid.bindings | Your key bindings. |
| solomid.record | Your own win/loss tally. It stays here and is never sent anywhere. The odd name is the game's old one, kept so that nobody's record was thrown away when it changed. |
| railmid.debug | Whether you asked for the extra diagnostic numbers under the status line. |
| railmid.visits | Two timestamps and a count, so a return visit can be counted as one rather than as a new person. No identifier is derived from it. |
| railmid.who | The account this browser last told the analytics below about, so that a later visit can take it back down again. It is the same random string the analytics library is already keeping, not a second one, and it is not a password: it signs nothing in and reaches nothing. Signing out empties it. |
| railmid.gate | That you were told this game wants a keyboard and a mouse, and went in anyway. |
on the server
Eight things, in one database, and this is the whole list:
No IP address, no user agent and no location is written against any of it.
It is the whole list for the accounts database. The one other thing this server writes down is the match tape, which is kept whether or not you have an account and is described below.
An account can hold either credential or both, and from a signed-in session you can add whichever one it does not have yet. That is the whole recovery story, and it is the one thing the game asks you for.
If your account is passkeys only, there is nothing else that reaches it: lose every device you have enrolled and the account and the handle it reserves are gone to you while still existing. A second passkey, or an email and a password, is what stops one device being all that holds it. If your account has an email and a password, the address is what can get you back — and it is the only thing on this site that can reach you when you are not on the page: pressing I forgot my password mails a ten-character code to it, and typing that code back into the same card is what sets a new password. A forgotten password is recoverable; a mailbox you no longer hold is not.
deleting it
Open the game, press Account, and press Delete account. It asks once to be sure, and then removes the account, the handle it reserved, every passkey on it, your email address and the derived password beside it, every session, and every password reset code still outstanding — immediately and irreversibly. Your handle is free for somebody else the moment it returns, and so is the address: nothing is kept back to stop it being used again.
It is one press from inside a signed-in session and there is no form to fill in, no email to confirm and nobody to ask. A signed-out connection cannot delete anything, which is the same rule that stops anybody deleting yours.
Deleting the account takes your rating with it, so you leave the ladder the moment you press it. The rows for the matches themselves are kept, including the per-seat rows that name you: they hold a random account id that no longer belongs to anybody, and blanking it would rewrite the history of the people you played. There is nothing else left to join it to — no handle, no passkey, no session, no reset code.
Playing anonymously leaves no account on the server to delete, and clearing this site's data in your browser is the whole of it. The match tape is the exception either way: it is written for the match rather than for a player, so deleting an account does not delete the tapes of matches that account played, and they age out on their own.
while you play
Your handle. It is drawn on the seat you are in, on the arena list and beside anything you type in the arena chat, to everybody connected to the same server — which is what a handle is for. Chat is relayed live and kept nowhere a player can reach — but it is written into the match tape along with the rest of the match, so it is not gone the moment it scrolls off screen.
Your handle and your rating are also what the ladder is, if you are in the top hundred: a rank, the handle, the number and how many rated duels are behind it, on a public page anybody can open. It says nothing about when you played.
Nothing else about you is broadcast. There is no profile to open and no match history to look up, because there is not one to look up.
while you play
A match that a human sat down in is written down by the server while it runs. A match nobody sat down in — the bot playing itself in an empty arena — is not written down at all.
What a tape holds is what a spectator standing in that arena would have been sent, and nothing a spectator would not have been sent:
Nothing private to a seat is in one. The stream a tape is cut from is the ownerless one — the same projection a stranger watching gets — so the things the server sends only to the player they belong to are not in it, and neither is your account, your session, your IP address or anything about your device.
It is stored as gzipped pieces in Cloudflare R2, under the match's own id, and a bucket rule deletes it after ninety days. Nothing reads it back yet: there is no listing, no link and nothing to press, in the game or anywhere else. If that changes — a replay you can watch, a link you can share — this page changes in the same release, which is the promise at the bottom of it.
if you write to us about sponsorship
This is the only address on railmid that is not a player's own way back into their account, and it is not about playing the game: it is the form on /sponsor, filled in by a company that wants to buy a placement. A player never sees it and never needs it.
What a sponsorship application keeps: the company name, the contact email it asked to be answered at, an optional link, the bid, anything written in the note, and the artwork that was uploaded. The row is written as applied, which means nothing in it is on any public screen — the artwork is not served to anybody until a person has looked at it and approved it. Looking at it is the one exception, and it is a person holding an administrator's key rather than a page anybody can open. The address the application arrived from is used to bound how many applications an hour one caller can make, and is not written down.
How long. An application that goes nowhere is deleted within twelve months; a sponsorship that runs is kept while it runs and for twelve months after it ends, because it is a record of a commercial arrangement. There is no automatic sweep behind that — a person deletes the row — and writing to the address you applied from is enough to have it deleted sooner. An application that is turned down is the one case that is not a wait: declining it deletes the artwork immediately, in the same moment, and there is no undo.
One thing a player should know about it. A sponsor bids for first pick of the players, and a pick is made against a reserved handle — so a handle at the top of the ladder can be picked without being asked, and the sponsor's mark would then ride that champion for the month. It is a mark drawn next to a name; nothing about the account, the email address it may have been made with or how it plays is given to the sponsor, and no money reaches the player. If that ever becomes something you can decline or be paid for, this page says so in the release that makes it true.
counting, not tracking
Two things count how the game is doing. Neither is joined to your handle, and only one of them knows anything about your account: if you sign in, the funnel below is told your account's internal id — a random string, not a name — so that two visits from two of your devices count as one person. That is the whole of it, and signing out puts it down again. The arena's own rows know nothing about either.
The funnel. The landing page, the game, the ladder and the sponsorship page load PostHog, on this site's own hostnames and nowhere else — the privacy page you are reading loads no script at all, and neither does the write-up. What the game itself reports is a fixed list of moments: the landing page opened, the game opened, a socket connected (or failed to), an arena joined, a queue asked for or given up, a seat taken, waiting past the cap, a connection refused, a first shot fired, a match finished, and whether this was a return visit. Five more are about accounts: that the account half of the handle card was drawn to somebody who has none, that this machine has nowhere to keep a passkey, that Register or Sign in was pressed, that the server refused that press (and which of its seven refusals it was), and that an account was made. Two more come off the sponsorship page: that it was opened, and that an application was sent from it. Every property on those events is a count, a duration or a fixed category — the device class, for instance, is one of three words. Your handle is on none of them.
Signing in. When you sign in, the funnel is told the account's own id — the random string this site generated when the account was made. It is not your handle, it is not a password, and it means nothing anywhere but here: presenting it proves nothing and reaches nothing. It exists so that a player who comes back on a second machine is counted as the same person rather than as a stranger, and so that "how far does a signed-in player get" is a question with an answer. It applies from the moment you sign in onward; what was recorded before that stays as it was, under the random device id below. Signing out, deleting the account, or a session that has expired all put it down again and go back to that device id, and signing into a different account on this browser puts the first one down before it picks the second one up. Playing without an account never sends it, because there is nothing to send.
Being honest about the rest of what that library does: on its own defaults it also records
page views and clicks on the four pages it is loaded on, it keeps a random device id in this
browser so that two visits can be counted as one person rather than two, and — like every
request any website makes — the analytics request carries your IP address to it. Nothing here
ever tells it a name: the single identify call in this codebase sends the account
id above, and nothing else is ever sent with it — not your handle, not an email address,
nothing you typed. Profiles are configured as identified-only, so a browser that never signs
in never becomes one at all, and a browser that does becomes a profile keyed on that random
id. Clearing this site's data resets the device id.
The arena's own rows. The server writes one row at each boundary an arena crosses — somebody entering it or leaving it, a pre-game lobby resolving, a match starting or ending. Every field on them is a count, a duration, a fixed category or a code: how many seats a human held, how long it lasted, which weapons, which side won. No handle and no account id is on any of them, and nothing on one could be joined back to either.
Two of those fields are geographic, and only a row about a connection carries them: the three-letter code of the Cloudflare datacentre the socket landed in, and the two-letter country it came from. They are there because where a player terminates and where they are turned out to disagree constantly, and the game is unplayable at the wrong distance. A country is a closed list of 249 codes shared by tens of millions of people; the finer geography Cloudflare offers with it — city, postcode, coordinates — is used to pick a server while the request is being handled and is never written down.
PostHog is the one third party this site talks to about you at all — the only others are a font host and Cloudflare, which serves the game. There is no ad network and no cross-site tracking.
the rest
Children. This is a game for a general audience and no account of any kind is required to play it. Nothing here is directed at children under 13, and nothing is knowingly collected from them.
Changes. If what is kept ever changes, this page changes in the same release as the code — it is built from this repository rather than written separately.
Asking. Everything on this page is either yours to clear or yours to delete from inside the game, so there is no request queue to write to. If something here is wrong or unclear, the game is built in the open and the issue tracker is the place to say so.