FiveM Resource คืออะไร? พื้นฐาน Script, fxmanifest.lua และโครงสร้าง Resource

 FiveM Resource คือชุดของไฟล์ที่รวมกันเป็นหนึ่งระบบหรือหนึ่งฟีเจอร์ของ FiveM Server และสามารถ Start, Stop หรือ Restart แยกจาก Resource อื่นได้ เช่น ระบบ Garage, Inventory, Jobs, HUD, Vehicles, Maps หรือ Scripts ต่าง ๆ

ตัวอย่าง Resource หนึ่งตัวอาจมีโครงสร้าง

my_resource/
├── fxmanifest.lua
├── client.lua
├── server.lua
├── config.lua
└── html/

FiveM จะมอง Folder นี้เป็น Resource ได้เมื่อมีไฟล์ Manifest ที่ถูกต้อง เช่น

fxmanifest.lua

ตัวอย่าง Manifest พื้นฐาน

fx_version 'cerulean'
game 'gta5'

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

จากนั้น Resource สามารถเปิดผ่าน server.cfg

ensure my_resource

เมื่อเข้าใจ Resource แล้ว คุณจะเข้าใจโครงสร้างของ FiveM Script แทบทุกตัว เพราะไม่ว่าจะเป็น ESX, QBCore, Qbox, ox_lib, ox_inventory หรือ Script ที่เขียนเอง ต่างก็ถูกโหลดเข้าสู่ FXServer ผ่านระบบ Resource

① FiveM Resource คืออะไร

Resource คือ Folder ที่รวม Files สำหรับ Feature หนึ่งของ Server

Cfx.re อธิบายว่า Resource เป็น Collection of Files ซึ่งอาจประกอบด้วย

Client Scripts
Server Scripts
Streaming Assets
NUI
Configuration
Metadata

และ Resource สามารถ

Start
Stop
Restart

ได้อย่างอิสระ

ตัวอย่าง

ox_inventory

เป็น Resource หนึ่ง

my_garage

ก็เป็นอีก Resource

police_job

ก็เป็น Resource แยกอีกตัว

② Resource ต่างจาก Script อย่างไร

คำว่า Script มักถูกใช้กว้าง ๆ เพื่อหมายถึงระบบที่เราเขียน

แต่ใน FiveM โครงสร้างจริงมักเป็น

Resource
↓
ประกอบด้วย Scripts หลายไฟล์

ตัวอย่าง

garage/
├── fxmanifest.lua
├── client/
│   ├── main.lua
│   └── menu.lua
├── server/
│   ├── main.lua
│   └── database.lua
└── shared/
    └── config.lua

ทั้งหมดนี้คือ Resource เดียว

แต่มี Scripts หลายไฟล์

③ Resource อยู่ที่ไหน

โดยทั่วไป FXServer จะโหลด Resources จาก Folder

resources/

ภายใน Server Data Directory

ตัวอย่าง

server-data/
└── resources/

ข้างในอาจเป็น

resources/
├── [local]
├── [standalone]
├── [esx]
├── [qb]
└── [maps]

Folder ที่อยู่ในวงเล็บเหลี่ยมมักใช้เป็น Category

④ Folder [local] คืออะไร

เป็นรูปแบบ Category Folder ที่นิยมใช้สำหรับ Resource ที่เราเขียนเอง

ตัวอย่าง

resources/
└── [local]/
    ├── my_garage/
    ├── my_job/
    └── my_hud/

แต่ [local] ไม่ใช่ชื่อบังคับ

คุณสามารถตั้ง Category เป็น

[core]
[jobs]
[vehicles]
[maps]
[scripts]

ได้ตามการจัดระเบียบ Server

⑤ Folder ที่มี [ ] เป็น Resource ไหม

Folder Category ที่อยู่ในวงเล็บเหลี่ยมไม่ได้ถูกมองเป็น Resource แบบ Folder ลูกโดยตรง

เช่น

[jobs]/
├── police/
└── ambulance/

Resources จริงคือ

police
ambulance

โดยแต่ละ Resource ต้องมี Manifest ของตัวเอง

⑥ Resource จำเป็นต้องมี fxmanifest.lua ไหม

Resource ปัจจุบันควรมี

fxmanifest.lua

อยู่ใน Root Folder ของ Resource

เช่น

my_resource/
├── fxmanifest.lua
├── client.lua
└── server.lua

หากไม่มี Manifest FiveM จะไม่สามารถ Parse Folder นั้นเป็น Resource ปกติได้

⑦ fxmanifest.lua คืออะไร

fxmanifest.lua คือ Resource Manifest

มันบอก FiveM ว่า Resource นี้

