Individual Signs



This plugin displays the text on signs for each player individual differently.
Right now, it only replaces "[PLAYER]" on the sign with the name of the player looking at it.
However, it also includes an API for developers of other plugins to easily add own, custom player-specific sign content.
So when two players look at a sign at the same time with "[PLAYER]" somewhere on it they will see a different text.
You don't believe me? Then test it out for yourself!
This could for example be used for individual greeting signs at your spawn. Your players will be amazed to see their own name on a sign!
Permission to create a sign with "[PLAYER]" on it: insigns.create.player

How this works

To achieve this the plugin manipulates the sign packet that is sent to a player.
But keep in mind, that each line can still only hold 15 characters. So if the text is longer, it will automatically cut it at the 15's character. If the next lines of the sign are empty, InSigns will try to continue there.


This plugin needs ProtocolLib to work.
Make sure you have installed the right version of ProtocolLib.
This plugin should stay compatible with further versions of minecraft and bukkit, as long as ProtocolLib doesn't have to change anything on it's API which InSigns is relying on.

Quick Presentation by VariationVault

For plugin developers: easy-to-use API

Here is a small example of how you can use this in your own plugin to display player-specific values on signs.
1.) First of all: add the Individual_Signs jar to your build path (just like you do it with the bukkit.jar)
2.) You can then create a listener which listens for the SignSendEvent (just like you create listeners for bukkit events): this event gets called every time the server is about to send a player the text of a sign.
3.) The event provides easy methods to get the current sign text and to change it:

  • getPlayer() - Gets the player which receives the sign packet.
  • getLocation() - Gets the location of the sign which text is being sent.
  • getLine(int index) - Gets the line of text at the specified index (0-3).
  • setLine(int index, String line) - Sets the line of text at the specified index.
  • Note that lines longer than the allowed 15 characters will be either cut or continued in the next lines (if those are empty) AFTER the event is over.
  • isModified() - Whether or not this event was already modified by some plugin.
  • setCancelled(boolean cancelled) - If the event is cancelled the sign packet will not be sent to the player, leaving the sign blank.
  • isCancelled() - Checks whether or not some plugin cancelled this event already.

Example usage of the event to replace "[PLAYER]" with the player's name:

public class SignSendListener implements Listener {

