Skip to content

twinded_lgw_npc

A non-networked NPC spawner for RedM. Spawn peds locally to avoid consuming network entity slots, with distance-based spawn/despawn, native RedM prompts, map blips, animations, scenarios, text3d, and a full exports API.

Dependencies

ResourceRequiredNotes
twinded_libsYesFree shared library

Compatibility

Framework-independent — this script does not use any framework. It only requires twinded_libs for utility modules (prompts, blips, text3d, entities).

Installation

bash
ensure twinded_libs
ensure twinded_lgw_npc

Config Files

FileDescription
settings.luaSpawn delay, distance check interval, text3d config, debug toggle
lang.luaTranslation strings (debug messages)
text3d.luaCustom text3d handler (when Config.Text3D.type = 'custom')
npcs/examples.luaExample NPC definitions (shopkeeper, guard, ambient)

See the Configuration guide for how to override these files.

Configuration Reference

settings.lua

OptionTypeDefaultDescription
Config.SpawnDelaynumber200Delay (ms) between staggered NPC spawns
Config.DistanceCheckIntervalnumber2000How often (ms) to check player distance for spawn/despawn
Config.Text3D.typestring"default"'default' for built-in text3d, 'custom' for your own handler
Config.Text3D.scalenumber0.30Text scale
Config.Text3D.background_alphanumber180Background opacity (0-255)
Config.DebugbooleanfalseEnable debug commands

NPC Definition Fields

Each NPC in Config.NpcList or in npcs/*.lua files:

FieldTypeRequiredDescription
idstringYesUnique identifier
namestringYesDisplay name
coordstableYes{x, y, z, heading}
look.modelstringYesPed model name
look.outfittableNoOutfit components
look.scalenumberNoPed scale
spawn_radius_in_metersnumberYesDistance at which NPC spawns
face_playerstring or nilNo"full" (body) or "head_only"
prevent_place_on_groundbooleanNoPrevent ground placement (for indoor NPCs)
weaponstring or nilNoWeapon model name (e.g., "WEAPON_REVOLVER_CATTLEMAN")
scenariostring or nilNoRedM scenario name (e.g., "WORLD_HUMAN_STAND_BAR")
animationstable or nilNoArray of {anim_dict, anim_name, loop, anim_only_upper_body, times, delay_in_ms}
text3dtable or nilNo{text, radius, offset_z}
bliptable or nilNo{icon, default_color, scale, title, modifiers, time_window_color}
promptstable or nilNoArray of prompt pages (see below)
time_windowstable or nilNoArray of {start_hour, start_minute, end_hour, end_minute}
on_spawnfunction or nilNoCallback when NPC spawns
on_despawnfunction or nilNoCallback when NPC despawns

Prompt Page Fields

FieldTypeDescription
page_labelstringPrompt group title
page_radius_in_metersnumberDistance to show this prompt page
page_promptstableArray of {label, key, hold, callback}

text3d.lua

Custom text3d handler (when Config.Text3D.type = 'custom'):

lua
function DrawNpcText3D(options)
    -- options.x, options.y, options.z  — world coordinates
    -- options.text                      — text to display
    -- options.npc_id                    — NPC identifier
    -- options.npc_name                  — NPC display name
end

Features

  • Non-networked peds — Zero network entity consumption
  • Distance-based spawn/despawn — NPCs spawn when player is within radius
  • Anti-pop despawn — NPCs in line of sight are not despawned until hidden
  • Staggered spawning — One at a time with configurable delay
  • Native RedM prompts — Multi-page prompt system with press/hold support
  • Map blips — Configurable blips with time-window color changes
  • Animations & scenarios — Looping animations, multi-step sequences, RedM scenarios
  • Text3D — Floating text above NPCs
  • Face player — Full body or head only rotation
  • Attached props — Attach objects to NPC bones
  • Time windows — NPCs visible only during specific in-game hours
  • Exports API — 10 exports for inter-script integration
  • Runtime NPCs — Register/unregister dynamically from other scripts
  • Callbackson_spawn and on_despawn hooks per NPC

Debug Commands

Set Config.Debug = true to enable:

CommandDescription
/npc_debugList all NPCs with state, distance, and animation status
/npc_debug <npc_id>Detailed info for a specific NPC
/npc_respawn <npc_id>Force respawn a specific NPC
/npc_respawn_allRespawn all currently spawned NPCs

Exports API

Read

lua
-- Get all currently spawned NPCs
local npcs = exports['twinded_lgw_npc']:GetSpawnedNpcs()

-- Get entity handle of a specific NPC
local entity = exports['twinded_lgw_npc']:GetNpcByID('my_npc')

-- Check if a NPC is currently spawned
local spawned = exports['twinded_lgw_npc']:IsNpcSpawned('my_npc')

Actions

lua
-- Force spawn/despawn regardless of distance
exports['twinded_lgw_npc']:ForceSpawnNpc('my_npc')
exports['twinded_lgw_npc']:ForceDespawnNpc('my_npc')

-- Override animation
exports['twinded_lgw_npc']:SetNpcAnimation('my_npc', 'anim_dict', 'anim_name', true, false)

-- Override scenario
exports['twinded_lgw_npc']:SetNpcScenario('my_npc', 'WORLD_HUMAN_STAND_BAR')

-- Enable/disable prompts
exports['twinded_lgw_npc']:SetPromptEnabled('my_npc', false)

Dynamic NPCs

lua
-- Register a new NPC at runtime
exports['twinded_lgw_npc']:RegisterNpc({
    id = 'my_custom_npc',
    name = 'Custom NPC',
    coords = { x = 0.0, y = 0.0, z = 0.0, heading = 0.0 },
    look = { model = "a_m_m_rancher_01" },
    spawn_radius_in_meters = 100,
})

-- Unregister and despawn
exports['twinded_lgw_npc']:UnregisterNpc('my_custom_npc')

Troubleshooting

ProblemSolution
Script doesn't startMake sure twinded_libs is started before
NPCs not spawningCheck spawn_radius_in_meters and your distance to the NPC
NPCs stuck in groundSet prevent_place_on_ground = true (common inside custom buildings)
Prompts not showingVerify the NPC has a prompts field and page_radius_in_meters
Debug commands not workingCheck Config.Debug is true
Text3D not visibleVerify text3d field with text and radius, and you're within range

Premium RedM Scripts — Multi-Framework