ใช้ FX Version อะไร
รองรับเกมอะไร
โหลด Client Script อะไร
โหลด Server Script อะไร
โหลด Shared Script อะไร
มี Dependencies อะไร
มี Files อะไร
ใช้ NUI หรือไม่

ตัวอย่าง

fx_version 'cerulean'
game 'gta5'

author 'comsiam'
description 'Example FiveM resource'
version '1.0.0'

client_script 'client.lua'
server_script 'server.lua'

⑧ fxmanifest.lua เป็น Lua Script ปกติไหม

Manifest ใช้ Syntax แบบ Lua แต่ Cfx.re ระบุว่ามันถูก Run ใน Runtime แยกจาก Lua Scripts ของ Resource

ดังนั้นอย่าคิดว่า Variable ที่ประกาศใน fxmanifest.lua

local test = 10

จะกลายเป็น Variable ที่ client.lua หรือ server.lua ใช้ร่วมกันได้โดยอัตโนมัติ

Manifest มีหน้าที่หลักในการประกาศ Metadata และ Resource Configuration

⑨ fx_version คืออะไร

ตัวอย่าง

fx_version 'cerulean'

กำหนด Feature Set ของ Resource Manifest

เอกสาร Cfx.re ปัจจุบันระบุ cerulean เป็น FXv2 Resource Version ปัจจุบันที่ใช้ทั่วไป

หัวข้อ 444 จะอธิบาย cerulean โดยละเอียดอีกครั้ง

⑩ game 'gta5' คืออะไร

สำหรับ FiveM ใช้

game 'gta5'

เพื่อระบุว่า Resource รองรับ GTA V/FiveM APIs

ตัวอย่าง Manifest ขั้นต่ำที่พบได้บ่อย

fx_version 'cerulean'
game 'gta5'

จากนั้นเพิ่ม Scripts ที่ Resource ต้องใช้

⑪ Client Script คืออะไร

Client Script คือ Code ที่ทำงานบนเครื่องของ Player

ตัวอย่าง Manifest

client_script 'client.lua'

client.lua

RegisterCommand(
    'coords',
    function()

        local ped =
            PlayerPedId()

        local coords =
            GetEntityCoords(ped)

        print(coords)

    end,
    false
)

Logic นี้ใช้ Game Client APIs จึงเหมาะกับ Client

⑫ Server Script คืออะไร

Server Script ทำงานบน FXServer

Manifest

server_script 'server.lua'

ตัวอย่าง

RegisterNetEvent(
    'example:test',
    function()

        local src =
            source

        print(
            'Player:',
            src
        )

    end
)

Server Script เหมาะกับ

Permissions
Database
Money
Inventory
Server Validation
Global State

⑬ Shared Script คืออะไร

Shared Script ถูกโหลดทั้ง Client และ Server

Manifest

shared_script 'config.lua'

เช่น

Config = {}

Config.MaxDistance = 5.0
Config.JobName = 'police'

Client และ Server ต่างโหลด Configuration นี้ได้

แต่ไม่ได้แชร์ Memory เดียวกัน

⑭ Shared Script ไม่ได้หมายถึง Shared Memory

นี่เป็นจุดที่มือใหม่สับสนมาก

สมมติ config.lua

Counter = 0

Client เปลี่ยน

Counter = 100

Server จะไม่ได้เห็นเป็น 100 โดยอัตโนมัติ

เพราะ Client Runtime กับ Server Runtime แยกกัน

ถ้าต้อง Synchronize State ต้องใช้ระบบอื่น เช่น

Network Events
Callbacks
State Bags
Database

ตาม Use Case

⑮ client_scripts คืออะไร

ถ้ามีหลาย Client Files สามารถใช้

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

แทนเขียน client_script ทีละบรรทัด

เหมาะกับ Resource ที่เริ่มใหญ่ขึ้น

⑯ server_scripts คืออะไร

เช่นเดียวกัน

server_scripts {
    'server/main.lua',
    'server/database.lua',
    'server/commands.lua'
}

FiveM จะโหลด Files ตาม Manifest Entries

การแยก File ตามหน้าที่ช่วยให้ Maintain Resource ง่ายขึ้น

⑰ shared_scripts คืออะไร

ตัวอย่าง

shared_scripts {
    'shared/config.lua',
    'shared/constants.lua',
    'shared/utils.lua'
}

ควรใส่เฉพาะ Code ที่สามารถ Run ได้ทั้งสอง Context

อย่าใส่ Server-only Code เช่น Database Credentials ลง Shared Script

⑱ Manifest รองรับ Wildcard ไหม

รองรับ Globbing สำหรับ Entries หลายชนิด

