Solved Scoreboard Flickers With Packet Based Scoreboard

Discussion in 'Spigot Plugin Development' started by MrGamingLion66, Mar 27, 2020.

  1. Hey! I've been trying to create a scoreboard system using packets directly. Although it's mostly working at this point I still can't get rid of the dreaded scoreboard flicker. The timing on the flicker isn't very consistent. It will go a while without flickering and then flicker a few times. I am consistently updating the scoreboard though. I've been using this resource to create and send the packets:
    https://gist.github.com/MrZalTy/f8895d84979d49af946fbcc108b1bf2b
    I had to alter it slightly to work on 1.12, but other than the flickering the resource works just fine. Any help would be appreciated.
     
  2. This typically appears when you're resending the scoreboard, didn't worked with packets scoreboard but i assume that it's working kinda same.
    The fix would be to have a line cache, where placeholders exists.
    Example:

    you've created a scoreboard and on line 5 there's %player_name% placeholder
    when it's creating you can add in a hashmap integer string
    integer is the line, string is the original line without the placeholder replace
    and in a bukkit task, you can simply make a for player (assuming you have like a datatype class for each player)
    and there you can get the scoreboard and make a method refresh that works with the hashmap
     
  3. @MrDarkness462
    I already have a line cache, it's in the VirtualLine array in the ScoreboardWrapper. As for a refresh method, I also have one, although not in the class that sends the packets. From what I understand of scoreboard flickers they are usually caused by removing and replacing a line in rapid succession. If I were to guess, it likely has something to do with the packet mode for PacketPlayOutScoreboardTeam and/or PacketPlayOutScoreboardScore.
     
  4. It has been a long time since I have interacted with Scoreboards (not even on the packet level), but if I recall I always needed a buffer between the current scoreboard and the updated one - even if the buffer was the same as the old scoreboard. Setting the scoreboard to the current one when updating caused a disgusting flicker.

    I'm not sure if things have changed, let me know.
     
    • Agree Agree x 1
  5. @View
    I believe what your talking about is updating the objective that is being displayed for a player (correct me if I'm wrong). The way my system is built currently circumvents this problem entirely because I'm keeping everything on the same objective. The only thing I'm updating is the individual scores. The method I'm using involves only updating the scoreboard team that is being displayed on a line, that way only one packet is being sent to update any given line. I believe the problem I'm currently having exist because, in order to get the team updates to register, I am forced to send a packet to update the score afterward. What I'm trying to figure out is how to update only the team without resetting the score, or setting the score in such a way that only one packet needs to be sent.
     
  6. It is a little bit off topic but there is no reason to create scoreboard by using packets.
    Just set the player a new scoreboard with player#setScoreboard and access with player#getScoreboard the current scoreboard of player and do the changes.

    I think you are using packets because of you think that it isn’t possible to create objective and team at the same team. But yes, it does work.
    Just create the teams in the individual scoreboard of the current player, loop through all online players and add the players into the team.

    Don’t use packets, if you don’t need to.
     
  7. @Haoshoku
    Thanks for the input, but I've actually already made a scoreboard system with the built-in Bukkit method. The reason I'm using packets is rather complicated but the gist of it is that I'm trying to get around the 32 character limit for 1.8 clients. I did tag this post with 1.12 because that's the version I'm coding in, but the server I'm programming this for supports 1.8 through 1.15. Part of the system I'm creating involves animating chat colors on scoreboard lines, which is problematic for two reasons. First, because splitting chat colors between the prefix and suffix of a team name means that I have to fix colors on the other side. If I'm using an animation with multiple chat colors (possibly bolded as well), this drastically decreases the number of characters I have available. Additionally, although I'm not 100% certain about this, I've heard that directly using packets improves performance ever so slightly, and as I'm sending multiple packets per second to make these animations work, I'll take what performance improvements I can get. The ultimate goal of using packets is to leverage the display name of a scoreboard team, which I've tried to use in Bukkit to no avail, hence why I had to split chat colors. Not only does using the display name mean that I get 16 extra characters, chat colors carry over into the display name and suffix meaning I don't lose as many characters fixing chat colors.

    On an unrelated note, given the responses I've gotten so far, I feel the need to clarify something about the nature of the flicker. Most people seem to assume the whole objective is flickering, which I believe is more common as it happened to me a lot when I first started working with scoreboards. What's actually happening is that individual lines are collapsing and expanding, I assume as they are being added and readded. As I mentioned before I believe this is because I'm forced to send a scoreboard score packet after the scoreboard team packet in order to get the team update to register on the scoreboard. To clarify I am only sending an objective packet once and as such, it shouldn't be causing the flicker. From what I've gleaned after looking through the Bukkit and Minecraft source code, they only send a scoreboard team packet when updating the lines. If you look at the sendLine method in the resource I attached in my first post, it sends both the team update packets and a score update packet after those team packets. I think that if I can find a way to stop sending the score packet every time an update happens, it should fix the flicker as I've already determined that the team packets do not cause the flicker.

    I apologize for the long-winded response, I just felt the need to clarify a few things!
     
  8. I've heard something about two scoreboard switching each other off to prevent flickering.
    Maybe you can try make 2 scoreboard and display 1, then update 2, after that display 2 and update 1.....
    I also wrote this util for scoreboard updates.
    You could intercept the packets to see which one in what order you need to send.
    https://gist.github.com/DanielTheDev/99079d0036cea4bbc765711560410eba
     
  9. @DanielTheDev
    Hey sorry about the late response to this thread. While I was attempting to make a buffer scoreboard to achieve the double scoreboard effect, I actually found that I could get rid of the flicker when I downgraded to 32 characters by just not removing the score and only updating the team, which unfortunately defeats the purpose of setting the scoreboard up with packets, but at least it works now. I think I'm going to keep the 32 character limit for the time being, but on a very limited scale, I did get the alternating scoreboards working with no flicker. When I have a little extra time, maybe I'll try to transition the system over. Thanks for the help!