Skript Scoreboards in 5 Minutes! [2025]

  • Welcome to skUnity!

    Welcome to skUnity! This is a forum where members of the Skript community can communicate and interact. Skript Resource Creators can post their Resources for all to see and use.

    If you haven't done so already, feel free to join our official Discord server to expand your level of interaction with the community!

    Now, what are you waiting for? Join the community now!

Jake

Supporter
Jan 30, 2022
244
19
18
Italy
github.com

Need help making a scoreboard? No sweat, this tutorial is for you!

All you need is Skript (obviously) and skBee OR skript-scoreboards.

Note: In recent skBee updates the scoreboard syntax has switched from using the word(s) "scoreboard" to "fastboard", there is no difference in behavior, it can also be shortened with just "board" which is what we'll be using for the sake of simplicity.

Scoreboards are made of a title and 15 lines of text, the concept of dynamically creating them is very simple and it all starts when the player joins:
code_language.skript:
on join:

Many make the mistake of using this event with a while loop (or even worse a periodical event) and calling it a day, this is bad for a number of reasons, the main one being: you don't need to update the entire scoreboard continuously, all you NEED to do is update each scoreboard line (and/or the title) IF and WHEN the information in the respective line is updated, not following? Don't worry, we all love examples so here's one:

❌ Wrong
code_language.skript:
on join:
    while player is online:
        set title of players board to "My Server"
        set line 1 of player's board to "Money: %{money::%player's uuid%}%"
        wait 1 tick

✅ Right (mostly!)
code_language.skript:
on join:
    set title of players board to "My Server"
    set line 1 of player's board to "Money: %{money::%player's uuid%}%"

That's a good step in the right direction, but it comes with a flaw which needs to be addressed: redundancy.
A good rule of thumb when programming is that when doing something many times – whether it be the same task or slightly different – you should always do your best not to repeat yourself, this is called DRY (Don't Repeat Yourself), so if we were to update the first line of the board once that variable is updated, we should ensure it always happens that way and it's consistent, thankfully – functions exist! :emoji_slight_smile:
If you don't understand functions here's a simple rundown: a function is a section of code that has a name (the name of the function, that is), parameters (or none; they are placed inside a pair of parentheses; each parameter has a name and a type, they are separated by a colon ":", when using more than one parameter you must separate them with a comma; additionally, parameters can have default values, but that's more advanced ) and an optional return value.

Example of a function:
code_language.skript:
function giveDiamond(selectedPlayers: players, amount: int):
    give players in {_selectedPlayers::*} {_amount} of diamond

Here's a very simple function approach that modifies the player's money variable while also keeping the board up to date with that very variable's value by using another function for the actual board modification:

code_language.skript:
# Note: for the sake of simplicity we are counting line 0 as the title
function board(player: player, lines: ints):
    loop {_lines::*}:
        if loop-value = 0:
            set title of {_player}'s board to "My Server"
        else if loop-value = 1:
            set line 1 of {_player}'s board to "Money: %{money::%uuid of {_player}%}%"
 

function addMoney(player: player, increase: number):
    increase {money::%uuid of {_player}%} by {_increase}
    board({_player}, 1)

With this approach you never need to update the board – it does it by itself!
Moving forward this is what you should do to manage your scoreboards, and to help establish this concept, here is a more in-depth example:

code_language.skript:
# Note: for the sake of simplicity we are counting line 0 as the title
function board(player: player, lines: ints):
    loop {_lines::*}:
        if loop-value = 0:
            set title of {_player}'s board to "&3&lMy Server"
            continue
        else if loop-value = 1 or 4:
            set {_content} to " "
        else if loop-value = 2:
            set {_content} to "&3&l⎢&7 Money: &3$%{money::%uuid of {_player}%} ? 0%"
        else if loop-value = 3:
            set {_content} to "&3&l⎢&7 Rank: &3%{rank::%uuid of {_player}%} ? "Player"%"
        else if loop-value = 5:
            set {_content} to "&3mc.mynewserver.net"
        if {_content} exists:
            set line loop-value of {_player}'s board to {_content}
            clear {_content}

function addMoney(player: player, increase: number):
    increase {money::%uuid of {_player}%} by {_increase}
    board({_player}, 2)

function setRank(player: player, newRank: string):
    set {rank::%uuid of {_player}%} to {_newRank}
    board({_player}, 3)

on join:
    board(player, integers from 0 to 5) # 5 being the index of the biggest expected line, if your board has all 15, use that

u0g2CUx.png


Since 1.20.4 you can now use minecraft's number format, I won't bore you with the details, but it essentially means you can set the score of the board's lines (on the right), you simply need to set the line to two strings instead of one (Note: this way of doing it is specific to skBee, if you wish to use skript-scoreboards you'll have to use this expression), here is the updated example with a slightly different design to make use of this feature:

code_language.skript:
function board(player: player, lines: ints):
    loop {_lines::*}:
        if loop-value = 0:
            set title of {_player}'s board to "&3&lMy Server"
            continue
        else if loop-value = 1 or 4:
            set {_content::*} to " "
        else if loop-value = 2:
            set {_content::*} to "&3&l⎢&7 Money: &3$%{money::%uuid of {_player}%} ? 0%" and "&3&l⎢"
        else if loop-value = 3:
            set {_content::*} to "&3&l⎢&7 Rank: &3%{rank::%uuid of {_player}%} ? "Player"%" and "&3&l⎢"
        else if loop-value = 5:
            set {_content::*} to "&3mc.mynewserver.net"
        if {_content::*} exists:
            set line loop-value of {_player}'s board to {_content::*}
            clear {_content::*}

function addMoney(player: player, increase: number):
    increase {money::%uuid of {_player}%} by {_increase}
    board({_player}, 2)

function setRank(player: player, newRank: string):
    set {rank::%uuid of {_player}%} to {_newRank}
    board({_player}, 3)

on join:
    board(player, integers from 0 to 5)
HS4wrYm.png


Notes to the reader:
- AI has not been used to write any part of this tutorial, I just really like em and en dashes!
- This tutorial was made with the latest versions in mind.
- Enjoy this free knowledge, go out in the digital world of Minecraft and Skript and do your worst (well – actually – your best!).

Made with :emoji_heart: for the community! ✝️
 
Last edited:
By any chance am i able to create a timer that goes down in minutes that i can do /settimer 30 which will make a 30 minute timer on my scoreboard?
 
could you maybe add a player count of how many players have joined and how many players are currently in the server?