Theriodex – Privacy Policy
Last updated: 27 July 2026
Theriodex is meant as a light-weight and ad-free Pokédex. Thus, we strive to store only the least amount of data required to run our service and our game properly. To ensure compliance and as an act of transparency, however, this privacy policy may look somewhat intimidating! To mitigate this, here is a brief overview of what we store, why and for how long.
Short overview
Sessions and logs are stored for 24h and leaderboard scores persist only if you submit them. We do not use any sort of tracking cookies, analytics (anymore), ads or other such things. You are free to inspect the source code of Theriodex yourself on Codeberg to verify these claims.
What we store:
- Temporary session/game data:
- For the Pokémon Guessing Game (username, guesses, skips, current Pokémon and its ID, guess text, whether or not guess was correct, calculated score).
- User preferences such as theme, font and cursor
- Optional leaderboard entries (username, score, submission date) – stored only if you choose to submit, requires active consent.
- Server access logs (IP, timestamp, requested resource, actions such as which Pokémon was shown).
Retention:
- Session cookies & server access logs: deleted after a maximum of 24 hours.
- Leaderboard entries: kept perpetually until you request deletion.
Where data is processed / stored:
All processing and storage is done in the EU.
- Website and Redis (leaderboard) hosted by: netcup (Germany).
- DNS provided by: deSEC (Germany).
- Email provided by: mailbox.org (Germany).
- Operator based in: Germany.
How to delete data:
- You can delete the current session data yourself by navigating to https://theriodex.net/reset_session (Warning: Clicking this link will immediately delete your current game data as well as your selected customisation options).
- Contact us to delete leaderboard data.
- Contact: privacy@theriodex.net – include details (username, date) to request removal (e.g., leaderboard entry).
1. Controller
- Hexaitos, henceforth referred to as simply "operator", based in Germany
- Contact: privacy@theriodex.net
We ask for your understanding that we do not provide a legal name nor a summonable address in this document. Should you have an actual, legal reason for requiring these, please provide your proof and send your request to the same privacy email above.
2. What we collect
Only basic server logs are collected automatically. These may include:
- IP address, timestamp, request method and path, HTTP status, response size, User‑Agent, and referrer.
- Internal application events needed for operation or debugging (for example: which Pokémon ID was requested, request processing messages, error messages).
- We do not collect user accounts, profiles, or behavioural tracking data for advertising. No third‑party trackers are used.
Server logs (netcup)
- Logs are stored on our netcup VPS and are retained for 1 day. They include the IP address from which the request was made and information about activity on the website (for example: which Pokémon was displayed). When a user chooses to play the Pokémon Guessing Game, relevant current game data is also logged.
Leaderboard (optional, persistent)
- If the user chooses to store a score in the leaderboard, the following is stored persistently:
- Calculated score
- Username
- Date of submission
We make sure that storing data persistently in the leaderboard requires constent and that it cannot be done by accident. Before submitting one's score, the user must toggle a switch that acknowledges that they have read the privacy policy and that they wish their data to be stored.
2.1 Session data
The most amount of information is stored in a session cookie. A server‑side session mechanism is used (implemented with Rack::Session::Redis) which stores a single transient cookie containing only a session identifier on your machine, the actual cookie data is stored on the Redis server. Therefore, Rack::Session::Redis keeps session data server‑side rather than storing full session payloads in client cookies.
Redis is running in the same Docker network as Theriodex itself and has no access to the outside world at all. It can only communicate with Theriodex. Data is stored as-is and is not encrypted so that a server restart does not wipe sessions.
Session data for the Pokémon Guessing Game
- The following data items are stored in the session while the user is playing:
- Username
- Number of guesses
- Number of correct guesses
- Number of skipped Pokémon
- The guess typed in by the user
- The name and ID of the Pokémon the user was guessing at that time
- Whether the guess was correct
- The user's calculated score
Session data for user preferences
Additionally, we store user preferences in Rack::Session::Redis as well. These include (but may not necessarily be limited to) things such as the theme, cursor or font a user has selected as well as information about whether a specific theme has been unlocked.
Query parameter caching
Theriodex makes heavy use of full-page caching. This is to ensure that database queries, especially on more popular pages, are not run more frequently than absolutely necessary, reducing overall load and increasing response times dramatically.
Because Theriodex allows the user to customise their experience by changing things such as their theme, we cannot cache every request in the same manner – if we did, someone with a custom theme would be served a page with, potentially, another theme or no theme at all because that is what had been cached previously.
To mitigate this problem, a custom middleware was written ("app/middleware/customcache.rb") which appends hidden query parameters to each request depending on customisation options; as such, your customisations will be visible in a hidden query parameter and the server would see this as follows: "'GET /en/settings?font=retro-future-spaced&_theme=arcanine.css HTTP/1.1' 200 10672 0.001".
These query parameters are invisible to the user and are not used for tracking; their only purpose is to ensure that each customisation option combination gets cached separately.
Serial for unlocking themes
When the user plays the Pokémon Guessing Game and manages to reach a certain number of points, they may unlock additional themes. To unlock these themes later on, a serial is generated with which the user may unlock the theme again at a later point in time. These serials are not stored and contain – in a slightly obfuscated manner – the number of points achieved. No personally-identifiable information is stored within these serials, simply the number of points acquired.
List of all session cookies
The following is an overview of all the cookies / data stored per session. You may verify where and how this data is used by looking for "session[:key_name_here]" in the software's source code. Replace "key_name_here" with the session key found in the first column of the following table:
| Session Key | Description / Stored Data |
|---|---|
cursor |
Stores the name of the currently selected cursor |
database_username |
The username formatted for database storage |
difficulty |
Selected difficulty level |
font |
Stores the name of the currently selected font |
gen |
Stores the generation for the Pokémon Guessing Game |
guesses |
Number of guesses in the game |
points |
Calcuated game score |
pokemon_info |
Pokémon game information |
results |
Game results (how many guesses, points etc.) |
saved_in_leaderboard |
Flag indicating if score was submitted to leaderboard |
serial |
Serial number for unlocking themes |
skips |
Number of skips used |
theme |
Stores the name of the currently selected theme |
unlocked_themes |
List of themes unlocked by the user |
username |
Username selected when starting Pokémon Guessing Game |
3. Examples of collected logs
- Logs stored on netcup include IPs, timestamps, requested resources (e.g., Pokémon sprite or page), and, when applicable, current game state data recorded at the time the user is playing.
Logs stored by Theriodex look as follows. Below is an example of logs collected from a locally-running instance of Theriodex with a user who is using a custom font and theme:
theriodex-dev-1 | 172.21.0.1 - - [27/Jul/2026:12:09:52 +0000] "GET /icons/dice-five.svg?_font=retro-future-spaced&_theme=arcanine.css HTTP/1.1" 304 - 0.0130
theriodex-dev-1 | I, [2026-07-27T12:09:54.820348 #9] INFO -- : cache: [GET /en?_font=retro-future-spaced&_theme=arcanine.css] miss, store
theriodex-dev-1 |
theriodex-dev-1 | 172.21.0.1 - - [27/Jul/2026:12:09:54 +0000] "GET /en?_font=retro-future-spaced&_theme=arcanine.css HTTP/1.1" 200 7550 0.0141
theriodex-dev-1 | I, [2026-07-27T12:09:54.878707 #9] INFO -- : cache: [GET /sprites/pokemon/10010.png?_font=retro-future-spaced&_theme=arcanine.css] miss, store
theriodex-dev-1 |
theriodex-dev-1 | 172.21.0.1 - - [27/Jul/2026:12:09:54 +0000] "GET /sprites/pokemon/10010.png?_font=retro-future-spaced&_theme=arcanine.css HTTP/1.1" 200 865 0.0059
theriodex-dev-1 | I, [2026-07-27T12:09:54.881532 #9] INFO -- : cache: [GET /types/electric.svg?_font=retro-future-spaced&_theme=arcanine.css] miss
theriodex-dev-1 |
theriodex-dev-1 | 172.21.0.1 - - [27/Jul/2026:12:09:54 +0000] "GET /types/electric.svg?_font=retro-future-spaced&_theme=arcanine.css HTTP/1.1" 304 - 0.0014
theriodex-dev-1 | I, [2026-07-27T12:09:54.882139 #9] INFO -- : cache: [GET /types/ice.svg?_font=retro-future-spaced&_theme=arcanine.css] miss
theriodex-dev-1 |
theriodex-dev-1 | 172.21.0.1 - - [27/Jul/2026:12:09:54 +0000] "GET /types/ice.svg?_font=retro-future-spaced&_theme=arcanine.css HTTP/1.1" 304 - 0.0011
theriodex-dev-1 | I, [2026-07-27T12:09:56.937064 #9] INFO -- : cache: [GET /en/settings?_font=retro-future-spaced&_theme=arcanine.css] miss
theriodex-dev-1 |
theriodex-dev-1 | 172.21.0.1 - - [27/Jul/2026:12:09:56 +0000] "GET /en/settings?_font=retro-future-spaced&_theme=arcanine.css HTTP/1.1" 200 10672 0.0019
4. Why we collect it (purposes) and legal basis
Purposes:
- Operation and maintenance of the service (ensure availability, debugging, caching).
- Security and abuse prevention (detect and respond to attacks or misuse).
- Performance monitoring and troubleshooting.
- Enabling the Pokémon Guessing Game and an optional public leaderboard.
- Enabling user customisation and accessibility.
Legal basis:
Session data (game progress, 3-letter username, customisation): Processed based on our legitimate interest (Art. 6(1)(f) GDPR) in operating the service. This data is stored temporarily in Redis and expires after 24 hours.
Leaderboard data (3-letter username + score): Processed based on your consent (Art. 6(1)(a) GDPR), which you give by checking the privacy box before saving. You can request deletion anytime via the contact form.
5. Where data is stored
- All server processing and storage take place in the European Union.
- Hosting and compute:
- The application runs on a netcup VPS located in Nuremberg, Germany.
- Server logs are stored on the same VPS (retained for 1 day).
- Leaderboard database:
- The leaderboard is stored in a Redis database running on the same netcup VPS.
- DNS is hosted by deSEC (Germany).
- Emails hosting is provided by mailbox.org (Germany).
- netcup ensures all hosting services are fully compliant with the EU's General Data Protection Regulation (GDPR).
- DPAs can be provided upon request.
6. Retention
- Server logs: retained for 1 day. These logs may contain IP addresses and activity data (including Pokémon shown and game state when a user plays).
- Session / game data (Rack::Session::Redis): deleted after 24 hours or when the user uses the "Reset Session" link above.
- Leaderboard entries: stored perpetually (unless a deletion request is processed – see section 9).
- In case of an ongoing security investigation or legal obligation, relevant logs or data may be kept for longer as necessary.
7. Recipients and disclosures
- Logs, session data, and leaderboard data are accessible only to the operator (and any personnel explicitly authorised by the operator).
- We do not share logs with advertising or analytics companies.
- We may be required to disclose data to comply with legal obligations or official requests.
8. Security
- Reasonable technical and organisational measures are in place to protect data (restricted access, server security features, limited retention of logs, modern TLS encryption, HTTP-to-HTTPS redirects etc.). However, no internet service is 100% secure.
- If you believe you have found a security issue with this application, please contact us promptly with details so it can be handled. The source code of this application is freely available on the operator's public repositories.
9. Your rights
You have the right to:
- Access the personal data we hold about you.
- Request rectification, erasure, restriction of processing, or object to processing.
- Request portability of any personal data you have provided.
- Lodge a complaint with your national supervisory authority.
To exercise these rights, contact the operator at privacy@theriodex.net. For deletion requests related to specific leaderboard entries, provide the username and date of the entry to help locate the record.
As the operator of this site is based in the German state of NRW, you may contact the Landesbeauftragte für Datenschutz und Informationsfreiheit Nordrhein-Westfalen (LDI NRW) for complaints.
10. Changes to this policy
This policy may be updated. The "Last updated" date above will indicate the current version.
Full changelog
Initial version – 28 August 2025
- First published privacy policy establishing data collection practices for the Theriodex service.
Rev. 1 – 13 September 2025
- Server logs: now stored on Scaleway's Grafana logging/dashboard service and retained for 1 day. Logs include IP addresses, website activity (e.g., which Pokémon was displayed) and current game data when a user plays.
- Hosting: clarified that the application runs on Scaleway Serverless Containers (no longer hosted on OpenBSD or multiple providers).
- DNS: changed to Bunny (Slovenia).
- Session handling: added a server‑side session mechanism implemented with Rack::Session::Pool; no cookies are stored on the user's machine, session data is created only when the user starts playing and is kept in memory (deleted on server restart).
- Retention and logging rules: clarified that session/game data is deleted after 24 hours, on reset, or on server restart; leaderboard entries remain persistent unless a deletion request is made.
- Removed references to prior reverse proxy / OpenBSD log storage and any providers no longer used.
Rev. 2 – 31 October 2025
- Added self-hosted Plausible Analytics for basic, GDPR-compliant usage statistics.
- Hosting: moved from Scaleway to netcup VPS (Germany), with servers located in Nuremberg.
- DNS: changed from Bunny (Slovenia) to deSEC (Germany).
- Clarified that Plausible is self-hosted on our netcup VPS in Germany (not hosted by Plausible in Netherlands).
- Analytics data retention: self-hosted Plausible analytics data is retained for 30 days.
- Updated "Where data is stored" section to reflect new providers and their GDPR compliance commitments.
- Updated retention periods to include analytics data.
- Added public analytics URL where anyone can view the available analytics data.
Rev. 3 – 27 February 2026
- Session architecture clarification: Corrected technical description of Rack::Session::Pool implementation to clarify that while session data is stored server-side in memory, a single transient cookie containing only the session identifier is stored on the user's machine (previously stated "No cookies are stored"). The actual session data remains server-side and is lost on server restart.
- Session data transparency: Added comprehensive breakdown of all server-side session data in new Section 2.1, including detailed table of all 14 session keys and their specific purposes.
- User preferences: Clarified that session storage includes user customisation data (selected theme, cursor style, font choice, difficulty settings) alongside game data.
- Theme unlock mechanism: Documented serial generation system for unlocking themes via gameplay achievements; confirmed serials contain only obfuscated point counts with no personal data.
- Reset functionality: Updated description of reset link to clarify it deletes both current game data and selected customisation options/preferences.
- Purposes: Added "Enabling user customisation and accessibility" to the list of data processing purposes in Section 4.
- Short overview: Expanded bullet points to explicitly mention user preferences (theme, font, cursor) as stored data categories.
Rev. 4 – 14 March 2026
- Removed Plausible Analytics: Discontinued use of self-hosted Plausible Analytics; all analytics-related data collection and references have been removed.
- Updated data collection: Removed analytics data from "What we store" and retention sections.
- Updated purposes: Removed analytics-related purposes from Section 4.
- Updated storage: Removed analytics infrastructure from Section 5.
- Updated recipients: Removed analytics-related disclosures from Section 7.
- Updated short overview: Removed mention of analytics service and public analytics URL.
Rev. 5 – 27 July 2026
- Session backend: Migrated from Rack::Session::Pool (in-memory) to Rack::Session::Redis (persistent across restarts). Session data now expires after 24 hours in Redis instead of being lost on server restart.
- Session isolation: Clarified that Redis runs in the same Docker network as the application with no external access.
- Query parameter caching: Documented the custom cache middleware that appends hidden query parameters ("font", "theme") to ensure proper cache separation for user customisations.
- Log examples: Added real example log entries showing the full Puma access log format with customisation query parameters.
- Legal basis: Split Section 4 to distinguish between legitimate interest (session data, Art. 6(1)(f)) and consent (leaderboard submissions, Art. 6(1)(a)).
- Security: Added mention of TLS encryption and HTTP-to-HTTPS redirects in Section 8.
- Rights: Specified the responsible supervisory authority (LDI NRW) with link in Section 9.
- Controller: Added disclaimer about not providing a legal name/address in Section 1, with offer to provide it upon verified request.
- Leaderboard consent: Clarified in Section 2 that leaderboard submission requires active consent via a toggle switch.
- Introduction: Rewrote the opening section with a friendlier tone to give a brief summary of what this site is even intended for and why this privacy policy may seem long.
- Reset link: Fixed the wrong display of the link and updated it to "/reset_session".
- Fixed a few formatting issues here and there.