Astral Realms Documentation Help

Audit Logs

Every meaningful state change writes a typed TownLog row. Logs persist in the town_logs table; their metadata is JSON serialised from a LogPayload subclass chosen by the LogType.

TownLog model

Field

Type

Description

uniqueId

UUID

Primary key.

townId

UUID

Owning town.

memberId

UUID?

The acting member, or null for system events.

action

LogType

Discriminator.

metadata

JsonElement

Serialised LogPayload.

createdAt

long

Timestamp.

LogType catalogue

Type

Payload

Meaning

CREATE

Town created.

TRANSFER

MemberLogPayload

Ownership transferred.

UPDATE_MOTD/CLEAR_MOTD

MOTD changed.

UPDATE_SPAWN

PositionLogPayload

Spawn moved.

UPDATE_SETTINGS

SettingsLogPayload

Town settings toggled.

CLAIM/UNCLAIM

ChunkLogPayload

Chunk claimed / unclaimed.

CREATE_INVITATION/CANCEL_INVITATION

MemberLogPayload

Invitation lifecycle.

ACCEPT_INVITATION/DECLINE_INVITATION

Recipient action.

LEFT

Member left.

KICK

MemberLogPayload

Member kicked.

BAN

BanLogPayload

Ban created (player UUID + reason).

UNBAN

MemberLogPayload

Ban removed.

ASSIGN_ROLE

MemberRoleLogPayload

Role assigned.

CREATE_ROLE/UPDATE_ROLE/DELETE_ROLE

RoleLogPayload

Role CRUD.

UPDATE_ROLE_PERMISSIONS

RolePermissionLogPayload

Permissions diff.

UPDATE_WARP/DELETE_WARP

PositionLogPayload/ —

Warp lifecycle.

DEPOSIT/WITHDRAW

BankLogPayload

Bank movement.

SUBZONE_CREATE/SUBZONE_UPDATE/SUBZONE_DELETE

SubZoneLogPayload

Subzone lifecycle.

Reading logs

Logs are exposed through the in-game log menu (gated by the LOGS permission) — entries are rendered as items using the icon from logs.yml and the %log_*% placeholders.

items: log-item: taints: [ "log" ] item-stack: material: PAPER name: "<gray>[%log_date%] <white>%log_action%" lore: - "<gray>By: <white>%log_member%" - "%log_payload%"

Available placeholders inside a log item:

Placeholder

Value

%log_id%

UUID.

%log_townId%

Town UUID.

%log_member%

Acting member (resolves through the member placeholder).

%log_action%

LogType name.

%log_payload%

A formatted description, type-aware.

%log_icon%

The ItemStackWrapper from logs.yml.

%log_date%

Formatted timestamp.

logs.yml > displays.<LogType> defines the icon used for each log type — missing entries fall back to a default item.

API

LogService logs = plugin.logs(); logs.create(townId, actorId, LogType.CLAIM, new ChunkLogPayload(chunkX, chunkZ, world)); CompletableFuture<List<TownLog>> recent = logs.findByTownId(townId);

Payload classes live under model/logs/payload/; each is @ConfigSerializable so they round-trip through the JSON store cleanly.

Last modified: 25 July 2026