Documentation

Holograms, built on
Display entities.

JHolograms renders text, items, and blocks as native Minecraft Display entities — no ProtocolLib, no armor stands. It supports MiniMessage with gradients, per-player text via placeholders, conditional visibility, frame animation, glow, and full transform control.

Platform Paper 1.19.4–1.21.x Storage SQLite Optional PlaceholderAPI Command /jholo · jh · holo

Quick Start

Every editing command targets a hologram by name, and lines by a zero-based index counted from the top down.

in-game
# Create a hologram 2.5 blocks above you (starts with one text line)
/jh create spawn

# Add lines — text, an item, then a block
/jh addline spawn <gradient:#3fe0d0:#ffb454>Welcome to Spawn</gradient>
/jh addline spawn &7Right-click the villager to trade
/jh additem spawn DIAMOND
/jh addblock spawn GLOWSTONE

# Tweak it
/jh glow spawn 0 true
/jh scale spawn 2 1.5 1.5 1.5
/jh info spawn

Core Concepts

📝
Three line types

TEXT, ITEM, and BLOCK — each line is its own Display entity stacked under the one above it.

🧱
Stacking & gap

Lines flow downward from the base location. gap controls the vertical spacing between them.

🌐
Global vs per-player

Global = one shared entity for everyone. Per-player = each viewer gets their own copy.

💾
Persistent

Everything saves to SQLite and respawns on load. Entities never write to the world file.

Global vs per-player

A global hologram spawns a single set of entities seen identically by everyone — fast and lightweight, and a condition can still hide it from individual players. A per-player hologram (/jh perplayer <name> true) spawns a private set of entities for each viewer, hidden from everyone else. This is what unlocks per-viewer placeholders (each player sees their own balance, rank, etc.) and per-player conditions.

💡

Only switch a hologram to per-player when its text actually changes per viewer. Global holograms cost one entity set total; per-player costs one set per online viewer.

Text & Color

Text lines accept MiniMessage, legacy & codes, and &#RRGGBB hex. MiniMessage is auto-detected whenever the text contains <tags>; otherwise the legacy parser runs.

formatting
# MiniMessage gradient
/jh addline shop <gradient:#ff6b9d:#3fe0d0>Premium Shop</gradient>

# MiniMessage tags: bold, italic, single hex, rainbow
/jh addline shop <bold><#ffb454>LIMITED OFFER
/jh addline shop <rainbow>party time

# Legacy codes still work
/jh addline shop &b&lAqua bold &#ff0000red hex

# Multi-line in a single line entity — use \n
/jh addline shop Line one\nLine two

Gradients and hex colors are emitted as per-character §x hex sequences, so they render correctly across the entire 1.19.4–1.21.x range without relying on client-side resource packs.

Placeholders

If PlaceholderAPI is installed, any %placeholder% in a text line is resolved live.

On global holograms placeholders resolve at the server level (no specific player), so use server-wide placeholders there. On per-player holograms they resolve against each viewer, and per-player lines re-resolve roughly once per second so values stay current.

placeholders
/jh perplayer stats true
/jh addline stats &fHello &b%player_name%
/jh addline stats &7Balance: &a$%vault_eco_balance%
/jh addline stats &7Rank: %luckperms_prefix%

Animation

Cycle a text line through frames on a fixed tick interval. Frames are separated by | and the interval is in ticks (20 ticks = 1 second).

animation
# Cycle 4 frames, switching every 10 ticks (half a second)
/jh animate title 0 10 &cS&6E&eR&aV&bE&9R|&6E&eR&aV&bE&9R&cS|&eR&aV&bE&9R&cS&6E|&aV&bE&9R&cS&6E&eR

# Each frame can use MiniMessage too
/jh animate title 0 20 <red>Online|<green>Online

Animation is time-synced from a single server tick counter, so every viewer sees the same frame at the same moment. A line with two or more frames is automatically treated as animated.

Transform

Position, scale, and rotation apply to any line type.

Position

