# esx-overextended/esx_multicharacter architecture

> Architecture diagram of the GitHub repository esx-overextended/esx_multicharacter, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-15). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/esx-overextended/esx_multicharacter
- Repository: https://github.com/esx-overextended/esx_multicharacter

## Overview

1. **What this repo is**
   - A single **FiveM resource** for **ESX Legacy** that implements a multicharacter login/selection flow.
   - It runs as an in-game resource, not as a standalone app: the main boundaries are **client Lua**, **server Lua**, and a **NUI frontend** (`html/`).

2. **Resource packaging**
   - `fxmanifest.lua` is the integration point that declares the resource’s Lua scripts, UI files, and shared assets.
   - `config.lua` centralizes feature settings such as the default slot count and likely behavior flags that affect both client and server logic.

3. **Server-side subsystem**
   - `server/main.lua` is the core authoritative layer for character state, player setup, and persistence coordination.
   - `server/commands.lua` adds administrative operations for character-slot management, so slot changes can be applied per player rather than only globally.

4. **Client-side subsystem**
   - `client/main.lua` handles the player-facing flow: opening the character selector, reacting to server events, and controlling the local UI/spawn transition.
   - In this kind of resource, the client is the presentation and input boundary; it does not own persistence decisions.

5. **NUI / browser UI boundary**
   - `html/ui.html`, `html/css/main.css`, and `html/js/app.js` implement the character selection interface rendered inside FiveM’s NUI browser.
   - The UI is separate from Lua runtime logic and communicates with the client via NUI messages/callbacks, making it the visual layer for selecting/creating/deleting characters.

6. **Data flow for login and character selection**
   - On player connect, the server determines how many slots a user has and loads their available characters.
   - That character list is sent to the client, then into the NUI frontend for display.
   - When the player selects or creates a character, the UI → client → server path is used to confirm the choice and continue the ESX spawn/load sequence.

7. **Persistence model**
   - The README states characters are stored in the `users` table using identifiers like `char#:license`.
   - `esx_multicharacter.sql` provides the database-side setup required by the resource, and character deletion is handled so it does not require manual cleanup of every dependent table entry.

8. **Administration and slot control**
   - The resource supports both global and per-player character counts.
   - Commands such as `setslots`, `remslots`, `enablechar`, and `disablechar` are the operational boundary for changing character availability without editing code.

9. **Localization**
   - There are two translation layers: Lua locales under `locales/` and frontend locales under `html/locales/`.
   - This means both the server/client messages and the browser UI text are localized independently, which matters for architecture because strings are not hardcoded in a single place.

10. **External dependencies and runtime context**
   - The repo is tightly coupled to the **FiveM runtime** and the **ESX framework**, with a database backing store for player records.
   - No separate backend service is present; the resource itself is the full application boundary, coordinating database access, game events, and UI.

11. **Project hygiene / tooling**
   - `.github/workflows/lint.yml` shows the repository includes CI linting, likely for Lua/JS/resource quality checks.
   - The rest of the repo is intentionally small and self-contained, which makes the architecture easy to diagram as one resource with three main execution surfaces: server, client, and NUI.

