> For the complete documentation index, see [llms.txt](https://docs.allout.game/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.allout.game/core-engine-concepts/social-features.md).

# Social Features

### Reading Chat

Use `core_globals.server_on_chat_message_received` when game code needs to react to normal chat messages on the server:

```go
ao_before_scene_load :: proc() {
    core_globals.server_on_chat_message_received = on_chat_message;
}

on_chat_message :: proc(player: Player, message: string) {
    log_info("% said %", {player.get_username(), message});
}
```

### Chat API reference

```go
Chat :: struct {
    Mode :: enum {
        DEFAULT;
        BUBBLE_ONLY;
    }

    set_mode :: proc(mode: Mode);
    server_send_message :: proc(message: string, player: Player = null);
    is_open :: proc() -> bool;
}
```

`Chat.server_send_message` is for server-side code such as chat command handlers. Pass `player` to target one player, or leave it `null` to send broadly. Use `Chat.set_mode(.BUBBLE_ONLY)` on the local client for games that want bubble chat without the standard chat panel.

### Chat Commands

Chat commands are mostly a **developer/admin tool** for testing and live-ops:

* Start rounds early / skip waves
* Grant test item sets or currency
* Trigger game events for debugging

To create a command, write a `proc` and annotate it with `@chat_command`.

Players can type commands into chat with a leading `/`:

* `/start_round`
* `/grant_test_loadout`
* `/trigger_event meteor_shower`

{% hint style="info" %}
Chat commands run on the server. Use `Notifier.notify(player, "...")` to send feedback back to a single player.
{% endhint %}

{% hint style="warning" %}
Not all players will have text chat enabled (parental controls and moderation mutes can disable the text box), so you shouldn't rely on chat commands for critical gameplay systems.
{% endhint %}

#### Common dev/admin commands

```go
// Start a round early (admin-only)
start_round :: proc(player: Player) {
    g_round_manager.start_round();
    Notifier.notify(player, "Round started.");
} @chat_command

// Give yourself a test loadout (admin-only)
grant_test_loadout :: proc(player: Player) {
    // Example: use your own item-granting logic here
    // item := Items.create_item_instance(sword_defn);
    // Items.move_item_to_inventory(item, player.default_inventory);
    Notifier.notify(player, "Granted test loadout.");
} @chat_command

// Trigger an event by name (admin-only, with an optional argument)
trigger_event :: proc(player: Player, event_name: string = "meteor_shower") {
    g_event_system.trigger(event_name);
    Notifier.notify(player, "Triggered event: %", {event_name});
} @chat_command
```

#### Permissions

Use permission annotations to control who can run a command:

| Annotation         | Who can use                     |
| ------------------ | ------------------------------- |
| `@any`             | All players                     |
| `@vip`             | VIP players and admins          |
| `@youtuber`        | Youtuber players and admins     |
| `@owner`           | Game owner and admins           |
| `@owner_or_editor` | Game owner, editors, and admins |
| (none)             | Admins only                     |

```go
// VIPs and admins can use this
skip_wave :: proc(player: Player) {
    g_wave_manager.skip_to_next_wave();
    Notifier.notify(player, "Skipped wave.");
} @chat_command @vip
```

{% hint style="info" %}
When launching from the editor, chat commands are allowed for faster iteration/testing.
{% endhint %}

#### Arguments & optional parameters

The first parameter must always be `Player`. After that you can add arguments (and give them default values to make them optional).

By default, commands are **admin-only**.

```go
// Admin only (default)
give_currency :: proc(player: Player, amount: s64 = 100) {
    Economy.deposit_currency(player, "Coins", amount);
    Notifier.notify(player, "Gave you % coins.", {amount});
} @chat_command
```

Admins can call:

* `/give_currency` → gives 100 coins
* `/give_currency 500` → gives 500 coins

#### Strings with spaces

Wrap strings in quotes if they contain spaces:

```go
say :: proc(player: Player, message: string) {
    // Your own broadcast function/game message here
    log_info("% says: %", {player.get_username(), message});
} @chat_command @any
```

Example:

```
/say "Hello everyone!"
```

#### Getting command usage

Players can append `?` to a command to see parameter info:

```
/spawn_enemy?
```

### Enabling Voice Chat

TODO

### Moderation

All Out automatically monitors text and voice chat for behavior that violates our [community guidelines](https://help.allout.game/hc/en-us/articles/27854798873243-Code-Of-Conduct) and will disable social features for first offenses or apply suspensions for repeat offenders.

If you see repeat bad behavior or behavior that makes it past our automated detection, please report the player to us using the in-game report system or from their profile.

If a player has been suspended accidentally, please direct them to [contact us](https://help.allout.game/) to reverse the action.


---

# 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 dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.allout.game/core-engine-concepts/social-features.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