Use /jh movehere <name> to relocate a hologram to your position (placed ~2.5 blocks above your feet), or /jh tphere <name> to teleport yourself to it.

Scale

/jh scale <name> <index> <x> <y> <z> — scales a single line on each axis. 1 1 1 is default size.

Rotation

/jh rotate <name> <index> <pitchX> <yawY> <rollZ> — rotation in degrees.

⚠️

Rotation is only visible when the line's billboard is fixed. With center, vertical, or horizontal, the display continuously turns to face the player and overrides the rotation. Pair rotate with /jh billboard <name> fixed.

Appearance

These options apply to text lines.

  • align  left · center · right — horizontal text alignment.
  • background  default · none · #RRGGBB · #AARRGGBB — text panel color. none is fully transparent; an 8-digit hex sets a custom alpha.
  • opacity  0–255 — text fill opacity.
  • shadow  true · false — drop shadow behind the text.
  • seethrough  true · false — render the text through solid blocks.
  • viewrange  number — render-distance multiplier (1.0 ≈ vanilla default; raise it for far-visible holograms).
  • gap  number — vertical spacing between stacked lines.
appearance
/jh background spawn 0 #1a000000   # near-transparent dark panel
/jh background spawn 0 none        # no panel
/jh align spawn 0 center
/jh shadow spawn 0 true
/jh seethrough spawn 0 true
/jh viewrange spawn 2.0
/jh gap spawn 0.1

Glow

Add an entity outline glow to any line type, with an optional color tint.

glow
/jh glow spawn 2 true              # turn on the outline
/jh glowcolor spawn 2 #3fe0d0      # tint it (also enables glow)
/jh glowcolor spawn 2 reset        # back to default white-ish
💡

Setting a glowcolor turns glow on automatically — you don't need a separate glow … true. The tint only affects the outline, not the text fill.

Billboard

Billboard controls how a hologram faces the camera. It is set per hologram.

center

Always faces the player on all axes. The default — best for readable text.

vertical

Rotates to face the player but stays upright (no pitch).

horizontal

Faces the player only on the horizontal plane.

fixed

Never rotates. Required for visible rotate values. Block lines always use this.

billboard
/jh billboard spawn center
/jh billboard logo fixed

Visibility & Conditions

A condition decides whether a player can see a hologram. It is re-checked on join, world change, respawn, and about once per second.

Syntax

  • Permissionperm:<node>  → player must have the permission.
  • Comparison<value> <op> <value> with operators >= <= == != > <. Values may be placeholders; numbers compare numerically, otherwise as text.
  • Chaining — join multiple checks with && (all must pass).
  • Clear/jh condition <name> clear removes the condition.
conditions
# Only VIPs see it
/jh condition vipboard perm:rank.vip

# Only players level 10+
/jh condition levelgate %player_level% >= 10

# Rich VIPs only (both must be true)
/jh condition elite %vault_eco_balance% > 100000 && perm:rank.vip

# Remove it
/jh condition vipboard clear
⚠️

Comparisons against placeholders need PlaceholderAPI installed. On a global hologram, player placeholders won't resolve per-viewer — use perm: checks or switch the hologram to per-player for value comparisons.

All Commands

Base command /jholo (aliases /jh, /holo, /jholograms). <index> is the zero-based line number. Use the filter in the sidebar to search.

No commands match that filter.

Permissions

  • jholograms.admin — full access to every command. Default: op.

All management commands require this single node. Holograms themselves render to any player who meets a hologram's condition.

Storage & Lifecycle

All holograms live in plugins/JHolograms/holograms.db (SQLite).

  • Non-persistent entities — Display entities are flagged so they never save into the world file, preventing duplicates.
  • Orphan cleanup — on enable, any leftover tagged Display entities from a crash are removed before spawning fresh ones.
  • Resilient rendering — a single broken line is logged and skipped rather than failing the whole hologram.
  • Reload/jh reload despawns, reloads from the database, and respawns everything.
  • Unloaded worlds — holograms in worlds that aren't loaded are skipped (with a console note) until that world is available.