Astral Realms Documentation Help

Event Catalogue

Every row in the events table has a type discriminator and a payload JSONB blob. This page lists the event types AstralAnalytics emits out of the box and the payload shape for each one.

Storage row

events ├── id SERIAL ├── created_at TIMESTAMPTZ DEFAULT NOW() ├── type VARCHAR(50) ├── player_uuid UUID NULL ├── server_name VARCHAR(50) ← "main", "spawn", "survival-1", … or "proxy" / "magehic" ├── server_group VARCHAR(50) ← server group from AstralCore's server info └── payload JSONB ← per-event shape (below)

server_name = "proxy" and server_group = "proxy" mark events that come from the Velocity proxy. server_name = "magehic" and server_group = "magehic" mark events that come from MageHic services via the direct shortcut.

Velocity proxy events

player_join

Fired on PostLoginEvent. The richest connection-time event.

Field

Type

Notes

username

String

Player name.

ip

String

Remote address. Triggers GeoIP enrichment → adds country.

country

String

ISO 3166-1 alpha-2 (e.g. "FR") or "UNKNOWN". Appended by the master.

client_brand

String

What the client identified itself as during handshake.

protocol_version_id

int

Numeric protocol version.

protocol_version_name

String

Human-readable version (e.g. 1.21.4).

virtual_host

String

The hostname the client used (e.g. play.astralrealms.fr). Pattern-extracted from the raw vhost.

first_join

Boolean

true when AstralCore's MinecraftPlayer profile is freshly created.

player_quit

Fired on DisconnectEvent. Only fires when a corresponding player_join was seen (so reconnect storms don't generate orphans).

Field

Type

Notes

username

String

session_duration

long

Milliseconds between join and quit.

client_brand

Fired on PlayerClientBrandEvent.

Field

Type

Notes

username

String

client_brand

String

Updated brand.

player_mod_info

Fired on PlayerModInfoEvent (Forge clients).

Field

Type

Notes

username

String

mod_count

int

mods

Array<Object>

Each entry: {id, version}.

player_settings_changed

Fired on PlayerSettingsChangedEvent.

Field

Type

Notes

locale

String

IETF tag (e.g. fr-FR).

view_distance

int

Chunks.

particle_status

String

Mojang enum name.

chat_mode

String

Mojang enum name.

text_filtering_enabled

Boolean

Paper events

player_join_server

Fired on PlayerJoinEvent. Tracks per-server hops, not the initial proxy join.

Field

Type

Notes

username

String

player_quit_server

Fired on PlayerQuitEvent. Like player_join_server, scoped to the current server.

Field

Type

Notes

username

String

playtime

long

Milliseconds spent on this server in this session.

command_execute

Fired on PlayerCommandPreprocessEvent — every command, before any plugin handles it.

Field

Type

Notes

command

String

The full command line without the leading /.

luckperms-promote/luckperms-demote

Emitted by LuckPermsHook on UserPromoteEvent/UserDemoteEvent. Only present when LuckPerms is on the same server.

Field

Type

Notes

from

String

Previous group, or "null" if none.

to

String

New group, or "null" if none.

Custom events

Custom events do not have a dedicated registry — anything emitted through the AnalyticsService or the track-event action becomes a row with the type you pass and the JSON payload you provide.

See Developer API for both paths.

Conventions

There is no schema enforcement, so the network relies on convention. When introducing new event types:

  • snake_case for type. Dashes are allowed (LuckPerms hook uses them) but snake_case is the norm.

  • Stable field names inside payload — adding fields is safe; renaming is breaking for every dashboard that already queries them.

  • username whenever a player is involved. The player_uuid column already has the UUID, but dashboards benefit from a denormalised name.

  • ip to trigger GeoIP. Set the field and the master fills in country. Don't include ip if you don't want the lookup (and don't want to store the address).

  • Booleans, numbers, and nested arrays welcomeJSONB handles them, the GIN index makes them queryable with payload->>'…' and payload @> operators.

Example queries

-- Daily Active Users from joins SELECT date_trunc('day', created_at) AS day, COUNT(DISTINCT player_uuid) AS dau FROM events WHERE type = 'player_join' GROUP BY day ORDER BY day DESC; -- Country distribution SELECT payload->>'country' AS country, COUNT(*) AS joins FROM events WHERE type = 'player_join' AND payload->>'country' IS NOT NULL AND created_at > NOW() - INTERVAL '7 days' GROUP BY country ORDER BY joins DESC; -- Top commands SELECT split_part(payload->>'command', ' ', 1) AS cmd, COUNT(*) FROM events WHERE type = 'command_execute' GROUP BY cmd ORDER BY COUNT(*) DESC LIMIT 20;
Last modified: 25 July 2026