Skip to content

These docs were made completely by AI, so they might be right, or wrong, you'll need to test them yourself. This was made for a easier understanding of everything. So use at your own risk. If anything is wrong, please don't hurt to make a PR on the page you have a problem with. ON GITHUB

Scoreboard & Teams

The scoreboard system tracks player statistics, displays scores, and manages teams. It’s a C++ port of the Java Edition scoreboard. Most of the logic lives in headers, and the .cpp file has partially-stubbed implementations (methods are defined but their bodies are commented out, so it’s still a work in progress).

Key source files: Scoreboard.h/cpp, ServerScoreboard.h, Objective.h, ObjectiveCriteria.h, Score.h, ScoreHolder.h, PlayerTeam.h, Team.h, ScoreboardSaveData.h (in Minecraft.World/ and Minecraft.Client/).

The Scoreboard class is the central manager. It stores:

  • Objectives in unordered_map<wstring, Objective*> objectivesByName
  • Objectives by criteria in unordered_map<ObjectiveCriteria*, vector<Objective*>*>
  • Player scores in unordered_map<wstring, unordered_map<Objective*, Score*>>
  • Display slots in a fixed-size array of Objective* pointers (size DISPLAY_SLOTS = 3)
  • Teams by name in unordered_map<wstring, PlayerTeam*>
  • Teams by player in unordered_map<wstring, PlayerTeam*> (reverse lookup)

Three display slots are defined:

ConstantValueSlot nameWhere it shows
DISPLAY_SLOT_LIST0"list"Tab player list
DISPLAY_SLOT_SIDEBAR1"sidebar"Right side of the screen
DISPLAY_SLOT_BELOW_NAME2"belowName"Under player nametags

getDisplaySlotName(int) and getDisplaySlotByName(wstring) convert between integer and string representations. Both are static methods.

  • addObjective(name, criteria) creates an Objective, registers it by name and criteria, and fires onObjectiveAdded
  • getObjective(name) looks up by name
  • findObjectiveFor(criteria) finds all objectives using a given criteria, returns a vector<Objective*>*
  • removeObjective(objective) removes from all maps and display slots, fires onObjectiveRemoved
  • getObjectives() returns all objectives as a vector<Objective*>*
  • setDisplayObjective(int slot, Objective*) assigns an objective to a display slot
  • getDisplayObjective(int slot) returns which objective is in a given display slot
  • getPlayerScore(playerName, objective) retrieves or creates a score for a player-objective pair
  • getPlayerScores(objective) returns all scores for an objective as vector<Score*>*
  • getPlayerScores(playerName) returns all scores for a player as unordered_map<Objective*, Score*>*
  • getScores() returns every score in the system
  • resetPlayerScore(playerName) removes all scores for a player, fires onPlayerRemoved
  • getTrackedPlayers() returns all player names that have scores as vector<wstring>*
  • getPlayer(wstring) returns a shared pointer to the actual Player object for a given name
  • addPlayerTeam(name) creates a PlayerTeam, fires onTeamAdded
  • getPlayerTeam(name) looks up by team name
  • addPlayerToTeam(player, team) removes the player from any existing team first, then assigns them
  • removePlayerFromTeam(player) removes from current team (returns bool success)
  • removePlayerFromTeam(player, team) removes from a specific team
  • removePlayerTeam(team) removes a team and all its player-team mappings
  • getPlayersTeam(playerName) returns which team a player belongs to
  • getTeamNames() / getPlayerTeams() lists all teams

The base Scoreboard class defines virtual callback methods that do nothing by default:

  • onObjectiveAdded / onObjectiveChanged / onObjectiveRemoved
  • onScoreChanged
  • onPlayerRemoved
  • onTeamAdded / onTeamChanged / onTeamRemoved

These are all public virtual methods, designed to be overridden by ServerScoreboard.

An objective ties a name and display name to a criteria type.

FieldMax lengthDescription
nameMAX_NAME_LENGTH (16 chars)Internal identifier, used for commands and serialization
displayNameMAX_DISPLAY_NAME_LENGTH (32 chars)Shown in the UI
criteriaPointer to an ObjectiveCriteria
scoreboardBack-pointer to the owning Scoreboard

Constructor takes (Scoreboard*, wstring name, ObjectiveCriteria*). Methods include getScoreboard(), getName(), getCriteria(), getDisplayName(), and setDisplayName(wstring).

Defines how a score is calculated. Five built-in criteria are registered in a static CRITERIA_BY_NAME map (unordered_map<wstring, ObjectiveCriteria*>):

Static instanceCriteria namePurposeRead-only?
DUMMY"dummy"Manual scores only, no auto-updateNo
DEATH_COUNT"deathCount"Number of deathsNo
KILL_COUNT_PLAYERS"playerKillCount"Player killsNo
KILL_COUNT_ALL"totalKillCount"Total kills (all entities)No
HEALTH"health"Current healthYes

Interface methods:

  • getName() returns the string identifier for serialization
  • getScoreModifier(vector<shared_ptr<Player>>*) computes an automatic score update
  • isReadOnly() if true, the score can’t be set manually (only HEALTH returns true)

