What we record
All of it, listed. No ad networks, nothing sold, no accounts, and we never learn who you are.
Last updated 2026-10-01 · generated from the product's own event registry, so it cannot drift from the code
The short version. We count which changes people actually read, so we know what to build next. That is the whole reason any of this exists. We do not store your IP address, we do not store your browser's user agent, we have no advertising on this site, and there is no one we sell anything to.
What we never collect
- No IP address is ever stored. It is used inside a single request to work out a country and a daily identity code, then discarded. The database has no column that could hold it.
- No user agent is stored. It is reduced to "mobile" or "desktop" and a browser family, then discarded.
- Nothing above needs an account, and reading this site never asks for one. Accounts exist only for commenting, and everything they involve is set out under Accounts and comments below - it is deliberately a separate section, because analytics and an account are different promises and merging them would blur both.
- No advertising, no data brokers, no selling. Not now, and if that ever changes this page changes first.
- No keystroke capture and no reading of anything you did not type into a search box.
Two levels, and you choose
The banner you saw is a real choice, not a formality. Saying no costs you nothing and is one click, the same as saying yes.
If you say no, or never answer
Nothing whatsoever is stored on your device. Your visit is counted using a code derived from a secret that is thrown away and replaced every 24 hours, which means the code cannot be linked back to you and cannot be linked to your visit yesterday. We still learn which changes get read. We just cannot tell a returning visitor from a new one.
If you say yes
A random ID is stored in your browser so we can tell that someone came back after a patch dropped, which is the single most useful thing we can know about whether this tool works. Session replay is also enabled, with every input and every piece of text masked before it leaves your browser. Changing your mind clears the ID immediately.
Every event we can record
All 88 of them, with the reason each one exists. This list is generated from the same file the code checks against, so it cannot quietly fall out of date.
What you looked at
| Event | Why it exists |
|---|---|
| session_start | Denominator for every rate in the funnel. Fired once per tab. |
| page_view | Which game is actually getting traffic. Decides where the next 100 hours go. |
| page_hide | Carries engaged time and max scroll so a bounce is measurable without a second event. Fired on pagehide, which is the only reliably-delivered exit signal on mobile. |
| picker_view | The denominator for question 1. If people bounce here nothing else matters. |
| picker_mode_select | Do people want a time window or a single patch? We currently build both. |
| picker_since_change | How far back people actually claim to have stopped. Tells us which seasons deserve the deepest data. |
| patch_index_view | Denominator for index clicks. It sits below the picker so reaching it is itself a signal the picker did not satisfy. |
| patch_index_click | People who know exactly which patch they want. A high rate means the "since you left" framing is not the only job to be done. |
| review_start | Question 1 answered, and question 2 via the entry prop. We maintain three doors into the review; this says which one people use. |
| catchup_wait | Which "thinking" wait and style the Catch me up button showed before opening the review (an A/B test per game, 2026-09-24), so engagement after it can be compared. |
| review_view | Denominator for activation. Carries the size of the window so we can tell whether huge windows behave differently from small ones. |
| top5_click | Activation. Which rank gets opened tells us whether our impact ranking matches what players care about. |
| board_tab | Legends vs weapons, heroes vs maps. Which half of the game people are catching up on. |
| pick_open | The aha moment: someone opened a specific change to read it. This is the activation numerator. |
| focus_close | Time in focus separates a real read from a misclick. |
| change_scope_click | Going back to change the window means the first answer was wrong. A high rate indicts the picker. |
| notes_reach | Did anyone scroll to the full documented notes? Decides whether that whole layer earns its maintenance. |
| notes_fold_toggle | Which categories people open. Category-level demand for content depth. |
| notes_fold_all | Expand-all is power-user behaviour. Tells us whether a default-open variant is worth testing. |
| card_modal_open | Deepest read of a single change short of leaving for the source. |
| costume_section_view | Whether a review is scrolled far enough to reach the costumes at all. The denominator for the two below - an open rate against page loads would flatter it. |
| costume_open | A costume opened, and which of the five surfaces it came from. Settles whether cosmetics are worth the page weight, and which surface actually drives them. |
| costume_show_all | Whether twelve is the right number to show before asking. A high rate means the cap is too low. |
| source_click | Nobody clicks a citation unless they are deciding whether to trust you. Direct read on whether the accuracy work lands, and which claims look surprising. |
| entity_view | The entity leaderboard. Decides which content to deepen and seeds programmatic SEO pages. |
| entity_since_change | The default is everything-on-record. If people narrow it constantly the default is wrong. |
| entity_back | Return path from lookup into review. Distinguishes a dead end from a loop. |
| lookup_open | Demand for the "how did my main change" job, which is a different product from "what changed since I left". |
| game_switch | Cross-game browsing. If it is common, a shared multi-game review is worth building. |
| home_view | Landing denominator for the multi-game gallery. |
| home_tab | Tabbed game grid usage. |
| home_game_select | Which game people pick, and whether they click a card or use the combobox. |
| home_update_click | The last-updates rail as an entry path straight into a patch. |
| home_request_game_click | Explicit unmet demand, the strongest version of question 8. |
| home_handoff | The #last= handoff into a game page. Tells us whether prefilling the memory actually shortcuts the picker. |
| twitch_click | Whether the creator tie-in converts, split by placement and by whether the stream was live. |
| discord_click | Community conversion, split by the floating button vs the footer. Also settles whether the footer needs its own Discord button. |
| subscribe_submit | Email capture is the only durable retention channel we have while identity is cookieless. |
| flag_submit | Report an error is stored and earns points now (2026-10-01). How often readers send one is the measure of whether the in-place form gets used. |
| recap_click | The recap is a funnel (5 second sentence, 30 second top 5, 5 minute list, sign-up). Which step a reader acts on tells us where they stop reading. |
| drawer_open | A name or ability opens its page in a drawer over the review instead of a new tab. Whether readers use it, and on what, says whether the drawer keeps them in the recap. |
| video_play | Is the creator-video hero worth the slot it occupies? It is the largest element on the review page and currently a placeholder. |
| video_seek | Transcript-seek chips are a bet that people want to jump to a specific change. This says whether the bet paid. |
What you typed into a search box
| Event | Why it exists |
|---|---|
| memory_focus | Intent to use the free-text box, separate from actually typing. The gap between focus and input is a usability read on the placeholder. |
| memory_input | Debounced. Length only, never content at this stage. Shows abandonment mid-typing. |
| memory_match | THE event. interpretMemory() has a fallback branch that means "could not pin it down". Every false here is a phrasing real players use that we do not understand. Twenty of them is a spec. |
| memory_abandon | Typed something, never confirmed a suggestion, left the picker. The clearest signal the box is failing people. |
| memory_suggestion_click | Did the matcher offer the right thing, and at which rank? Rank 2+ means the top suggestion was wrong. |
| notes_filter_search | What people hunt for inside a patch. Feeds the entity leaderboard alongside lookups. |
| notes_filter_zero_results | A search inside our own notes that finds nothing. Either missing coverage or vocabulary we do not speak. |
| notes_filter_direction | Do people care more about buffs or nerfs? A persistent skew would change the default sort. |
| notes_filter_impact | Whether the 1-5 impact score is trusted enough to filter by. |
| lookup_search | Typing behaviour in the entity type-ahead. |
| lookup_zero_results | Someone asked for a hero, legend or weapon we do not cover. Literally the backfill queue, written by users. |
| home_game_filter | Type-to-filter usage on the game combobox. |
| home_game_zero_results | Someone typed a game we do not have. This single event is the entire which-game-next decision, sourced from demand instead of taste. |
| home_patch_search | The patch search at the top of the games block, opening one patch by name. Tells us whether people reach patch notes this way at all, and whether they pick a result or just press the button. |
| home_patch_search_zero | A patch someone searched for and we list nothing for. Either a game or patch we do not carry, or a name our index spells differently - both fixable once seen. Fired on submit only, never while typing, so a half-typed word is not counted. |
Whether the site worked
| Event | Why it exists |
|---|---|
| click_point | Heatmap primitive. Records both element-relative and document-relative position because the review page is data-rendered: pure page pixels drift as content changes and aggregate into nonsense. |
| scroll_depth | Scroll map at 10% granularity. The number that matters is what share of sessions ever reach the full notes. |
| section_time | Attention map. Gated on visibilityState so a backgrounded tab does not read as engagement. For a reading product attention beats clicks. |
| rage_click | Three or more clicks in a 30px radius within a second. Means "I think this is a button and it is not responding". |
| dead_click | A click on nothing interactive that changes nothing. On a card-heavy UI this is the most likely real defect and it is invisible from the outside. |
| error_click | A JS error within a second of a click: an actually broken control, with a line number attached. |
| js_error | No build step and no CI on these pages, so this is the only smoke alarm we have. Carries the last five event names as breadcrumbs. |
| web_vital | data.js is 337KB and marvel-rivals.html is 359KB, both eager. LCP on a mid-range phone on 4G is a real open question nobody has measured. |
Accounts and comments
| Event | Why it exists |
|---|---|
| auth_register | The top of the account funnel. Paired with auth_verify it separates "nobody wants an account" from "the confirmation email is not arriving", which are the same number on a dashboard and completely different problems. |
| auth_verify | Did the confirmation link actually work. A drop here is a mail deliverability failure and nothing on the site can see it otherwise. |
| auth_login | Returning accounts. The one signal that says whether an account is worth having: nobody signing in twice means nobody wanted one. |
| auth_forgot | Password resets requested. A high rate against sign-ins is a usability read on the sign-in form, not on people. |
| auth_reset | Did the reset link work. Same deliverability read as auth_verify, on the flow people reach when they are already frustrated. |
| auth_delete | Account deletions. Rare by nature, and a spike is the loudest possible feedback about something that just shipped. |
| comments_view | The denominator for every comment rate. Fired when the thread actually renders, which on an origin with no Worker in front of it never happens - so a zero here distinguishes "nobody reads the comments" from "the comments are not being served". |
| comment_post | THE event. Whether a catch-up tool has a conversation in it at all. Carries `held` because a high hold rate means the automatic moderation is eating real comments, which is invisible from the comment count alone. |
| comment_card_open | Comment pressed on a change card, the hover button added 2026-09-13. Against comment_post with ref=1 it says whether people who start a comment about a specific change finish one. `switched` is 1 when the press moved them from a recap to that change's own patch, which is the bigger ask of the two. `from` is notes or focus. |
| comment_ref_open | A reader pressed the change shown above a comment to go to that card. It is the only signal of whether the reference is read as a link between the conversation and the patch, or ignored as decoration. |
| comment_rejected | A comment refused at write time, carrying the rule code. Every entry is either a spam attempt stopped or a real person told no by a rule that misfired, and the code is what tells them apart. This is the moderation corpus own feedback loop. |
| comment_vote | Voting is the cheapest possible participation, so it is the earliest signal that anyone is reading the thread at all - it moves long before anyone writes. |
| change_vote | Up and down votes on a single change card. Tells us whether readers react to changes at all, and on which game, before anything is built on top of the scores (a sort, a most-disliked list). |
| comment_sort | Best, New or Top. Three sorts were built on the assumption people want them; this is the check on that assumption. |
| comment_delete | Authors removing their own comments. A rate that climbs is usually a posting UX problem - a double-submit, or an edit window that expired. |
| comment_report_open | The report dialog opened. Paired with comment_report_send it measures whether the reason list is answerable - a big gap means people opened it and could not find their reason. |
| comment_report_send | A report actually filed, and whether it crossed the auto-hide threshold. The only measure of how much work the automatic moderation is leaving to readers. |
| notes_view | Whether anyone opens the developer's own notes under a patch review. It is the receipt under our curated cards, and if nobody ever reads it the curation is carrying the whole product - which is worth knowing either way. |
| notes_show_all | The notes are folded at 60 lines. This says whether the fold is a kindness or an obstacle - a high rate means people want the whole document and the cap is in their way. |
| mains_open | The picker opened, and from where (the Edit button in the review, or the link on the account page). If nobody opens it, the tailored review and the per-main vote counts have no inputs, and the feature is decoration. |
| mains_set | A main saved. How many a player keeps and whether roles get used decide whether the cap of three and the role option earn their place. Never which hero - that stays in the database, not the analytics. |
| mains_view | The review rendered with the reader's mains on top. The denominator for whether a tailored review keeps people reading further than an untailored one. |
About the search boxes
The "describe when you last played" box and the search fields are the only places we keep what you typed, because what people ask for is how we decide what to build. Before it is stored it is lowercased, cut to 80 characters, and thrown away entirely if it looks like an email address, a web address, or a long run of digits.
Accounts and comments
You can read every page, and vote on comments and on individual changes, without an account. Posting, replying and reporting need one. This section is what changes if you vote, make an account or leave a comment - it is separate from everything above because analytics and an account are different promises.
If you never comment or vote
Nothing in this section applies to you. No cookie is set, no row is written, and the comment thread is read-only from our side of it.
One cookie, and it is not analytics
- pn_s is set when you sign in and is how the site knows it is you on the next page. It holds a random value and nothing else - not your name, not your email. It lasts 90 days and is cleared when you sign out.
It is strictly necessary for a feature you actively used, which is why it does not wait on the consent banner. It is not readable by any script on the page, and it is sent nowhere but this site. An older pn_a cookie was once set for anonymous comments; nothing sets or reads it any more.
What a vote without an account stores
So that one vote means one vote, and not one vote per page refresh, a vote cast without a confirmed account is tied to your network: your IP address, or the first half of it for IPv6. The address itself is not stored. What is stored is a keyed code computed from it, different for every comment thread and every change, so your votes in two places cannot be connected to each other, and it cannot be turned back into an address without a secret key that lives only in the server. The cost is that everyone sharing one connection - a household, an office - shares one vote per comment and one per change. Signing in with a confirmed account gives you your own.
What an account stores
- Your email address. Used to confirm the account, to reset the password, and - if you leave it switched on - to tell you when somebody replies to you. Nothing else, ever.
- Your display name, which is public on your comments.
- Your password, stored only as a slow one-way hash (PBKDF2-SHA256). It cannot be read back, including by us.
- When you joined, when you were last seen, and how many comments you have posted.
- If you pick mains (up to three things you play, per game), which ones and when you picked them. Your mains are public: they show next to your name on the comments you post in that game. They also put those changes first in your review, and votes on changes from confirmed accounts are counted per main, for example "Accounts that main Cloak & Dagger: 12 down, 3 up". A count is shown only once at least five accounts voted and names nobody, but because mains are public, someone who watches a count move right after you change your mains could work out that one vote was yours, and so could a few accounts that pick the same rarely played main and vote together, since they can take their own votes off the count. Remove a main and it leaves your comments and your votes stop counting toward it; delete the account and your mains go with it.
- Error reports you send with Report an error: the text, the page and when. They are emailed to reports@ so a person reads them. Delete the account and they go with it.
- No points are stored. Your points and badges are counted from your error reports, comments, votes on changes and the upvotes your comments got, each time they are shown. Your badges and the top five lists show beside your name on comments and on your profile.
What a comment stores
The text you wrote, when you wrote it, which page it is on, and a daily-rotating code derived from your IP address in exactly the way described at the top of this page - the address itself is not stored and there is no column for it. That code exists to rate-limit and to stop a spam run, and it stops being linkable to a new one the next day.
Comments are checked automatically, by a machine, before they appear
Every comment goes through a fixed list of rules and, when those rules cannot settle it, a content-safety model running on Cloudflare's own infrastructure. No human reads your comment before it is published. If something is refused you are told which rule refused it, on the spot. Nothing is used to train anything, and the check happens on the same infrastructure that serves this site.
Deleting things
- A comment: yours to delete at any time. The text goes and the reply structure stays, so the answers other people wrote underneath do not lose the thing they were answering.
- Your account: deleted immediately from the account page. The account, its sessions and its votes are gone. Your comments stay, with the author replaced by [deleted] and every link to you cut - the same reason as above: the replies under them are other people's words.
- Reply emails: one click in any of them, no sign-in needed.
Comments and accounts are not on the 90 day analytics clock. A conversation that deleted itself after three months would not be much of a conversation. They stay until you remove them.
Patch emails
If you type your email into "Notify me" under a recap, we store that address, the game you signed up for, where on the page you signed up, and when. It is used only to tell you about that game's patches. It is not shared, and it is not joined to the analytics above. To be removed, email help@patchnoter.com from that address.
The Discord bot
Patchnoter has a Discord bot. It answers slash commands (like /catchup) and can post new patches in
a channel a server manager chose. It reads no messages, no member lists and no presence: Discord only sends it the
commands people type to it.
- What it keeps: for each automatic-post setup, the server and channel IDs, the game, and the ID of the person who set it up; which patches it has already posted; and a daily count of how often each command was used, per game. No names, no message text, and nothing about who used a command.
- How to remove it:
/unsubscribestops the posts and deletes that setup. Removing the bot from a server stops everything; a setup whose channel it can no longer reach switches itself off.
Who else sees it
- Cloudflare serves the site and stores the events, in the EU.
- PostHog (EU region) receives behaviour data only if you said yes. It is routed through our own domain, so it is not a third-party tracker in your browser.
- Twitch is asked whether a stream is live. That request comes from our server, not from you.
- Cloudflare Workers AI runs the automatic comment check, on the same infrastructure that serves this site. Your comment text reaches it; nothing else does, and it trains nothing.
- Resend delivers account email - confirmation, password resets, and reply notifications. It receives your address and the text of that message, and only when one is actually being sent.
- Discord receives what the bot posts or answers, in the servers that added it.
- That is the complete list.
How long we keep it
Events are deleted after 90 days. Daily archives are kept so we can re-check our own numbers, and they contain no more than what is listed above.
Comments and accounts are the exception, and it is a deliberate one rather than an oversight: they are kept until you delete them, because a conversation that erased itself after three months would not be much of a conversation. They live in a separate database from the analytics above, so the clock that empties one cannot reach the other.
Turning it off entirely
- Choose No thanks on the banner. Nothing is stored on your device.
- Turn on Do Not Track or Global Privacy Control in your browser and we collect nothing at all, not even the anonymous count. We check before anything is queued.
- Use an ad blocker. We would rather you did not, but we do not fight it and nothing here tries to evade one.
Questions
Ask in the Discord. A real person reads it.