(Java Minecraft 1.14.3) Can a bossbar show different values to different players?

I would like to use a bossbar, with value set with execute store result bossbar, to hold the 'mana' value for each player in my datapack (which is held in a scoreboard so it can be manipulated in the background by various functions).

However, I can't find an option for which player's value to set, and can only find a setting for which players the bossbar is visible for. Are bossbar values global or would I need to make one bossbar per player that I want to display a mana amount for?

If bossbar values are global, what alternatives are there for making some type of bar type display? I don't want to use scoreboard numbers because they are ugly. I'm open to particles, resource packs, anything but mods really.


Solution 1:

You can make one bossbar per mana level, rather than per player. To make a mana system where you can have between 0 and 4 mana you would have to first create the bossbars, set their values, and set their maximal values. You only need to do this once:

bossbar add mana0 "Mana"
bossbar add mana1 "Mana"
bossbar add mana2 "Mana"
bossbar add mana3 "Mana"
bossbar add mana4 "Mana"

bossbar set minecraft:mana0 max 4
bossbar set minecraft:mana1 max 4
bossbar set minecraft:mana2 max 4
bossbar set minecraft:mana3 max 4
bossbar set minecraft:mana4 max 4

bossbar set minecraft:mana0 value 0
bossbar set minecraft:mana1 value 1
bossbar set minecraft:mana2 value 2
bossbar set minecraft:mana3 value 3
bossbar set minecraft:mana4 value 4

You would then repeatedly (each tick) set the players for each bossbar.
I'm assuming that the mana value is held in a scoreboard objective with the objective name mana. If that is not the case for you, then you may have to modify these commands.

bossbar set minecraft:mana0 players @a[scores={mana=..0}]
bossbar set minecraft:mana1 players @a[scores={mana=1}]
bossbar set minecraft:mana2 players @a[scores={mana=2}]
bossbar set minecraft:mana3 players @a[scores={mana=3}]
bossbar set minecraft:mana4 players @a[scores={mana=4..}]

Solution 2:

Bossbar values are global, yes. If you have a limited number of players, you could just make multiple boss bars and display each to just one player. If you could have an arbitrarily high amount of players or don't want to put in that much effort to create boss bars for everyone, then you could use the XP bar instead, using /xp set <selector> <number> points.

Solution 3:

So what I decided was that I would have the mana bar cycle through every player's mana value one player per tick, so that it would appear to "flicker" with the correct value. It is super ugly, but works when you have less than ten total players. The one I made changes once per tick but one changing every four ticks might be better, because then it would be flashing rather than flickering.

First, I set up an ID system, so whenever a player joins the game, the global ID scoreboard is incremented and the new player gets a new ID value. In this way, every player has a unique id number.

Then, I run this function, which uses recursion to get the next player who is online, once every tick. It adds one to the manaTimer value, resetting it if it reaches the player with the highest ID. Then, if the player with the current manaTimer value's ID is not online (or, stated differently, unless he is online), run the function again, increasing once per repetition, so it ends up at the next player who is online. In this way, if there's one player online it will stay on, if there's two it will flicker at 10hz, if there's 4 it will go at 5hz, etc. ID and manaTimer are fake players in the objective global.

scoreboard players add manaTimer global 1
execute if score manaTimer global >= ID global run scoreboard players set manaTimer global 1
execute as @a unless score @s playerID = manaTimer global run function dark_magic:tick_functions/get_next_player

Then, I have another function running once per tick. It has three commands, which first make the bossbar invisible to everyone, then store the currently displayed player's mana score in the bossbar, and finally make the bossbar visible to that player.

bossbar set minecraft:mana players @s[tag=nobody]
execute as @a if score @s playerID = manaTimer global run execute store result bossbar minecraft:mana value run scoreboard players get @s mana
execute as @a if score @s playerID = manaTimer global run bossbar set minecraft:mana players @s

It's not pretty, but it works. I will probably optimize it so it flickers at different speeds depending on how many people are online.