The DummyCriteria class provides a concrete implementation (source files: DummyCriteria.h/cpp). The HealthCriteria class provides the health-specific implementation (HealthCriteria.h/cpp).

Represents a single player’s score for one objective:

  • owner, the player name (wstring)
  • count, the integer score value
  • objective, which objective this belongs to
  • scoreboard, a back-pointer for change notification

Methods:

  • add(int) / remove(int) / increment() / decrement() adjust the count
  • setScore(int) / getScore() for direct access
  • getObjective() / getOwner() / getScoreboard() for field access
  • updateFor(vector<shared_ptr<Player>>*) recalculates from criteria

A minimal interface with one method: getScoreboard(). It returns a Scoreboard* and is meant for entities that participate in the scoreboard system.

The Team class defines the team interface:

  • getName() returns the team identifier
  • getFormattedName(teamMemberName) applies prefix/suffix formatting
  • canSeeFriendlyInvisibles() whether teammates can see each other when invisible
  • isAllowFriendlyFire() whether teammates can damage each other
  • isAlliedTo(Team*) checks if two teams are the same (compares by pointer)

All methods except isAlliedTo are pure virtual.

Concrete team implementation with these properties:

PropertyMax lengthConstantDescription
name16 charsMAX_NAME_LENGTHInternal team name
displayName32 charsMAX_DISPLAY_NAME_LENGTHShown in UI
prefix16 charsMAX_PREFIX_LENGTHPrepended to member names
suffix16 charsMAX_SUFFIX_LENGTHAppended to member names

Boolean options:

OptionBit positionConstantDefault
allowFriendlyFireBit 0BIT_FRIENDLY_FIRE
seeFriendlyInvisiblesBit 1BIT_SEE_INVISIBLES

The packOptions() and unpackOptions(int) methods serialize these booleans as a bitmask for network packets.

Player members are stored in an unordered_set<wstring>. getPlayers() returns a pointer to this set.

Static helpers:

  • formatNameForTeam(PlayerTeam*) formats the team name itself
  • formatNameForTeam(Team*, wstring name) applies the prefix/suffix wrapping to a player name

Full method list includes getScoreboard(), getName(), getDisplayName(), setDisplayName(), getPlayers(), getPrefix(), setPrefix(), getSuffix(), setSuffix(), getFormattedName(), isAllowFriendlyFire(), setAllowFriendlyFire(), canSeeFriendlyInvisibles(), setSeeFriendlyInvisibles(), packOptions(), unpackOptions().

ServerScoreboard extends Scoreboard on the server side (Minecraft.Client/ServerScoreboard.h). It adds:

  • A MinecraftServer* reference
  • A set of trackedObjectives (unordered_set<Objective*>) for network synchronization
  • A ScoreboardSaveData* pointer for persistence

It overrides all event hooks to push changes to connected clients and mark save data as dirty. Key networking methods:

  • getStartTrackingPackets(Objective*) builds the packet list (vector<shared_ptr<Packet>>*) to send when a client starts tracking an objective
  • getStopTrackingPackets(Objective*) builds the packet list to send when tracking stops
  • startTrackingObjective(Objective*) / stopTrackingObjective(Objective*) manage the tracked set
  • getObjectiveDisplaySlotCount(Objective*) returns how many display slots reference this objective
  • setDirty() marks the save data as needing a write (protected)
  • setSaveData(ScoreboardSaveData*) sets the persistence handler
  • getServer() returns the MinecraftServer*

The overridden methods setDisplayObjective, addPlayerToTeam, and removePlayerFromTeam take the same signatures as the base class but add network packet broadcasting.

ScoreboardSaveData (defined in a #if 0 block as unconverted Java) shows the intended NBT format. The FILE_ID is "scoreboard".

Objectives list ("Objectives"):

TagTypePurpose
"Name"StringInternal objective name
"CriteriaName"StringCriteria type identifier
"DisplayName"StringDisplayed name

Player scores list ("PlayerScores"):

TagTypePurpose
"Name"StringPlayer name
"Objective"StringObjective name
"Score"IntScore value

Teams list ("Teams"):

TagTypePurpose
"Name"StringTeam name
"DisplayName"StringDisplayed team name
"Prefix"StringName prefix
"Suffix"StringName suffix
"AllowFriendlyFire"BooleanFriendly fire toggle
"SeeFriendlyInvisibles"BooleanInvisible teammate visibility
"Players"String listTeam member names

Display slots ("DisplaySlots"):

A compound mapping "slot_0" through "slot_2" to objective names. Only written if at least one slot has an objective assigned.

The Java reference shows a delayLoad pattern: if the scoreboard reference isn’t set when load() is called, the data is stashed and loaded later when setScoreboard() is called. On save, a warning is logged if no scoreboard is available.

This save/load logic hasn’t been ported to C++ yet and only exists as reference Java code inside a #if 0 block.

LCEMP does not have any scoreboard implementation. The Scoreboard, Objective, ObjectiveCriteria, Score, PlayerTeam, Team, ScoreHolder, ServerScoreboard, and ScoreboardSaveData classes are all exclusive to MinecraftConsoles.