Data Browser
Browse and query your game's saved player and world data, inspect schemas, edit documents as the owner, and download automatic backups.
11 min read
What the Data Browser is#
The Data Browser (/dashboard/{gameId}/data, under the Data group of a game's sidebar) is a Compass-style window onto the data your live server persists. Every game gets its own database on the platform, and the server writes player saves and shared world stores into it. The browser lets you look at that data without touching the server, run ad-hoc queries and aggregations, inspect what fields exist, and — for the game owner — correct individual records.
It also exposes three things that come from the running server itself: the list of players who have played recently, the items.json and npcs.json config files the server is actually using, and the automatic backups it uploads every six hours.
| Who | Can |
|---|---|
| Owner | Everything below, including edit, insert, delete, bulk operations, index changes and redaction settings |
| Developer | Browse, query, schema, aggregate, list indexes, download snapshots |
| Moderator, Support, Finance | No access (the entry is hidden; the page needs the data.browse capability) |
Every query and write is recorded in the game's Audit log under a data.db.* action (for example data.db.query, data.db.replace, data.db.delete_many), and snapshot downloads under data.snapshot_download. See Members, roles and staff.
Layout#
The page takes the full width of the dashboard. A Sources rail on the left lists what you can open; the main pane shows the selected source. The rail has a Search sources… box, a collapse button, and two buttons at the bottom: Refresh Mongo (re-reads the collection list and counts) and Settings (credential status and PII redaction — see below).
Live server sources#
| Source | Sublabel | What it shows |
|---|---|---|
| players | who played | Everyone seen in the last 30 days, with login/logout sessions and an account summary |
| items | config | The data/items.json file on the live server, rendered as an expandable JSON tree |
| npcs | config | The data/npcs.json file on the live server |
| snapshots | R2 backups | The automatic backups of the player database, with download links |
items and npcs are fetched through the server's 5-second control poll, so they take a few seconds to appear and fail with "Timed out waiting for game server (is it running?)" after 30 seconds if the server is down. They are the same files the editor exports on publish — use them to confirm that a deploy actually shipped the content you expected. See Data editor for what these files contain.
Mongo collections#
Below the live sources, the Mongo section lists every collection in the game's database with its document count. A brand-new game shows "No collections yet." until the first player save lands. The server creates:
| Collection | Contents |
|---|---|
players | One document per player account: username, position, health and level, inventory, equipment, bank, skill XP, script variables (Vars) and staff rank |
world_data | Shared world stores written by scripts through ScriptWorld.GetStore(...) — minigame state, global counters, anything not tied to one player |
Player documents are keyed by Username, which carries a unique index; Username — not _id — is the player's real identity.
The players source#
The players pane is a master-detail view. The left column lists players by name with their id and "last seen" age; type in Search by player name… to filter (results cap at 200 and say "Results truncated" when there are more). Select a player to see:
- Four tiles: Last login, First seen, Total play time (with the session count) and Purchases (with the count of recent events).
- A Logins & logouts table with one row per session — Login, Logout (or "in-game now") and Duration.
- A Full profile → link to the player's page under Player Search, covered in Players and moderation.
This view is built from the activity store, not from save files, so it works even when the server is offline. To see a player's actual saved document, open the players collection and filter by Username.
Browsing a collection#
Selecting a collection opens it in the Documents view. The header shows the collection name, its document count and four view buttons: Documents, Schema, Aggregate and Indexes.
Filter#
The filter bar has two modes:
- Raw — a JSON object in MongoDB query syntax, for example
{ "Username": "nucky" }or{ "Level": { "$gte": 50 } }. Press/anywhere on the page to focus it andEscto clear it. Invalid JSON shows an error under the bar and the previous results stay. - Builder — rows of field, operator, value that compile to the same JSON. Operators:
=,≠,>,≥,<,≤, contains, starts with, in (CSV), exists and missing. Values are coerced automatically: numbers become numbers,true/falsebecome booleans,nullbecomes null, anything else stays a string. contains and starts with are case-insensitive.
The filter applies about a third of a second after you stop typing and resets you to page 1. × clear filter removes it.
Toolbar#
| Control | Action |
|---|---|
| Refresh | Re-runs the current query |
| Export | Downloads the documents matching the filter as {collection}-{timestamp}.json (up to 5,000; a warning tells you to tighten the filter if there were more) |
| Cards / Table | Switch between one expandable JSON card per document and a grid with one column per top-level field. In table view, click a column header to sort ascending, again for descending, a third time to clear |
| Bulk (owner only) | Opens the bulk insert / update / delete dialog |
| + Insert (owner only) | Opens the insert dialog |
| Auto-refresh 5s | Re-runs the query every five seconds while you stay on the Documents view |
The footer shows start–end of total, a Page size selector (10, 25, 50, 100 or 200; default 25), ← Prev / Next → and a page-number box you can type into.
Keyboard navigation in card view: j / ↓ and k / ↑ move the focused card, g / G jump to the first and last card, Enter expands or collapses the focused card.
Document cards#
Each card's header shows its position on the page, the _id, a field count, a copy button (copies the JSON), and for owners Edit and Delete. Cards open expanded; click the header to collapse. Fields listed in the redaction settings display as [redacted].
Editing data (owner)#
Quick set or unset a field#
Under an expanded card, + Quick set/unset a field opens a one-line editor:
- Type or pick a dotted path (the list suggests paths from the document, for example
Inventory.3.Amount). - Choose set or unset.
- For set, enter the value —
true,false,null, numbers and valid JSON are parsed as those types; everything else is stored as a string. - Click Apply. The card reloads with the change.
Paths containing $ are refused, so you cannot inject operators by accident.
Replace the whole document#
Edit turns the card into a JSON editor pre-filled with the current document. Save replaces the entire document; _id is locked to the existing value and any _id in the text is ignored. If the document carries a version marker and changed on the server since you opened it, the save is refused with "Document changed since you opened it" — collapse and re-open the card to load the latest version. Cancel discards the edit.
Insert#
+ Insert opens a dialog with an empty JSON object. Paste or type the document and click Insert; _id is generated if you omit it. On an empty collection the Documents view also offers + Insert the first document.
Delete#
Delete on a card asks for confirmation naming the _id and collection; the dialog warns that this cannot be undone from the dashboard.
Bulk operations#
Bulk opens a dialog with three tabs:
| Tab | Input | Confirmation |
|---|---|---|
| Insert | A JSON array of documents, at most 1,000 per call | None |
| Update | A filter JSON object, a set object of paths and values, and a comma-separated unset list | Type the collection name |
| Delete | A filter JSON object | Type the collection name |
An empty filter on Update or Delete means the whole collection; the dialog refuses it unless you tick I mean ALL documents (empty filter = whole collection). The result line reports how many documents were inserted, matched and modified, or deleted.
Fields you cannot write#
Regardless of role, the browser refuses any insert, replace, patch or bulk write that touches a field whose name is isModerator, isAdmin, isOwner, password, passwordHash, roles or permissions, at any depth. Those are read by the server for authorization decisions, so they are managed through Staff Ranks and the platform rather than by editing documents.
Schema view#
Schema samples 100 documents at random and lists every field path found:
| Column | Meaning |
|---|---|
| Field | Dotted path. A redacted badge marks fields whose values are blanked by the redaction list |
| Types | BSON/JSON types seen at that path across the sample |
| Cardinality | Distinct values in the sample (shown as "1024+ (capped)" beyond that), with a hint such as "low — enum-like" or "all distinct" |
| Frequency | Share of sampled documents that contain the field, as a bar and percentage |
Click a row to see up to five sample values. The result is cached for the session; Resample draws a fresh sample. An empty collection shows "No fields — collection is empty."
Aggregate view#
Aggregate runs a read-only aggregation pipeline. Write the pipeline as a JSON array of stages in the editor, or start from one of the templates — Count by field, Top N by numeric field, Distinct values and Recent N — and replace the <field> placeholders. Click Run pipeline or press Ctrl+Enter (Cmd+Enter on macOS).
Rules the platform enforces:
- Only read-only stages are accepted:
$match,$project,$group,$sort,$limit,$skip,$count,$lookup,$unwind,$facet,$addFields,$sortByCount,$bucketand$bucketAuto. Writing stages such as$outand$mergeare rejected. - At most 50 stages.
- Results are capped at 1,000 documents (the page says "capped at 1,000" and suggests a smaller
$limit) and the query times out after 10 seconds.
Results appear as collapsible cards with a copy button, along with the elapsed time.
Indexes view#
Indexes lists each index with its Name, Key (field and direction), Properties (unique, sparse) and Size. The automatic _id_ index is marked primary and cannot be dropped.
Owners can click + Create index, add one or more key fields in order (order matters for compound indexes), choose ascending or descending per field, tick unique or sparse, optionally name the index, and Create. Drop on any other index asks for confirmation.
Snapshots (backups)#
The snapshots source lists automatic backups of the player database. The live server exports the players collection as NDJSON, bundles it with anything under its data/saves/ folder and a manifest.json, uploads the archive as a compressed tar, and records a row here. It runs every six hours, but a run that finds nothing changed since the previous archive stores no duplicate, so a quiet game shows about one per day.
| Column | Meaning |
|---|---|
| Captured | When the archive was taken |
| Records | Player records captured, plus any save files |
| Size | Archive size |
| Download | Opens a short-lived download link (valid for 10 minutes) in a new tab |
Before restoring from an archive, read its manifest.json: playerExportStatus is ok for a complete export and truncated if the export hit its size ceiling. The manifest also carries the mongoimport command to restore the players collection and notes that files under saves/ go back into data/saves/. There is no one-click restore on the dashboard.
If the list stays empty on a live game that has players, open Logs and filter by the DataSnapshot tag: the server logs why it refused to record a backup. See Server controls and logs.
Database settings#
Settings at the bottom of the rail opens the Database settings dialog:
- Mongo credential — reports whether the game uses a Scoped per-game database user (shown with its username; rotated every 30 days on the next deploy) or is still on the shared cluster credential, which switches to a scoped one at the next deploy. This is informational.
- PII redaction — field names whose values are shown as
[redacted]in the browser. The platform defaults cover secrets and identifiers such aspassword,passwordHash,authToken,apiKey,ipAddress,deviceIdandemail, and cannot be removed. Owners can Add extra names (alphanumeric and underscore; matched case-insensitively on the leaf field name, not on nested paths) and Save.
Redaction applies to what the dashboard displays and exports; it does not change the stored data.
Common tasks#
Find a player's saved inventory#
- Open the
playerscollection. - In Raw filter mode enter
{ "Username": "<their username>" }. - Expand the card and open the
Inventoryarray in the JSON tree.
Fix a stuck quest flag#
- Make sure the player is offline (the players source shows "in-game now" for open sessions).
- Find their document as above and open + Quick set/unset a field.
- Script variables live in the
Varsarray asK/Vpairs, so the path looks likeVars.4.V; set the new value and apply.
Count players per region#
- Open the
playerscollection and switch to Aggregate. - Click Count by field and replace
<field>withRegion. - Press
Ctrl+Enter.
With AI (MCP)#
The MCP tools work on your project files rather than the live database — get_schema_data and set_schema_row edit the schema-driven JSON tables under server/data/, and read_server_logs reads the server console where DataSnapshot and save errors are reported. Browsing or editing live player documents is a dashboard-only operation.
