Client Script FiveM คืออะไร? ทำงานอย่างไร และใช้ทำอะไรได้บ้าง

Client Script FiveM คือ Script ที่ถูกโหลดและทำงานบนเครื่องของผู้เล่นแต่ละคนที่เชื่อมต่อเข้า FiveM Server โดยมักใช้ควบคุมสิ่งที่เกี่ยวข้องกับเกมฝั่งผู้เล่น เช่น Ped, Vehicle, Marker, Blip, Animation, Camera, Controls, NUI และการเรียก GTA V/FiveM Native ต่าง ๆ

ถ้า Server มีผู้เล่น 50 คน Client Script เดียวกันอาจถูกโหลดและทำงานแยกกันบนเครื่องของผู้เล่นทั้ง 50 คน ตาม Resource และสถานะของแต่ละ Client

จุดสำคัญที่ FiveM Developer ต้องเข้าใจคือ Client Script ไม่ใช่ Server Script และข้อมูลสำคัญอย่างเงิน Item Reward หรือ Permission ไม่ควรตัดสินผลโดยเชื่อ Client เพียงอย่างเดียว

บทความนี้จะอธิบาย Client Script ตั้งแต่พื้นฐาน วิธีสร้าง การใช้ Native, Command, Event, Thread, NUI ไปจนถึง Security และ Performance

① Client Script FiveM คืออะไร

Resource FiveM สามารถประกอบด้วย Script หลายประเภท เช่น

client.lua
server.lua
shared.lua

โดย

client.lua

เป็นชื่อที่นิยมใช้สำหรับ Client Script

แต่ FiveM ไม่ได้บังคับว่าต้องชื่อ client.lua เท่านั้น

คุณสามารถตั้งชื่อเป็น

main_client.lua
vehicle.lua
player.lua
garage_client.lua

ก็ได้

ตราบใดที่กำหนดไว้ใน fxmanifest.lua อย่างถูกต้อง

ตัวอย่าง

fx_version 'cerulean'
game 'gta5'

client_script 'client.lua'

คำสั่ง

client_script

บอก FiveM ว่าไฟล์ดังกล่าวต้องถูกโหลดฝั่ง Client

② Client Script ทำงานที่ไหน

Client Script ทำงานบน FiveM Client ของผู้เล่น

ตัวอย่างเช่นมีผู้เล่น

Player A
Player B
Player C

แต่ละคนจะมี Client Runtime ของตัวเอง

แนวคิดคือ

FiveM Server
     ↓
Resource
     ↓
ส่ง Client Script
     ↓
┌──────────┬──────────┬──────────┐
Player A   Player B   Player C
Client     Client     Client

ดังนั้น Variable ที่สร้างขึ้นบน Client ของ Player A ไม่ได้หมายความว่า Player B จะเห็นค่าตามโดยอัตโนมัติ

นี่เป็นพื้นฐานสำคัญมากของ Client/Server Architecture

③ Client Script ใช้ภาษาอะไรเขียนได้บ้าง

FiveM รองรับ Client Script ผ่าน Runtime หลัก ได้แก่

Lua
JavaScript
C#

ตัวอย่าง Lua

print('Hello from client')

JavaScript

console.log('Hello from client');

และ C# สามารถสร้าง Client Assembly ที่ FiveM โหลดผ่าน C# Runtime ได้

สำหรับบทความนี้จะใช้ Lua เป็นตัวอย่างหลัก เพราะอ่านง่ายและพบใน FiveM Community จำนวนมาก

④ วิธีสร้าง Client Script FiveM

สร้าง Resource เช่น

resources/
└── [local]/
    └── client_example/
        ├── fxmanifest.lua
        └── client.lua

ใน fxmanifest.lua

fx_version 'cerulean'
game 'gta5'

author 'Your Name'
description 'Client Script Example'
version '1.0.0'

client_script 'client.lua'

ใน client.lua

print('Client script loaded')

จากนั้นเพิ่ม Resource ใน server.cfg

ensure client_example

เมื่อผู้เล่นเข้า Server และ Resource ทำงาน Client Script จะถูกโหลดตามระบบ Resource ของ FiveM

⑤ client_script กับ client_scripts ต่างกันอย่างไร