ตัวอย่าง

client_scripts {
    'client/*.lua'
}

จะโหลด .lua ใน Folder นั้นแบบไม่ Recursive ตาม Pattern

ถ้าต้องการ Recursive สามารถพบ Pattern เช่น

client_scripts {
    'client/**/*.lua'
}

แต่ Resource ใหญ่ควรคำนึงถึง Load Order ด้วย

⑲ ทำไม Wildcard ต้องระวัง

สมมติมี

client/
├── config.lua
├── main.lua
└── menu.lua

ถ้า main.lua ต้องใช้ Function จากไฟล์หนึ่งก่อน แต่คุณพึ่ง Pattern กว้างโดยไม่รู้ Order อาจเกิด

attempt to call a nil value

Resource สำคัญจึงควรจัด Dependency/Initialization ให้ชัด

ไม่ควรพึ่งชื่อไฟล์โดยไม่เข้าใจ Load Order

⑳ Resource Name คืออะไร

โดยทั่วไปชื่อ Folder Resource คือชื่อที่ใช้กับ Commands และ Exports

ตัวอย่าง Folder

my_garage

Start ด้วย

ensure my_garage

และ Export อาจเรียก

exports['my_garage']:GetVehicle(...)

ดังนั้นชื่อ Resource เป็นส่วนสำคัญของ Public API

㉑ เปลี่ยนชื่อ Resource ได้ไหม

ได้ในหลายกรณี แต่ต้องระวัง Resource อื่นอ้างชื่อเดิม

เช่น

exports['old_name']:Function()

หรือ Manifest มี

dependency 'old_name'

เมื่อเปลี่ยน Folder เป็น

new_name

Dependencies/Exports/Config อาจพัง

จึงไม่ควร Rename Resource แบบสุ่มบน Production Server

㉒ Resource Category Start พร้อมกันได้ไหม

เอกสาร Server Commands ระบุว่าสามารถ Start Category ได้

เช่น

start [cars]

หรือใช้คำสั่ง Resource ที่รองรับ Category

ช่วยให้เปิด Resource หลายตัวภายใต้ Category เดียวได้

อย่างไรก็ตาม Production server.cfg ควรจัดลำดับ Dependency ให้ชัดเจน

㉓ start Resource คืออะไร

คำสั่ง

start my_resource

ใช้ Start Resource หาก Resource อยู่ในสถานะ Stopped

สามารถสั่งจาก Server Console หรือใส่ใน Configuration ได้

ตัวอย่าง

start my_garage

㉔ stop Resource คืออะไร

ใช้

stop my_resource

เพื่อ Stop Resource ที่กำลังทำงาน

ตัวอย่าง

stop my_garage

เมื่อ Stop

Client Scripts หยุด
Server Scripts หยุด
Resource Runtime ถูกปิด

และ Resource ควร Cleanup State ที่จำเป็น

㉕ restart Resource คืออะไร

ใช้

restart my_resource

เพื่อ Restart Resource หาก Resource กำลัง Start อยู่

Concept

Stop
↓
Start ใหม่

เหมาะตอนแก้ Script แล้วต้องการ Reload Resource โดยไม่ Restart FXServer ทั้ง Server

㉖ ensure คืออะไร

ensure เป็นคำสั่งที่นิยมมากใน server.cfg

ensure my_resource

เอกสาร Cfx.re ปัจจุบันระบุว่า

ถ้า Resource ยังไม่ Start
→ Start

ถ้า Resource Start อยู่แล้ว
→ Restart

จึงสะดวกกว่าการใช้ start ในหลายสถานการณ์

㉗ start กับ ensure ต่างกันอย่างไร

จำง่าย ๆ

start
→ Start ถ้ายัง Stopped
ensure
→ Start ถ้ายังไม่ทำงาน
→ Restart ถ้ากำลังทำงาน

ดังนั้นใน server.cfg มักพบ

ensure ox_lib
ensure oxmysql
ensure my_core
ensure my_garage

㉘ restart กับ ensure ต่างกันอย่างไร

restart

Resource ต้องกำลัง Started
→ Restart

ส่วน ensure

Stopped
→ Start

Started
→ Restart

ดังนั้น ensure ยืดหยุ่นกว่าในการ Apply Desired State ว่า Resource ต้องทำงาน

㉙ refresh คืออะไร

เมื่อเพิ่ม Resource Folder ใหม่ขณะ FXServer กำลังทำงาน Server อาจยังไม่รู้จัก Resource

ใช้

refresh

เพื่อ Scan resources ใหม่และโหลด Resource Manifests

จากนั้น

ensure my_new_resource

ได้

