> For the complete documentation index, see [llms.txt](https://documentation.rcore.cz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://documentation.rcore.cz/paid-resources/rcore_formula/api/client.md).

# Client

## Zone/Track Exports

### getPolyFromZone

Converts a zone point array into a sorted polygon.

```lua
local poly = exports['rcore_formula']:getPolyFromZone(zone)
```

| Parameter | Type  | Description                              |
| --------- | ----- | ---------------------------------------- |
| `zone`    | table | Array of points with x, y, z coordinates |

**zone structure:**

```lua
{
    {x = 0.0, y = 0.0, z = 0.0},
    {x = 10.0, y = 0.0, z = 0.0},
    {x = 10.0, y = 10.0, z = 0.0},
    ...
}
```

**Returns:** `table` - Array of vector3 points sorted counter-clockwise (polygon vertices).

***

### isPointInPoly

Checks if a point is inside a polygon.

```lua
local isInside = exports['rcore_formula']:isPointInPoly(point, poly)
```

| Parameter | Type          | Description                         |
| --------- | ------------- | ----------------------------------- |
| `point`   | table/vector3 | Point with x, y coordinates         |
| `poly`    | table         | Array of polygon vertices (vector3) |

**Returns:** `boolean` - `true` if point is inside polygon, `false` otherwise.

**Example:**

```lua
local point = vector3(100.0, 200.0, 30.0)
local trackBoundary = exports['rcore_formula']:getPolyFromZone(zoneData)
local onTrack = exports['rcore_formula']:isPointInPoly(point, trackBoundary)
```

***

### createWallPoly

Creates a rectangular wall polygon between two points.

```lua
local wallPoly = exports['rcore_formula']:createWallPoly(pointA, pointB, width)
```

| Parameter | Type          | Description       |
| --------- | ------------- | ----------------- |
| `pointA`  | table/vector3 | First point       |
| `pointB`  | table/vector3 | Second point      |
| `width`   | number        | Width of the wall |

**Returns:** `table` - Array of 4 vector3 points forming a rectangle perpendicular to line AB.

***

### getVehicleCorners

Gets the world coordinates of a vehicle's four corners.

```lua
local corners = exports['rcore_formula']:getVehicleCorners(vehicle)
```

| Parameter | Type   | Description           |
| --------- | ------ | --------------------- |
| `vehicle` | number | Vehicle entity handle |

**Returns:** `table` - Array of 4 vector3 corner points in world coordinates.

**Example:**

```lua
local myVehicle = GetVehiclePedIsIn(PlayerPedId(), false)
local corners = exports['rcore_formula']:getVehicleCorners(myVehicle)
-- corners[1] = front left
-- corners[2] = front right
-- corners[3] = rear right
-- corners[4] = rear left
```

***

### isVehicleInVirtualWall

Checks if any corner of a vehicle intersects with a wall polygon.

```lua
local inWall = exports['rcore_formula']:isVehicleInVirtualWall(vehicle, wall)
```

| Parameter | Type   | Description                              |
| --------- | ------ | ---------------------------------------- |
| `vehicle` | number | Vehicle entity handle                    |
| `wall`    | table  | Wall polygon (array of 4 vector3 points) |

**Returns:** `boolean` - `true` if any vehicle corner is inside the wall, `false` otherwise.

***

### isPointInCircuit

Checks if a point is within the circuit boundaries (between inner and outer polygons).

```lua
local inCircuit = exports['rcore_formula']:isPointInCircuit(point, inner, outer)
```

| Parameter | Type          | Description                    |
| --------- | ------------- | ------------------------------ |
| `point`   | table/vector3 | Point to check                 |
| `inner`   | table         | Inner circuit boundary polygon |
| `outer`   | table         | Outer circuit boundary polygon |

**Returns:** `boolean` - `true` if point is inside outer but outside inner polygon, `false` otherwise.

**Example:**

```lua
local playerPos = GetEntityCoords(PlayerPedId())
local inCircuit = exports['rcore_formula']:isPointInCircuit(playerPos, innerBoundary, outerBoundary)
if not inCircuit then
    print("Player went off-track!")
end
```

***

## Team Exports

### getPlayerTeams

Gets all teams the local player belongs to.

```lua
local teams = exports['rcore_formula']:getPlayerTeams()
```

**Returns:** `table` - Dictionary of teams `{teamId = role, ...}`

**Example:**

```lua
local myTeams = exports['rcore_formula']:getPlayerTeams()
for teamId, role in pairs(myTeams) do
    print("Team: " .. teamId .. " Role: " .. role)
end
```

***

### getPlayerTeamsWithPermission

Gets teams where the local player has a specific permission.

```lua
local teams = exports['rcore_formula']:getPlayerTeamsWithPermission(permission)
```

| Parameter    | Type       | Description                                   |
| ------------ | ---------- | --------------------------------------------- |
| `permission` | string/nil | Permission to filter by, or nil for all teams |

**Permission Types:**

* `MANAGE_TEAM` - Can edit team settings
* `MANAGE_MEMBERS` - Can kick/change roles
* `MANAGE_MONEY` - Can handle transactions
* `RACE` - Can participate in races

**Returns:** `table` - Dictionary of teams with matching permission `{teamId = role, ...}`

**Example:**

```lua
-- Get teams where player can manage members
local managerTeams = exports['rcore_formula']:getPlayerTeamsWithPermission("MANAGE_MEMBERS")
```

***

## Tyre Exports

### setTyreCompound

Sets the tire compound for the current vehicle.

```lua
exports['rcore_formula']:setTyreCompound(tyres)
```

| Parameter | Type   | Description        |
| --------- | ------ | ------------------ |
| `tyres`   | string | Tire compound type |

**Tire Compound Types:** (depending on config)

* `soft` - High grip, fast wear
* `medium` - Balanced performance
* `hard` - Low grip, slow wear
* `wet` - Rain conditions

**Example:**

```lua
-- Switch to soft tires for qualifying
exports['rcore_formula']:setTyreCompound("soft")
```

***

### getTyreCompound

Gets the currently equipped tire compound.

```lua
local compound = exports['rcore_formula']:getTyreCompound()
```

**Returns:** `string` - Current tire compound type.

***

## Race Time Exports

### getBestLapTime

Gets the best lap time in the current race.

```lua
local bestLap = exports['rcore_formula']:getBestLapTime()
```

**Returns:** `number` - Best lap time in milliseconds, or 0 if no laps completed.

**Example:**

```lua
local bestLap = exports['rcore_formula']:getBestLapTime()
local seconds = bestLap / 1000
print("Best lap: " .. string.format("%.3f", seconds) .. " seconds")
```

***

### getCurrentLapTime

Gets the elapsed time for the current lap.

```lua
local lapTime = exports['rcore_formula']:getCurrentLapTime()
```

**Returns:** `number` - Current lap time in milliseconds.

***

### getTimeFromLastOutOfCircuit

Gets the time since the player last went off-track.

```lua
local timeSinceOffTrack = exports['rcore_formula']:getTimeFromLastOutOfCircuit()
```

**Returns:** `number` or `nil` - Milliseconds since last off-track incident, or nil if never went off-track.

***

## Race State Exports

### getPlayerCurrentRace

Gets the track ID of the race the player is currently in.

```lua
local trackId = exports['rcore_formula']:getPlayerCurrentRace()
```

**Returns:** `number` or `nil` - Track ID if in a race, nil otherwise.

**Example:**

```lua
local trackId = exports['rcore_formula']:getPlayerCurrentRace()
if trackId then
    print("Currently racing on track: " .. trackId)
else
    print("Not in a race")
end
```

***

### getCurrentLap

Gets the current lap number.

```lua
local lap = exports['rcore_formula']:getCurrentLap()
```

**Returns:** `number` - Current lap number, or 0 if not racing.

***

### disqualifyRace

Disqualifies the player from the current race.

```lua
exports['rcore_formula']:disqualifyRace()
```

Sets the player's race status to disqualified and prepares to leave the race.

***

### retireRace

Retires the player from the current race.

```lua
exports['rcore_formula']:retireRace()
```

Voluntarily removes the player from the race (counts as DNF - Did Not Finish).

***

## HUD Exports

### showHud

Shows the racing HUD overlay.

```lua
exports['rcore_formula']:showHud()
```

Displays the HUD with vehicle telemetry (speed, RPM, gear, etc.) and starts the sync thread.

***

### hideHud

Hides the racing HUD overlay.

```lua
exports['rcore_formula']:hideHud()
```

Removes the HUD from view and stops the telemetry sync.

***

### isHudVisible

Checks if the HUD is currently visible.

```lua
local visible = exports['rcore_formula']:isHudVisible()
```

**Returns:** `boolean` - `true` if HUD is visible, `false` otherwise.

***

## Spectator/Watching Exports

### getWatchingTrack

Gets the track ID the player is currently spectating.

```lua
local trackId = exports['rcore_formula']:getWatchingTrack()
```

**Returns:** `number` or `nil` - Track ID being spectated, or nil if not spectating.

***

### getWatchingDriver

Gets the driver being spectated.

```lua
local driver = exports['rcore_formula']:getWatchingDriver()
```

**Returns:** `number` or `nil` - Player server ID of spectated driver, or nil if not spectating anyone.

***

### getWatchingCameraIndex

Gets the current spectator camera index.

```lua
local cameraIndex = exports['rcore_formula']:getWatchingCameraIndex()
```

**Returns:** `number` - Current camera angle index.

***

## UI State Exports

### isLeaderboardOpened

Checks if the race leaderboard is currently open.

```lua
local opened = exports['rcore_formula']:isLeaderboardOpened()
```

**Returns:** `boolean` - `true` if leaderboard is displayed, `false` otherwise.

***

### isInPitBox

Checks if the player is currently in the pit box.

```lua
local inPit = exports['rcore_formula']:isInPitBox()
```

**Returns:** `boolean` - `true` if player is in pit, `false` otherwise.

**Example:**

```lua
if exports['rcore_formula']:isInPitBox() then
    -- Allow tire changes or repairs
    print("You can change tires here")
end
```

***

## Complete Usage Example

```lua
-- Check if player is in a race
local trackId = exports['rcore_formula']:getPlayerCurrentRace()
if trackId then
    -- Get current race stats
    local currentLap = exports['rcore_formula']:getCurrentLap()
    local currentLapTime = exports['rcore_formula']:getCurrentLapTime()
    local bestLap = exports['rcore_formula']:getBestLapTime()
    local compound = exports['rcore_formula']:getTyreCompound()

    print(string.format("Lap %d | Current: %.3fs | Best: %.3fs | Tyres: %s",
        currentLap,
        currentLapTime / 1000,
        bestLap / 1000,
        compound
    ))

    -- Check if in pit for tire change
    if exports['rcore_formula']:isInPitBox() then
        exports['rcore_formula']:setTyreCompound("soft")
    end
end

-- Check team membership
local myTeams = exports['rcore_formula']:getPlayerTeamsWithPermission("RACE")
for teamId, role in pairs(myTeams) do
    print("Can race for team " .. teamId .. " as " .. role)
end
```