ถ้ามีไฟล์เดียวสามารถใช้

client_script 'client.lua'

หากมีหลายไฟล์สามารถใช้

client_scripts {
    'client/main.lua',
    'client/vehicle.lua',
    'client/player.lua'
}

FiveM Resource Manifest ยังรองรับ Globbing

เช่น

client_scripts {
    'client/*.lua'
}

หรือถ้าต้องการค้นไฟล์ใน Folder ย่อยด้วย สามารถใช้ Pattern ที่เหมาะสมตาม Resource Manifest

สำหรับ Project ใหญ่ การแบ่ง Client Code ออกเป็นหลาย Module จะดูแลง่ายกว่ารวมทุกอย่างไว้ใน client.lua ไฟล์เดียว

⑥ Client Script ใช้ทำอะไรได้บ้าง

Client Script เหมาะกับสิ่งที่เกี่ยวข้องกับ Game Client โดยตรง เช่น

  • ตรวจ Player Ped

  • ตรวจ Coordinates

  • ตรวจ Vehicle

  • Spawn หรือจัดการ Entity ตามระบบที่เหมาะสม

  • Marker

  • Blip

  • Animation

  • Camera

  • Control

  • Notification

  • HUD

  • NUI

  • Effects

  • Gameplay Interaction

  • ตรวจ Player อยู่ใกล้จุดหรือไม่

ตัวอย่างเช่น

local ped = PlayerPedId()

ใช้ดึง Ped ของผู้เล่นใน Client ปัจจุบัน

⑦ PlayerPedId คืออะไร

หนึ่งใน Native ที่ Client Script ใช้บ่อยมากคือ

PlayerPedId()

ตัวอย่าง

local ped = PlayerPedId()

print(ped)

ค่าที่ได้คือ Handle ของ Ped ที่เป็นตัวละครผู้เล่นฝั่ง Client

จากนั้นสามารถนำไปใช้กับ Native อื่นได้

เช่น

local coords = GetEntityCoords(ped)

Flow คือ

Player
↓
PlayerPedId()
↓
Ped Entity
↓
GetEntityCoords()
↓
Coordinates

⑧ วิธีหา Coordinates ของผู้เล่น

ตัวอย่างง่าย ๆ

local ped = PlayerPedId()
local coords = GetEntityCoords(ped)

print(coords)

สามารถสร้าง Command ได้

RegisterCommand('coords', function()
    local ped = PlayerPedId()
    local coords = GetEntityCoords(ped)

    print(coords)
end, false)

เมื่อเรียก

coords

Client Script จะอ่านตำแหน่งของผู้เล่น

ระบบ Coordinates ถูกใช้ใน Script จำนวนมาก เช่น

  • Shop

  • Garage

  • Job

  • Teleport

  • Marker

  • Mission

  • Interaction

⑨ Client Script ใช้ GTA V Native ได้อย่างไร

Native คือ Function ที่ให้ Script ติดต่อกับระบบ GTA V และ FiveM

ตัวอย่าง

PlayerPedId()
GetEntityCoords()
IsPedInAnyVehicle()
GetVehiclePedIsIn()
SetEntityCoords()

Native แต่ละตัวมี

  • Parameter

  • Return Value

  • API Set

  • Context ที่รองรับ

FiveM Developer จึงไม่ควรจำเพียงชื่อ Function

ควรอ่านด้วยว่า Native นั้นใช้ฝั่ง

Client
Server
Shared

หรือมีข้อจำกัดอะไร

⑩ Client Script กับ Entity

Entity เป็นสิ่งที่สำคัญมากใน FiveM

ตัวอย่าง Entity ได้แก่

Ped
Vehicle
Object

Client สามารถหา Entity ต่าง ๆ และจัดการผ่าน Native

ตัวอย่าง

local ped = PlayerPedId()

if IsPedInAnyVehicle(ped, false) then
    local vehicle = GetVehiclePedIsIn(
        ped,
        false
    )

    print('Vehicle:', vehicle)
end

Code นี้ตรวจว่า Player อยู่ในรถหรือไม่

ถ้าอยู่ก็หา Vehicle Entity

⑪ Client Script ใช้สร้าง Command ได้ไหม

