Poradniki

W jakim języku są komendy i skrypty FiveM?

FiveM pozwala pisać resource’y (mody) w trzech językach skryptowych:

  1. Lua – najpopularniejszy i najprostszy na start.
  2. JavaScript / TypeScript – działa na runtime’ie Node.js w FiveM (zwykle piszesz JS, TS kompilujesz do JS).
  3. 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 (-1 do wszystkich lub podaj id gracza).
  • NUI – front (HTML/JS) ↔ backend (Lua/JS/C#) przez SendNUIMessage i RegisterNUICallback.

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 w client.ts, buduj do client.js.

Ćwiczenie:

  • Przepisz swoją komendę Lua /hello do 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)

  1. W swoim cf_hello_world dodaj:
  • /hp (client) – wypisz HP.
  • /where <id> (server) – wyślij graczowi koordy (S→C).
  • Blip na mapie + 3D-tekst w pobliżu (client).
  1. Wersja z NUI:
  • /panel otwiera okienko, przycisk „Wyślij” odsyła tekst do klienta → klient pokazuje go na czacie.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *