About Creating personalized scoreboards (per-player) can be difficult if not done correctly. This tutorial will show you how to not only create a scoreboard that displays the player's stats but also how to prevent flickering. Note: I prefer using the section sign (§) for color codes over ChatColor.COLOR, sorry if this bothers you! Code (All sections will be in a spoiler named according to their classes) Spoiler: Main.Java Code (Java): public class Main extends JavaPlugin { @Override public void onEnable() { this.getServer().getPluginManager().registerEvents(new PlayerJoin(), this); this.getServer().getPluginManager().registerEvents(new PlayerLeave(), this); sbmanager.start(); } } Spoiler: ScoreboardManager.java Code (Java): public class ScoreboardManager { private final MapHandler map = new MapHandler(); private final Main plugin = new Main(); public void createScoreboard(Player player) { Scoreboard scoreboard = Bukkit.getScoreboardManager().getNewScoreboard(); Objective objective = scoreboard.registerNewObjective("§bTest", "dummy"); objective.setDisplaySlot(DisplaySlot.SIDEBAR); map.addPlayerScoreboard(player, scoreboard); Score blankLine = objective.getScore("§0"); blankLine.setScore(15); if (scoreboard.getTeam("name") == null) { scoreboard.registerNewTeam("name"); } scoreboard.getTeam("name").addEntry("§7"); scoreboard.getTeam("name").setPrefix("§fName: §7"); scoreboard.getTeam("name").setSuffix(player.getName()); objective.getScore("§7").setScore(14); if (scoreboard.getTeam("health") == null) { scoreboard.registerNewTeam("health"); } scoreboard.getTeam("health").addEntry("§7§7"); scoreboard.getTeam("health").setPrefix("§fHealth: §7"); scoreboard.getTeam("health").setSuffix("" + player.getHealth()); objective.getScore("§7§7").setScore(13); map.addOnlinePlayer(player); player.setScoreboard(scoreboard); } public void updateScoreboards() { for (Player player : Bukkit.getOnlinePlayers()) { Scoreboard scoreboard = map.getPlayerScoreboard(player); if (scoreboard.getTeam("name") == null) { scoreboard.registerNewTeam("name"); } scoreboard.getTeam("name").setPrefix("§fName: §7"); scoreboard.getTeam("name").setSuffix(player.getName()); if (scoreboard.getTeam("health") == null) { scoreboard.registerNewTeam("health"); } scoreboard.getTeam("health").setPrefix("§fHealth: §7"); scoreboard.getTeam("health").setSuffix("" + player.getHealth()); } } public void start() { new BukkitRunnable() { @Override public void run() { updateScoreboards(); } }.runTaskTimer(plugin, 0L, 5L); } } Spoiler: MapHandler.java Code (Java): public class MapHandler { public HashMap<Player, Scoreboard> playerScoreboards = new HashMap<Player, Scoreboard>(); public boolean checkPlayerScoreboard(Player player) { if (playerScoreboards.containsKey(player)) { return true; } return false; } public void addPlayerScoreboard(Player player, Scoreboard scoreboard) { if (checkPlayerScoreboard(player)) { playerScoreboards.remove(player); } playerScoreboards.put(player, scoreboard); } public void removePlayerScoreboard(Player player) { if (checkPlayerScoreboard(player)) { playerScoreboards.remove(player); } } public Scoreboard getPlayerScoreboard(Player player) { if (!checkPlayerScoreboard(player)) { Bukkit.getServer().getConsoleSender() .sendMessage("§cThere was an error getting " + player.getName() + "'s scoreboard!"); return null; } return playerScoreboards.get(player); } } Spoiler: PlayerJoin.java Code (Java): public class PlayerJoain implements Listener { private final ScoreboardManager sb = new ScoreboardManager(); @EventHandler public void playerJoin(PlayerJoinEvent event) { sb.createScoreboard(event.getPlayer()); } } Spoiler: PlayerLeave.java Code (Java): public class PlayerLeave implements Listener { private final MapHandler map = new MapHandler(); @EventHandler public void playerLeave(PlayerQuitEvent event) { map.removePlayerScoreboard(event.getPlayer()); } } Explanation In onEnable() we register the PlayerJoin listener to listen for when a player joins. The last line in onEnable() runs the method from the ScoreBoardManager class to start updating scoreboards every quarter of a second (5 ticks). When a player joins, a new scoreboard is created and the player along with the scoreboard is added to a hashmap for later use. When updating, we call the scoreboard from our hashmap using Bukkit#getOnlinePlayers() as the object. As we update, the teams aren't modified rather the prefixes and suffixes are to prevent flickering. When a player leaves, they are removed from the hashmap to prevent un-needed usage of the CPU as it must look through more entries in the hashmap. If you have any questions, feel free to reply below and I will do my best to provide help. Thanks for reading, I hope this helped. If it did, consider leaving a rating as they are much appreciated!
Isn't it easier to give 1 scoreboard to all players than to create a scoreboard for each player? (PlayerJoinEvent) I have this fairly simple class created with the Netherboard api, which is updated, does not blink and has an animated title. Class: Spoiler: ScoreboardAdmin Code (Text): public class ScoreboardAdmin { private final Main plugin; public ScoreboardAdmin(Main plugin){ this.plugin = plugin; } private int ini; private List<String> list; private BPlayerBoard board; public void createScoreboard(Player player){ if(plugin.getConfig().getString("LobbyBrain.Scoreboard.enable").contains("true")) { BPlayerBoard gboard = Netherboard.instance().getBoard(player); if(gboard == null){ gboard = Netherboard.instance().createBoard(player, "MyScoreboard"); } this.board = gboard; List<String> lista = plugin.getConfig().getStringList("LobbyBrain.Scoreboard.Scores"); for(int i = 0;i < lista.size(); i++){ board.set(PlaceholderAPI.setPlaceholders(player, ChatColor.translateAlternateColorCodes('&', lista.get(i))) , lista.size()-(i)); } board.setName(PlaceholderAPI.setPlaceholders(player, ChatColor.translateAlternateColorCodes('&', list.get(ini)))); } } public void RunnableScoreboard(){ //then the RunnableScoreboard method is called in onEnable (); List<String> lista2 = plugin.getConfig().getStringList("LobbyBrain.Scoreboard.Tittle"); int ticks = plugin.getConfig().getInt("LobbyBrain.Scoreboard.ticks"); this.list = lista2; BukkitScheduler sc = Bukkit.getServer().getScheduler(); sc.scheduleSyncRepeatingTask(plugin, new Runnable(){ @Override public void run(){ for(Player p : Bukkit.getOnlinePlayers()){ createScoreboard(p); } if(ini < list.size()-1){ ini++; }else{ ini = 0; } } }, 0, ticks); } } And don't need so many classes and this gives 1 scoreboard to all players instead of creating 1 scoreboard per player. NetherboardAPI: https://github.com/MinusKube/Netherboard
This way of creating the scoreboards was to prevent the usage of an external API. Also, you cannot change the values to just a single scoreboard but display different content without editing packets.