ได้

ตัวอย่าง

RegisterCommand('hello', function()
    print('Hello from client')
end, false)

หรือ Command ตรวจรถ

RegisterCommand('myvehicle', function()
    local ped = PlayerPedId()

    if IsPedInAnyVehicle(ped, false) then
        local vehicle = GetVehiclePedIsIn(
            ped,
            false
        )

        print('Vehicle:', vehicle)
    else
        print('Player is not in a vehicle')
    end
end, false)

Command เป็นวิธีที่ดีสำหรับฝึก Client Script เพราะสามารถทดสอบ Logic ได้ทันที

⑫ Client Script ใช้ Thread ได้อย่างไร

ระบบที่ต้องตรวจสิ่งใดสิ่งหนึ่งต่อเนื่องมักใช้

CreateThread()

ตัวอย่าง

CreateThread(function()
    while true do
        Wait(1000)

        print('Client thread running')
    end
end)

Flow คือ

CreateThread
↓
while true
↓
ทำ Logic
↓
Wait
↓
วนกลับ

แต่ควรใช้ Thread เท่าที่จำเป็น

ไม่ได้หมายความว่าทุกระบบต้องสร้าง Loop

⑬ Wait ใน Client Script สำคัญอย่างไร

Wait() ใช้ Yield Coroutine

ตัวอย่าง

Wait(1000)

คือพักประมาณ 1 วินาที

ส่วน

Wait(0)

จะ Yield จนถึง Game Tick ถัดไปโดยประมาณ และมักใช้กับ Logic ที่ต้องทำต่อเนื่องระดับ Frame/Tick เช่น Drawing บางประเภท

แต่ถ้าระบบไม่ต้องตรวจทุก Tick ไม่ควรใช้ Wait(0) โดยไม่มีเหตุผล

ตัวอย่าง

CreateThread(function()
    while true do
        Wait(1000)

        local ped = PlayerPedId()
        local coords = GetEntityCoords(ped)

        -- Logic
    end
end)

อาจประหยัดทรัพยากรกว่าการทำทุก Tick หากระบบยอมรับ Interval นี้ได้

⑭ Client Script กิน FPS ได้ไหม

ได้

ถ้า Client Resource ทำงานหนัก ผู้เล่นอาจได้รับผลกระทบด้าน Performance

ตัวอย่างปัจจัยที่ควรระวัง

  • Loop ทุก Frame จำนวนมาก

  • Native Calls จำนวนมาก

  • การค้น Entity จำนวนมาก

  • Calculation หนัก

  • NUI Update ถี่เกินไป

  • Drawing จำนวนมาก

  • Table Processing ขนาดใหญ่

  • Thread จำนวนมากเกินไป

ดังนั้น Client Script ต้อง Optimize เช่นเดียวกับ Server Script

⑮ ตัวอย่าง Loop ที่ควรระวัง

ตัวอย่างที่ไม่ควรเขียน

CreateThread(function()
    while true do
        local ped = PlayerPedId()
    end
end)

เพราะไม่มี Wait()

อย่างน้อยต้อง Yield

CreateThread(function()
    while true do
        Wait(0)

        local ped = PlayerPedId()
    end
end)

แต่การเพิ่ม Wait(0) อย่างเดียวไม่ได้หมายความว่า Script Optimize แล้ว

ต้องถามต่อว่า

จำเป็นต้องทำ Logic นี้ทุก Tick จริงหรือไม่?

ถ้าไม่จำเป็น ควรเพิ่ม Interval หรือเปลี่ยนเป็น Event-driven Design

⑯ Event-driven ดีกว่า Loop เสมอไหม

ไม่เสมอไป แต่ควรใช้เมื่อเหมาะสม

สมมติข้อมูลจะเปลี่ยนเฉพาะเมื่อมี Event

แทนที่จะทำ

ตรวจทุก Frame
ตรวจทุก Frame
ตรวจทุก Frame

อาจใช้

ข้อมูลเปลี่ยน
↓
Event
↓
Update State

ช่วยลดงานที่ไม่จำเป็น

แต่ระบบอย่าง Marker Rendering หรือ Input บางประเภทอาจต้องทำงานต่อเนื่อง

