> For the complete documentation index, see [llms.txt](https://code-after-sex.gitbook.io/script-documentation/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://code-after-sex.gitbook.io/script-documentation/cas-advanced-gang/developers/events-and-nui.md).

# Events and NUI

How CAS Advanced Gang System splits work between server, client and interface: NUI requests, Lua messages and NUI focus.

## Who decides what

| Side                   | Owns                                                                                                    |
| ---------------------- | ------------------------------------------------------------------------------------------------------- |
| **Server** (`server/`) | Every rule: permissions, limits, prices, distances, money and items. The only place a rule is enforced. |
| **Client** (`client/`) | Prompts, the blip, prop streaming, the placing tool, the bell's toll, and passing requests on.          |
| **Interface** (`web/`) | Drawing what it's given and sending requests. It keeps no rule of its own.                              |

Every button takes the same path:

1. The interface posts a request to the client.
2. The client sends it to the server with `TriggerServerEvent`.
3. The server checks it, makes the change and saves it.
4. The server sends `bearclaw:client:state` to every member.
5. Each client passes the new state to its interface.

{% hint style="info" %}
The `bearclaw:server:*` events are internal. They're how the client talks to the server, and each one checks the sender itself. Don't trigger them from other resources. Use the [exports](/script-documentation/cas-advanced-gang/developers/exports.md).
{% endhint %}

## Interface to Lua

The interface posts to two callbacks. Request names contain a colon, and a callback name is part of a URL, so every request goes through `request`.

| Callback  | Body             |
| --------- | ---------------- |
| `close`   | `{}`             |
| `request` | `{ name, data }` |

| `name`                | `data`                                                                                                                      |
| --------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `gang:found`          | `{ name, tag, motto }`                                                                                                      |
| `gang:foundCancel`    | `{}`                                                                                                                        |
| `member:invite`       | `{ name }`, a character name or server id                                                                                   |
| `member:kick`         | `{ memberId }`                                                                                                              |
| `member:setRank`      | `{ memberId, rankId }`                                                                                                      |
| `member:handOver`     | `{ memberId }`                                                                                                              |
| `member:leave`        | `{}`                                                                                                                        |
| `gang:disband`        | `{}`                                                                                                                        |
| `invite:revoke`       | `{ inviteId }`                                                                                                              |
| `invite:respond`      | `{ inviteId, accept }`                                                                                                      |
| `rank:setPermission`  | `{ rankId, key, value }`                                                                                                    |
| `rank:setLimits`      | `{ rankId, stashDaily, treasuryCeiling }`                                                                                   |
| `stash:satchel`       | `{}`, asks for what the player carries                                                                                      |
| `stash:deposit`       | `{ itemId, qty }`                                                                                                           |
| `stash:withdraw`      | `{ itemId, qty }`                                                                                                           |
| `treasury:contribute` | `{ amount, note }`                                                                                                          |
| `treasury:withdraw`   | `{ amount, note }`                                                                                                          |
| `treasury:approve`    | `{ requestId, accept }`                                                                                                     |
| `camp:upgrade`        | `{ tier }`                                                                                                                  |
| `camp:placement`      | `{ action, structureId }` with `enter`, `select` or `exit`, or `{ action = 'move', rowId }` to pick up a standing structure |
| `structure:remove`    | `{ rowId }`                                                                                                                 |

## Lua to interface

| `action`    | Carries                                                                                                                      |
| ----------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `open`      | `screen` (`camp`, `found` or `invite`), its data, and `strings`, the locale table                                            |
| `state`     | A new gang state while the ledger is open                                                                                    |
| `founding`  | The creator's data                                                                                                           |
| `satchel`   | What the player carries that the stash keeps                                                                                 |
| `invited`   | A waiting invitation, or `nil` to clear it                                                                                   |
| `toast`     | A notice: `{ tone, title, body }`                                                                                            |
| `placement` | The placing tool's live reading, with `mode` `enter`, `update` or `exit`, and `moving` while a standing structure is carried |
| `close`     | Hide the interface                                                                                                           |

The full shapes are written at the top of `web/src/lib/nui.js`. `web/src/data/mock.js` has exactly that shape, and it's what the interface shows in a browser with no server.

## Focus

The interface is hidden when the resource starts. It only takes the mouse while a panel is open, and closing always gives it back. Notices are drawn over the game without taking focus.