㉚ ตัวอย่างเพิ่ม Resource ใหม่โดยไม่ Restart Server

สมมติ Copy Folder

resources/[local]/my_test

เข้า Server ขณะรันอยู่

ใน Console ใช้

refresh

แล้ว

ensure my_test

ถ้า Manifest ถูกต้อง Resource จะเริ่มทำงานได้

㉛ ทำไม Resource ขึ้น Couldn't find resource

ตรวจ

ชื่อ Folder ถูกไหม?
อยู่ resources/ จริงไหม?
ใช้ refresh หรือยัง?
ชื่อใน ensure ตรงไหม?

เช่น Folder

my_garage

แต่ Config เขียน

ensure my-garage

ถือว่าเป็นคนละชื่อ

㉜ Resource ไม่มี Manifest จะเกิดอะไร

FiveM สามารถแสดง Warning ว่า Resource ไม่มี Resource Manifest

เช่น

does not have a resource manifest

ตรวจว่าไฟล์ชื่อ

fxmanifest.lua

จริง

ไม่ใช่บน Windows กลายเป็น

fxmanifest.lua.txt

โดยไม่รู้ตัว

㉝ __resource.lua คืออะไร

ก่อน fxmanifest.lua FiveM ใช้

__resource.lua

Resource เก่ายังอาจพบไฟล์นี้

แต่เอกสารปัจจุบันระบุว่าเป็นรูปแบบเก่าและควรย้ายไปใช้ fxmanifest.lua

หัวข้อ 445 จะเปรียบเทียบสองแบบโดยละเอียด

㉞ lua54 'yes' ยังต้องใส่ไหม

ไม่จำเป็นแล้ว

เอกสาร Resource Manifest ปัจจุบันระบุว่า

lua54 'yes'

ถูก Deprecated

ตั้งแต่เดือนมิถุนายน 2025 Lua 5.3 ถูก Deprecated และ Lua Scripts ทั้งหมดใช้ Lua 5.4 แล้ว

ดังนั้น Resource ใหม่ไม่ต้องเพิ่มบรรทัดนี้เพื่อเปิด Lua 5.4

㉟ Resource เขียนด้วย JavaScript ได้ไหม

ได้

Manifest

client_script 'client.js'
server_script 'server.js'

FiveM เลือก Runtime จากนามสกุลไฟล์

.js ใช้ JavaScript Runtime ที่เกี่ยวข้อง

Resource เดียวสามารถมี Files หลายภาษาได้ในบาง Architecture แต่ควรทำเมื่อมีเหตุผล

㊱ Resource เขียนด้วย C# ได้ไหม

ได้

C# Resource ใช้ CitizenFX .NET Assemblies ตาม Runtime ที่รองรับ

Manifest ยังคงใช้

fxmanifest.lua

แม้ Main Script จะเขียนด้วย C#

ดังนั้น Manifest เป็นส่วนกลางของ Resource ไม่ได้ขึ้นกับภาษาหลัก

㊲ Resource มี NUI ได้ไหม

ได้

ตัวอย่าง

ui_page 'html/index.html'

files {
    'html/index.html',
    'html/style.css',
    'html/app.js'
}

Resource สามารถมี HTML/CSS/JavaScript สำหรับ UI

เช่น

HUD
Inventory
Phone
Menu
Garage UI
Character Selection

หัวข้อ 456 จะลงรายละเอียด FiveM NUI โดยเฉพาะ

㊳ files ใน Manifest คืออะไร

files ใช้เพิ่ม Files เข้า Resource Packfile สำหรับให้ Client ดาวน์โหลดตาม Resource

ตัวอย่าง

files {
    'html/index.html',
    'html/style.css',
    'html/app.js'
}

เหมาะกับ

  • NUI Assets

  • Images

  • Data Files

  • Client-required Files

ไม่จำเป็นต้องใส่ Server-only Secret Files ให้ Client ดาวน์โหลด

㊴ server_only คืออะไร

Manifest รองรับ

server_only 'yes'

Cfx.re ระบุว่า Resource ที่ Mark server_only จะไม่ให้ Clients ดาวน์โหลด Content ของ Resource นั้น

เหมาะกับ Resource ที่ทำงานเฉพาะ Server และไม่มี Client Files

แต่อย่ามองเป็นระบบซ่อน Secret ที่แทน Security Architecture ทุกอย่าง

㊵ Resource มี Stream Folder ได้ไหม

ได้

Resource สำหรับ Vehicles, Models, Maps, Clothing หรือ Assets มักมี

stream/

ตัวอย่าง

my_vehicle/
├── fxmanifest.lua
└── stream/
    ├── vehicle.yft
    └── vehicle.ytd