ดังนั้นต้องเลือกตามลักษณะงาน

⑰ Client Script ส่งข้อมูลไป Server อย่างไร

ใช้ Network Event

ใน Lua มักพบ

TriggerServerEvent()

ตัวอย่าง

RegisterCommand('helloServer', function()
    TriggerServerEvent(
        'example:hello'
    )
end, false)

จากนั้น Server รับ

RegisterNetEvent(
    'example:hello',
    function()
        print('Received from client')
    end
)

Flow คือ

Client
↓
TriggerServerEvent
↓
Network
↓
Server
↓
RegisterNetEvent

นี่คือพื้นฐานของ FiveM Client/Server Communication

⑱ Client ส่ง Parameter ไป Server ได้ไหม

ได้

ตัวอย่าง

TriggerServerEvent(
    'example:data',
    'hello'
)

Server

RegisterNetEvent(
    'example:data',
    function(message)
        print(message)
    end
)

แต่ต้องจำว่า Server ไม่ควรเชื่อ Parameter จาก Client โดยอัตโนมัติ

โดยเฉพาะข้อมูลสำคัญ

⑲ ทำไม Server ไม่ควรเชื่อ Client Script

เพราะ Client อยู่บนเครื่องผู้เล่น

ข้อมูลและ Logic ฝั่ง Client จึงสามารถถูกดัดแปลงหรือเลียนแบบโดย Client ที่ไม่ปลอดภัยได้

ตัวอย่างระบบที่อันตราย

Client ส่ง

TriggerServerEvent(
    'job:reward',
    1000000
)

แล้ว Server ทำ

RegisterNetEvent(
    'job:reward',
    function(amount)
        GiveMoney(source, amount)
    end
)

นี่เป็น Design ที่ไม่ดี

เพราะ Server เชื่อจำนวน Reward ที่ Client ส่งมาโดยตรง

⑳ Reward ควรตรวจฝั่งไหน

ข้อมูลสำคัญควรตรวจ Server-side

ตัวอย่าง Flow ที่ดีกว่า

Client
↓
แจ้งว่าทำงานเสร็จ
↓
Server
↓
ตรวจ Player
↓
ตรวจสถานะงาน
↓
ตรวจตำแหน่ง
↓
ตรวจ Cooldown
↓
Server คำนวณ Reward
↓
ให้เงิน

แทนที่จะ

Client
↓
บอก Server ว่าให้เงินเท่าไร
↓
Server เชื่อทันที

หลักนี้ใช้กับ

  • Money

  • Item

  • Weapon

  • Reward

  • Permission

  • Experience

  • Transaction

ทั้งหมด

㉑ Client Script ซ่อนไฟล์จากผู้เล่นได้ไหม

สิ่งที่ถูกส่งไปทำงานบน Client ไม่ควรถูกถือว่าเป็น Secret

ดังนั้นไม่ควรเก็บ

Database Password
API Secret
Private Key
Admin Secret

ไว้ใน Client Script

รวมถึง Shared Script ที่ถูกส่งไป Client

ข้อมูลลับต้องอยู่ Server-side หรือระบบ Secret Management ที่เหมาะสม

หลักง่าย ๆ คือ

ถ้า Client จำเป็นต้องดาวน์โหลด Code หรือข้อมูลนั้น อย่าถือว่ามันเป็นความลับ

㉒ Client Script กับ Shared Script ต่างกันอย่างไร

client_script

โหลดเฉพาะ Client

เช่น

client_script 'client.lua'

shared_script

โหลดทั้ง Client และ Server

shared_script 'config.lua'

ตัวอย่าง Config

Config = {}

Config.Shop = vector3(
    25.0,
    -1345.0,
    29.0
)

เหมาะสำหรับข้อมูลที่ทั้งสองฝั่งต้องใช้และไม่ใช่ Secret

แต่ถ้าเป็น

Database Credentials
Secret Token
Private Configuration

ไม่ควรใส่ใน Shared Script

㉓ Client Script รับ Event จาก Server อย่างไร

Server สามารถส่ง Network Event ไป Client

Server

TriggerClientEvent(
    'example:welcome',
    source
)

Client

