> 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

All out provides text and optional voice chat for you to use in your games

### 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`.

The procedure name is the command name: `start_round` is invoked as `/start_round`. Invocation ignores surrounding whitespace and prefers an exact-case name, then falls back to a case-insensitive match.

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**.

Supported argument types are `string`, integer types, floating-point types, `bool`, and `Player`.

A `Player` argument uses the complete space-delimited or quoted token and matches the player's display name exactly. Names containing digits or underscores work directly; quote names containing spaces.

```go
// Admin only (default)
give_currency :: proc(player: Player, amount: s64 = 100) {
    if amount < 0 {
        Notifier.notify(player, "Amount must be zero or greater.");
        return;
    }

    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

Players control voice chat through their account and device settings. Games cannot force it on or bypass microphone permission, parental controls, or moderation restrictions.

Voice is positional. The default audible range is 10 world units:

```go
Voice :: struct {
    set_range :: proc(range: float);
    get_range :: proc() -> float;
}
```

Set a positive range during scene startup:

```go
ao_start :: proc() {
    Voice.set_range(14);
}
```

`Voice.set_range` changes the scene-wide range. Non-positive values are ignored.

### Communication channels

Each player has speaking and listening masks that apply to both voice and text chat. Two players can communicate when the sender's speaking mask overlaps the receiver's listening mask.

```go
TEAM_RED  :: 1.(u64) << 0;
TEAM_BLUE :: 1.(u64) << 1;

put_on_red_team :: proc(player: Player) {
    player.comms_channel_speak_mask = TEAM_RED;
    player.comms_channel_listen_mask = TEAM_RED;
}
```

Players listen and speak on all channels by default.

### 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.
