How It Works
Where Lightning sits, how it decides what to touch, and the words you'll see around these docs.
You don't need this page to use Lightning. It explains what happens behind the scenes, for when you want to know.
The idea
Lightning sits at the very end of the line, right before text leaves your server. When a message passes through and holds a real tag, Lightning charges it: tags come alive, sparks fill in, and bolts fire. The plugin that wrote the message never knows Lightning was there, which is why it works with plugins that have never heard of MiniMessage.
Words you'll see
| Word | What it means |
|---|---|
| Charge | What happens to a piece of text when Lightning formats it |
| Sense | The quick check that decides whether text is worth charging |
| Surface | A place players read text, like chat, the tab list or a boss bar |
| Sparks | Your own tags, written in YAML, used as <spark:name> |
| Bolts | Tags that do something besides showing text, like playing a sound |
| Glyphs | Tags that change how text looks, like small caps |
| Faces | Player heads drawn right inside text |
| Guard | Keeps whatever players type from being charged |
| Rewires | Rules that restyle messages you can't edit anywhere else |
| Pulse | Keeps animated sparks moving on lines a plugin only sends once |
Detection
Smart mode
This is the default. Lightning only charges text holding a tag someone actually typed. A tag counts when Lightning knows it: a MiniMessage tag, a hex color like <#FFB347>, or one of Lightning's own.
| Text | Charged? | Why |
|---|---|---|
<red>Hello | Yes | red is a real tag |
<#FFB347>Hi | Yes | A hex color |
<spark:prefix> Hi | Yes | A Lightning tag |
Usage: /home <name> | No | name isn't a tag |
I <3 this server | No | Not a tag |
Balance: %vault_eco_balance% | Yes, with PlaceholderAPI on | It holds a placeholder |
| Text a plugin already styled itself | No | There's nothing written to read |
That's why help messages full of <arguments> stay untouched, and plugins that already style their own text cost almost nothing.
Marker mode
Set detect: marker in config.yml and Lightning only charges text containing <charge>. The marker disappears from the final message.
welcome: "<charge><gradient:gold:yellow>Welcome!</gradient>"When to use marker mode
Use it if you want full control over what gets charged, or if a plugin on your server prints things that happen to look like real tags.
Surfaces
Each surface can be turned on or off under surfaces in config.yml. A surface that's off is never even looked at.
| Surface | Covers | Good to know |
|---|---|---|
chat | Messages plugins send | The only surface where bolts work. Signed player chat is never touched |
actionbar | Action bars | |
titles | Titles and subtitles | |
bossbars | Boss bar titles | |
tablist | Tab list header and footer | |
scoreboards | Sidebar title, lines, team prefixes and suffixes | |
inventories | Menu titles | |
items | Item names and lore | Off by default. Skipped for creative players. No click or hover |
entities | Holograms, text displays, name tags | No click or hover |
kicks | Kick screens and "Failed to connect" screens | Works for bans, whitelists and full servers too |
dialogs | Dialog titles, messages, buttons and tooltips | Needs 1.21.6 or newer. Input fields are left alone |
motd | The server list message |
Why items skip creative players
A creative client sends items back to the server, which would save Lightning's formatting onto the real item for good. Skipping creative players keeps your items clean.
Items and entities never get click or hover actions, because players can rename items and name tags themselves. Even with Guard on, those surfaces only get looks, never actions.
On kick and ban screens there's no player yet during login. Rewires and sparks still work there, placeholders only fill in server-wide values, <face> shows its fallback, and locale and permission sparks use their default line.
Guard
Charging text you never marked carries one real risk. A player types <click:run_command:'/op me'> into chat, a chat plugin repeats it as a server message, and suddenly it's a working button. Guard shuts that door.
Lightning remembers anything players type that could be a tag or placeholder: chat, command arguments and sign lines. If that text later shows up inside something being charged, it's shown exactly as typed, and placeholders players type are never filled in.
Guard deliberately skips a few things:
- Trusted players. Anyone with
lightning.trusted, ops by default, can use tags in what they type, so staff broadcasts work. - Bare tags. A message that's only
<red>or%player_name%isn't remembered. Otherwise one player typing<red>would switch off every red message on the server for ten minutes. - Lightning's own commands.
/lightningand/ltare never remembered.
guard in config.yml sets how long Lightning remembers, 10 minutes by default. 0 turns Guard off, which we don't recommend.
Why it stays fast
Lightning runs on every packet that carries text, so it's built to do as little as possible:
Surfaces that are off are never looked at.
Text without a < is skipped after one quick look. That's almost every message on most servers.
Text with a < but no real tag is skipped before any parsing, like /home <name>.
Repeated text is answered instantly. Tab lists and scoreboards resend the same lines constantly, and Lightning remembers them.
Live text is never cached. Anything that depends on the clock, chance, placeholders or the reader is charged fresh, so it's always right.
Last updated on