Files ใน stream ใช้กับ Streaming Assets ตามประเภท

㊶ Map ก็เป็น Resource ได้ไหม

ได้

Map Resource ก็ยังอยู่ภายใต้ Resource System

ตัวอย่าง

my_map/
├── fxmanifest.lua
└── stream/
    └── city.ymap

Manifest อาจมี Metadata ที่เกี่ยวข้องกับ Map

ดังนั้นคำว่า Resource ไม่ได้หมายถึง Lua Script เท่านั้น

㊷ Vehicle Pack ก็เป็น Resource ได้ไหม

ได้

Vehicle Resource อาจประกอบด้วย

stream/
vehicle.meta
handling.meta
carcols.meta
carvariations.meta
fxmanifest.lua

แล้วใช้ files และ data_file ใน Manifest

ดังนั้น Resource สามารถเป็นทั้ง Code และ Game Assets

㊸ Resource Dependency คืออะไร

Resource หนึ่งสามารถต้องการอีก Resource ก่อนตัวเอง

ตัวอย่าง Garage ต้องใช้

oxmysql
ox_lib

Manifest สามารถระบุ

dependencies {
    'oxmysql',
    'ox_lib'
}

Cfx.re ระบุว่า Dependency Resource จะต้อง Load ก่อน Resource ปัจจุบัน

หัวข้อ 448 จะลงรายละเอียด Dependency โดยเฉพาะ

㊹ ทำไม Start Order สำคัญ

สมมติ my_garage เรียก

exports.oxmysql:query(...)

แต่ oxmysql ยังไม่ Start

อาจเกิด Error

ดังนั้น server.cfg

ensure oxmysql
ensure my_garage

ควรเรียง Dependency ก่อน

และ Manifest Dependency ช่วยประกาศ Requirement เพิ่มอีกชั้น

㊺ อย่าแก้ Start Order ด้วย Wait แบบสุ่ม

ไม่ควรทำ

Wait(10000)

แล้วหวังว่า Dependency จะ Start เสร็จ

ควรใช้

Manifest Dependency
Resource Lifecycle
Exports
Proper Initialization

ให้ถูกต้อง

Wait() ไม่ใช่ Dependency Manager

㊻ Resource Lifecycle คืออะไร

Resource มีวงจรชีวิตประมาณ

Discovered
↓
Started
↓
Running
↓
Stopped

และสามารถ

Restart

กลับเข้าสู่ Running State ใหม่

Resource ที่ดีควรออกแบบ Initialization และ Cleanup ให้รองรับ Lifecycle นี้

㊼ onResourceStart คืออะไร

FiveM มี Resource Lifecycle Event

เช่น

AddEventHandler(
    'onResourceStart',
    function(resourceName)

        if resourceName ~=
            GetCurrentResourceName() then
            return
        end

        print(
            'Resource started'
        )
    end
)

ใช้สำหรับ Logic ที่ต้องทำเมื่อ Resource Start

เช่น

Initialize Cache
Register Runtime State
Load Database Data
Start Service

ตาม Architecture

㊽ onResourceStop สำคัญไหม

สำคัญมากสำหรับ Cleanup

ตัวอย่าง

AddEventHandler(
    'onResourceStop',
    function(resourceName)

        if resourceName ~=
            GetCurrentResourceName() then
            return
        end

        -- cleanup
    end
)

Resource ที่สร้าง Temporary Entities, Threads หรือ Runtime State ควรคิดว่าเมื่อ Resource Stop จะเกิดอะไรขึ้น

㊾ Client Resource Stop ต้อง Cleanup อะไร

ตัวอย่าง Resource สร้าง

Local Ped
Temporary Vehicle
NUI Focus
Blip
Marker State
Camera

เมื่อ Resource Stop อาจต้อง

Delete Entity
Remove Blip
Destroy Camera
Release Focus
Reset Player State

เพื่อไม่ทิ้ง Side Effects

㊿ Server Resource Stop ต้อง Cleanup อะไร

เช่น

Temporary Server Entities
Mission State
Timers
Cache
Handlers
Runtime Locks

บาง State อาจหายเองพร้อม Runtime

แต่ External Effects เช่น Database Transaction หรือ Entity ที่ถูกสร้างไว้ควรออกแบบ Cleanup ให้ชัด

51 Resource Restart มีผลกับ Local Variables อย่างไร

เมื่อ Resource Restart Runtime ใหม่จะถูกสร้าง

เช่น

local vehicles = {}

ข้อมูลใน Table นี้จะหาย

ถ้าต้องการข้อมูลคงอยู่หลัง Resource Restart ต้องใช้ Source of Truth อื่น เช่น

