These client-only helpers cover the chores most scripts repeat: loading an asset before using it, finding the closest vehicle or player, spawning and deleting vehicles, and turning coordinates into a street name.
Loading assets
Each loader requests an asset and yields until it is ready.
| Function | Returns on success | Checks the asset exists first |
|---|---|---|
encore.requestModel(model, timeout?) | the model hash | yes (IsModelInCdimage) |
encore.requestAnimDict(dict, timeout?) | dict | yes (DoesAnimDictExist) |
encore.requestAnimSet(set, timeout?) | set (a movement clipset) | no |
encore.requestPtfx(asset, timeout?) | asset (a named particle asset) | no |
encore.requestTextureDict(dict, timeout?) | dict (a streamed texture dictionary) | no |
Behaviour:
modelmay be a name or a hash. A name is hashed withjoaat.- If the asset is already loaded, the loader returns straight away.
- If the asset doesn't exist, the loader returns
niland warns once, for examplemodel "x" does not exist. - If the asset doesn't load within
timeout(default 10000 ms), the loader returnsniland logs... did not load within 10000ms. - None of them throw. Always check for
nil. - Anim sets, particle assets and texture dictionaries have no existence check, so a typo waits for the full timeout before returning
nil.
The loaders don't release assets. When you are done, call SetModelAsNoLongerNeeded, RemoveAnimDict, RemoveAnimSet, RemoveNamedPtfxAsset or SetStreamedTextureDictAsNoLongerNeeded yourself.
local hash = encore.requestModel('u_m_y_zombie_01')
if not hash then return end
local ped = CreatePed(4, hash, coords.x, coords.y, coords.z, 0.0, true, false)
SetModelAsNoLongerNeeded(hash)
if encore.requestAnimDict('move_m@drunk@verydrunk') then
TaskPlayAnim(ped, 'move_m@drunk@verydrunk', 'idle', 3.0, 3.0, -1, 1, 0, false, false, false)
RemoveAnimDict('move_m@drunk@verydrunk')
endNearby entities
All distances are in metres from coords.
| Function | Returns |
|---|---|
encore.getNearbyPlayers(coords, maxDistance, includeSelf?) | A list of { id, serverId, ped, coords, distance } |
encore.getClosestPlayer(coords, maxDistance, includeSelf?) | playerId?, ped?, coords?, distance? |
encore.getNearbyVehicles(coords, maxDistance, includePlayerVehicle?) | A list of { entity, coords, distance } |
encore.getClosestVehicle(coords, maxDistance, includePlayerVehicle?) | vehicle?, coords?, distance? |
encore.getClosestPed(coords, maxDistance) | ped?, coords?, distance? |
encore.getClosestObject(coords, maxDistance) | object?, coords?, distance? |
- Player lists come from the players your client currently knows about.
idis the client player index,serverIdis the id the server uses. - Your own player is left out unless
includeSelfistrue. - The vehicle you are sitting in is left out unless
includePlayerVehicleistrue. getClosestPedonly considers non-player peds, which makes it the right call for zombies and NPCs.- The
getClosest*functions returnnilwhen nothing is in range.
local myCoords = GetEntityCoords(PlayerPedId())
local target, targetPed = encore.getClosestPlayer(myCoords, 3.0)
if not target then
return encore.notify({ description = 'Nobody nearby', type = 'error' })
end
TriggerServerEvent('my-medical:revive', GetPlayerServerId(target))
for _, entry in ipairs(encore.getNearbyVehicles(myCoords, 25.0)) do
SetVehicleDoorsLocked(entry.entity, 2)
endVehicles
| Function | Returns | Notes |
|---|---|---|
encore.spawnVehicle(model, cb?, coords?, heading?, networked?) | vehicle? | Yields while the model loads. Returns nil if the model can't load |
encore.deleteVehicle(vehicle) | none | Marks it as a mission entity, then deletes it |
encore.getVehiclePlate(vehicle) | string | The plate text with surrounding spaces trimmed |
encore.spawnVehicle arguments:
| Argument | Default | Meaning |
|---|---|---|
model | required | Name or hash |
cb | none | Called with the vehicle once it exists |
coords | your position | A vector3 or vector4 |
heading | coords.w, then your heading | Heading in degrees |
networked | true | Whether other players see it |
The model is released for you after the vehicle is created.
local vehicle = encore.spawnVehicle('rebel', nil, vec4(1730.2, 3310.5, 41.2, 195.0))
if vehicle then
SetVehicleFuelLevel(vehicle, 20.0)
encore.notify({ description = 'Plate ' .. encore.getVehiclePlate(vehicle) })
endAnything spawned from the client happens because a client decided to. For vehicles that players own or that cost money, decide on the server whether the spawn is allowed.
On-screen text
These draw GTA text for a single frame, so call them every frame from a loop. They are meant for debugging and simple world labels. Player-facing interface belongs in en-ui, see UI services.
| Function | Notes |
|---|---|
encore.drawText2d(text, x, y, scale?, font?) | Screen position from 0 to 1. scale defaults to 0.5, font to 4. Centred |
encore.drawText3d(coords, text) | Draws at a world position, scaled by camera distance and field of view |
CreateThread(function()
while DebugZones do
for _, zone in ipairs(Zones) do
encore.drawText3d(zone.coords, zone.name)
end
Wait(0)
end
end)Location
| Function | Returns | Notes |
|---|---|---|
encore.getCardinalDirection(heading) | 'North', 'West', 'South' or 'East' | GTA headings run counter-clockwise, so 90 is West |
encore.getStreetName(coords) | street, crossing? | crossing is nil when there is no cross street |
encore.getZoneName(coords) | string | The zone's display label, such as a district name |
local coords = GetEntityCoords(PlayerPedId())
local street, crossing = encore.getStreetName(coords)
local where = crossing and (street .. ' / ' .. crossing) or street
TriggerServerEvent('my-radio:distress', where .. ', ' .. encore.getZoneName(coords))