Skip to main content
TRACK B·FIVEM FUNDAMENTALS·Verified June 2026 · Lua 5.4 · ox_lib 3.x
Learning with an AI assistant?
Copies this lesson plus 2026 ground rules (no lua54 'yes', Cfx.re Portal, correct callback signatures) as a ready-to-paste mentor prompt.

Two worlds, one resource

This is one of the first big FiveM ideas that confuses beginners. Your resource folder looks like one thing, but it actually runs as two separate programs: one on the server, one on each player's PC. They do not share variables, and they do not secretly sync. By the end you will be able to point at any line in a resource and say which world it runs in, and how the two worlds talk to each other.

You'll learn
Why a resource runs as two programs, and which code lives on each side.
Time
~20 minutes
Prereqs
A running server and one resource you can edit.
BEFORE YOU START

Build it

Make the resource folder

The server has one folder for this lesson.

Inside your server's resources folder, create this folder:

code
resources/qu_two_worlds

Create the files

Every file named in the manifest exists.

Create this exact file layout:

code
resources/qu_two_worlds/
fxmanifest.lua
config.lua
server.lua
client.lua

Write fxmanifest.lua

FiveM knows which files to load, and on which side.

Open fxmanifest.lua and paste this:

code
fx_version 'cerulean'
game 'gta5'

shared_script 'config.lua'
server_script 'server.lua'
client_script 'client.lua'

Notice the three different keys. server_script and client_script send each file to a different world. shared_script is the odd one out, and the next section explains why. Older tutorials add a lua54 'yes' line here. As of June 2025 that setting is deprecated and ignored, because Lua 5.4 is now the only Lua runtime, so you leave it out.

Write the lesson code

The topic is now represented by runnable code.

Open config.lua and paste this:

code
Config = {}
Config.Label = 'qu_two_worlds shared config'

Open server.lua and paste this:

code
print('[qu_two_worlds] server loaded, Config.Label = ' .. Config.Label)

ServerOnlySecret = 'only the server knows this'

RegisterCommand('splitproof', function(src)
print('[qu_two_worlds] server handled splitproof, ServerOnlySecret = ' .. ServerOnlySecret)
TriggerClientEvent('qu_two_worlds:clientProof', src)
end, false)

Open client.lua and paste this:

code
print('[qu_two_worlds] client loaded, Config.Label = ' .. Config.Label)

RegisterNetEvent('qu_two_worlds:clientProof', function()
local ped = PlayerPedId()
print('[qu_two_worlds] client got the event, my ped handle = ' .. ped)
print('[qu_two_worlds] client sees ServerOnlySecret as ' .. tostring(ServerOnlySecret))
end)

Start and test it

The expected proof appears across two consoles.

Open server.cfg and add this line:

code
ensure qu_two_worlds

Save, then run this in the txAdmin Live Console:

code
restart qu_two_worlds

Join your server, then open the chat box and run:

code
/splitproof

Your ped handle will be some integer, not 132 exactly. The number does not matter. What matters is that it is a number, that it shows up in F8 and not in the server console, and that the client reports ServerOnlySecret as nil. That last line is the whole lesson in one word.

Keep reading the full lesson

Sign in to start, then unlock every step of this lesson and the full FiveM School with a membership.

Still ahead in this lesson
  • How it works
  • If something went wrong
  • What you can do now
  • Try it yourself

The remainder of Two worlds, one resource is available to FiveM School members.