Database
KVP
Persistent Storage
Framework State

ตาม Requirement

52 Resource Restart ต่างจาก Server Restart อย่างไร

Resource Restart

หยุด Resource ตัวเดียว
↓
Start Resource นั้นใหม่

FXServer และ Resource อื่นยังทำงาน

Server Restart

FXServer ปิด
↓
Resources ทั้งหมดหยุด
↓
Server เริ่มใหม่

ผลกระทบกว้างกว่ามาก

53 Resource Name หาใน Script อย่างไร

ใช้

GetCurrentResourceName()

เช่น

local resourceName =
    GetCurrentResourceName()

print(resourceName)

มีประโยชน์กับ

  • Logs

  • Lifecycle Events

  • Debugging

  • Dynamic Resource Code

54 Resource สามารถเรียก Resource อื่นได้อย่างไร

วิธีหลักมีหลายแบบ

Exports
Events
Callbacks
State Bags

ตัวอย่าง Export

exports['my_core']:GetPlayer(...)

ควรสร้าง Public API ที่ชัดเจนแทนให้ Resource เข้าไปแก้ Local State ของ Resource อื่นโดยตรง

55 Resource ไม่ควรเข้าถึง File ภายใน Resource อื่นมั่ว ๆ

Architecture ที่ดีควรมี Boundary

เช่น

garage
↓
เรียก inventory export

แทน

garage
↓
ไปแก้ Table ภายใน inventory โดยตรง

Resource Isolation ช่วยให้

  • Update ง่าย

  • Debug ง่าย

  • Replace Dependency ง่าย

  • ลด Coupling

56 Resource หนึ่งควรทำทุกอย่างไหม

ไม่ควรสร้าง Resource เดียวขนาดใหญ่เกินไปแบบ

server.lua
20,000 lines

แล้วรวม

Jobs
Garage
Inventory
Banking
Housing
Phone

ทุกอย่างไว้ด้วยกันโดยไม่มี Boundary

แต่ก็ไม่จำเป็นต้องแตก Resource เล็กจนทุก Function เป็น Resource แยก

เลือก Boundary ตาม Domain และ Dependency

57 โครงสร้าง Resource ที่อ่านง่าย

ตัวอย่าง

my_garage/
├── fxmanifest.lua
├── shared/
│   ├── config.lua
│   └── constants.lua
├── client/
│   ├── main.lua
│   └── ui.lua
├── server/
│   ├── main.lua
│   └── database.lua
└── html/
    ├── index.html
    ├── app.js
    └── style.css

Manifest

fx_version 'cerulean'
game 'gta5'

shared_scripts {
    'shared/config.lua',
    'shared/constants.lua'
}

client_scripts {
    'client/main.lua',
    'client/ui.lua'
}

server_scripts {
    'server/main.lua',
    'server/database.lua'
}

ui_page 'html/index.html'

files {
    'html/index.html',
    'html/app.js',
    'html/style.css'
}

โครงสร้างแบบนี้เข้าใจง่ายและขยายต่อได้

58 วิธี Debug Resource ไม่ Start

ตรวจตามลำดับ

① Folder อยู่ resources หรือไม่?
② มี fxmanifest.lua หรือไม่?
③ ชื่อ File ถูกต้องหรือไม่?
④ Manifest Syntax ถูกหรือไม่?
⑤ fx_version ถูกหรือไม่?
⑥ game 'gta5' มีหรือไม่?
⑦ client/server script path ถูกหรือไม่?
⑧ Dependency Start หรือยัง?
⑨ ใช้ refresh หลังเพิ่ม Resource หรือยัง?
⑩ ensure ชื่อ Resource ตรง Folder หรือไม่?
⑪ Server Console แจ้ง Error อะไร?
⑫ Lua/JS/C# Runtime มี Error หรือไม่?

อย่าแก้โดย Restart Server ซ้ำโดยไม่อ่าน Error

59 Checklist ก่อนทำ FiveM Resource

ตรวจอย่างน้อย

