Skip to content

Releases: CaptainParis/HeadSprites

v1.4 - Stability audit and Experimental parity

Choose a tag to compare

@CaptainParis CaptainParis released this 06 Sep 10:33

Stability

  • Every event handler, command and placeholder now contains exceptions: a bad sprite, bad image or failed MineSkin call logs once at WARNING and the chat message / command proceeds unmodified.
  • All sprites.yml reads and writes moved off the server thread (single IO thread, atomic writes). /sprite reload is now async.
  • Sprite, sequence and animation maps are immutable snapshots, so chat rendering can never race a reload.
  • onDisable now stops the web server, the MineSkin pool, the IO thread and every animated text display with bounded waits. No more leaked threads on reload.
  • Animated TextDisplays run on one shared ticker, update only when the frame changes, and no longer persist across restarts.

1.21.11 crash guards

  • %headsprites_tab_*% now rewrites <head name=...>, bare <head> and quoted forms, and strips any leftover name-only head tag before TAB sees it.
  • sanitizeHeads recurses into hover text.

Ported from Experimental

  • Tolerant tag grammar (<head : "x" />), <head_texture:hash>, <head:texture:hash> / <head:name:X> forms.
  • Sprite delete (/api/sprite/delete + gallery button in the web UI).
  • MineSkin: retries on transient errors, handles immediate skin responses for duplicate uploads, clearer job errors.

Performance

  • Head components and texture hashes are computed once per sprite; sequences and animation frames are cached and rebuilt only on change.
  • Web UI: request bodies capped at 6 MiB, images rejected above 2048 px before decode, ImageIO disk cache disabled, 4 worker threads.
  • MineSkin generation from /sprite generate runs on a bounded pool with one shared HTTP client.

Notes

  • Names for new sprites/sequences/animations are restricted to [a-z0-9_-] (max 48 chars). Existing entries load unchanged.
  • Default web.token on first run is now generated with SecureRandom.
  • Full finding list: AUDIT.md.

v1.2 - Animated head sprites

Choose a tag to compare

@CaptainParis CaptainParis released this 17 Aug 02:23
4843440

What's new

  • Animated head sprites. A new animation type sits alongside static sprites and sequences. An animation is an ordered list of frames (each frame is a row of one or more heads) played on a loop at a configurable interval. Animations are stored in sprites.yml and authored in the built-in web editor.
  • Chat & MiniMessage tag: use <anim:name> to insert a live, looping animation inline. The <sprite:name> tag also falls back to an animation's first frame when the name matches an animation.
  • PlaceholderAPI: new %headsprites_anim_name% placeholder returns the current animation frame as a JSON text component for Skript/custom chat formats.
  • Commands: /sprite anim list, /sprite anim display <name> (spawns a looping animated TextDisplay in-world), and /sprite anim stop (removes running displays), all with tab completion.
  • Web API: new /api/animation and /api/animation/delete endpoints; animations are included in the editor state.

Install

Drop HeadSprites-1.2.jar into your server's plugins/ folder. Requires Paper 1.21.x and Java 21. PlaceholderAPI is optional (needed only for the Skript/placeholder bridge).

v1.1 - PlaceholderAPI / Skript chat bridge

Choose a tag to compare

@CaptainParis CaptainParis released this 31 Jul 11:23
68d371f

What's new

  • PlaceholderAPI/Skript chat bridge. New %headsprites_msg% placeholder returns the sender's chat message already rendered as a JSON text component, with <head:...>, <sprite:...>, and <seq:...> tags resolved into inline heads. This lets Skript/SkBee (or any plugin that cancels and rebuilds chat) show inline sprites in custom chat formats.
  • The rendered message is captured at LOWEST priority, before the chat event is cancelled, so it is always available.
  • The placeholder returns a valid empty component ({"text":""}) when nothing is stored, so text component from json never throws.
  • Added PlaceholderAPI as a soft dependency; the bridge and placeholder only register when PlaceholderAPI is installed. Without it, the plugin falls back to the built-in vanilla chat renderer.
  • README: added a "Using with Skript" section with requirements, the placeholder, an example, and a note on listener priority.

Install

Drop HeadSprites-1.1.jar into your server's plugins/ folder. Requires Paper 1.21.9+ and Java 21. PlaceholderAPI is optional (needed only for the Skript bridge).

HeadSprites 1.0

Choose a tag to compare

@CaptainParis CaptainParis released this 30 Jul 11:08
f6c0b0c

HeadSprites 1.0 - first release.

HeadSprites shows custom 8x8 pixel art as player heads inline in chat. Draw a
sprite or paste an image in the built-in web editor, the plugin signs it through
MineSkin, and you drop a short tag like head:heart into chat to show it. No
resource pack needed.

Requirements

Install

  1. Put HeadSprites-1.0.jar in your server's plugins/ folder.
  2. Start the server once to create plugins/HeadSprites/sprites.yml.
  3. Add your MineSkin key to mineskin-api-key, then /sprite reload or restart.

See the README for the full config, the web editor walkthrough, chat tags, and
commands.

Download

Grab HeadSprites-1.0.jar below. It is the shaded jar with dependencies bundled.