Astral Realms Documentation Help

Installation

1. Prerequisites

Ensure these are installed on every server running AstralMobs:

Dependency

Required

Notes

Paper 1.21.x

Yes

api-version: '1.21' in plugin.yml. AstralMobs uses raw NMS entity construction.

AstralCore

Yes

Hard dependency (depend: [AstralCore, packetevents, LibBL] in plugin.yml). Required for configuration loading and placeholders.

PacketEvents

Yes

Hard dependency for metadata spoofing. Packet listener registered at MONITOR priority (see Boot sequence).

LibBL

Yes

Hard dependency backing the non-boss overhead health-text display (PacketTextDisplay).

AstralSkill

No

Soft dependency for cast-skill AI goals. If not present, cast-skill goals kite normally but do not cast. Checked at runtime via Bukkit.getPluginManager().isPluginEnabled("AstralSkill").

2. Drop the JAR

Copy AstralMobs-<version>.jar into plugins/ alongside AstralCore, then start the server.

3. First start

On first start the plugin generates:

plugins/AstralMobs/ ├── config.yml ├── messages.yml └── blueprints/ ← empty; drop your *.yml here

No database or external service is required — all configuration is file-based YAML.

4. Data folder structure

Three files/folders in plugins/AstralMobs/:

Item

Purpose

config.yml

Global settings: health-display format, update intervals

messages.yml

Localised strings for reload feedback (three keys: reloading, reloaded, reload-failed)

blueprints/

Folder scanned recursively; every .yml file is loaded as a mob blueprint

Blueprint discovery

BlueprintService.load() walks plugins/AstralMobs/blueprints/ recursively (subfolders included) and deserializes every YAML file into a MobBlueprint. Each blueprint is keyed by its id: field, not filename — two files with the same id will have the second silently overwrite the first. Parsing errors are logged and skipped; they do not stop the folder walk.

Example structure:

blueprints/ ├── dummy.yml ← id: dummy ├── overworld/ │ └── zombie.yml ← id: zombie (loaded recursively) └── nether/ └── piglin.yml ← id: piglin (loaded recursively)

After deserialization, each blueprint's initialize() is called immediately, failing fast if goals, selectors, or move-control are malformed.

5. Boot sequence

When AstralMobs starts (onEnable):

  1. NMS cache buildNMSBukkitAdapter.buildCache() (warnings logged if it fails, but startup continues)

  2. Create BlueprintService — ready to load blueprints

  3. Register type serializerEquipmentSlot for YAML deserialization

  4. Load configuration — calls loadConfiguration():

    • Load messages.ymlMobsMessages enum

    • Load config.ymlMainConfiguration record

    • Load all blueprints via BlueprintService.load() (logs total count)

  5. Create MobService and start repeating loops — health-display refresh, requirement-gated gear/effect refresh, metadata reconciliation (see Runtime loops)

  6. Register command completion and context resolvers — for /mobs summon blueprint name completion

  7. Register /mobs command — subcommands: summon, reload

  8. Register mob actionsspawn-mob-location, store-memory, start-timer, send-entity-status, edit-entity-metadata

  9. Register entity listenerMobListener for lifecycle events

  10. Register PacketListener — at MONITOR priority for metadata spoofing (pose, invisibility, custom names)

  11. Initialize MobsAPI — public API for external plugins

6. Configuration

config.yml

The main configuration file:

mob-health: "<dark_green>%imgmanip_test-mob-bar%<black>%imgmanip_test-mob-bar-neg%<white>%img_tower:health_container_up%" # force-update-interval: 20

Key

Type

Default

Description

mob-health

MiniMessage

(required)

Display format for health-display placeholders. Supports image manipulation placeholders like %imgmanip_*% and %img_*%.

force-update-interval

int

0 (disabled)

If > 0, health-display is refreshed every N ticks (see Runtime loops).

requirement-update-interval

int

1

Requirement-gated gear/effects refresh cadence in ticks (minimum 1; see Runtime loops).

messages.yml

Localised reload feedback (three keys):

reloading: "Reloading..." reloaded: "Reloaded successfully." reload-failed: "Reload failed. Check the console for errors."

Used by /mobs reload to notify the command sender of progress.

7. First mob

Start by creating your first blueprint. Create plugins/AstralMobs/blueprints/my-mob.yml:

id: my-mob type: VILLAGER health: 100.0 move-control: type: walking

Then reload configuration:

/mobs reload

The console should log Loaded X mob blueprints. (where X ≥ 1). Summon the mob:

/mobs summon my-mob

This spawns a mob at your location. See Mob Blueprints for the full field reference and AI Goals, Targeting & Movement for behavior configuration.

8. Runtime loops

Once enabled, MobService.start() launches three repeating scheduler tasks:

Health-display refresh

  • Condition: only if force-update-interval > 0

  • Frequency: every force-update-interval ticks

  • Effect: updates health-display component for all alive mobs (calls entity.updateHealthDisplay())

  • Cost: minimal; skipped if interval is high (e.g. 20+ ticks ≈ once per second)

Requirement-gated gear & effect refresh

  • Always active

  • Frequency: every requirement-update-interval ticks (minimum 1, default 1)

  • Effect: re-applies equipment and potion effects only to mobs with requirements in their blueprint (dynamic blueprints). Static blueprints are skipped.

  • Cost: proportional to requirement-gated mobs; negligible if no blueprints use requirements

Metadata reconciliation

  • Always active

  • Frequency: fixed 10 ticks (twice per second)

  • Effect: re-broadcasts spoofed entity metadata (pose overrides, invisibility, custom names) to tracking players to self-heal dropped or mis-ordered packets

  • Cost: proportional to mobs with active metadata overrides; negligible if overrides are rare

9. Reloading

Reload configuration, messages, and blueprints at runtime without restarting:

/mobs reload

This re-runs loadConfiguration():

  • Reloads messages.yml

  • Reloads config.yml

  • Clears all blueprints and reloads blueprints/ from disk

  • Logs Loaded X mob blueprints.

Existing mobs in the world are not affected — they retain their current blueprint state. Only new spawns use the reloaded blueprint.

Errors during reload (e.g. malformed YAML, missing goal classes) are caught, logged to console, and the sender receives reload-failed.

10. Mob persistence

Mobs are intentionally non-persistent:

  • Every spawned mob has entity.persist = false, so they are never written to chunk data.

  • On plugin disable (server restart, /reload, plugin update), MobService.shutdown() removes all tracked mobs and cancels repeating tasks.

  • Custom mobs do not survive server restarts. They must be re-summoned or re-triggered by whatever spawning system uses them.

11. Permissions

Node

Scope

mobs.command

Required for all /mobs subcommands (summon, reload). Declared at command class level, not granted by default.

12. Known limitations

Stale metadata keys

Production blueprints contain some metadata keys not yet recognized by AstralMobs. Configurate silently ignores unknown keys:

  • prevent-sunburn — planned but not implemented

  • movement-speed — use attributes.movement_speed instead

  • attack-speed — use attributes.attack_speed instead

See Attributes & Metadata for the authoritative list of supported keys.

PacketEvents required

If PacketEvents is not installed, AstralMobs will fail to enable (hard dependency). Metadata spoofing (pose, invisibility, custom names) will not work without it.

Last modified: 25 July 2026