① Resource มีหน้าที่อะไร?
② ชื่อ Resource สั้นและชัดไหม?
③ fxmanifest.lua อยู่ Root หรือไม่?
④ ใช้ fx_version cerulean หรือไม่?
⑤ game gta5 ถูกต้องหรือไม่?
⑥ อะไรควรอยู่ Client?
⑦ อะไรควรอยู่ Server?
⑧ อะไรควรเป็น Shared?
⑨ มี Secret ใน Shared/Client หรือไม่?
⑩ Scripts แยก Folder ชัดหรือไม่?
⑪ Load Order ถูกหรือไม่?
⑫ Dependencies ถูกประกาศหรือไม่?
⑬ Resource ต้องใช้ OneSync หรือไม่?
⑭ Resource ต้องใช้ Database หรือไม่?
⑮ Resource มี NUI หรือไม่?
⑯ NUI Files ถูกประกาศหรือไม่?
⑰ มี Streaming Assets หรือไม่?
⑱ มี Cleanup ตอน Resource Stop หรือไม่?
⑲ Restart Resource แล้ว State พังหรือไม่?
⑳ Temporary Entities ถูก Delete หรือไม่?
㉑ Exports/Public API ชัดเจนหรือไม่?
㉒ Resource Name ถูก Hardcode ที่ไหนบ้าง?
㉓ server.cfg ใช้ ensure ถูกหรือไม่?
㉔ เพิ่ม Resource ใหม่แล้ว refresh หรือยัง?

⑥⓪ ตัวอย่าง FiveM Resource ตัวแรกแบบสมบูรณ์

สร้าง Folder

resources/
└── [local]/
    └── com_example/
        ├── fxmanifest.lua
        ├── config.lua
        ├── client.lua
        └── server.lua

fxmanifest.lua

fx_version 'cerulean'
game 'gta5'

author 'comsiam'
description 'Example FiveM resource'
version '1.0.0'

shared_script 'config.lua'

client_script 'client.lua'

server_script 'server.lua'

config.lua

Config = {}

Config.CommandName =
    'helloresource'

client.lua

RegisterCommand(
    Config.CommandName,
    function()

        TriggerServerEvent(
            'com_example:hello'
        )

    end,
    false
)

server.lua

RegisterNetEvent(
    'com_example:hello',
    function()

        local src =
            source

        local playerName =
            GetPlayerName(src)

        print(
            ('Hello from %s')
            :format(
                playerName
                or src
            )
        )

        TriggerClientEvent(
            'com_example:response',
            src,
            'Resource is working'
        )

    end
)

เพิ่ม Client Event

RegisterNetEvent(
    'com_example:response',
    function(message)

        print(message)

    end
)

จากนั้นใน server.cfg

ensure com_example

หรือถ้าเพิ่ง Copy Resource เข้ามาระหว่าง Server กำลังทำงาน

refresh
ensure com_example

Flow ทั้งหมดคือ

FXServer
↓
resources/
↓
พบ com_example
↓
อ่าน fxmanifest.lua
↓
โหลด config.lua
↓
โหลด client.lua
↓
โหลด server.lua
↓
Resource Running
↓
Player ใช้ /helloresource
↓
Client Event
↓
Server
↓
Response

นี่คือพื้นฐาน Resource Architecture ของ FiveM

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

FiveM Resource คืออะไร

คือชุด Files สำหรับ Feature หนึ่งของ FiveM Server ซึ่งสามารถ Start, Stop และ Restart แยกจาก Resource อื่นได้

Resource อยู่ Folder ไหน

โดยทั่วไปอยู่ใน

resources/

ของ Server Data Directory

Resource ต้องมีไฟล์อะไร

Resource ปัจจุบันควรมี

fxmanifest.lua

เพื่อให้ FiveM Parse Resource ได้

fxmanifest.lua คืออะไร

คือ Manifest ที่ระบุ Metadata, Client Scripts, Server Scripts, Shared Scripts, Files, Dependencies และ Resource Configuration

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

บน FiveM Client ของ Player

Server Script ทำงานที่ไหน

บน FXServer

Shared Script ทำงานที่ไหน

โหลดทั้ง Client และ Server แต่ Runtime Memory แยกกัน

Resource เขียน Lua อย่างเดียวไหม

ไม่ สามารถใช้ JavaScript และ C# ตาม Runtime ที่รองรับได้

Manifest ยังต้องเป็น Lua ไหม

ใช่ fxmanifest.lua ใช้ Manifest Syntax แบบ Lua แม้ Resource หลักเขียน JS หรือ C#

Resource มี HTML ได้ไหม

ได้ผ่าน NUI และ ui_page/files

Resource มีรถหรือ Map ได้ไหม

ได้ Resources สามารถมี Streaming Assets และ Data Files ได้

ensure คืออะไร

ถ้า Resource ยังไม่ทำงานจะ Start และถ้ากำลังทำงานอยู่จะ Restart

start ต่างจาก ensure อย่างไร

start Start Resource ที่ Stopped ส่วน ensure ทำให้ Resource อยู่ในสถานะ Started และจะ Restart หากกำลัง Started อยู่

stop คืออะไร

หยุด Resource

restart คืออะไร

Restart Resource ที่กำลัง Started อยู่

