> For the complete documentation index, see [llms.txt](https://docs.cuxial.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.cuxial.com/scripts/leisure/cuxial-danceclass/developers.md).

# Exports & events

Public API of Cuxial Dance Class: server exports and events to read classes and react to them.

Read the open classes, close one, or react when a class starts, a student joins or a dance ends. Everything here runs on the server; there are no client exports.

## Server exports

### GetRooms

Returns every open class.

```lua
local rooms = exports.cuxial_danceclass:GetRooms()
```

**Returns:** `table[]`, sorted by `id`. Each entry is a [room summary](#room-summary).

```lua
for _, room in ipairs(exports.cuxial_danceclass:GetRooms()) do
    print(room.name, room.studentCount .. '/' .. room.maxStudents)
end
```

### GetPlayerRoom

Returns the class a player is in and their role.

```lua
local room, role = exports.cuxial_danceclass:GetPlayerRoom(source)
```

| Parameter | Type   | Description              |
| --------- | ------ | ------------------------ |
| `source`  | number | Server id of the player. |

**Returns:** `table | nil`, `string | nil`. The [room summary](#room-summary) and the role, `'instructor'` or `'student'`. `nil` when the player is not in a class.

```lua
local room, role = exports.cuxial_danceclass:GetPlayerRoom(source)
if role == 'instructor' then
    print(('Teaching %s'):format(room.name))
end
```

### IsInClass

Tells whether a player is in a class, as instructor or student.

```lua
local inClass = exports.cuxial_danceclass:IsInClass(source)
```

| Parameter | Type   | Description              |
| --------- | ------ | ------------------------ |
| `source`  | number | Server id of the player. |

**Returns:** `boolean`.

```lua
if exports.cuxial_danceclass:IsInClass(source) then return end
```

### CloseRoom

Closes a class from another resource. If at least one dance was played, the class ends with its podium and the history is saved; otherwise it just closes and fees are refunded as set in `rooms.refundIfNoRound`.

```lua
local closed = exports.cuxial_danceclass:CloseRoom(id)
```

| Parameter | Type   | Description      |
| --------- | ------ | ---------------- |
| `id`      | number | Id of the class. |

**Returns:** `boolean`. `false` when no class has that id.

```lua
for _, room in ipairs(exports.cuxial_danceclass:GetRooms()) do
    exports.cuxial_danceclass:CloseRoom(room.id)
end
```

### Room summary

| Field             | Type             | Description                                                                                          |
| ----------------- | ---------------- | ---------------------------------------------------------------------------------------------------- |
| `id`              | number           | Id of the class.                                                                                     |
| `name`            | string           | Name of the class.                                                                                   |
| `difficulty`      | string           | Difficulty id: `easy`, `normal` or `hard`.                                                           |
| `difficultyLabel` | string           | Difficulty name from the config.                                                                     |
| `fee`             | number           | Entry fee. `0` = free.                                                                               |
| `maxStudents`     | number           | Capacity.                                                                                            |
| `instructor`      | table            | `{ id, name, points }`.                                                                              |
| `students`        | table\[]         | `{ id, name, points, rounds, accuracy, bestAccuracy }`, sorted by points. Accuracy goes from 0 to 1. |
| `studentCount`    | number           | Students in the class.                                                                               |
| `phase`           | string           | `lobby` (not started), `countdown`, `round` or `results` (between dances).                           |
| `roundIndex`      | number           | Dances played so far.                                                                                |
| `maxRounds`       | number           | Dances allowed per class.                                                                            |
| `playlist`        | string\[] \| nil | Dances picked by the instructor. `nil` = random.                                                     |
| `currentDance`    | table \| nil     | `{ command, label }` of the current or last dance.                                                   |
| `role`            | string \| nil    | Only with `GetPlayerRoom`: role of that player.                                                      |

## Server events

Each event is triggered on the server with one table. Listen with `AddEventHandler`.

| Event                             | Payload                          | When                                                                                            |
| --------------------------------- | -------------------------------- | ----------------------------------------------------------------------------------------------- |
| `cuxial_danceclass:roomCreated`   | `{ id, instructor, difficulty }` | A class opens. `instructor` is a server id.                                                     |
| `cuxial_danceclass:roomClosed`    | `{ id, reason }`                 | A class closes. `reason`: `closed`, `left`, `ended` or `disconnected`.                          |
| `cuxial_danceclass:studentJoined` | `{ id, source }`                 | A student joins.                                                                                |
| `cuxial_danceclass:studentLeft`   | `{ id, source, reason }`         | A student leaves a class that stays open. `reason`: `left`, `zone`, `kicked` or `disconnected`. |
| `cuxial_danceclass:roundStarted`  | `{ id, index, dance }`           | A dance starts. `dance` is its command.                                                         |
| `cuxial_danceclass:roundEnded`    | `{ id, index, results }`         | A dance ends.                                                                                   |
| `cuxial_danceclass:classEnded`    | `{ id, rounds, ranking }`        | A class with at least one dance ends, right before `roomClosed`.                                |

Each entry of `results` has `id`, `name`, `perfect`, `good`, `miss`, `total`, `accuracy`, `maxStreak`, `points` and `totalPoints`. Each entry of `ranking` has `id`, `name`, `points`, `rounds`, `accuracy` and `bestAccuracy`.

{% hint style="info" %}
`studentLeft` is not sent for the students still inside when a class closes. Use `roomClosed` for that case.
{% endhint %}

```lua
AddEventHandler('cuxial_danceclass:roundEnded', function(data)
    for _, result in ipairs(data.results) do
        if result.accuracy >= 0.9 then
            print(('%s nailed dance %d'):format(result.name, data.index))
        end
    end
end)
```

### on / off

The same events as hooks, without the prefix. `on` returns a handle and `off` removes the hook.

```lua
local handle = exports.cuxial_danceclass:on(event, fn)
local removed = exports.cuxial_danceclass:off(handle)
```

| Parameter | Type     | Description                                                                                                |
| --------- | -------- | ---------------------------------------------------------------------------------------------------------- |
| `event`   | string   | `roomCreated`, `roomClosed`, `studentJoined`, `studentLeft`, `roundStarted`, `roundEnded` or `classEnded`. |
| `fn`      | function | Receives the same table as the event.                                                                      |
| `handle`  | number   | Value returned by `on`.                                                                                    |

**Returns:** `on` returns `number`, or `nil` when the arguments are not valid. `off` returns `boolean`.

```lua
local handle = exports.cuxial_danceclass:on('classEnded', function(data)
    local winner = data.ranking[1]
    if winner then print(('%s won the class'):format(winner.name)) end
end)
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.cuxial.com/scripts/leisure/cuxial-danceclass/developers.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
