Skip to content
CyberNex Logo
Back to Tutorials
FiveM8 min readJuly 2, 2026

FiveM Scripting Introduction - Creating Your First Resource

Roshan David
Game Server Engineer at CyberNex | 6+ years infrastructure experience

Understanding FiveM Resources

Everything in a FiveM server is a resource - scripts, maps, vehicles, UI elements, even loading screens. A resource is a folder containing scripts and a fxmanifest.lua file that tells FiveM what to load. Resources can be written in Lua, JavaScript, or C#. Lua is the most popular choice for FiveM scripting due to its simplicity and the large ecosystem of existing scripts. Every resource runs independently - communication between resources happens through events. Resources are organized in your server's /resources directory.

Creating Your First Script in Lua

Create a folder named 'my_first_script' in your server's resources directory. Inside, create fxmanifest.lua with: fx_version 'cerulean', game 'gta5', client_script 'client.lua'. Then create client.lua with a simple script: 'Citizen.CreateThread(function() while true do Citizen.Wait(0) local playerPed = PlayerPedId() -- Your code here end end)'. This creates a continuous loop that runs every frame. Restart the resource with 'refresh' in the server console, then 'start my_first_script'. The Citizen.Wait(0) is crucial - without it, the thread blocks FiveM and freezes the game.

Using Native Functions

Native functions are the building blocks of FiveM scripting - they're GTA V's internal commands exposed to Lua. For example: SetEntityCoords(entity, x, y, z) moves an entity, GiveWeaponToPed(ped, weaponHash, ammo, false, true) gives a weapon, SetPlayerWantedLevel(player, level, false) sets wanted level. Each native function accepts specific parameters and returns values. The FiveM Native Reference (docs.fivem.net/natives) documents every available native. Common ones to learn first: GetPlayerPed, SetEntityCoords, GiveWeaponToPed, AddBlipForCoord, TriggerServerEvent, TriggerClientEvent, Citizen.Wait, and SetNotificationTextEntry.

Client vs Server Scripts

Client scripts run on each player's PC - they handle visual elements, UI, local game mechanics, and player input. Server scripts run on the host machine - they handle persistent data, player authentication, economy, and anything that must be synchronized. Never trust client-side validation for money, inventory, or bans - always validate on the server. Use server events to communicate between client and server: TriggerServerEvent sends data to server, TriggerClientEvent sends to specific client, TriggerLatentClientEvent handles large data. Server scripts use 'exports' to share functions between resources.

Working with Events

Events are the communication backbone of FiveM. RegisterNetEvent('eventName') listens for an event. TriggerServerEvent('eventName', data) sends to server. TriggerClientEvent('eventName', playerId, data) sends to a client. Built-in events: 'onResourceStart', 'playerConnecting', 'playerDropped', 'baseevents:onPlayerDied'. Custom events can pass any Lua data type. Use AddEventHandler inside a resource to respond to events. Example money system: client triggers 'bank:withdraw', server validates the amount against the player's database balance, deducts if valid, then triggers 'bank:updateUI' back to the client.

Networking and State Bags

State bags are FiveM's modern approach to data synchronization. Instead of manually syncing variables, state bags automatically replicate data between server and clients. Server sets: entity.SetStateBag(entityId, { key = value }). Client reads: entity.GetStateBag(entityId). State bags are optimized - they only send changed data, not entire objects. Use them for: player data (job, money, hunger), vehicle data (fuel, damage, ownership), and world objects. State bags work with routing buckets for instanced content. Global state bag: GlobalState.Set('key', value, replicate: true) makes data available server-wide.

Debugging and Testing Your Scripts

Enable the FiveM profiler by typing 'profiler record 10' in console - it captures 10 seconds of performance data. Use print() statements for basic debugging in both client and server scripts. The client console (F8) shows Lua errors with line numbers. For visual debugging, use DrawText3D or CreateThread to display variable values on screen. Test scripts on a local dev server before deploying to production. CyberNex provides instant test servers - deploy, test, and reset with one click. Use 'restart [resource]' not 'stop/start' - it preserves resource state. Set 'onesync_enableInfinity 1' in server.cfg for modern OneSync features.

Related Hosting Services
// Frequently Asked Questions

FAQ

Was this guide helpful?

Join our Discord for more guides and direct help from our engineering team.

FiveM Scripting Introduction - Creating Your First Resource | CyberNex