
# Server

Text values are [text](text.md) snapshots.

## Connection

| Function | Returns |
|----------|---------|
| `server.address()` | Server address, `nil` in singleplayer |
| `server.ping()` | Your ping in ms |
| `server.brand()` | `"vanilla"`, `"paper"`, …; `nil` until the server says |
| `server.session()` | Number naming the current world, `nil` outside one |
| `server.disconnect(reason)` | Leaves the server showing `reason` (string or [text](text.md)); `false` when not connected |

`server.session()` changes on every join, reconnect, server switch and dimension change. Keep
it next to cached results and drop them once it differs; the
[`world_change` and `disconnect` events](events.md#world-and-modules) tell you the moment it
happens, but only while the module is on.

```lua
local session, found = nil, {}

module:event("tick", function()
    if server.session() ~= session then
        session, found = server.session(), {}
    end
end)
```

## Tab list

| Function | Returns |
|----------|---------|
| `server.tablist.header()` | Custom header, or `nil` |
| `server.tablist.footer()` | Custom footer, or `nil` |
| `server.tablist.entries()` | Listed players in tab order |

An entry is `{name, uuid, display_name, ping, gamemode}`: account name, the rendered row with
team styling, latency in ms, and a gamemode like `"survival"`.

```lua
for i, entry in ipairs(server.tablist.entries()) do
    print(i, entry.display_name:string(), entry.ping .. "ms")
end
```

## Boss bars

`server.bossbars()` returns every visible bar in display order as
`{uuid, name, percent, color, style}`:

- `name` is a text component
- `percent` runs `0..1`
- `color` is `"pink"` · `"blue"` · `"red"` · `"green"` · `"yellow"` · `"purple"` · `"white"`
- `style` is `"progress"` · `"notched_6"` · `"notched_10"` · `"notched_12"` · `"notched_20"`

```lua
for _, bar in ipairs(server.bossbars() or {}) do
    print(bar.name:string(), math.floor(bar.percent * 100) .. "%")
end
```
