> For the complete documentation index, see [llms.txt](https://docs.lostdev.store/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.lostdev.store/territories/client-modules.md).

# client modules

Load order (`fxmanifest.lua` → `client_scripts`):

```
client/bridge.lua
client/zones.lua
client/blips.lua
client/main.lua
```

## `bridge.lua` — `ClientBridge`

Client-side counterpart of `ServerBridge` — fetches the local player's data for UI purposes (the actual faction authority is always the server).

* `ClientBridge.Initialize()` / `GetPlayerData()` — detects/queries the local framework (QBCore, QBX, ESX, or standalone).
* `ClientBridge.Notify(message, type)` — local notification, uses `ox_lib` (`lib.notify`) if `Config.Notifications.system == 'ox'`, otherwise falls back to the framework's native notification or the chat.

{% hint style="info" %}
Unlike `server/bridge.lua` (already fixed), this file still uses `exports['qbcore']` (no hyphen) for QBCore. If you use QBCore on the client and notice the bridge fails to initialize, double-check the exact name of the installed resource.
{% endhint %}

## `zones.lua` — `ZoneSystem`

Creates proximity-detection zones using `ox_lib` (`exports.ox_lib:AddZone`).

* `ZoneSystem.CreateZone(territoryId, territory)` — registers a circular zone with callbacks `onEnter` → `territories:entered`, `onExit` → `territories:exited`, `inside` → `territories:inside` (**local** events, handled in `client/main.lua`).
* `ZoneSystem.InitializeZones(territories)` — creates zones for the whole territory map.
* `ZoneSystem.DebugDraw()` — draws a 3D marker + text over each zone when `Config.Debug` and `Config.Zones.drawDebug` are both enabled.
* `ZoneSystem.IsPlayerInZone(territoryId)` — local distance check.

## `blips.lua` — `BlipManager`

Full blip management on the map (extensively documented in the source itself).

* **Sprite**: `neutral` / `contested` / `cooldown`, controlled by `Config.Blips.stateSprites`.
* **Color**: state (contested/cooldown) takes priority; otherwise it uses the owning gang's color (`Config.Blips.gangColors`, falling back to a deterministic hash into a curated palette of 10 native game colors — `GANG_COLOR_PALETTE`).
* **Visual radius**: `BlipManager.CreateRadius` draws a semi-transparent circle matching the real capture radius; its color can follow the owning gang (`Config.Blips.gangColoredRadius`) or use a fixed "owned" color.
* **Blacklist**: `BlipManager.SetMyGroup(group)` — called when the server informs the local player's faction (`territories:receiveMyGroup`); if it's on the blacklist (`Config.Blips.blacklist`), all territory blips are removed for that player.
* **Contested color cycle**: a background thread (`CreateThread`) cycles the blip icon's color through each faction involved in a contested territory, every `Config.Blips.contestedColorCycle.interval` ms.
* `BlipManager.FlashAlert(territoryId, duration)` — makes the blip flash (used on `territories:underAttack`).

## `main.lua` — Main Loop and NUI

The client's "brain".

### Initialization

`ClientInitialize()` is called at the end of the file, when the script starts.

{% stepper %}
{% step %}

## Request territory state

Requests the state of every territory with `territories:requestTerritoryData`.
{% endstep %}

{% step %}

## Request the local faction

Requests its own faction from the server with `territories:requestMyGroup`, only needed for blip blacklisting.
{% endstep %}

{% step %}

## Register callbacks and events

Registers NUI callbacks and network events.
{% endstep %}

{% step %}

## Start monitoring

Starts the monitoring loop with `ClientStartMonitoring`.
{% endstep %}
{% endstepper %}

### Proximity Loop (`ClientCheckTerritoriesProximity`)

Every `Config.Performance.checkInterval` ms, computes which territory, if any, the player is in and fires `territories:playerEntered` / `playerExited` on the server when it changes. It also updates the HUD via `ClientSendNUIMessage`.

### Territory HUD (Passive NUI)

`ClientUpdateNUI` polls the server with `territories:getTerritoryInfo` every `Config.UI.updateInterval` ms while the player is inside a zone. The result, `territories:updateTerritoryInfo`, updates the React `TerritoryCard`.

This HUD never takes input focus — the player keeps controlling their character normally.

### Tactical Tablet

* `ClientOpenTablet()` / `ClientCloseTablet()` / `ClientToggleTablet()` — controlled by the `Config.UI.tabletCommand` / `tabletKeybind` command/keybind, defaulting to `/territories` and **F6**.
* On open, the client calls `SetNuiFocus(true, true)`, sends the current data immediately to avoid a blank flash, requests a fresh snapshot, and requests "extras" (stats/activity).
* `BuildTabletTerritories` / `BuildTabletFactions` — transform the server's raw territory map into the shape the React tablet consumes: a territory list and aggregated faction leaderboard.

### NUI Callbacks → Server

Every `RegisterNuiCallback` simply forwards to a matching `TriggerServerEvent` — business logic always lives on the server.

See the full table in [Events & Exports](broken://pages/45047c47c6f21c126c33711bdc4c80b000b95d77#nui-callbacks-client).

### Alerts and Sounds

* `territories:underAttack` (server → client) — plays a sound, flashes the blip, and shows the banner via the NUI.
* `territories:captureResult` (server → client) — plays the win/lose sound for whoever won/lost, even far from the territory.

### Debug

`ClientDebugDraw()` draws spheres and 3D text with owner/progress over each territory when `Config.Zones.drawDebug` is enabled.

This is independent of the `Config.Debug` used by `ZoneSystem.DebugDraw`, which is a redundant variant of the same concept.


---

# 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.lostdev.store/territories/client-modules.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.
