Astral Realms Documentation Help

Subzones

A subzone is a cuboid region nested inside a town's claims. It has its own roles, its own members, and either inherits the parent town's TownSettings or overrides them per setting. Subzones are perfect for shop districts, member-only basements, or PvP arenas inside an otherwise peaceful town.

Model

Field

Type

Description

uniqueId

UUID

Primary key.

townId

UUID

Parent town.

name

String

Unique within the town.

description

String

Optional.

x1 / y1 / z1 / x2 / y2 / z2

int

Cuboid corners.

world/serverId

identifiers

Origin.

inheritSettings

boolean

When true, the parent town's TownSettings decide; otherwise the subzone's own copy decides.

settings

EnumSet<TownSettings>

Loaded from subzone_settings. Only used when inheritSettings = false.

roles

List<TownRole>

Roles whose scope is this subzone's UUID.

members

List<SubZoneMember>

Player → subzone-scoped role mapping.

Lifecycle

/town subzone create ▼ SubZoneService → SUBZONE_SELECT_CORNER_1 ──► player right-clicks block A ▼ SUBZONE_FIRST_CORNER_SELECTED ──► SUBZONE_SELECT_CORNER_2 ▼ player right-clicks block B ──► SUBZONE_SECOND_CORNER_SELECTED ▼ Creation dialog (SUBZONE_CREATION_DIALOG_*) ├── name field ├── description field ├── copy roles from town (boolean) └── inherit settings (boolean) ▼ Persist + audit log (SUBZONE_CREATE)

Cancellation paths:

Cause

Message

Selection timed out

SUBZONE_CREATION_EXPIRED

Player cancelled the dialog

SUBZONE_CREATION_CANCELLED

Player started a second creation flow

SUBZONE_CREATION_ALREADY_IN_PROGRESS

Validation:

Cause

Message

Name pattern fails

INVALID_SUBZONE_NAME

Name already used in this town

ALREADY_EXISTING_SUBZONE

Any corner is outside the town's claims

SUBZONE_NOT_IN_TOWN_CLAIM

Cuboid overlaps another subzone

SUBZONE_OVERLAPPING

Per-town cap reached

SUBZONE_LIMIT_REACHED

Editing

Operation

Action / command

Edit metadata (name, description, inherit flag)

edit-subzone action

Re-select corners

edit-subzone-cuboid action

Toggle a single setting

toggle-subzone-settings

Save many settings at once

update-subzone-settings

Delete

delete-sub-zone action or /town subzone delete <subzone>

Each edit writes a SUBZONE_UPDATE audit log entry; deletes write SUBZONE_DELETE.

Roles

Subzones can have their own role registry. Roles scoped to a subzone set the scope field on TownRole to the subzone's UUID. Town-wide roles leave scope = null.

Action

Purpose

create-subzone-role

Add a role with scope = subzone.id.

cycle-subzone-member-role

Cycle a subzone member to the next role by weight.

kick-subzone-member

Remove the member from the subzone (they remain a town member).

The default subzone role is the first one created — additional roles inherit no permissions by default.

SUBZONE_NO_DEFAULT_ROLE fires if you try to assign a member before one role is marked default.

Members

A subzone member is a (player_uuid, subzone_uuid, role_uuid) triple. Players can be subzone members without being town members in practice (although the UI nudges town membership first).

Common flows:

  • "Grant access" — add the player with the default subzone role (SUBZONE_ACCESS_GRANTED).

  • "Revoke access" — kick-subzone-member (SUBZONE_ACCESS_REVOKED).

  • "Promote" / "Demote" — cycle role action (SUBZONE_MEMBER_PROMOTED, SUBZONE_MEMBER_DEMOTED).

Permission resolution

When a player acts inside a subzone:

  1. town.admin short-circuits everything.

  2. If the player is a subzone member, use the subzone role's permissions.

  3. Otherwise, use the town role's permissions.

For settings, inheritSettings decides whose copy is consulted (see Settings).

Visualisation

SubzoneListener exposes a per-player particle view for the currently selected town's subzones — toggled from the same /town particles switch as claim borders. SubzoneParticleViewTask renders the cuboid edges.

Last modified: 25 July 2026