> ## Documentation Index
> Fetch the complete documentation index at: https://velas.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Coordinates: Display player coordinates in real-time on a scoreboard

> Learn how to create a real-time coordinates display using the Scoreboard API.

This example demonstrates how to build a dynamic sidebar that continuously displays a player’s current coordinates in real time. Using the `Velaboard` API, a personal scoreboard is created for each player when they join the server, and its content is updated at regular intervals to reflect changes in their position. As the player moves through the world, their X, Y, and Z values are refreshed on the `Sidebar`, providing a live and responsive coordinates display. This showcases how the API can be used to handle per-player scoreboards, respond to events like player joins, and efficiently update information without recreating the entire scoreboard.

## 🔗 Useful Links

* 📖 **Documentation:** [*Link*](./introduction)
* 📚 **API Reference:** [*Link*](./api/scoreboard-api)
* 🧩**Download Coordinates Sidebar Plugin(this):** [*Link*](https://modrinth.com/plugin/coordinates-sidebar)
* 🧩 **Download Velaboard Plugin:** *Coming-Soon*

## Overview

* **Create individual player sidebars**
* **Update sidebar content in real-time**
* **Display player coordinates (X, Y, Z)**
* **Handle player join events**
* **Update coordinates of players on sidebar**

## Result

Players see a scoreboard showing their current coordinates:

<CardGroup cols={2}>
  <Frame>
    <img src="https://mintcdn.com/velas/uAALIUzH04TUwoB4/images/Coordinates-Sidebar(Velaboard).png?fit=max&auto=format&n=uAALIUzH04TUwoB4&q=85&s=53683d277cc06cb0c605f1fab351678a" alt="Coordinates Sidebar(velaboard)" title="Coordinates Sidebar(velaboard)" className="mx-auto" width="469" height="474" data-path="images/Coordinates-Sidebar(Velaboard).png" />
  </Frame>
</CardGroup>

## Step-by-Step Guide: Creating a Coordinates Sidebar

### Step-1: **Create the Main Plugin Class**

```java theme={null}
import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin;
import org.velas.scoreboard.api.ScoreboardAPI;

public class Coordinates extends JavaPlugin {

    private boolean API_INITIALIZED;

    @Override
    public void onEnable(){
        try{
            if(ScoreboardAPI.isInitialized()) API_INITIALIZED=true;
        }catch (Exception ignored){
            API_INITIALIZED=false;
        }
        if(API_INITIALIZED)
            Bukkit.getPluginManager().registerEvents(new Listener(), this);
    }
}
```

<a name="listener" />

### Step-2: Create the Listener

```java theme={null}
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.jetbrains.annotations.Nullable;
import org.velas.scoreboard.api.Scoreboard;
import org.velas.scoreboard.api.ScoreboardAPI;
import org.velas.scoreboard.api.sidebar.PlayerSidebar;

public class Listener implements org.bukkit.event.Listener {

    @Nullable
    private final Scoreboard scoreboard;

    public Listener(){
        this.scoreboard=ScoreboardAPI.getHandler().createScoreboard();
    }

    @EventHandler
    public void onPlayerJoin(PlayerJoinEvent event){
        if(scoreboard==null) return;
        Player player = event.getPlayer();
        scoreboard.addPlayer(player);
        if(!scoreboard.hasSidebar(player)){
            PlayerSidebar sidebar = scoreboard.createPlayerSidebar("§8✦ §6§lCoordinates §8✦");
            sidebar.setPlayer(player);
            Location loc = player.getLocation();
            sidebar.setLine(7, "§7 ");
            setCoordinateLines(sidebar, loc);
            sidebar.setLine(3, "§7  ");
            sidebar.setLine(2, "§8§m -------------- ");
            sidebar.setLine(1, "§f§lWorld §8» §a" + loc.getWorld().getName());
            sidebar.setLine(0, "§8§m----------------");
            sidebar.show();
        }
    }

    @EventHandler
    public void onPlayerMove(PlayerMoveEvent event){
        Player player = event.getPlayer();
        Scoreboard scoreboard = ScoreboardAPI.getHandler().getScoreboard(player);
        if(scoreboard==null) return;
        PlayerSidebar sidebar = scoreboard.getPlayerSidebar(player);
        if(sidebar==null) return;
        setCoordinateLines(sidebar, player.getLocation());
    }

    private void setCoordinateLines(PlayerSidebar sidebar, Location loc){
        sidebar.setLine(6, "§f§lX §8» §e" + loc.getBlockX());
        sidebar.setLine(5, "§f§lY §8» §e" + loc.getBlockY());
        sidebar.setLine(4, "§f§lZ §8» §e" + loc.getBlockZ());
    }
}
```

### Step-3: Add this in your `plugin.yml`

Check [`Installation`](./installation#declare-the-plugin-dependency) for more information.

```yaml theme={null}
depend: [Velaboard]
```

## **🔑 Key Components**

### **1. Scoreboard Creation:**

When the plugin is enabled, the `onEnable()` lifecycle method is invoked. During this phase, the plugin attempts to verify whether the ScoreboardAPI has been properly initialized.

This check is performed inside a `try-catch` block to safely handle any unexpected errors like `ClassNotFoundException` that may occur during the verification process.

```java theme={null}
@Override
public void onEnable() {
	try {
		if (ScoreboardAPI.isInitialized()) API_INITIALIZED = true;
	} catch (Exception ignored) {
		API_INITIALIZED = false;
	}

	if (API_INITIALIZED)
		Bukkit.getPluginManager().registerEvents(new Listener(), this);
}
```

* If the API is confirmed to be initialized (`API_INITIALIZED == true`), the plugin proceeds to register its event listeners using Bukkit’s plugin manager.
* The `Listener` class is registered to handle events during runtime.

### **2. Scoreboard Creation:**

At the time of event listener registration, the [`Listener`](#listener) instance is created, and during its construction, the [`Scoreboard`](./concepts/scoreboard) is conditionally instantiated and stored for later use.\\

When the plugin is enabled, the following line is executed inside `onEnable()` method:

```java theme={null}
Bukkit.getPluginManager().registerEvents(new Listener(), this);
```

Inside your constructor:

```java theme={null}
public Listener(){
    this.scoreboard=ScoreboardAPI.getHandler().createScoreboard();
}
```

`Scoreboard` is created and stored in the instance field `scoreboard` for Later Use in Events.

### **3. Sidebar Setup:**

A player [`Sidebar`](./concepts/sidebars) is created with a title, if the players is not associated with any sidebar in the scoreboard.

```java theme={null}
PlayerSidebar sidebar = scoreboard.createPlayerSidebar("Coordinates");
sidebar.setPlayer(player);
Location loc = player.getLocation();
sidebar.setLine(7, "§7 ");
setCoordinateLines(sidebar, loc);
sidebar.setLine(3, "§7  ");
sidebar.setLine(2, "§8§m -------------- ");
sidebar.setLine(1, "§f§lWorld §8» §a" + loc.getWorld().getName());
sidebar.setLine(0, "§8§m----------------");
sidebar.show();
```

### **4. Real-Time Updates:**

Updates content of the`sidebar` whenever the player moves.

```java theme={null}
@EventHandler
public void onPlayerMove(PlayerMoveEvent event) {
	// Updates the coordinates
}
```

### **5. Line Management:**

For creating/updating `lines` in the  [`Sidebar`](./concepts/sidebars) , use `sidebar.setLine("text")` .

```java theme={null}
sidebar.setLine(6, "§f§lX §8» §e" + loc.getBlockX());
sidebar.setLine(5, "§f§lY §8» §e" + loc.getBlockY());
sidebar.setLine(4, "§f§lZ §8» §e" + loc.getBlockZ());
```

Line indices go from 0 (bottom) to 14 (top). More than 14 or less than 0 throws `Exception` .

## 🤔 FAQs

#### 1. Do I need to manually add players to the scoreboard when they join the server?

No, it is not always necessary to manually add players to the scoreboard on every join event.

In this system, players only need to be added to a scoreboard **when required** (for example, when creating or assigning a new scoreboard). There is no need to repeatedly add the player each time they join.

Unlike traditional Bukkit scoreboards, this implementation handles player–scoreboard association internally. If a player was previously associated with a scoreboard, it will be **automatically restored or maintained**, eliminating the need for redundant additions during the join event.

#### 2. Do I need to manually add or show the sidebar to a player when they join the server?

No, you do not need to manually add or show the sidebar when a player joins the server.

Similar to scoreboards, sidebars are **automatically restored**. If a player is already associated with a sidebar in the scoreboard they belong to, it will be **automatically displayed** when they join.

🔹 **Controlling Auto-Display on Join**

If you want to prevent the sidebar from showing automatically on player join, you can listen to the `SidebarShowEvent` and cancel it when the reason is `PLAYER_JOIN`.

**Example:**

```java theme={null}
@EventHandler
public void onSidebarShow(SidebarShowEvent event) {
    if (event.getReason() == SidebarShowEvent.Reason.PLAYER_JOIN) {
        event.setCancelled(true);
    }
}
```

## **📋 Requirements**

### **1. Dependencies**

The latest dependency configuration is maintained [here](./installation#add-the-dependency). Please refer to it for up-to-date details.

### **2. Server Requirements**

* ✅ **Minecraft 1.20-1.21.11**
* ✅ **Spigot/Paper server**
* ✅ **Velaboard plugin installed**

## **🚀 Usage**

### **Install the Plugin**

1. Compile your plugin: `mvn clean package`
2. Place JAR in server's `plugins/` folder
3. Restart server
4. Players see coordinates on join! ✅

<CardGroup cols={2}>
  <Card title="How the Scoreboard Object Works in VelaBoard" horizontal href="./concepts/scoreboard">
    All you need you know
  </Card>

  <Card title="Sidebar and its Types" horizontal href="./concepts/sidebars">
    PlayerSidebar vs SharedSidebar
  </Card>
</CardGroup>
