6.4 KiB
Permissions schema reference
Overview
The legacy permissions table stores:
- one row per rank
- one column per permission key
That works for runtime, but it becomes very hard to read and maintain once the number of permission keys grows.
The updated design keeps only the rank metadata separated, while the permission matrix itself becomes one readable table:
permission_ranks- one row per rank
- stores rank metadata such as
rank_name,badge,level,prefix,room_effect, and the automatic currency amounts
permission_definitions- one row per permission key
- stores the permission comment in the same row
- stores one column per rank using the format
rank_<id>
Example:
| permission_key | max_value | comment | rank_1 | rank_2 | rank_7 |
|---|---|---|---|---|---|
acc_ads_background |
1 |
Allows editing room advertisement backgrounds. | 0 |
0 |
1 |
Runtime behavior
- The emulator still supports the legacy
permissionstable as a fallback. - If
permission_ranksandpermission_definitionsexist and contain data, the emulator loads the new schema instead. - If the new schema is missing, incomplete, or fails to load, the emulator falls back to the legacy
permissionstable automatically.
Relevant runtime files:
Arcturus-Morningstar-Extended/Emulator/src/main/java/com/eu/habbo/habbohotel/permissions/PermissionsManager.java:45Arcturus-Morningstar-Extended/Emulator/src/main/java/com/eu/habbo/habbohotel/permissions/Rank.java:71Arcturus-Morningstar-Extended/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolManager.java:57
Tables
permission_ranks
This table stores only rank metadata:
idrank_namehidden_rankbadgejob_descriptionstaff_colorstaff_backgroundlevelroom_effectlog_commandsprefixprefix_colorauto_credits_amountauto_pixels_amountauto_gotw_amountauto_points_amount
permission_ranks field meanings
id- Numeric rank id used everywhere else in the emulator, including
users.rankand the dynamicrank_<id>columns inpermission_definitions.
- Numeric rank id used everywhere else in the emulator, including
rank_name- Human-readable name of the rank, such as
User,Moderator, orAdministrator.
- Human-readable name of the rank, such as
hidden_rank- When enabled, the rank is treated as hidden in places where staff visibility should be reduced.
badge- Badge code automatically associated with the rank.
job_description- Staff/job description text shown in features that expose rank profile details.
staff_color- Hex color used by staff UI or visuals that depend on the rank color.
staff_background- Background asset name used for staff visuals tied to the rank.
level- Priority/order value of the rank; higher values usually mean stronger staff level or broader access.
room_effect- Default avatar effect id associated with the rank when that feature is used.
log_commands- Controls whether commands executed by users with this rank should be logged in command logs.
prefix- Short in-room staff prefix/tag associated with the rank.
prefix_color- Hex color used for the displayed rank prefix.
auto_credits_amount- Automatic credit amount granted by rank-based reward/payday style logic, if used by the hotel.
auto_pixels_amount- Automatic duckets/pixels amount granted by rank-based reward/payday style logic, if used by the hotel.
auto_gotw_amount- Automatic GOTW-style points amount granted by rank-based reward/payday style logic, if used by the hotel.
auto_points_amount- Automatic activity-points amount granted by rank-based reward/payday style logic, if used by the hotel.
permission_definitions
This table stores:
permission_keymax_valuecomment- one dynamic column per rank:
rank_1rank_2rank_3- ...
That means the table itself is already the readable matrix you wanted:
- rows = permission keys
- columns = rank values
- comment stays next to the key
Value semantics
Permission values keep the same meaning as today:
0= disabled1= allowed2= allowed only when room-owner rights may be used
The schema stores that information in:
permission_definitions.max_value
Migration behavior
Database Updates/004_normalize_permissions_schema.sql does the following:
- keeps the legacy
permissionstable untouched - creates
permission_ranks - creates
permission_definitions - copies rank metadata from
permissionsintopermission_ranks - creates any missing
rank_<id>columns inpermission_definitions - creates one row per permission key with
max_valueand a comment - applies curated per-key comments so every permission explains what it actually does in code
- copies each old permission value into the proper
rank_<id>column
It also removes the older experimental objects if they already exist:
permission_rank_valuespermission_nodespermissions_matrix_viewrefresh_permissions_matrix_view
Adding a new rank later
When you add a new rank after the migration:
- insert the rank metadata into
permission_ranks - reload permissions with emulator restart or
:update_permissions - the emulator automatically creates the missing
rank_<id>column inpermission_definitionsif it does not exist yet - set the new
rank_<id>values inpermission_definitions
You can still run the helper procedure manually if you want to sync the schema before the next reload:
CALL refresh_permission_definition_rank_columns();
If you want to refresh all values again from the old legacy table during rollout, you can also run:
CALL refresh_permission_definition_values();
Notes about comments and legacy keys
The comments stored in permission_definitions.comment are intentionally hand-curated.
- Where a Java handler exists, the comment follows the real runtime behavior.
- Where only legacy command texts exist, the comment marks the key as legacy and explains the intended behavior from those texts.
- Where a key is still present for compatibility but no direct handler is found in the current tree, the comment says so explicitly.
The new schema intentionally preserves legacy and inconsistent permission keys so current functionality stays intact.
Examples:
cmd_word_quizcmd_wordquizcms_dancekiss_cmd
Those can be cleaned up later only after runtime behavior has been verified and the hotel no longer depends on the old names.