Overview
AstralHeads is a player-head ("HeadDB"-style) catalog plugin: it stores a searchable library of decorative player-head ItemStacks (community skin heads pulled from a public catalog, plus every network player's own skin) in a shared MariaDB table, and exposes it in-game through a menu-driven /heads command, a full-text search, per-player favorites, and a coin-priced "buy" flow. plugin.yml declares AstralCore and AstralSync as hard dependencies (main: com.astralrealms.heads.AstralHeads, api-version: '26.1').
Two-module architecture
The plugin ships as two independent builds, both named AstralHeads but built from different bases and pointed at the same heads MariaDB schema (database.properties):
Module | Base class | Role |
|---|---|---|
Paper |
| The player-facing side: |
Master (MageHic) |
| A headless background worker: periodically imports a public head catalog CSV into a |
The master module is the only writer that populates heads with Source.CATALOG rows; the paper module only reads the catalog (and separately writes its own Source.PLAYER rows — see Player heads below). See Catalog Import & Resolve Worker for the master module's full pipeline.
Data model
Both modules share one heads table (master/src/main/resources/schema.sql), mapped to HeadEntity (@Entity("heads")):
Column | Field | Notes |
|---|---|---|
|
| Primary key. For |
|
|
|
|
|
|
|
| Catalog display name, or the player's Minecraft username. |
|
| Signed Mojang |
|
| Catalog texture-CDN key; also stored (denormalized) for player heads. |
|
|
|
|
|
|
|
|
|
|
|
|
|
| DB-maintained timestamp. |
HeadEntity#itemStack() lazily builds and caches a PLAYER_HEAD ItemStack: it creates a Bukkit PlayerProfile (using the real player UUID for PLAYER heads, or the head's own uniqueId under the display name "AstralHeads" for CATALOG heads), applies the texture — preferring the signed textures property, falling back to deriving a skin URL from textureHash (honoring skinModel), and finally the raw unsigned textureValue — sets the display name, and stamps the head's number into the item's PersistentDataContainer under astralheads:number (see PDCUtils).
Player heads
The paper module's HeadEntity is also a ComplexPlaceholder (namespace head, see Placeholders) resolving id, number, name, category, tags, item, favorite (per-viewing-player, via AstralSync HeadPlayerData) and price/currency (looked up from config.yml's prices map, keyed by source).
In-memory indexing & search
HeadService (paper) warms up on construction by loading every row from heads into a Caffeine AsyncLoadingCache<UUID, HeadEntity> (max 500k entries) and building two in-memory Multimaps — tag → UUID and category → UUID — plus a number → UUID map, kept in lock-step with the cache via its eviction listener and loader. HeadService#search(term) runs entirely against this in-memory cache (no per-query SQL): it tokenizes the (lower-cased, trimmed) term on whitespace, scores every CATALOG head against each token (exact name > numeric number match > name prefix > name whole-word > exact tag > name substring > tag substring > category substring > single-edit-distance fuzzy name match, in that order — a token that matches nothing disqualifies the whole head, i.e. AND semantics across tokens), and returns up to 50 UUIDs ranked by total score (ties broken alphabetically). Typo-tolerant fuzzy matching only kicks in as a fallback when the exact/substring scan finds nothing, and only for tokens of at least 4 characters. Results are cached per normalized search term for 5 minutes (searchCache, max 10k entries).
Buying & favoriting
Buying (
buy-headaction, see Actions) looks up the head'sSourceinconfig.yml'spricesmap; if unpriced, the head isn't for sale. On success it withdraws throughEconomyService, then gives the head viaMailboxService(if present) or directly into the player's inventory (dropping overflow at their feet).Favoriting (
toggle-favoriteaction) stores aSet<UUID>of favorited head ids inHeadPlayerData, an AstralSync player-data record synced across the network viaHeadSnapshotAdapter(snapshot keyastralheads:data).
Feature map
Area | Page |
|---|---|
| |
| |
| |
| |
Master module: catalog CSV import + Mojang/Microsoft resolve queue |
Requirements
Dependency | Required by | Notes |
|---|---|---|
AstralCore | Paper module | Configuration loading, |
AstralSync | Paper module |
|
MariaDB | Both modules | Both connect to the same |
Mojang/Microsoft session-server & CDN APIs | Master module |
|