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 |
|---|---|---|
| UUID | Primary key. |
| UUID | Owning town. |
| UUID? | The acting member, or null for system events. |
|
| Discriminator. |
|
| Serialised |
| long | Timestamp. |
LogType catalogue
Type | Payload | Meaning |
|---|---|---|
| — | Town created. |
|
| Ownership transferred. |
| — | MOTD changed. |
|
| Spawn moved. |
|
| Town settings toggled. |
|
| Chunk claimed / unclaimed. |
|
| Invitation lifecycle. |
| — | Recipient action. |
| — | Member left. |
|
| Member kicked. |
|
| Ban created (player UUID + reason). |
|
| Ban removed. |
|
| Role assigned. |
|
| Role CRUD. |
|
| Permissions diff. |
|
| Warp lifecycle. |
|
| Bank movement. |
|
| 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.
Available placeholders inside a log item:
Placeholder | Value |
|---|---|
| UUID. |
| Town UUID. |
| Acting member (resolves through the member placeholder). |
|
|
| A formatted description, type-aware. |
| The |
| Formatted timestamp. |
logs.yml > displays.<LogType> defines the icon used for each log type — missing entries fall back to a default item.
API
Payload classes live under model/logs/payload/; each is @ConfigSerializable so they round-trip through the JSON store cleanly.