Permissions
Permissions
Complete guide to the Hytale Admin permission system — 16 granular permissions, custom permission groups, and OP management.
Permission Reference
The plugin defines 16 custom permissions that control access to every feature:
| Permission |
Grants Access To |
hytale-admin.dashboard |
View the dashboard (status, TPS, uptime) |
hytale-admin.players-read |
View the player list |
hytale-admin.players-manage |
Kick, heal, teleport, set gamemode, OP/de-OP players |
hytale-admin.players-inventory |
View and edit player inventories, give items, clear inventory |
hytale-admin.moderation-read |
View the ban list and mute list |
hytale-admin.moderation-manage |
Ban/unban, mute/unmute players |
hytale-admin.chat-read |
View the live chat monitor and death log |
hytale-admin.chat-broadcast |
Send broadcast messages to all players |
hytale-admin.world-read |
View world information (time, weather, seed) |
hytale-admin.world-manage |
Set time, set weather, manage warps |
hytale-admin.serverconfig-read |
View server configuration and whitelist |
hytale-admin.serverconfig-manage |
Edit server config, manage whitelist |
hytale-admin.backups-read |
View the backup list |
hytale-admin.backups-manage |
Create, restore, and delete backups |
hytale-admin.setup |
Access the setup page (install/uninstall mod, settings) |
hytale-admin.activity |
View the activity log tab |
Permission Hierarchy
Permissions follow a read → manage pattern:
*-read = view-only access
*-manage = full control (includes read)
Having *-manage without *-read still works — the manage permission implies read access.
Permission Groups
Permission groups allow you to define reusable sets of permissions for roles.
Create Permission Group
| Detail |
Value |
| Permission |
hytale-admin.serverconfig-manage |
| API |
POST /permissions/groups |
| Body |
Group name + selected permissions |
| Success |
"Permission group created: {group}" |
| Failure |
"Failed to create permission group" |
| Logged as |
server:hytale-admin.group-create |
Delete Permission Group
| Detail |
Value |
| Permission |
hytale-admin.serverconfig-manage |
| API |
DELETE /permissions/groups/{name} |
| Success |
"Permission group deleted: {group}" |
| Failure |
"Failed to delete permission group" |
| Logged as |
server:hytale-admin.group-delete |
Example Groups
| Group Name |
Suggested Permissions |
| Moderator |
moderation-read, moderation-manage, chat-read, players-read |
| Builder |
world-read, world-manage, players-read |
| Admin |
All 16 permissions |
| Viewer |
dashboard, players-read, chat-read, world-read |
OP Management
Grant or revoke operator status for players:
Grant OP
| Detail |
Value |
| Permission |
hytale-admin.serverconfig-manage |
| API |
POST /permissions/op/{uuid} |
| Success |
"OP granted: {uuid}" |
| Failure |
"Failed to grant OP" |
| Logged as |
server:hytale-admin.op-grant |
Revoke OP
| Detail |
Value |
| Permission |
hytale-admin.serverconfig-manage |
| API |
DELETE /permissions/op/{uuid} |
| Success |
"OP revoked: {uuid}" |
| Failure |
"Failed to revoke OP" |
| Logged as |
server:hytale-admin.op-revoke |
Note: OP management uses UUIDs, not player names. The plugin resolves names to UUIDs for you.
Data Storage
Permissions are stored in permissions.json on the server. The Java mod reads this file on startup and the panel can modify it via the API.
Game Translation System
For the item search and inventory editor, item names are translated using a priority chain:
| Priority |
Source |
Description |
| 1 |
Java Mod I18n |
Server-side item translations from the mod |
| 2 |
Static PHP translations |
Bundled translation files in the plugin |
| 3 |
Formatted key fallback |
Item key formatted as readable name |
13 locale mappings are supported. The gameLanguage setting ('auto' by default) follows the panel locale.
Troubleshooting
User can't access a feature
- Check which permission is required for that feature (see table above)
- Verify the user/subuser has the permission assigned
- Server owners have all permissions by default
Permission group creation fails
- Group name may already exist
- API connection lost
permissions.json file locked or corrupted
OP status doesn't persist
- OP changes should persist across restarts (stored server-side)
- If not persisting, check
permissions.json write permissions
- Server may overwrite permissions on certain events
Activity log shows "unknown" actor
- The admin username is passed from the panel session
- If session expired during action, actor may be empty
Permissions don't take effect immediately
- Some permission changes may require the affected user to refresh their page
- Server-side permission groups may need a server restart to reload
API Client & Internal Architecture
Full API endpoint documentation is available in the HytaleAdminAPI Reference. This section covers the PHP client that the panel plugin uses internally to communicate with the Hytale server mod. For endpoint parameters, response schemas, and request examples, see the HytaleAdminAPI documentation.
HytaleApiService — PHP Client
The panel plugin communicates with the Hytale server mod via a HytaleApiService class that wraps all HTTP calls. Every feature (Dashboard, Players, Chat, etc.) uses this service.
Client Configuration Parameters
| Parameter |
Type |
Source |
Description |
host |
string |
Server allocation |
Resolved from egg environment: SERVER_IP |
port |
int |
Egg variable |
Hytale mod API port (default: 8080) |
token |
string |
Admin settings |
Bearer token for API authentication |
timeout |
int |
Plugin config |
HTTP timeout in seconds (default: 10) |
baseUrl |
string |
Computed |
http://{host}:{port}/api |
// How the API service is constructed — from server allocation + egg variables
$allocation = $server->allocation;
$host = $allocation->ip; // Server IP from allocation
$port = $server->egg_variable('HYTALE_API_PORT') ?? 8080;
$token = $server->egg_variable('HYTALE_API_TOKEN');
$service = new HytaleApiService($host, $port, $token);
// Base request method — all API calls go through this
protected function request(string $method, string $endpoint, array $data = []): array
{
$response = Http::timeout($this->timeout)
->withToken($this->token) // Bearer token
->withHeaders([
'Accept' => 'application/json',
'Content-Type' => 'application/json',
])
->{$method}("{$this->baseUrl}/{$endpoint}", $data);
if ($response->failed()) {
throw new HytaleApiException(
"API {$method} /{$endpoint} failed: HTTP {$response->status()}",
$response->status()
);
}
return $response->json();
}
Request Flow — Panel to Server Mod
┌──────────────┐ HTTP/JSON ┌─────────────────┐ Java API ┌──────────────┐
│ Panel Plugin │ ──────────────> │ Hytale Mod HTTP │ ──────────── > │ Hytale Server│
│ (PHP/Laravel)│ <────────────── │ Server (Netty) │ < ──────────── │ (Game) │
│ │ JSON response│ │ Game state │ │
└──────────────┘ └─────────────────┘ └──────────────┘
Key architectural notes:
- The mod embeds a Netty HTTP server inside the Hytale server process
- All game-affecting operations (kick, ban, teleport) execute on the server main thread
- Read-only operations (status, player list) may use cached data
- The API is synchronous from the panel's perspective but internally queues to the game thread
Feature → API Endpoint Mapping
See HytaleAdminAPI Reference for request/response details of each endpoint.
| Panel Feature |
API Endpoints Used |
Notes |
| Dashboard Status Widget |
GET /api/status, GET /api/stats |
TPS cached every 5s, player count live |
| Player List |
GET /api/players |
Returns all online players with UUID, name, position |
| Kick Player |
POST /api/players/{uuid}/kick |
Executes on server main thread |
| Teleport Player |
POST /api/players/{uuid}/teleport |
Thread-safe, main thread execution |
| Inventory Editor |
GET /api/players/{uuid}/inventory, POST /api/items/give |
BSON-encoded item data |
| Ban System |
GET /api/bans, POST /api/bans, DELETE /api/bans/{uuid} |
Persists to data/bans.json |
| Mute System |
GET /api/mutes, POST /api/mutes, DELETE /api/mutes/{uuid} |
Persists to data/mutes.json |
| Chat Monitor |
GET /api/chat/messages |
Polled every 2s (configurable) |
| Broadcast |
POST /api/chat/broadcast |
Supports & color codes |
| Death Log |
GET /api/deaths |
Includes cause, position, timestamp |
| World Info |
GET /api/world |
Seed, time, weather, difficulty |
| Set Time/Weather |
POST /api/world/time, POST /api/world/weather |
Main thread execution |
| Warp System |
GET /api/warps, POST /api/warps, DELETE /api/warps/{name} |
Persists to data/warps.json |
| Backup System |
GET /api/backup, POST /api/backup/create, POST /api/backup/restore |
Async creation, auto-saves world first |
| Server Config |
GET /api/config, POST /api/config |
Restart may be required |
| Whitelist |
GET /api/whitelist, POST /api/whitelist, DELETE /api/whitelist/{uuid} |
Immediate effect |
| Permissions |
GET /api/permissions, POST /api/permissions |
Stored in permissions.json |
| OP Management |
POST /api/permissions/op, DELETE /api/permissions/op/{uuid} |
Immediate effect |
| Installed Mods |
GET /api/version |
Returns mod list from mod loader |
BSON Item Data Handling
Hytale uses BSON (Binary JSON) for item serialization. The panel must handle encoding/decoding for inventory operations.
// Item data structure — as returned from the API
$item = [
'id' => 'hytale:wooden_sword', // Namespaced item ID
'count' => 1, // Stack count
'slot' => 3, // Inventory slot index
'nbt' => [ // BSON-encoded properties
'damage' => 15,
'enchants' => [
['id' => 'sharpness', 'level' => 3],
],
'customName' => '§6Legendary Blade', // Color-coded display name
],
];
// Give item to player — constructs BSON payload
$this->request('POST', "items/give", [
'uuid' => $playerUuid,
'item_id' => $itemId, // e.g. 'hytale:iron_ore'
'count' => $count,
'nbt_data' => $nbtData, // Optional BSON properties
]);
// Executes on server main thread, item appears in player's inventory immediately
Player Data Merge (UUID Resolution)
The plugin handles UUID-to-name resolution with merge logic for players who change names.
// UUID resolution — the mod tracks players by UUID, panel displays names
$players = $this->request('GET', 'players');
// Each player has both UUID and current name
// The panel caches UUID→name mappings
// When a player renames, the old name is replaced on next login
foreach ($players as $player) {
// $player['uuid'] => "550e8400-e29b-41d4-a716-446655440000"
// $player['name'] => "Steve"
// $player['position'] => { "x": 100.5, "y": 64.0, "z": -200.3 }
// $player['gameMode'] => "SURVIVAL"
// $player['health'] => 20.0
// $player['food'] => 18
}
Caching Strategy
| Data Type |
Cache TTL |
Reason |
| Server status (TPS, uptime) |
5 seconds |
Frequently changing, low-cost API call |
| Player list |
5 minutes |
Moderate change frequency |
| Mod list |
24 hours |
Changes only on server restart |
| Ban/mute lists |
10 minutes |
Rarely changes frequently |
| World info |
30 seconds |
Time changes every tick |
| Warp list |
10 minutes |
Manual admin action only |
| Backup list |
5 minutes |
Creation is infrequent |
| Config values |
1 hour |
Manual change only, restart needed |
// Cache example — status with 5-second TTL
$status = Cache::remember("hytale_status_{$serverId}", 5, function () {
return $this->apiService->getStatus();
});
Demo Mode Architecture
When the server is offline, the plugin enters demo mode — it shows mock data so admins can explore the UI without a running server.
// Demo mode detection — automatically activates when API is unreachable
try {
$status = $this->apiService->getStatus();
$demoMode = false;
} catch (HytaleApiException $e) {
$demoMode = true;
$status = $this->getDemoStatus(); // Returns hardcoded mock data
}
// Demo data includes:
// - 0 TPS, 0 players, all features show placeholder data
// - UI is fully interactive but changes are not sent to server
// - Yellow banner shows "Demo Mode — Server is offline"
API Client Error Map
| Error / Log Message |
Cause |
Impact |
Solution |
HytaleApiException: HTTP 0 |
Server unreachable (no response) |
Demo mode activates |
Start server, check port/firewall |
HytaleApiException: HTTP 401 |
Invalid or missing token |
All API calls fail |
Set correct HYTALE_API_TOKEN in egg variables |
HytaleApiException: HTTP 403 |
Token valid, wrong permissions |
Specific features fail |
Check mod permission configuration |
HytaleApiException: HTTP 500 |
Mod internal error |
Feature-specific failure |
Check Hytale server logs |
Connection refused on port X |
Mod not loaded or wrong port |
Full plugin failure |
Verify HYTALE_API_PORT matches mod config |
SSL certificate problem |
HTTPS misconfigured |
All API calls fail |
Use HTTP (not HTTPS) for local connections |
Timeout after Xs |
Server overloaded or network delay |
Partial data shown |
Increase timeout value, check server performance |
JSON decode error |
Mod returned non-JSON response |
Feature shows error |
Update mod, check for mod conflicts |
BSON decode error |
Corrupted inventory data |
Inventory editor fails |
Try /api/players/{uuid}/inventory directly |
| CSRF token mismatch |
Session expired |
Livewire calls fail |
Refresh browser page |
Complete Error Reference (All Features)
Connection Errors
| Error / Symptom |
Cause |
Solution |
| Dashboard shows all zeroes |
Server API not responding |
Start the server, verify Hytale mod is loaded |
| "Connection timed out" |
API unreachable within timeout |
Increase timeout, check firewall rules for port |
| "Connection refused" |
API not running on expected port |
Verify mod config uses correct port |
| "Failed to connect" |
Server offline or networking issue |
Start server, check port bindings, verify no port conflict |
| All features show loading spinner |
CSRF token expired or JS error |
Refresh page, check browser console (F12) |
| Intermittent failures |
Server overloaded or unstable |
Check server TPS, reduce poll intervals |
Authentication / Token Errors
| Error / Symptom |
Cause |
Solution |
| "⚠ Token Required" |
No API token configured for test page |
Enter token in the API test page token field |
| "⚠ Token Too Short" |
Token less than 8 characters |
Use a token with at least 8 characters |
| HTTP 401 Unauthorized |
Wrong or expired token |
Regenerate token in Hytale mod config |
| HTTP 403 Forbidden |
Token valid but insufficient permissions |
Check mod permission configuration |
| Token not persisting |
Token only stored in browser session |
Re-enter after clearing browser data |
Player Management Errors
| Error / Symptom |
Cause |
Solution |
| "Player not found" |
Player offline or invalid name |
Verify player is online or exists |
| "Failed to kick player" |
API reject or player already disconnected |
Check API response, try again |
| "Ban failed" |
Missing hytale-admin.moderation-ban permission |
Grant permission to admin user |
| Player list empty |
No players online |
Expected when server is empty |
| Player data stale |
Cached player list outdated (5-min cache) |
Clear cache or wait for refresh |
Chat System Errors
| Error / Symptom |
Cause |
Solution |
| No messages appearing |
WebSocket not connected |
Check browser console, refresh page |
| "Message send failed" |
API reject or connection lost |
Reconnect, check token validity |
| Old messages not loading |
Chat history not supported by mod |
Only live messages from WebSocket |
| Special characters garbled |
Encoding mismatch |
Use UTF-8 in message content |
World Management Errors
| Error / Symptom |
Cause |
Solution |
| "Failed to get world info" |
API endpoint not available |
Update Hytale mod to latest version |
| World operations timeout |
Large world data |
Increase timeout in settings |
| Time change not working |
Permission hytale-admin.world-manage missing |
Grant permission |
| Weather change fails |
Same as time change |
Check permissions |
Backup System Errors
| Error / Symptom |
Cause |
Solution |
| "Backup creation failed" |
Disk space insufficient or permissions |
Free disk space, check write permissions |
| Backup takes too long |
Large world files |
Increase timeout, consider scheduling during low usage |
| "Restore failed" |
Backup file corrupted or missing |
Re-create backup, check storage path |
| Old backups not appearing |
Backup directory changed |
Verify backup storage path matches |
Server Configuration Errors
| Error / Symptom |
Cause |
Solution |
| Settings not saving |
hytale-admin.serverconfig-manage permission missing |
Grant permission |
| Config changes not taking effect |
Server restart required |
Restart server after config changes |
| "Config file locked" |
Another process accessing config |
Wait or restart server |
| Invalid value rejected |
Value outside allowed range |
Check min/max constraints in UI |
API Response Code Reference
| HTTP Status |
Meaning |
Common Scenario |
Resolution |
| 200 |
Success |
Normal operation |
— |
| 400 |
Bad request |
Invalid parameters sent |
Check request parameters |
| 401 |
Unauthorized |
Missing or invalid token |
Configure correct token |
| 403 |
Forbidden |
Insufficient permissions |
Grant required permission |
| 404 |
Not found |
Player or resource doesn't exist |
Verify target exists |
| 408 |
Request timeout |
Server too slow to respond |
Increase timeout |
| 429 |
Too many requests |
Too rapid polling |
Reduce poll frequency |
| 500 |
Server error |
Hytale mod internal error |
Check server logs, update mod |
| 502 |
Bad gateway |
Proxy or networking issue |
Check networking config |
| 503 |
Service unavailable |
Server starting/stopping |
Wait for server to be ready |
Complete Notification Reference
| Event |
Type |
Notification |
| Player kicked |
Success |
"Player kicked: {name}" |
| Player banned |
Success |
"Player banned: {name}" |
| Command sent |
Success |
"Command executed" |
| Command failed |
Danger |
"Command execution failed" |
| Server stopped |
Success |
"Server stop command sent" |
| Chat message sent |
Success |
"Message sent" |
| Backup created |
Success |
"Backup created successfully" |
| Backup failed |
Danger |
"Backup creation failed" + error |
| Restore started |
Info |
"Restoring from backup…" |
| Restore failed |
Danger |
"Restore failed" + error |
| Config saved |
Success |
"Configuration saved" |
| Config error |
Danger |
"Configuration save failed" + error |
| OP granted |
Success |
"OP granted: {uuid}" |
| OP revoked |
Success |
"OP revoked: {uuid}" |
| Permission denied |
Warning |
"Permission denied" |
| Whitelist updated |
Success |
"Whitelist updated" |
| World time changed |
Success |
"World time set to {time}" |
| World weather changed |
Success |
"Weather set to {weather}" |