Members, Roles and Staff
Invite teammates as Owner, Developer, Moderator, Finance or Support, grant in-game staff ranks for ::commands, and read the audit log.
9 min read
Two kinds of access#
A game has two separate permission systems, managed on two separate pages under Team in the game sidebar:
| Page | Controls | Identity used |
|---|---|---|
| Members | Who can open this game's dashboard, and which pages they see | A Vastopia account, invited by email |
| Staff Ranks | Who has in-game powers: built-in ::commands and HasRank checks in your scripts | A player ID, as seen by the game server |
They do not overlap. Inviting someone as a dashboard Moderator gives them no power inside the game, and granting a player the in-game Admin rank gives them no access to the dashboard. Both pages, and the Audit page that records changes to them, are Owner-only.
Dashboard roles#
Every member has exactly one role. The role is a bundle of capabilities, and each dashboard page is gated on one capability: the sidebar hides entries you cannot use, and opening a gated URL directly shows "Insufficient permissions" with the missing capability's name.
Capability matrix#
| Capability | Unlocks | Owner | Developer | Moderator | Finance | Support |
|---|---|---|---|---|---|---|
server.read | Live → Overview, Live → Logs, the online-player roster | Yes | Yes | Yes | — | Yes |
server.shutdown | Live → Server (shutdown, drain, restart, maintenance, announce) | Yes | Yes | — | — | — |
version.deploy | Builds, update posts, beta and scheduling on the game page's Update and History tabs | Yes | Yes | — | — | — |
players.read | Live → Players, Data → Player Search, player profiles and the activity feed | Yes | Yes | Yes | — | Yes |
mod.act | Data → Moderation | Yes | — | Yes | — | — |
data.browse | Data → Data Browser | Yes | Yes | — | — | — |
analytics.read | Game → Analytics | Yes | Yes | Yes | — | Yes |
shop.manage | Shop → Items, Shop → Shop Analytics | Yes | Yes | — | — | — |
revenue.read | The game's revenue page (/dashboard/{gameId}/revenue) and billing details | Yes | — | — | Yes | — |
shop.payout | Payouts (account-level, under Payouts in the main sidebar) | Yes | — | — | Yes | — |
members.manage | Team → Members, Team → Staff Ranks | Yes | — | — | — | — |
audit.read | Team → Audit | Yes | — | — | — | — |
In words:
- Owner — everything. The owner is the account that pushed the game's first build from the editor; the role cannot be assigned to anyone else from the dashboard.
- Developer — runs the game: deploys builds, controls the server, reads logs, browses data, manages shop items, and can see players. Cannot moderate from the Moderation page, manage the team, or see money.
- Moderator — watches and moderates: overview, logs, players, sanctions and reports, analytics.
- Finance — money only: revenue and payouts.
- Support — read-only on operations: overview, logs, players, analytics.
Where the dashboard shows a page, the platform enforces the same rule on the request, so a hidden page cannot be reached by guessing the URL. Which pages each role sees is summarized on the Creator Dashboard overview.
Members#
Team → Members (/dashboard/{gameId}/members) lists the team and, for the owner, offers the invite form. The page is visible only to the Owner.
Invite a member#
- Open Team → Members.
- In Invite a member, enter the teammate's Email and choose a Role from Developer, Moderator, Finance or Support (Moderator is preselected).
- Click Invite. A green "Invited EMAIL." confirmation appears and the person joins the Team list.
What happens next depends on whether the email already belongs to a Vastopia account:
- Existing account — access is granted immediately.
- No account yet — the invite is held and the row shows a Pending badge. When someone signs up with that exact email, the invite resolves automatically and access begins.
Either way, send them the game's dashboard URL (/dashboard/{gameId}). The My Games grid on /dashboard lists only games you own, so an invited game does not show up there; the game's sidebar and the pages their role allows appear as soon as they open that URL.
The form refuses a few cases: an email already on the team ("That email is already a member of this game."), an email that has already been invited, and the owner's own address ("Invitee is already the game owner"). Emails are lowercased before they are compared and stored, so capitalization differences do not create duplicates.
Change a role or remove a member#
The Team list shows each member's avatar, username (or email), their email beneath it, and badges: Root owner for the owning account and Pending for an unaccepted invite.
- To change a role, pick a new value from the Role dropdown in the row. The change applies immediately and a "Updated role to ROLE." confirmation appears.
- To remove someone, click Remove in the row and confirm in the Remove member dialog: "They will immediately lose access to this game's dashboard. You can re-invite them later."
The root owner's row has no dropdown and no Remove button. Other members see the list read-only, without the invite form or any controls.
Every invite, role change and removal is written to the audit log as member.invited, member.role_changed or member.removed.
In-game staff ranks#
The game server gives every player a numeric rank. Ranks gate the built-in chat commands and are readable from your own scripts, so they are how you appoint in-game helpers without writing any code.
| Rank | Label | What the server allows |
|---|---|---|
| 0 | Player | The player-safe commands only: ::gender, ::home, ::run, ::togglerun, ::walk, ::clearmove, ::moveinfo, ::rank, ::setname, ::whois |
| 1 | Moderator | Everything a player can do. ::whois additionally reveals the looked-up player's raw ID to staff. No item or teleport commands |
| 2 | Admin | Every built-in command — the server treats any built-in not on the player-safe list as Admin-only, including spawning items, teleporting and reloading scripts |
| 3 | Owner | Everything an Admin can do, plus ::setrank |
A player who lacks the rank for a built-in command is told "Unknown command." rather than "permission denied", so the command set is not discoverable by ordinary players. Commands you write yourself are checked before this gate and carry their own rank requirement; in a script, the player object's HasRank(2) is true for rank 2 and above. See Commands.
The game's owner is always rank 3 on their own server — no grant needed, and it cannot be removed. That is what prevents locking yourself out: the first rank has to come from somewhere, and the owner is it.
Grant a rank#
- Open Team → Staff Ranks (
/dashboard/{gameId}/staff). - In Grant a rank, enter the Player ID. If the player is online right now, an Online now — click to fill row lists up to 12 connected players who are not yet staff; click one to fill the field.
- Choose the Rank: Moderator, Admin or Owner. A one-line description of the chosen rank appears beneath the form.
- Optionally add a Note (optional) — for example why this player has staff access. Notes are kept with the grant and shown in the list.
- Click Grant. The confirmation reads "NAME is now RANK. Live servers apply this within ~5s."
Granting to a player who already holds a rank simply changes it. The player ID is the same identity used by Player Search and sanctions; see Players and moderation for how to find it.
Change or remove a rank#
The Staff list shows each staff member with a rank badge, their player ID, the note, and when the grant was last changed. The owner's implicit entry carries a Game owner badge and reads "Always Owner" in place of a dropdown.
- Change a rank with the dropdown in the row.
- Click Remove and confirm Remove rank: "NAME will drop to a normal player and immediately lose access to staff commands. You can re-grant a rank later."
How ranks reach the server#
The platform sends the whole staff list to your game server on every control poll, about every 5 seconds. An online player whose rank changed is updated on the spot and sees a chat message ("Your staff rank is now RANK." or "Your staff rank has been changed to RANK."); a player who is offline gets the new rank at their next login. Because the list is sent whole, removing a player from it is what demotes them — there is no separate revoke.
Locally, the picture is different: Play Local starts the server with every player as rank 3 so you are never locked out of commands while testing, and a server that has not yet received a staff list falls back to the rank saved in each player's own save file. See Test your game.
Grants and removals are audited as staff.set_rank and staff.remove.
Audit log#
Team → Audit (/dashboard/{gameId}/audit) is the owner's record of "every mutating action taken by anyone with access to this game's dashboard", retained for one year. Each entry shows the time, the action name as a badge, the actor's account ID, and a plain-language description for member actions.
The list polls for new entries every 5 seconds while the tab is visible and loads older entries as you scroll, 50 at a time. Filter with Action (All actions, Member invited, Member role changed, Member removed) and Actor (Clerk user ID) — paste an account ID and click Apply or press Enter.
Actions you will see, grouped by where they come from:
| Prefix | Actions | Page |
|---|---|---|
member. | invited, role_changed, removed | Members |
staff. | set_rank, remove | Staff Ranks |
mod. | warn, mute, kick, ban, revoke, report_resolved | Moderation and player profiles — see Players and moderation |
server. | kick, shutdown, shutdown_scheduled, shutdown_cancelled, drain, resume, restart_now, restart_scheduled, restart_cancelled, maintenance_set, maintenance_cleared, announce, announce_cleared | Server and Players — see Server controls and logs |
data. | db.query, db.insert, db.insert_many, db.patch, db.replace, db.update_many, db.delete, db.delete_many, db.aggregate, db.schema, db.list_collections, db.list_indexes, db.create_index, db.drop_index, db.set_redaction_config, player_get, snapshot_download | Data Browser — see Data browser |
revenue. | refund_issued | Revenue — see Shop, revenue and payouts |
engine. | update_started | The engine-update banner on the game page |
Only the three member actions get a descriptive sentence ("Invited EMAIL as ROLE", "Changed EMAIL to ROLE", "Removed member ID"); everything else shows its action name, and the details live on the page that performed it.
Setting up a small team#
- Invite the people who ship builds as Developer. They can push and deploy, restart the server and read logs, but cannot touch revenue or the team.
- Invite community helpers as Moderator on Members so they can read reports and apply sanctions from the dashboard, then grant the same people the in-game Moderator rank on Staff Ranks if you also want them recognized as staff in chat.
- Reserve in-game Admin for yourself and trusted developers: it can spawn any item and teleport anywhere.
- Give an accountant Finance; they see nothing operational.
- Check Audit periodically. Every grant, invite, sanction and server action is there, with who did it.
With AI (MCP)#
Team membership, staff ranks and the audit log have no MCP tools; they are managed on the dashboard only.