RegisterNetEvent(
    'example:welcome',
    function()
        print('Welcome!')
    end
)

Flow คือ

Server
↓
TriggerClientEvent
↓
Network
↓
Client
↓
RegisterNetEvent

นี่คือทิศทางตรงข้ามกับ TriggerServerEvent

㉔ RegisterNetEvent ใช้ทุก Event หรือไม่

ไม่ควรใช้โดยไม่มีเหตุผล

ถ้า Event ต้องทำงานภายใน Context เดียว เช่น Client → Client ภายใน Resource/Context สามารถใช้ Local Event Pattern อย่าง

AddEventHandler()

ตามระบบ Event ที่เหมาะสม

ส่วน Event ที่ต้องข้าม Network Context เช่น

Client → Server
Server → Client

จึงใช้ Network Event

การเปิด Event ให้ Network เข้าถึงโดยไม่จำเป็นเพิ่ม Attack Surface ของระบบ

㉕ Client Script ใช้ NUI ได้ไหม

ได้ และเป็นหนึ่งในหน้าที่สำคัญของ Client Script

NUI ใช้สร้าง Interface เช่น

  • Inventory

  • Phone

  • Banking

  • HUD

  • Garage

  • Job Menu

  • MDT

  • Character Creator

Flow ตัวอย่าง

Client Script
↓
SendNUIMessage
↓
NUI JavaScript
↓
HTML/CSS
↓
UI

Client Script จึงเป็นตัวกลางระหว่าง Game Logic กับ Browser UI

㉖ SendNUIMessage ใช้อย่างไร

ตัวอย่าง Lua

SendNUIMessage({
    action = 'open',
    title = 'Garage'
})

NUI JavaScript สามารถรับ Message

แนวคิดคือ

Lua Table
↓
SendNUIMessage
↓
NUI
↓
JavaScript Event
↓
Update UI

ควรระวังไม่ส่ง NUI Message ทุก Frame หากข้อมูลไม่ได้เปลี่ยน

เพราะอาจสร้างภาระโดยไม่จำเป็น

㉗ SetNuiFocus คืออะไร

เมื่อเปิด Interface ที่ต้องใช้ Mouse หรือ Keyboard อาจต้องใช้

SetNuiFocus(true, true)

เมื่อปิด UI

SetNuiFocus(false, false)

ถ้าจัดการ Focus ผิด ผู้เล่นอาจพบปัญหา เช่น

  • ขยับตัวไม่ได้

  • Mouse ค้าง

  • UI ปิดแล้วแต่ยังควบคุมเกมไม่ได้

จึงควรมี Flow เปิดและปิด NUI ที่ชัดเจน

㉘ Client Script ใช้ Animation ได้ไหม

ได้

ระบบ Animation ส่วนใหญ่เกี่ยวข้องกับ Client

Flow ทั่วไป เช่น

เลือก Animation Dictionary
↓
Request
↓
รอโหลด
↓
เล่น Animation

Client Script ยังสามารถจัดการ

  • Scenario

  • Emote

  • Ped Task

  • Weapon Animation

  • Vehicle Interaction

ตาม Native ที่เกี่ยวข้อง

㉙ Client Script ใช้ Marker และ Blip ได้ไหม

ได้

Marker มักเป็น Visual Element ในโลกเกม

ส่วน Blip คือจุดหรือสัญลักษณ์บน Map

Client Script จึงเหมาะกับงานเหล่านี้

ตัวอย่างระบบ Shop อาจมี

Blip บนแผนที่
+
Marker หน้าร้าน
+
ตรวจระยะ Player
+
กด E
+
เปิด NUI

ทั้งหมดส่วนใหญ่เริ่มต้นจาก Client Logic

แต่ Transaction ซื้อของจริงควรส่งไป Server ตรวจอีกครั้ง

㉚ Client Script กับ Vehicle System

ระบบรถมักใช้ทั้ง Client และ Server

Client ทำ

  • หา Vehicle

  • Animation

  • Controls

  • Camera

  • Effects

  • UI

Server ทำ

  • Ownership

  • Database

  • Permission

  • Vehicle Data สำคัญ

ตัวอย่าง