refresh คืออะไร

Scan Folder Resources และ Resource Manifests ใหม่ เพื่อให้ FXServer รู้จัก Resource ที่เพิ่งเพิ่ม

เพิ่ม Resource ใหม่ต้อง Restart Server ไหม

ไม่จำเป็นเสมอไป สามารถใช้ refresh แล้ว ensure resource_name ได้ในหลายกรณี

__resource.lua ยังใช้ได้ไหม

อาจพบใน Resource เก่า แต่ปัจจุบันควรใช้ fxmanifest.lua

lua54 'yes' ต้องใส่ไหม

ไม่ เอกสาร Cfx.re ปัจจุบันระบุว่า Deprecated และ Lua Scripts ใช้ Lua 5.4 แล้ว

Dependency คืออะไร

Resource ที่ต้อง Load ก่อน Resource ปัจจุบัน เช่น Core หรือ Library

Manifest กำหนด Dependency ได้ไหม

ได้ เช่น

dependencies {
    'ox_lib',
    'oxmysql'
}

Resource ใช้ OneSync บังคับได้ไหม

สามารถประกาศ Runtime Constraint

dependency '/onesync'

เพื่อระบุว่า Resource ต้องการ State Awareness

Resource Restart แล้ว Variable หายไหม

Local Runtime State จะถูกสร้างใหม่ ดังนั้นข้อมูลที่ต้อง Persistent ควรเก็บใน Database หรือ Storage ที่เหมาะสม

Resource Stop แล้ว Entity หายไหม

ขึ้นกับ Entity/Runtime Architecture จึงควรออกแบบ Cleanup อย่างชัดเจน ไม่ควรพึ่งให้ทุกอย่างหายเอง

Resource หนึ่งเรียกอีก Resource ได้ไหม

ได้ ผ่าน Exports, Events, Callbacks และ APIs อื่นที่ออกแบบไว้

Resource ควรมีไฟล์เดียวไหม

Resource เล็กสามารถมีไฟล์เดียวได้ แต่ระบบใหญ่ควรแยก Client, Server, Shared, Database และ UI ตามหน้าที่เพื่อ Maintain ง่ายขึ้น

สรุป FiveM Resource คืออะไร

FiveM Resource คือหน่วยพื้นฐานของการติดตั้งและรัน Script หรือ Assets บน FXServer

โครงสร้างง่ายที่สุดคือ

my_resource/
├── fxmanifest.lua
└── client.lua

Manifest

fx_version 'cerulean'
game 'gta5'

client_script 'client.lua'

Resource ที่ซับซ้อนขึ้นสามารถมี

Client Scripts
Server Scripts
Shared Scripts
NUI
Streaming Assets
Data Files
Dependencies
Exports

ทั้งหมดอยู่ภายใต้ Resource เดียว

Resource ถูกควบคุมด้วย Commands อย่าง

start
stop
ensure
restart
refresh

โดย ensure เป็นคำสั่งที่พบได้บ่อยใน server.cfg

ensure ox_lib
ensure oxmysql
ensure my_core
ensure my_garage

และถ้า Resource A ต้องใช้ Resource B สามารถประกาศ Dependency

dependency 'resource_b'

เพื่อให้ B Load ก่อน A

สิ่งที่ผู้เริ่มต้นควรจำคือ

Resource
≠
Lua File หนึ่งไฟล์

แต่คือ Container ของ Feature หนึ่งที่สามารถประกอบด้วยหลาย Script และหลาย Asset

สำหรับผู้ที่เรียน FiveM Developer กับ comsiam การออกแบบ Resource ที่ดีควรเริ่มจากการแบ่งหน้าที่ให้ชัดว่าอะไรอยู่ Client, Server และ Shared ไม่ใช่โยนทุก Code ลง client.lua หรือ server.lua ไฟล์เดียว

อีกหลักสำคัญจาก comsiam คือ Resource ควรสามารถ Start, Stop และ Restart ได้โดยไม่ทิ้ง State หรือ Entity ที่ไม่ควรค้างอยู่ เพราะ Resource Lifecycle เป็นส่วนหนึ่งของการออกแบบ FiveM Script ไม่ใช่เพียงเรื่องของ Server Admin

เมื่อเข้าใจ Resource แล้ว หัวข้อถัดไปคือ FiveM fxmanifest.lua คืออะไร ซึ่งจะลงรายละเอียด Manifest โดยเฉพาะว่าแต่ละบรรทัดอย่าง fx_version, game, client_script, server_script, shared_script, files, dependency และ Metadata ทำหน้าที่อะไร

Comments

Popular posts from this blog

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

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

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