Astral Realms Documentation Help

Members & Invitations

Membership model

A TownMember ties a player UUID + name to a TownRole. Membership is per-town — a player can join multiple towns subject to their quota (see Towns).

Joins and leaves dispatch custom Bukkit events:

Event

When

Cancellable

TownMemberJoinEvent

Right after the player is added to the roster.

No

TownMemberLeaveEvent

Right after they leave (kick, leave, ban).

No

See Events.

Invitation flow

/town invite <player> │ permission: INVITE ▼ InvitationService.create ├── preflight packet (network) — refuse if the recipient is offline anywhere ├── persist invitation with expires-at ├── INVITATION_SENT to inviter └── INVITATION_RECEIVED to recipient (cross-server via packet)

The recipient responds:

/town accept [town] /town decline [town] │ │ ▼ ▼ acceptInvitation declineInvitation │ │ ├── add member ├── delete invitation ├── notify inviter ├── INVITATION_DECLINED_NOTIFICATION └── INVITATION_ACCEPTED

/town invitations lists pending invitations for the player.

Cancellation:

Cause

Message

Invitation expired before answer

INVITATION_EXPIRED

Inviter cancels manually

INVITATION_CANCELLED

Town deleted

(silent — cascade clears it)

Kick

/town members kick <member> removes the member after verifying:

  • The actor has KICK.

  • The actor's weight is strictly higher than the target's (CANNOT_KICK_OWNER).

  • The actor is not targeting themselves (CANNOT_KICK_SELF).

MEMBER_KICK_NOTIFICATION is sent to every other member; the target gets MEMBER_KICKED.

Leave

/town leave removes the member from the roster after a permission check.

  • Owners cannot leave (CANNOT_LEAVE_OWNED_TOWN) — they must transfer first.

Bans

Bans persist in town_bans (one row per (town, player) pair).

/town ban <player> [reason] │ permission: BAN ▼ BanService.create ├── unique (town_id, member_id) check ├── persist (reason optional) └── PLAYER_BANNED + PLAYER_BAN_NOTIFICATION

Effects:

  • The player cannot accept future invitations (CANNOT_INVITE_BANNED_PLAYER).

  • BanListener blocks entry into any of the town's claims (CANNOT_ENTER_BANNED_TOWN).

Lifted with /town unban <player> (also requires BAN).

/town bans lists active bans.

Online roster

/town online

Renders an ONLINE_MEMBERS_HEADER followed by one ONLINE_MEMBERS_ONLINE_ENTRY or ONLINE_MEMBERS_OFFLINE_ENTRY per member. Online status is resolved network-wide via AstralCore's PlayerService.

Per-player notifications

A player can opt in to a chat ping every time someone joins one of their towns:

Toggle

Action

Stored on

MEMBER_JOIN_NETWORK_NOTIFICATION

toggle-town-members-notification

TownPlayerData.membersJoinNotification

When enabled, the player receives MEMBER_JOIN_NETWORK_NOTIFICATION whenever any member of any of their towns connects to any server.

Last modified: 25 July 2026