Privacy Policy
Last updated: June 18, 2026
1. Data Controller
Pannonia Code d.o.o.
Email: [email protected]
We operate Command Tower, a virtual tabletop platform for multiplayer trading card games. This Privacy Policy explains what personal data we collect, why we collect it, and your rights under the General Data Protection Regulation (GDPR) and other applicable laws.
2. Data We Collect
2.1 Account Data
When you sign in with Google, we receive and store the following:
| Data | Stored | Purpose |
|---|---|---|
| Google account identifier (subject ID) | Yes | To uniquely identify your account |
| Selected in-game avatar (a reference to an image we host) | Yes | To display the avatar you chose on the game board and in your profile |
| Supporter status, optional expiry date, and Supporter-ended timestamp | Yes | To provide Supporter benefits (e.g., access to the full in-game avatar selection, a distinct username colour, higher uploaded card image storage limits, and extended replay retention), and to determine when those benefits apply, expire, or affect replay retention |
| Staff status flag | Yes | An internal role designation, set by administrators, used to identify platform staff (e.g., to display a distinct username colour) |
| Uploaded card image quota override | Only if set by an administrator | To apply a per-account uploaded image storage limit that overrides the default regular or Supporter limit |
| Keyed ban-enforcement hash for deleted banned accounts | Only if a banned account is deleted | To prevent ban evasion without retaining the raw Google account identifier |
| Email address | No | Not requested, read, or stored |
| Google profile picture / avatar URL | No | Not requested, read, or stored |
| Real name | No | Never collected or stored |
Your in-game display name is auto-generated using random fantasy words (e.g., "CrimsonDragon742") and is not derived from your real name.
2.2 Gameplay Data
| Data | Stored | Retention |
|---|---|---|
| Match history (winner, duration, turns played) | Yes, in database | Indefinite; account/profile identifiers are anonymized upon account deletion |
| Saved deck lists (card selections, custom card text, uploaded image asset references, and full-card/artwork placement mode) | Yes, in database | Until you delete them, or upon account deletion |
| Uploaded custom card image metadata (owner ID, status, object keys, content type, processed stored file size, dimensions, hashes, original file name, upload IP address, upload user-agent, timestamps, removal reason) | Yes, in database | Until deleted or upon account deletion, unless retained for an active moderation, legal, or takedown case |
| Uploaded custom card image objects | Yes, processed WebP variants in private Cloudflare R2 object storage | Until deleted or upon account deletion, unless retained for an active moderation, legal, or takedown case |
| Uploaded image reports (reporter ID, reported image ID, reason, message, snapshot hashes/metadata, moderation status/action, reporter IP address, reporter user-agent, timestamps) | Yes, in database | Retained as needed for moderation, safety, legal compliance, and auditability |
| Personal game type definitions (zone names, icons, options, visibility, and default positions) | Yes, in database | Until you delete them, or upon account deletion |
| Active game state (hands, life totals, board) | Yes, in cache (Redis) and temporary database snapshots | Deleted when the game ends, when an active room is abandoned through account deletion, or automatically after cache expiry |
| Completed multiplayer replay recordings | Yes, compressed in database | Regular accounts: 14 days after the game ends. Active Supporters: retained while Supporter status remains active. If Supporter status ends, retained replay copies expire 14 days after Supporter status ended unless Supporter status is restored before deletion. You may delete your own replay copy earlier |
| Room participation (seat, join time) | Yes, in database | Indefinite; account/profile identifiers are anonymized upon account deletion |
Live spectating is available only to authenticated accounts and only when the room host allows spectators before the game starts. Live spectators may see spectator-filtered public game state, public game log entries, public hub events, timer state, cosmetic events, and participant display metadata such as display name, seat, user class, and avatar reference/URL. Live spectator views are designed not to reveal hidden hand contents, hidden library contents, private search/peek/scry contents, or owner-only permission prompts.
Replay recordings are created only for completed multiplayer games, not solo practice. A replay contains spectator-safe game state, public game log entries, public game events, cosmetic events such as emotes, hover/selection, and arrows, room/match metadata, and participant display metadata such as display name, seat, user class, and avatar reference/URL. Replays are designed not to store private per-player information such as hidden hand contents, hidden library contents, private search/peek/scry contents, or owner-only permission prompts.
Each participant receives a separate replay copy with independent retention, sharing, and deletion controls. If you enable sharing for your copy, the replay becomes accessible to anyone who has the unlisted public link until you revoke sharing, delete the copy, or the copy expires.
Uploaded card images are user-generated content. They can be used as full custom card faces or as artwork inside generated custom-card frames. The image reference is stored as an internal asset ID; temporary signed media URLs are regenerated when needed for authorized display and are not intended to be permanent public links. When you delete an uploaded image, we remove saved-deck references to that image while leaving the custom cards themselves in place. Administrators can review uploaded image assets and image reports, including uploader and reporter account IDs, upload/report IP addresses and user-agents, image hashes, file metadata, and moderation status. If an upload appears to contain illegal content, we may preserve relevant evidence and report it to appropriate authorities or legally required reporting channels.
2.3 Technical Data
| Data | Stored | Retention |
|---|---|---|
| IP address | Reverse proxy access logs only | Kept per server log rotation policy (typically 30 days) |
| Upload/report IP address and user-agent | Stored only with uploaded image assets and image reports | Kept with the related image or report record as described above |
| WebSocket connection identifiers | In-memory only | Lost on server restart |
| JWT authentication token | Client-side (your browser localStorage) only | Expires after 24 hours |
2.4 Feedback
You may submit anonymous feedback through the in-game feedback form. When you do, we store only the message text and a timestamp. We do not store your user ID, email address, IP address, or any other identifying information alongside your feedback. Feedback messages cannot be traced back to your account.
Because feedback is anonymous, it does not constitute personal data. However, please avoid including personal information (such as your real name or email address) in feedback messages, as we cannot attribute or delete individual anonymous submissions.
2.5 Data We Do NOT Collect
- Email addresses
- Google profile picture or avatar URLs
- Real names
- Passwords (Google handles authentication)
- Phone numbers
- Location or GPS data
- Browser fingerprints or device identifiers
- Keystroke or behavioral analytics
- Payment information
- Chat messages (there is no chat feature)
- Hidden hand/library/search/peek/scry contents in live spectator views or replay recordings
3. Legal Basis for Processing (GDPR Art. 6)
| Processing Activity | Legal Basis |
|---|---|
| Account creation and authentication | Contractual necessity β required to provide the service (Art. 6(1)(b)) |
| Storing match history, deck data, and game type definitions | Contractual necessity β core features of the service (Art. 6(1)(b)) |
| Hosting uploaded custom card images for private decks, games, spectators, and replay views | Contractual necessity β custom card image display is a user-facing service feature (Art. 6(1)(b)) |
| Enforcing uploaded card image storage quotas and per-account quota overrides | Contractual necessity β needed to provide and limit the uploaded image feature (Art. 6(1)(b)) |
| Hashing uploaded images, storing upload/report IP and user-agent metadata, handling image reports, removals, and takedowns | Legitimate interest β abuse prevention, platform safety, legal compliance, and rights enforcement (Art. 6(1)(f)) |
| Providing authenticated live spectating when the host allows it | Contractual necessity β live spectating is a user-facing service feature (Art. 6(1)(b)) |
| Recording, retaining, and playing multiplayer replays; enabling user-controlled replay sharing | Contractual necessity β replay playback and sharing are user-facing service features (Art. 6(1)(b)) |
| Providing Supporter status and associated benefits | Contractual necessity β required to deliver the chosen features of the service (Art. 6(1)(b)) |
| IP address logging (reverse proxy) | Legitimate interest β server security and abuse prevention (Art. 6(1)(f)) |
| Ban enforcement and moderation | Legitimate interest β maintaining a safe environment (Art. 6(1)(f)) |
| Admin audit logging | Legitimate interest β accountability and security (Art. 6(1)(f)) |
4. Cookies and Local Storage
Cookies
Command Tower's game client does not use cookies. The admin dashboard uses a single authentication cookie (.AspNetCore.Identity.Application) that expires after 8 hours and is strictly necessary for admin sessions.
Browser Local Storage
The game client stores the following in your browser's localStorage:
| Key | Purpose | Lifetime |
|---|---|---|
sg_token | Authentication token (JWT) | Until expiry (24 hours) or logout |
sg_user | Cached user info (ID, display name, selected avatar reference and resolved URL) | Until logout |
sg_current_room | Room code for reconnection | Cleared on logout or room exit |
sg_settings | User preferences (e.g. high-quality card preview toggle, card drift, zone snap distance) | Until manually cleared |
We do not use any tracking cookies, analytics scripts, or advertising pixels.
5. Third-Party Services
5.1 Google OAuth 2.0
We use Google's OAuth 2.0 service solely for authentication. When you click "Login with Google," you are redirected to Google, which shares only your Google account identifier (subject ID) with us. We do not request, read, or store your Google email address, real name, profile picture, or avatar URL. Google's privacy policy applies to data Google processes: https://policies.google.com/privacy.
OAuth scopes requested: openid
Note: We use the OpenID Connect subject ID to identify your account. We do not request Google's
profilescopes.
5.2 Cloudflare
We use Cloudflare for DNS management, DDoS protection, reverse proxying, and private R2 object storage for uploaded custom card image variants. When you access Command Tower, your connection passes through Cloudflare's network, which may process your IP address and HTTP request metadata (such as URL and headers) in transit. Uploaded card image objects are stored in a private R2 bucket with EU jurisdiction and are served through GridServer signed media URLs rather than public bucket URLs. We may also use Cloudflare security and abuse-detection features, such as WAF/rate limiting and CSAM scanning where enabled, as supplementary controls. Cloudflare's privacy policy: https://www.cloudflare.com/privacypolicy/.
5.3 Scryfall API
We fetch publicly available trading card game data (card names, images, rules text) from the Scryfall API. No personal data is sent to Scryfall. Scryfall's privacy policy: https://scryfall.com/docs/privacy.
5.4 No Other Third Parties
We do not use any analytics services (Google Analytics, Mixpanel, etc.), advertising networks, or payment processors.
6. Data Transfers
All data is processed and stored on servers located in the European Union. We do not transfer your personal data outside the EU/EEA, with the following exceptions:
- Google OAuth: When you sign in, your browser communicates directly with Google's servers (which may be located outside the EU). This interaction is governed by Google's privacy policy and their compliance with applicable data transfer mechanisms.
- Cloudflare: Your connection passes through Cloudflare's global network, which may route traffic through servers outside the EU. Cloudflare processes only transit data (IP address, request metadata) and operates under EU Standard Contractual Clauses (SCCs).
7. Data Retention
| Data | Retention Period |
|---|---|
| Account data (Google account identifier, display name, selected in-game avatar reference, Supporter/Staff flags, Supporter expiry/ended timestamps, uploaded card image quota override if set) | Until you request deletion |
| Anonymized account reference for statistics | Retained after account deletion without Google identifier, avatar, Supporter/Staff status, or display name; used only to preserve aggregate match and room statistics |
| Keyed ban-enforcement hash for deleted banned accounts | Retained until an administrator removes the retained ban; stores a keyed hash of the login identity, provider, ban dates, and ban reason, not the raw Google identifier |
| Supporter status and expiry date | Until you request deletion, or until the status is removed or expires |
| Match history | Indefinite; account/profile identifiers are anonymized and per-player deck snapshots are cleared upon account deletion |
| Replay copies for regular accounts | 14 days after the multiplayer game ends, unless deleted earlier |
| Replay copies for active Supporters | Retained without expiry while Supporter status remains active, unless deleted earlier |
| Replay copies after Supporter status ends | Expire 14 days after Supporter status ended. If Supporter status is restored before deletion, non-expired copies are kept without expiry again |
| Shared replay links | Active until the replay owner revokes sharing, deletes the replay copy, the copy expires, or the underlying replay payload is removed |
| Shared replay payloads | Removed when no participant replay copies remain. If an account is deleted, that user's own replay copies are removed and their display name, avatar, and user reference are scrubbed from replay copies retained by other participants |
| Saved decks | Until you delete them, or upon account deletion |
| Uploaded card image assets and stored objects | Until you delete them, or upon account deletion, unless temporarily retained for an active moderation, legal, or takedown case. Owner deletion removes saved-deck references and deletes stored objects unless moderation retention applies |
| Uploaded image reports and moderation actions | Retained as needed for moderation, safety, legal compliance, and auditability |
| Personal game type definitions | Until you delete them, or upon account deletion |
| Active game state (Redis cache and database snapshots) | Automatically deleted when games end or cache expires; deleted immediately for active rooms abandoned during account deletion |
| Inactive room data | Marked as abandoned after 30 minutes of inactivity |
| Reverse proxy access logs (IP addresses) | Per server log rotation policy (typically up to 30 days) |
| Admin audit logs | Retained indefinitely for accountability |
8. Your Rights Under GDPR
As a data subject in the EU/EEA, you have the following rights:
| Right | How to Exercise |
|---|---|
| Access (Art. 15) | Request a copy of all personal data we hold about you |
| Rectification (Art. 16) | Request correction of inaccurate data |
| Erasure (Art. 17) | Delete your account and associated data |
| Restriction (Art. 18) | Request that we limit processing of your data |
| Data Portability (Art. 20) | Receive your data in a machine-readable format |
| Objection (Art. 21) | Object to processing based on legitimate interest |
| Withdraw Consent | Where processing is based on consent, withdraw it at any time |
How to Make a Request
- Account deletion: Use the account deletion feature in the app settings, or email us at [email protected]. Deletion removes your saved decks, loaded room decks, personal game type definitions, uploaded card images unless retained for an active moderation/legal case, active game snapshots, login identifiers, avatar data, Supporter/Staff status, uploaded card image quota override, ban fields, and your own replay copies. Match and room statistics may be retained only with your account/profile data anonymized; historical deck snapshots attached to your match records are cleared. If replay copies are retained by other participants, your user reference, display name, avatar, and user class are scrubbed and public replay log/cosmetic references to your display name are replaced on a best-effort basis with "Deleted User." If a banned account is deleted, we may retain a keyed hash of the login identity, provider, ban dates, and ban reason solely to enforce the ban until an administrator removes it.
- All other requests: Email [email protected]. We will respond within 30 days as required by GDPR.
Right to Lodge a Complaint
If you believe your data protection rights have been violated, you have the right to lodge a complaint with your local data protection authority. In Croatia, this is the Agencija za zaΕ‘titu osobnih podataka (AZOP) at https://azop.hr/.
9. Data Security
We implement the following measures to protect your data:
- Authentication: Google OAuth 2.0 with JWT tokens; no passwords stored for game accounts
- Admin passwords: Hashed using PBKDF2 with ASP.NET Core Identity
- Transport encryption: All connections secured via TLS/HTTPS
- Access control: Admin dashboard is separate from the game server with its own authentication
- Audit trail: All administrative actions (bans, account modifications) are logged
- Private uploaded media: Uploaded card images are stored in a private R2 bucket and served through short-lived signed GridServer URLs
- Upload safety controls: Uploaded images are validated, metadata-stripped through re-encoding, storage-quota checked, and subject to reports, moderation review, removal, and supplementary Cloudflare security controls where enabled
- Automatic cleanup: Ephemeral game state is automatically deleted after games end; replay copies expire according to the retention rules above
- Spectator-safe filtering: Live spectator views and replay recordings use the spectator-safe game view and are intended to exclude hidden hand/library/search/peek/scry information
- Minimal data collection: We deliberately collect as little personal data as possible
10. Children's Privacy
Command Tower is intended for users aged 13 and older. We do not knowingly collect personal data from children under 13. Since we use Google OAuth for authentication, users must have a Google account, which itself requires meeting Google's age requirements.
If you are a parent or guardian and believe your child under 13 has accessed Command Tower, please contact us at [email protected] and we will promptly delete the account.
For users in EU member states that set a higher age of digital consent (up to 16 under GDPR Art. 8), parental consent may be required. Since Command Tower does not collect email addresses or other direct contact information, we rely on Google's age verification through their OAuth service.
11. Moderation and Bans
Administrators may ban accounts that violate our terms of use. When a ban is issued, we store:
- Whether the account is banned (yes/no)
- The date the ban was applied
- The reason for the ban
All moderation actions are recorded in an audit log for accountability. Banned users are prevented from joining games but may still request data access or deletion.
For uploaded image moderation, administrators may review reported images, related uploader and reporter account profiles, upload/report IP addresses, upload/report user-agents, original file names, stored byte sizes, dimensions, SHA-256 hashes, perceptual hashes, report reasons/messages, and moderation actions. This information is used to investigate abuse, rights complaints, illegal content, safety issues, and takedown requests.
If a banned account is deleted, the ordinary account record is anonymized and its raw login identifier is removed. A separate retained ban record may keep a keyed hash of the login identity, provider, ban dates, and ban reason so the same login identity cannot immediately re-register to evade the ban. Administrators can remove this retained ban record after review.
12. Changes to This Policy
We may update this Privacy Policy from time to time. When we make material changes, we will update the "Last updated" date at the top of this page.
We encourage you to review this policy periodically. Continued use of Command Tower after changes constitutes acceptance of the updated policy.
13. Contact Us
For any questions about this Privacy Policy or your personal data:
Pannonia Code d.o.o.
Email: [email protected]