Permissions
Bots receive permissions as a Discord-shape 53-bit integer bitfield. The bits and meanings match Discord; the values come from GameVox's native group + channel permission tables. Bits without a GameVox equivalent return 0.
Native → Discord mapping
| Discord bit | Hex | GameVox source |
|---|---|---|
| ADMINISTRATOR | 0x8 | groups.group_type IN ('owner', 'admin') |
| VIEW_CHANNEL | 0x400 | channel_permissions.view_channel / group_permissions.view_channels |
| READ_MESSAGE_HISTORY | 0x10000 | Same as VIEW_CHANNEL (no separate history toggle) |
| SEND_MESSAGES | 0x800 | send_messages |
| MANAGE_MESSAGES | 0x2000 | manage_messages |
| EMBED_LINKS | 0x4000 | can_post_links |
| ATTACH_FILES | 0x8000 | send_files |
| ADD_REACTIONS | 0x40 | add_reactions |
| MENTION_EVERYONE | 0x20000 | Admin-only in v1 |
| CONNECT (voice) | 0x100000 | join_voice |
| SPEAK | 0x200000 | speak_in_voice |
| STREAM (screen share) | 0x200 | screen_share |
| USE_VAD | 0x2000000 | use_vad (default true; setting false forces PTT) |
| KICK_MEMBERS | 0x2 | kick_users != 'deny' |
| BAN_MEMBERS | 0x4 | ban_users != 'deny' |
| MUTE_MEMBERS | 0x400000 | mute_users != 'deny' |
| MOVE_MEMBERS | 0x1000000 | move_users != 'deny' |
| MANAGE_CHANNELS | 0x10 | create_channels / edit_channels / delete_channels all not 'deny' |
| MANAGE_GUILD | 0x20 | edit_server != 'deny' |
| MANAGE_ROLES | 0x10000000 | manage_members |
| MANAGE_NICKNAMES | 0x8000000 | manage_members (bundled with MANAGE_ROLES) |
| CHANGE_NICKNAME | 0x4000000 | Always granted (matches Discord default) |
| MANAGE_WEBHOOKS | 0x20000000 | Owner / admin in v1 |
| VIEW_AUDIT_LOG | 0x80 | Owner / admin in v1 |
| PRIORITY_SPEAKER | 0x100 | priority_speaker |
| MANAGE_EVENTS | 0x200000000 | manage_events != 'deny' |
| CREATE_EVENTS | 0x100000000000 | manage_events != 'deny' (bundled with MANAGE_EVENTS) |
| MANAGE_GUILD_EXPRESSIONS | 0x40000000 | manage_emojis != 'deny' |
| CREATE_GUILD_EXPRESSIONS | 0x80000000000 | manage_emojis != 'deny' (bundled) |
| DEAFEN_MEMBERS | 0x800000 | deafen_users != 'deny' |
| SEND_MESSAGES_IN_THREADS | 0x4000000000 | send_messages (bundled with SEND_MESSAGES) |
Default-on bits
These are set for every non-deny member, matching Discord's default role behavior. If your bot logic checks for them, they will always appear granted (unless the member is banned):
CREATE_INSTANT_INVITE(0x1)USE_APPLICATION_COMMANDS(0x80000000)USE_EXTERNAL_EMOJIS(0x40000)USE_EXTERNAL_STICKERS(0x2000000000)
Bits that always return zero
These have no equivalent in GameVox yet and are reported as unset. Bots that depend on them should degrade gracefully (most libraries treat a denied bit as “feature not supported here” already).
MANAGE_THREADS,USE_PUBLIC_THREADS,USE_PRIVATE_THREADS: threads are stubbed in v1.MODERATE_MEMBERS(timeout): no native equivalent.USE_EMBEDDED_ACTIVITIES: no Activities feature.USE_SOUNDBOARD,SEND_VOICE_MESSAGES: not implemented.- Monetization bits: no Premium Apps.
Permission computation
Identical to Discord's 7-step algorithm:
- Start with
@everyonepermissions for the guild. - OR in every role the member has.
- If the result includes ADMINISTRATOR, short-circuit: they have everything.
- Apply
@everyonechannel overwrites (allow then deny). - Apply each role's channel overwrites (allow then deny).
- Apply the user's channel overwrites (allow then deny).
- If the channel is in a category, the category's overwrites apply at the role / user step too.
Step 2 is where the difference below shows up: a GameVox member is in one group, so there is one role to OR in. See One group per member.
One group per member
The biggest behavioural difference from Discord. A GameVox member belongs to exactly one group per server, where a Discord member can hold many roles at once. Assigning a group replaces whatever group the member was in.
The role endpoints still work, and the libraries you already use still call them — they just resolve to that one group:
| Call | What happens |
|---|---|
PUT .../members/{id}/roles/{rid} | The member ends up in that group. Their previous group is replaced, not kept alongside. |
DELETE .../members/{id}/roles/{rid} | Removes it. If that was their only group they fall back to the server's default group rather than ending up in none. |
PATCH .../members/{id} with roles: [...] | Accepted, then collapsed to the highest-ranked group in the list. An empty list means the default group. |
A list is collapsed rather than rejected so an ordinary member.roles.set([...]) keeps working. Highest rank wins because rank is what decides standing: given a moderator group and a colour group, the member is a moderator.
Groups carry upload, voice, camera and screen-share ceilings, and a member gets the most generous ceiling among the groups they are in. With one group that is simply their group’s ceiling — which is the other reason an app cannot hold someone in two, since it would be a way to lift a cap the operator set.
An application's own group — the one its install created — is not affected by any of this. Its membership belongs to the install, and no app can add itself to or remove another app from it.
Role hierarchy
Native groups.rank maps to Discord role.position. A bot can manage roles strictly below its own highest role's position, matching Discord's rules. Calls to PATCH .../members/{id}/roles/{rid} with a role at or above the bot's top role return 403.
Timeouts
Discord's communication_disabled_until field has no GameVox equivalent in v1. A PATCH to a member with that field set returns 400 with a clear error. Use kick / mute / ban instead.