Player กดเก็บรถ
↓
Client หา Vehicle
↓
Client ส่ง Request
↓
Server ตรวจ Ownership
↓
Server บันทึก Database
↓
ส่ง Result
↓
Client Update UI

นี่เป็น Architecture ที่ดีกว่าปล่อยให้ Client ตัดสิน Ownership เอง

㉛ Client Script กับ Job System

เช่นระบบส่งของ

Client อาจทำ

Marker
Blip
Animation
Vehicle
Interaction

แต่ Server ควรทำ

ตรวจ Job
ตรวจ Progress
ตรวจ Player
ตรวจ Reward
ให้เงิน

ดังนั้น Script ระบบหนึ่งแทบไม่จำเป็นต้องเป็น Client-only เสมอไป

FiveM Resource ที่ดีมักแบ่ง Responsibility ระหว่าง Client กับ Server

㉜ Client Script กับ Framework

Framework เช่น

ESX
QBCore
Qbox

มี Client API และ Event ของตัวเอง

แต่ Framework ไม่ได้เปลี่ยนหลักการพื้นฐาน

คุณยังต้องเข้าใจ

Client
Server
Event
Network
Security

หากไม่เข้าใจ FiveM Core แล้วจำเฉพาะ Framework Function เวลาเปลี่ยน Framework หรือ Debug Error จะยากมาก

㉝ Client Script สามารถใช้ State Bags ได้ไหม

ได้ตาม State Bag API และ Ownership/Replication Rules ของ FiveM

State Bags ช่วยจัดการ State ที่เกี่ยวข้องกับ

  • Player

  • Entity

  • Global State

ตัวอย่าง Concept

Vehicle
├── locked
└── fuel

Client สามารถอ่าน State ที่ Replicate มาได้ และในบางบริบทสามารถจัดการ State ตาม Ownership/Authority ที่ระบบกำหนด

แต่ข้อมูลสำคัญยังต้องออกแบบ Authority ให้ถูกฝั่ง

㉞ Client Script กับ OneSync เกี่ยวข้องกันอย่างไร

OneSync มีผลกับการ Sync

  • Player

  • Entity

  • Network State

  • Scope

  • Ownership

เมื่อ Client Script ทำงานกับ Entity ใน Server ที่มีผู้เล่นจำนวนมาก Developer ต้องเข้าใจว่า Entity ใด

  • Networked หรือไม่

  • ใครเป็น Owner

  • อยู่ใน Scope หรือไม่

  • มี Network ID อะไร

ดังนั้นเมื่อพ้นระดับพื้นฐาน การเข้าใจ OneSync จะสำคัญมากขึ้น

㉟ Client Script Debug อย่างไร

วิธีง่ายที่สุดคือเริ่มจาก Output

print('client started')

หรือ

local ped = PlayerPedId()

print('ped:', ped)

จากนั้นตรวจ F8 Console ของ Client

เวลามี Error ให้ดู

Resource
↓
File
↓
Line
↓
Error Message

ตัวอย่าง

attempt to index a nil value

แล้วค่อยตรวจ Variable ที่เกี่ยวข้อง

ไม่ควรแก้ Script แบบสุ่ม

㊱ F8 Console สำคัญกับ Client Developer อย่างไร

F8 Console ช่วยดู

  • Client Script Error

  • print() Output

  • Resource Message

  • Warning

  • Native/Runtime Error บางประเภท

ถ้า Server Console ไม่มี Error แต่ระบบของ Player ไม่ทำงาน สิ่งแรกที่ควรตรวจคือ Client Console

เพราะ Error อาจเกิดเฉพาะฝั่ง Client

㊲ Client Error กับ Server Error แยกอย่างไร

ถ้า Error เกิดใน

client.lua

โดยทั่วไปดูที่ Client/F8 Console

ถ้าเกิดใน

server.lua

ดู Server Console

แนวคิดสำคัญคือ

ระบบไม่ทำงาน
↓
ถามก่อน
↓
Logic อยู่ Client หรือ Server?

จะช่วยลดพื้นที่ในการ Debug ลงมาก

㊳ Resource Restart มีผลกับ Client Script อย่างไร

เมื่อ Restart Resource

restart my_resource

Client Resource จะถูก Stop และ Start ใหม่ตาม Resource Lifecycle