Main entry points: [`server/main.lua`](https://github.com/esx-overextended/esx_multicharacter/blob/main/server/main.lua) (Server core), [`fxmanifest.lua`](https://github.com/esx-overextended/esx_multicharacter/blob/main/fxmanifest.lua) (fxmanifest), [`client/main.lua`](https://github.com/esx-overextended/esx_multicharacter/blob/main/client/main.lua) (Client flow), [`html/js/app.js`](https://github.com/esx-overextended/esx_multicharacter/blob/main/html/js/app.js) (UI app)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_group_resource["Resource core"]
  node_fxmanifest["fxmanifest<br/>resource manifest<br/>[fxmanifest.lua]"]
  node_config["Config<br/>shared settings<br/>[config.lua]"]
end

subgraph group_group_server["Server runtime"]
  node_server_main["Server core<br/>authoritative logic<br/>[main.lua]"]
  node_server_commands["Admin cmds<br/>slot admin<br/>[commands.lua]"]
end

subgraph group_group_client["Client runtime"]
  node_client_main["Client flow<br/>player flow<br/>[main.lua]"]
end

subgraph group_group_ui["NUI frontend"]
  node_ui_html["UI shell<br/>nui markup<br/>[ui.html]"]
  node_ui_css["UI styles<br/>nui css<br/>[main.css]"]
  node_ui_js["UI app<br/>nui client<br/>[app.js]"]
  node_ui_locale["UI locales<br/>nui i18n<br/>[en.js]"]
end

subgraph group_group_localization["Localization"]
  node_server_locale["Server locales<br/>lua i18n<br/>[en.lua]"]
  node_client_locale["Client locales<br/>lua i18n<br/>[en.lua]"]
end

subgraph group_group_data["Database"]
  node_sql_schema[("SQL schema<br/>db setup")]
end

subgraph group_group_tooling["Tooling"]
  node_ci_lint["Lint CI<br/>workflow<br/>[lint.yml]"]
end

node_fxmanifest -->|"includes"| node_config
node_fxmanifest -->|"registers"| node_server_main
node_fxmanifest -->|"registers"| node_server_commands
node_fxmanifest -->|"registers"| node_client_main
node_fxmanifest -->|"serves"| node_ui_html
node_fxmanifest -->|"serves"| node_ui_css
node_fxmanifest -->|"serves"| node_ui_js
node_server_main -->|"reads"| node_config
node_server_main -->|"persists via"| node_sql_schema
node_server_main -->|"formats"| node_server_locale
node_server_commands -->|"controls"| node_server_main
node_client_main -->|"receives"| node_server_main
node_client_main -->|"opens"| node_ui_js
node_client_main -->|"formats"| node_client_locale
node_ui_js -->|"callback to"| node_client_main
node_ui_js -->|"renders"| node_ui_locale
node_ui_html -->|"styles with"| node_ui_css
node_ui_js -->|"requests"| node_server_main
node_sql_schema -->|"supports"| node_server_main
node_ci_lint -.->|"checks"| node_fxmanifest
node_ci_lint -.->|"checks"| node_server_main
node_ci_lint -.->|"checks"| node_client_main
node_ci_lint -.->|"checks"| node_ui_js

click node_fxmanifest "https://github.com/esx-overextended/esx_multicharacter/blob/main/fxmanifest.lua"
click node_config "https://github.com/esx-overextended/esx_multicharacter/blob/main/config.lua"
click node_server_main "https://github.com/esx-overextended/esx_multicharacter/blob/main/server/main.lua"
click node_server_commands "https://github.com/esx-overextended/esx_multicharacter/blob/main/server/commands.lua"
click node_server_locale "https://github.com/esx-overextended/esx_multicharacter/blob/main/locales/en.lua"
click node_client_main "https://github.com/esx-overextended/esx_multicharacter/blob/main/client/main.lua"
click node_client_locale "https://github.com/esx-overextended/esx_multicharacter/blob/main/locales/en.lua"
click node_ui_html "https://github.com/esx-overextended/esx_multicharacter/blob/main/html/ui.html"
click node_ui_css "https://github.com/esx-overextended/esx_multicharacter/blob/main/html/css/main.css"
click node_ui_js "https://github.com/esx-overextended/esx_multicharacter/blob/main/html/js/app.js"
click node_ui_locale "https://github.com/esx-overextended/esx_multicharacter/blob/main/html/locales/en.js"
click node_sql_schema "https://github.com/esx-overextended/esx_multicharacter/blob/main/esx_multicharacter.sql"
click node_ci_lint "https://github.com/esx-overextended/esx_multicharacter/blob/main/.github/workflows/lint.yml"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_fxmanifest,node_config,node_ci_lint toneBlue
class node_server_main,node_server_commands toneAmber
class node_client_main toneMint
class node_ui_html,node_ui_css,node_ui_js,node_ui_locale toneRose
class node_server_locale,node_client_locale toneIndigo
class node_sql_schema toneTeal
```

## Components

### Resource core

FiveM resource packaging and shared configuration

- [fxmanifest](https://github.com/esx-overextended/esx_multicharacter/blob/main/fxmanifest.lua): resource manifest · Declares scripts, UI assets, and shared resource metadata · `fxmanifest.lua`
- [Config](https://github.com/esx-overextended/esx_multicharacter/blob/main/config.lua): shared settings · Central feature flags and default slot configuration · `config.lua`

### Server runtime

Authoritative character state, persistence, and admin control

- [Server core](https://github.com/esx-overextended/esx_multicharacter/blob/main/server/main.lua): authoritative logic · Loads characters, tracks slots, and coordinates persistence · `server/main.lua`
- [Admin cmds](https://github.com/esx-overextended/esx_multicharacter/blob/main/server/commands.lua): slot admin · Per-player character slot commands and operational controls · `server/commands.lua`

### Client runtime

Player flow and spawn transition handling

- [Client flow](https://github.com/esx-overextended/esx_multicharacter/blob/main/client/main.lua): player flow · Opens selector, handles events, and drives local spawn progression · `client/main.lua`

### NUI frontend

Browser-rendered character selector UI

- [UI shell](https://github.com/esx-overextended/esx_multicharacter/blob/main/html/ui.html): nui markup · Selector layout rendered in the FiveM browser UI · `html/ui.html`
- [UI styles](https://github.com/esx-overextended/esx_multicharacter/blob/main/html/css/main.css): nui css · Presentation and layout styling for the selector · `html/css/main.css`
- [UI app](https://github.com/esx-overextended/esx_multicharacter/blob/main/html/js/app.js): nui client · Handles selection actions and message exchange with Lua · `html/js/app.js`
- [UI locales](https://github.com/esx-overextended/esx_multicharacter/blob/main/html/locales/en.js): nui i18n · Browser-side translations for the selector interface · `html/locales/en.js`

### Localization

Lua and frontend translation layers

- [Server locales](https://github.com/esx-overextended/esx_multicharacter/blob/main/locales/en.lua): lua i18n · Localized strings used by client/server Lua runtime · `locales/en.lua`
- [Client locales](https://github.com/esx-overextended/esx_multicharacter/blob/main/locales/en.lua): lua i18n · Localized runtime strings shared across Lua-side messages · `locales/en.lua`

### Database

Character storage schema and SQL setup

- [SQL schema](https://github.com/esx-overextended/esx_multicharacter/blob/main/esx_multicharacter.sql): db setup · Database setup for character records and related tables · `esx_multicharacter.sql`

### Tooling

Repository linting and CI

- [Lint CI](https://github.com/esx-overextended/esx_multicharacter/blob/main/.github/workflows/lint.yml): workflow · Repository linting and quality checks · `.github/workflows/lint.yml`

## Connections

- fxmanifest → Config: includes · Resource manifest loads shared configuration
- fxmanifest → Server core: registers · Manifest exposes the core server runtime
- fxmanifest → Admin cmds: registers · Manifest exposes admin command logic
- fxmanifest → Client flow: registers · Manifest exposes the client runtime
- fxmanifest → UI shell: serves · Manifest bundles the NUI entrypoint
- fxmanifest → UI styles: serves · Manifest bundles the UI stylesheet
- fxmanifest → UI app: serves · Manifest bundles the UI application script
- Server core → Config: reads · Server logic uses shared slot and behavior settings
- Server core → SQL schema: persists via · Server coordinates character records in the database
- Server core → Server locales: formats · Server-side messages use localized strings
- Admin cmds → Server core: controls · Admin commands adjust server-side slot state
- Client flow → Server core: receives · Client consumes server events and character data
- Client flow → UI app: opens · Client shows and hides the browser UI
- Client flow → Client locales: formats · Client-side messages use localized strings
- UI app → Client flow: callback to · NUI actions are sent back to the client runtime
- UI app → UI locales: renders · UI text is translated in the browser layer
- UI shell → UI styles: styles with · HTML uses the bundled stylesheet
- UI app → Server core: requests · Selection and creation flow ultimately reaches the server
- SQL schema → Server core: supports · Schema underpins the resource persistence model
- Lint CI → fxmanifest: checks · CI validates resource packaging and code quality
- Lint CI → Server core: checks · CI covers server-side Lua quality
- Lint CI → Client flow: checks · CI covers client-side Lua quality
- Lint CI → UI app: checks · CI covers frontend JavaScript quality
