How esx-overextended/esx_multicharacter works
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 Server core · fxmanifest.lua fxmanifest · client/main.lua Client flow · app.js UI app
Components 13
Resource core
FiveM resource packaging and shared configuration
- fxmanifest · Declares scripts, UI assets, and shared resource metadata
fxmanifest.lua - Config · Central feature flags and default slot configuration
config.lua
Server runtime
Authoritative character state, persistence, and admin control
- Server core · Loads characters, tracks slots, and coordinates persistence
server/main.lua - Admin cmds · Per-player character slot commands and operational controls
server/commands.lua
Client runtime
Player flow and spawn transition handling
- Client flow · Opens selector, handles events, and drives local spawn progression
client/main.lua
NUI frontend
Browser-rendered character selector UI
- UI shell · Selector layout rendered in the FiveM browser UI
html/ui.html - UI styles · Presentation and layout styling for the selector
html/css/main.css - UI app · Handles selection actions and message exchange with Lua
html/js/app.js - UI locales · Browser-side translations for the selector interface
html/locales/en.js
Localization
Lua and frontend translation layers
- Server locales · Localized strings used by client/server Lua runtime
locales/en.lua - Client locales · Localized runtime strings shared across Lua-side messages
locales/en.lua
Database
Character storage schema and SQL setup
- SQL schema · Database setup for character records and related tables
esx_multicharacter.sql
Tooling
Repository linting and CI
- Lint CI · Repository linting and quality checks
.github/workflows/lint.yml
Connections 23
- 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