W jakim języku są komendy i skrypty FiveM?
FiveM pozwala pisać resource’y (mody) w trzech językach skryptowych:
- Lua – najpopularniejszy i najprostszy na start.
- JavaScript / TypeScript – działa na runtime’ie Node.js w FiveM (zwykle piszesz JS, TS kompilujesz do JS).
- C# (.NET) – najmniej „laickie” na początek, ale mocne, typowane.
Dodatkowo NUI (interfejsy) budujesz w HTML + CSS + JavaScript (przeglądarkowy) i łączysz go z Lua/JS/C# przez komunikaty.
Ten sam pomysł w 3 językach (porównanie)
Lua
-- Komenda /hello (klient)
RegisterCommand('hello', function()
TriggerEvent('chat:addMessage', { args = { 'CF', 'Cześć z Lua!' } })
end, false)
-- Serwer -> do wszystkich graczy
RegisterCommand('helloall', function(src)
TriggerClientEvent('chat:addMessage', -1, { args = { 'CF', 'Serwer mówi: hej!' } })
end, true)
JavaScript (client.js / server.js)
// client.js
RegisterCommand('hello', () => {
emit('chat:addMessage', { args: ['CF', 'Cześć z JS!'] });
}, false);
// server.js
RegisterCommand('helloall', (src) => {
emitNet('chat:addMessage', -1, { args: ['CF', 'Serwer mówi: hej!'] });
}, true);
C# (Client.cs / Server.cs)
// Client.cs
using static CitizenFX.Core.Native.API;
RegisterCommand("hello", new Action<int, List<object>, string>((src, args, raw) => {
TriggerEvent("chat:addMessage", new { args = new[] { "CF", "Cześć z C#!" } });
}), false);
// Server.cs
RegisterCommand("helloall", new Action<int, List<object>, string>((src, args, raw) => {
TriggerClientEvent("chat:addMessage", -1, new { args = new[] { "CF", "Serwer mówi: hej!" } });
}), true);
W praktyce początkujący wybierają Lua. Jest najprostsza, a 99% tutoriali i snippetów jest w Lua.
Jak to się komunikuje?
- TriggerEvent – lokalne zdarzenie (klient po swojej stronie albo serwer po swojej).
- TriggerServerEvent – z klienta do serwera.
- TriggerClientEvent – z serwera do klientów (
-1do wszystkich lub podaj id gracza). - NUI – front (HTML/JS) ↔ backend (Lua/JS/C#) przez
SendNUIMessageiRegisterNUICallback.
Start lekcji: ścieżka „od zera do własnych skryptów”
Poniżej plan w krótkich modułach. Każdy ma: wytłumaczenie → kod → ćwiczenie. Na koniec dam „mapę dalszej nauki”.
MODUŁ 1 – Podstawy Lua w FiveM
1.1 Zmienne i typy
- Lua nie ma typów statycznych; najczęstsze:
number,string,boolean,table,function,nil.
local hp = 100
local nick = "Maku"
local dead = false
local pos = { x = 0.0, y = 0.0, z = 0.0 } -- table = „słownik”
1.2 Instrukcje warunkowe i pętle
if hp <= 0 then
print("Padłeś")
elseif hp < 50 then
print("Uważaj")
else
print("Jest ok")
end
for i=1,5 do print(i) end
local i = 0
while i < 3 do i = i + 1 end
1.3 Funkcje
local function suma(a, b)
return a + b
end
print( suma(2,3) )
1.4 Wątki, Wait i „tick”
W FiveM używasz „wątków”:
CreateThread(function()
while true do
Wait(1000) -- ms
print("Mija sekunda")
end
end)
Zasada: unikaj wielu pętli z
Wait(0)bez potrzeby – to zjada FPS.
1.5 Natíwy GTA („natives”)
To wbudowane funkcje gry, np. pobranie pozycji gracza:
local ped = PlayerPedId()
local x,y,z = table.unpack(GetEntityCoords(ped))
1.6 Eventy klient ↔ serwer
-- klient
RegisterNetEvent('cf:ping')
AddEventHandler('cf:ping', function(msg)
print("Od serwera:", msg)
end)
-- serwer
RegisterCommand('pingme', function(src)
TriggerClientEvent('cf:ping', src, 'Siema, to serwer!')
end)
Ćwiczenie:
- Napisz komendę
/hp, która na czacie wypisze bieżące HP gracza (client). - Zrób komendę serwerową
/where <id>, która wyśle konkretnemu graczowi jego koordy (server → specific client).
MODUŁ 2 – Mini-NUI (interfejs) w 10 minut
2.1 Pliki
W resource zrób html/index.html + fxmanifest.lua dopisz:
ui_page 'html/index.html'
files { 'html/index.html' }
2.2 Klient ↔ NUI
-- client.lua
RegisterCommand('panel', function()
SetNuiFocus(true, true)
SendNUIMessage({ show = true })
end)
RegisterNUICallback('close', function(_, cb)
SetNuiFocus(false, false)
cb('ok')
end)
index.html (mega prosty):
<!doctype html><html><body>
<button id="close">Zamknij</button>
<script>
window.addEventListener('message', (e)=>{
if(e.data.show){ document.body.style.display='block'; }
});
document.getElementById('close').onclick=()=> {
fetch(`https://` + GetParentResourceName() + `/close`, {method:'POST',body:'{}'});
document.body.style.display='none';
};
</script>
<style>body{display:none;position:fixed;inset:40% auto auto 40%;background:#111;color:#fff;padding:20px;border-radius:10px}</style>
</body></html>
Ćwiczenie:
- Dodaj pole input i przycisk „Wyślij”, który wysyła tekst do klienta (NUICallback), a klient wyświetla go na czacie.
MODUŁ 3 – JavaScript/TypeScript w FiveM (opcjonalna ścieżka)
3.1 Manifest
-- fxmanifest.lua
fx_version 'cerulean'
game 'gta5'
client_scripts { 'client.js' }
server_scripts { 'server.js' }
3.2 Podstawy w JS (client)
RegisterCommand('hello', () => {
emit('chat:addMessage', { args: ['CF', 'Hello z JS'] });
}, false);
setInterval(() => {
// tick co 1s
}, 1000);
TS? Utwórz projekt z
tsconfig.json, pisz wclient.ts, buduj doclient.js.
Ćwiczenie:
- Przepisz swoją komendę Lua
/hellodo JS i porównaj.
MODUŁ 4 – C# w FiveM (dla chętnych)
- Wymaga środowiska .NET. Manifest:
fx_version 'cerulean'
game 'gta5'
client_scripts { 'bin/Release/net6.0/win-x64/Client.net.dll' }
server_scripts { 'bin/Release/net6.0/win-x64/Server.net.dll' }
- Korzystasz z
CitizenFX.Core.
Jeśli nie programowałeś wcześniej w C#, odłóż to na później – Lua/JS szybciej daje efekt.
MODUŁ 5 – Dobre praktyki i pułapki
- Nazwy bez spacji i PL-znaków.
- Jedna odpowiedzialność na resource.
- Kolejność resource’ów w
server.cfg(zależności wcześniej). - Nie spamuj pętli i
Citizen.Wait(0)bez sensu. - Debug: logi w konsoli serwera i F8,
print(), izolowanie problemu. - Zabezpieczenia: wrażliwe komendy rób „restricted” i nadaj ACE.
- NUI: nie rób ciężkich animacji w 60 fps bez potrzeby.
Plan nauki (proponowany harmonogram)
Tydzień 1 – Lua basic:
- Zmienne, tabele, funkcje → ćwiczenia z /hello, /hp, 3D-text w punkcie.
- Eventy K↔S → /where, serwer → klient.
Tydzień 2 – NUI mini-projekty:
- Prosty panel (pokaż/zamknij), formularz i callbacki.
- Notyfikacje, minimalny HUD (tekst/ikona).
Tydzień 3 – Integracje:
- Natives: blipy, markery, interakcje klawiszy.
- Exports (korzystanie z funkcji z innego resource’u).
Tydzień 4 – Struktura i porządek:
- Refaktoryzacja folderów, konwencje nazw, logi i obsługa błędów.
- (Opcjonalnie) Wersja JS/TS tej samej funkcjonalności.
Zadanie domowe (na teraz)
- W swoim
cf_hello_worlddodaj:
/hp(client) – wypisz HP./where <id>(server) – wyślij graczowi koordy (S→C).- Blip na mapie + 3D-tekst w pobliżu (client).
- Wersja z NUI:
/panelotwiera okienko, przycisk „Wyślij” odsyła tekst do klienta → klient pokazuje go na czacie.