ดังนั้นควรระวัง State ที่ Client เก็บอยู่ เช่น

  • Threads

  • NUI Focus

  • Temporary Entities

  • Blips

  • Local Variables

Resource ที่ดีควรมี Cleanup ที่เหมาะสมหากสร้างสิ่งที่ต้องถูกลบเมื่อ Resource Stop

㊴ ควร Cleanup อะไรเมื่อ Client Resource หยุด

ขึ้นอยู่กับ Resource

สิ่งที่อาจต้อง Cleanup เช่น

  • NUI Focus

  • Blip

  • Camera

  • Temporary Ped

  • Temporary Object

  • Temporary Vehicle

  • Scaleform

  • Runtime State

ไม่ใช่ทุก Resource ต้องลบทุกอย่าง แต่ Developer ต้องคิดเรื่อง Resource Lifecycle ตั้งแต่เริ่มออกแบบ

㊵ Client Script ควรเก็บ Database Password หรือไม่

ไม่ควร

Client Script ถูกส่งไปยังเครื่องผู้เล่นเพื่อทำงาน

ดังนั้นข้อมูล Secret ไม่ควรอยู่ Client-side

ผิด:

client.lua
→ Database Password

ควรเป็น

Client
↓
Server Event
↓
Server
↓
Database

Database Connection ควรเกิดฝั่ง Server ผ่านระบบ Database ที่เหมาะสม

㊶ Client Script ติดต่อ MySQL โดยตรงไหม

โดย Architecture ทั่วไป ไม่ควร

ระบบควรเป็น

Client Script
↓
Server Event / Callback
↓
Server Script
↓
Database Library
↓
MySQL / MariaDB

เหตุผลคือ

  • Security

  • Credential Protection

  • Validation

  • Centralized Logic

  • Data Integrity

Client ควรร้องขอ Action ส่วน Server เป็นผู้ตรวจและจัดการ Database

㊷ อะไรไม่ควรไว้ใน Client Script

หลีกเลี่ยงการให้ Client เป็น Authority ของ

  • เงิน

  • Item

  • Reward

  • Permission

  • Admin

  • Ownership

  • Database Transaction

  • Sensitive Secrets

Client สามารถช่วยตรวจเพื่อ UX ได้

เช่นตรวจว่าผู้เล่นอยู่ใกล้ร้านหรือไม่ก่อนเปิดเมนู

แต่เมื่อซื้อจริง Server ควรตรวจระยะอีกครั้งถ้ามีผลด้าน Security/Gameplay ที่สำคัญ

㊸ ตัวอย่าง Client/Server Shop ที่ถูกแนวทาง

Client

Player เข้าใกล้ Shop
↓
กด E
↓
เปิด Menu
↓
เลือกซื้อ Water
↓
ส่ง Request ไป Server

Server

รับ Request
↓
ตรวจ Item
↓
ตรวจราคา
↓
ตรวจเงิน
↓
ตรวจ Player State
↓
หักเงิน
↓
เพิ่ม Item
↓
ส่ง Result กลับ

Client มีหน้าที่ UX

Server มีหน้าที่ Authority

นี่เป็นแนวคิดสำคัญมากในการออกแบบ FiveM Script

㊹ Client Script ใช้กับ Lua JavaScript C# เลือกอะไร

หลักง่าย ๆ คือ

มือใหม่
→ Lua

Web Developer
→ JavaScript / TypeScript

.NET Developer
→ C#

ไม่ว่าภาษาใด Concept ของ Client Script ยังเหมือนเดิม

คือ Code ถูกโหลดและทำงานใน Client Context ของผู้เล่น

㊺ Checklist ก่อนเขียน Client Script

ก่อนเพิ่ม Logic ใหม่ ลองถามว่า

① ต้องทำบน Client จริงหรือไม่
② Native ตัวนี้เป็น Client API หรือไม่
③ ต้องทำทุก Tick หรือไม่
④ ใช้ Event แทน Loop ได้หรือไม่
⑤ มีข้อมูลลับหรือไม่
⑥ Client กำลังตัดสิน Reward หรือไม่
⑦ Server Validate ข้อมูลหรือยัง
⑧ NUI Update ถี่เกินไปหรือไม่
⑨ Resource Stop แล้ว Cleanup หรือไม่
⑩ ดู F8 Error แล้วหรือยัง