    public SignSendListener(Plugin plugin) {
        Bukkit.getServer().getPluginManager().registerEvents(this, plugin);

    @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
    public void onSignSend(SignSendEvent event) {
        for (int i = 0; i < 4; i++) {
            String line = event.getLine(i);
            if (line.contains("[PLAYER]")) {
                event.setLine(i, line.replace("[PLAYER]", event.getPlayer().getName()));

That's it. The InSigns-Plugin will handle all the needed packet manipulation for you.

Some other useful utilities provided by InSigns are:

  • the static method InSigns.sendSignChange(Player player, Sign sign) - Sends a SignUpdate-Packet to the specified player. Useful if you want to update certain signs periodically.
  • the SimpleChanger class, which can be used to easily create a listener for simple key->value replacements and permission checks during sign creation. Example for the built-in [PLAYER] -> playerName replacement:
public void onEnable() {
    Plugin insignsPlugin = getServer().getPluginManager().getPlugin("InSigns");
    if ((insignsPlugin != null) && insignsPlugin.isEnabled()) {
        // replaces "[PLAYER]" with the player's name on signs and checks for the 'insigns.create.player' permission
        // whenever a player tries to create a sign with "[PLAYER]" on it
        new SimpleChanger(this, "[PLAYER]", "insigns.create.player") {
            public String getValue(Player player, Location location, String originalLine) {
                return player.getName();
        System.out.println("Plugin 'InSigns' found. Using it now.");
    } else {
        System.out.println("Plugin 'InSigns' not found. Additional sign features disabled.");

Plugins using InSigns

Let me know if your plugin uses InSigns and you want to be mentioned here.




This plugin uses Hidendra's Metrics class to report usage stats to This can be disable by setting 'metrics-stats' to false in the config.

Similar plugins

Are you looking for individual player heads? Then IndividualHeads might be the right plugin for you!

You must login to post a comment. Don't have an account? Register to get one!

  • Avatar of MinecraftAdmin MinecraftAdmin Dec 09, 2014 at 17:34 UTC - 0 likes

    As of this moment, V2.0 does not work on Spigot 1.8 and
    Protocollib for 1.8 has been released at this website

  • Avatar of blablubbabc blablubbabc Nov 16, 2014 at 03:42 UTC - 0 likes

    @LethalWrath: Go

    I hope and assume that ProtocolLib will keep functioning and maybe even getting maintained for the near future.
    After that I will of course have to look for alternative ways of hooking into minecraft's packet sending.

  • Avatar of LethalWrath LethalWrath Nov 16, 2014 at 03:10 UTC - 0 likes

    ProtocolLib has now become INACTIVE on its plugin page, I was wondering what will happen will happen to this plugin?

  • Avatar of pgmann pgmann Aug 28, 2014 at 17:40 UTC - 0 likes

    @blablubbabc: Go

    Ok, I moved the signs out of the way (to the paintball lobby), which will make it less likely for players to log in there. I guess I'll manage... :-)

    Make sure to take a look at my Bukkit plugins!

  • Avatar of blablubbabc blablubbabc Aug 28, 2014 at 17:21 UTC - 0 likes

    @pgmann: Go

    That is because paintball loads your player statistics in the background after you finished joining the server (for performance reasons).
    And IndividualSigns only intercepts sign packets (which get sent immediately when you join the server). It doesn't keep track of it's affected signs, nor does it automatically update those signs (for performance reaons as well).
    So your player statistics are not yet loaded when the server sends you the sign text, therefore it prints the '-not found-' thing instead.

    I don't think that is that big of a problem though.

    Last edited Aug 28, 2014 by blablubbabc
  • Avatar of pgmann pgmann Aug 28, 2014 at 17:13 UTC - 0 likes

    @blablubbabc: Go

    I found a bug when using this plugin to display scores from your paintball plugin. If I log in looking at the signs they will display '-not foun' in red until I right click them or go away to another location.

  • Avatar of PyroKraft PyroKraft May 17, 2014 at 16:56 UTC - 0 likes

    How can i use this plugin for my paintball plugin, what do i need to write in the signs (PLEASE HELP !!!)

  • Avatar of rsod rsod May 02, 2014 at 19:51 UTC - 1 like

    Well, thanks a lot for that API, I was just about to write own method to show individual signs, and I found that plugin, you saved a lot of my time =)

  • Avatar of blablubbabc blablubbabc Apr 20, 2014 at 00:17 UTC - 0 likes

    @xXBadeye: Go

    The error with the + is very likly an issue of your String.matches() method which checks for regexes and the + has a special meaning for regexes.. So you will have to escape that character.

  • Avatar of xXBadeye xXBadeye Apr 19, 2014 at 23:34 UTC - 0 likes

    @blablubbabc: Go

    Well, i hate spaming your comments but i got strange stack traces now. I have now (finaly) got it working, problem was that the plugin loaded BEFORE protocolLib and InSigns and taht i forgot the onEnable part :D Well, one more, strange packet error. The class is still the same as in the commend underneath.

    Stack Trace aaa is being printed out (see class in my last comment), so the getValue is called. Something seems to be wrong with the "+" on the sign, but it should be okay since it is just a string, right?

    Edit: Didn't refreshed the page, your comment came to late, but you figured the problems i had :)

    Edit 2: Well, it worked with removing the "+" from the string check... this is realy weird. So the text got replaced with the correct value, but there are no chat colors yet :D &4 did not work, have you implemented something like that?

    Edit 3: Tryed return (ChatColor.GREEN + "My text"); and it worked :> only problem are the god damm "+" :D

    Last edited Apr 19, 2014 by xXBadeye



Date created
Sep 18, 2012
Last update
Jan 14, 2014
Development stage
  • deDE
  • enUS
All Rights Reserved
Curse link
Individual Signs
Recent files



Required dependency