Checklist นี้ช่วยป้องกันปัญหาหลายอย่างตั้งแต่ก่อน Resource โตขึ้น

คำถามที่พบบ่อยเกี่ยวกับ Client Script FiveM

Client Script FiveM คืออะไร

คือ Script ที่ถูกโหลดและทำงานบน FiveM Client ของผู้เล่นแต่ละคน

Client Script ใช้ทำอะไร

มักใช้จัดการ Ped, Vehicle, Marker, Blip, Controls, Animation, Camera, NUI และ Gameplay Interaction

Client Script เขียนด้วยภาษาอะไร

FiveM รองรับ Lua, JavaScript และ C# สำหรับ Client Scripting ตาม Runtime ที่เกี่ยวข้อง

client.lua ต้องชื่อแบบนี้ไหม

ไม่จำเป็น สามารถตั้งชื่ออื่นได้ ตราบใดที่ระบุไว้ใน fxmanifest.lua

Client Script เชื่อม Database โดยตรงได้ไหม

Architecture ที่เหมาะสมควรให้ Client ติดต่อ Server แล้ว Server เป็นผู้จัดการ Database

Client Script ให้เงิน Player ได้ไหม

ไม่ควรใช้ Client เป็น Authority สำหรับเงินหรือ Reward สำคัญ ควรให้ Server ตรวจและดำเนินการ

Client Script ใช้ Native ได้ไหม

ได้ และ Native จำนวนมากที่เกี่ยวข้องกับ GTA V Gameplay ถูกใช้งานจาก Client

Client Script ใช้ NUI ได้ไหม

ได้ Client Script เป็นตัวกลางสำคัญในการส่งข้อมูลเข้า NUI และรับ Callback กลับ

Client Script ทำให้ FPS ตกได้ไหม

ได้ หากมี Loop, Native Calls, Drawing หรือ NUI Processing มากเกินไป

Client Script กับ Server Script ต่างกันอย่างไร

Client Script ทำงานบนเครื่องผู้เล่น ส่วน Server Script ทำงานบน FXServer และควรเป็น Authority ของข้อมูลสำคัญหลายประเภท

สรุป Client Script FiveM คืออะไร

Client Script FiveM คือ Script ที่ FiveM โหลดไปทำงานบนเครื่องผู้เล่นแต่ละคน และเป็นส่วนสำคัญของระบบ Gameplay ที่ต้องติดต่อกับ GTA V Client

งานที่เหมาะกับ Client เช่น

Ped
Vehicle
Coordinates
Marker
Blip
Animation
Camera
Controls
NUI
Gameplay Interaction

ส่วนข้อมูลสำคัญ เช่น

Money
Items
Rewards
Permissions
Database
Transactions

ควรมี Server-side Authority และ Validation ที่เหมาะสม

โครงสร้างที่ควรจำคือ

Player
↓
Client Script
↓
Gameplay / UI
↓
Request
↓
Server Script
↓
Validation
↓
Business Logic
↓
Database

สำหรับผู้ที่กำลังเรียน FiveM Developer กับ comsiam การเข้าใจ Client Script ให้แน่นก่อนจะช่วยให้หัวข้อ Event, Native, Entity, NUI และ OneSync หลังจากนี้ง่ายขึ้นมาก

อย่ามอง Client Script เป็นเพียงไฟล์ client.lua แต่ให้มองว่าเป็น หนึ่งใน Execution Context หลักของ FiveM ที่ต้องออกแบบร่วมกับ Server อย่างถูกต้อง ทั้งด้าน Performance และ Security ซึ่งบทความต่อไปของ comsiam จะต่อด้วย Server Script FiveM โดยตรง

Comments

Popular posts from this blog

FiveM ยังน่าเล่นไหม? Enhanced เปลี่ยน FiveM แค่ไหน

FiveM คืออะไร เล่นอย่างไร สำหรับมือใหม่ เริ่มต้นตั้งแต่ศูนย์

วิธีตั้ง Admin Permission ด้วย add_ace และ add_principal FiveM แบบละเอียด