วิธีเขียน fxmanifest.lua สำหรับ FiveM ตั้งแต่พื้นฐานจนใช้กับ Resource จริง

การเขียน fxmanifest.lua สำหรับ FiveM เริ่มจากกำหนด FX Version และเกมที่ Resource รองรับ จากนั้นระบุว่าไฟล์ใดต้องทำงานฝั่ง Client, Server หรือทั้งสองฝั่ง รวมถึง Files, NUI และ Dependencies ที่ Resource ต้องใช้

โครงสร้างขั้นต่ำสำหรับ FiveM Resource คือ

fx_version 'cerulean'
game 'gta5'

หากมี client.lua และ server.lua

fx_version 'cerulean'
game 'gta5'

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

ถ้ามี Configuration ที่ทั้ง Client และ Server ใช้

shared_script 'config.lua'

Resource ที่สมบูรณ์ขึ้นอาจเป็น

fx_version 'cerulean'
game 'gta5'

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

shared_script 'shared/config.lua'

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

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

หลักสำคัญคือ อย่า Copy fxmanifest.lua จาก Resource อื่นมาทั้งหมดโดยไม่รู้ว่าแต่ละบรรทัดทำอะไร เพราะ Manifest ควรสะท้อน Files และ Requirements ที่ Resource ของคุณใช้จริง

① สร้าง Folder Resource ก่อน

สมมติต้องการสร้าง Resource ชื่อ

my_resource

สร้างไว้ใน

resources/
└── [local]/
    └── my_resource/

จากนั้นสร้าง

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

FiveM จะใช้ fxmanifest.lua เพื่อรู้ว่า Folder นี้เป็น Resource และต้องโหลดอะไร

② สร้างไฟล์ fxmanifest.lua

ชื่อไฟล์ต้องเป็น

fxmanifest.lua

ระวัง Windows ซ่อน File Extension แล้วทำให้กลายเป็น

fxmanifest.lua.txt

หาก Server แจ้งว่า Resource ไม่มี Manifest ให้ตรวจจุดนี้ก่อน

③ เขียน fx_version

เริ่มด้วย

fx_version 'cerulean'

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

ไม่ต้องใช้ GUID resource_manifest_version แบบ Resource รุ่นเก่า

④ เขียน game

FiveM ใช้

game 'gta5'

ดังนั้น Manifest ขั้นต่ำคือ

fx_version 'cerulean'
game 'gta5'

ถ้าสร้าง Script สำหรับ FiveM ทั่วไป นี่คือสองบรรทัดพื้นฐานที่ควรมี

⑤ ใส่ Metadata

เพิ่มข้อมูล Resource ได้ เช่น

author 'Your Name'
description 'My FiveM resource'
version '1.0.0'

รวมแล้ว

fx_version 'cerulean'
game 'gta5'

author 'Your Name'
description 'My FiveM resource'
version '1.0.0'

Metadata ช่วยให้ Developer คนอื่นเปิด Manifest แล้วเข้าใจ Resource ได้เร็วขึ้น

⑥ author จำเป็นไหม

ไม่บังคับสำหรับการทำงานพื้นฐาน

แต่แนะนำให้ใส่

author 'Your Name'

โดยเฉพาะ Resource ที่

  • แจกให้ผู้อื่น

  • ใช้หลาย Server

  • มีหลาย Developer

  • ทำ Version Control

⑦ description ควรเขียนอย่างไร

เขียนสั้น ๆ ว่า Resource ทำอะไร

ตัวอย่าง

description 'Garage system for FiveM'

ดีกว่า

description 'Script'

เพราะให้ Context ที่ชัดกว่า

⑧ version ควรใช้รูปแบบไหน

ตัวอย่างมาตรฐานที่อ่านง่าย

version '1.0.0'

จากนั้นเมื่อ Update

1.0.1
1.1.0
2.0.0

สามารถจัด Version ตามระบบ Release ของคุณ

⑨ เพิ่ม client_script

ถ้ามี Client Script

client.lua

เขียน

client_script 'client.lua'

Manifest:

fx_version 'cerulean'
game 'gta5'

client_script 'client.lua'

⑩ client.lua เหมาะกับอะไร

Client Script เหมาะกับ Logic เช่น

  • PlayerPedId

  • Controls

  • Camera

  • Markers

  • Local Vehicle

  • NUI

  • HUD

  • Rendering

ตัวอย่าง

RegisterCommand(
    'coords',
    function()

        local ped =
            PlayerPedId()

        print(
            GetEntityCoords(ped)
        )
    end,
    false
)

⑪ เพิ่ม server_script

หากมี

server.lua

เขียน

server_script 'server.lua'

Manifest

fx_version 'cerulean'
game 'gta5'

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

⑫ Server Script เหมาะกับอะไร

เหมาะกับ

Database
Money
Inventory
Permissions
Server Events
Security Validation
Global State

เช่น

RegisterNetEvent(
    'example:hello',
    function()

        local src =
            source

        print(
            'Player:',
            src
        )
    end
)

⑬ เพิ่ม shared_script

สมมติมี

config.lua

ที่ทั้ง Client และ Server ต้องใช้

เพิ่ม

shared_script 'config.lua'

Manifest

fx_version 'cerulean'
game 'gta5'

shared_script 'config.lua'

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

⑭ ตัวอย่าง config.lua

Config = {}

Config.MaxDistance =
    5.0

Config.JobName =
    'police'

ทั้ง Client และ Server สามารถ Load File นี้ได้

แต่ต้องจำว่า Client และ Server ไม่แชร์ Memory เดียวกัน

⑮ อย่าใส่ Password ใน shared_script

ไม่ควรทำ

Config.DatabasePassword =
    'secret-password'

ใน Shared File

เพราะ Client ต้องได้รับ Shared Script

Server-only Secrets ต้องอยู่ Server Environment หรือ Configuration ที่เหมาะสม

⑯ มีหลาย Client Files ทำอย่างไร

ใช้

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

โครงสร้าง

my_resource/
├── fxmanifest.lua
└── client/
    ├── main.lua
    ├── menu.lua
    └── vehicle.lua

อ่านง่ายกว่าเอาทุกอย่างรวมไว้ใน client.lua

⑰ มีหลาย Server Files ทำอย่างไร

ใช้

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

โครงสร้าง

server/
├── main.lua
├── commands.lua
└── database.lua

ช่วยแยก Business Logic ได้ชัดเจน

⑱ มีหลาย Shared Files ทำอย่างไร

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

เช่น

shared/
├── config.lua
├── constants.lua
└── utils.lua

ควรให้ Shared Utilities เป็น Function ที่ใช้ได้ทั้งสอง Runtime จริง ๆ

⑲ Load Order สำคัญอย่างไร

สมมติ main.lua ต้องใช้ Config

ต้องให้ Config ถูกโหลดก่อน

shared_script 'shared/config.lua'

client_script 'client/main.lua'

ถ้า File A ต้องประกาศ Function ก่อน File B เรียกใช้ ก็ต้องคิด Load Order เช่นกัน

⑳ ตัวอย่างโครงสร้าง Resource ที่ดี

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

Manifest

fx_version 'cerulean'
game 'gta5'

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

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

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

㉑ ใช้ Wildcard ได้ไหม

ได้ใน Directives ที่รองรับ Globbing

ตัวอย่าง

client_scripts {
    'client/*.lua'
}

หรือ

server_scripts {
    'server/*.lua'
}

ช่วยลดจำนวนบรรทัด

㉒ Recursive Wildcard

Resource ที่มี Subfolders สามารถพบ Pattern เช่น

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

เช่น

client/
├── core/
│   └── main.lua
└── modules/
    ├── garage.lua
    └── vehicle.lua

แต่ต้องคิดเรื่อง Load Order ให้ดี

㉓ Wildcard ดีเสมอไหม

ไม่

Manifest แบบ

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

สะดวก

แต่เมื่อ Resource ใหญ่ คุณอาจมองไม่ออกว่า File ไหนถูกโหลดก่อน File ไหน

Resource ที่มี Dependency ภายในซับซ้อนอาจเขียน Paths แบบ Explicit ดีกว่า

㉔ วิธีเพิ่ม Dependency

ถ้า Resource ต้องใช้ ox_lib

dependency 'ox_lib'

ถ้ามีหลาย Dependency

dependencies {
    'ox_lib',
    'oxmysql'
}

ช่วยประกาศว่า Resource เหล่านี้ต้องพร้อมก่อน Resource ปัจจุบัน

㉕ ตัวอย่าง Resource ที่ต้องใช้ ox_lib และ oxmysql

fx_version 'cerulean'
game 'gta5'

dependencies {
    'ox_lib',
    'oxmysql'
}

shared_script 'shared/config.lua'

client_script 'client/main.lua'
server_script 'server/main.lua'

จากนั้นควรจัด server.cfg ตาม Dependency ด้วย เช่น

ensure ox_lib
ensure oxmysql
ensure my_resource

㉖ อย่าใช้ Wait แทน Dependency

ไม่ควรเขียน

CreateThread(function()

    Wait(10000)

    -- หวังว่า oxmysql start แล้ว
end)

เพื่อแก้ Start Order

ควรใช้ Manifest Dependency และ Server Resource Order ที่ถูกต้อง

㉗ Resource ต้องใช้ OneSync ทำอย่างไร

เพิ่ม Runtime Constraint

dependency '/onesync'

หรือ

dependencies {
    '/onesync'
}

เหมาะกับ Resource ที่ต้องใช้

State Bags
Routing Buckets
Server-side Entity State
OneSync APIs

㉘ /onesync เปิด OneSync ให้ไหม

ไม่

Manifest

dependency '/onesync'

เพียงประกาศ Requirement

FXServer ยังต้องเปิด OneSync ตาม Configuration ของ Server

Resource ไม่ควรเป็นผู้เปลี่ยน Server Architecture เองผ่าน Manifest

㉙ กำหนด Minimum Server Build

ถ้า Resource ต้องใช้ Feature ที่ต้องการ FXServer Build ขั้นต่ำ สามารถใช้

dependency '/server:4500'

หรือ

dependencies {
    '/onesync',
    '/server:4500'
}

ช่วยหยุด Resource ตั้งแต่ต้นถ้า Environment ไม่ตรง Requirement

㉚ ต้องใส่ /server ทุก Resource ไหม

ไม่

ใส่เมื่อ Resource มีเหตุผลจริงว่าต้องใช้ Minimum Build

อย่า Copy

dependency '/server:99999'

จาก Resource อื่นมาโดยไม่รู้ว่าทำไม

อาจทำให้ Resource Start ไม่ได้โดยไม่จำเป็น

㉛ JavaScript Server Resource เขียนอย่างไร

ตัวอย่าง

fx_version 'cerulean'
game 'gta5'

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

Manifest ยังคงเป็น Lua

FiveM จะเลือก JavaScript Runtime จาก .js

㉜ ต้องใช้ Node.js 22 ทำอย่างไร

Resource Manifest ปัจจุบันรองรับ

node_version '22'

สำหรับ Server JavaScript Runtime

ตัวอย่าง

fx_version 'cerulean'
game 'gta5'

node_version '22'

server_script 'server.js'

ค่า Default ปัจจุบันในเอกสารคือ Node 16 และรองรับเลือก 22

อย่ากำหนด 22 หาก Dependencies ยังไม่ Compatible

㉝ Resource C# เขียน Manifest อย่างไร

Manifest ยังคงเริ่มจาก

fx_version 'cerulean'
game 'gta5'

จากนั้นประกาศ Assembly/Script ตาม C# Runtime Architecture ของ Resource

ดังนั้น fxmanifest.lua ไม่ได้มีไว้เฉพาะ Lua Resource

㉞ วิธีเพิ่ม NUI

สมมติโครงสร้าง

my_resource/
├── fxmanifest.lua
├── client.lua
└── html/
    ├── index.html
    ├── style.css
    └── app.js

เพิ่ม

ui_page 'html/index.html'

และ

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

㉟ NUI Manifest แบบเต็ม

fx_version 'cerulean'
game 'gta5'

client_script 'client.lua'

ui_page 'html/index.html'

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

นี่เป็นพื้นฐานสำหรับ

HUD
Inventory
Phone
Menu
Garage
Character UI

㊱ ทำไม NUI ต้องใส่ files

ui_page บอกว่า Root Page คืออะไร

ส่วน files บอก Resource Packfile ว่า Client ต้องได้รับ Files อะไร

ดังนั้นถ้ามี

<script src="app.js"></script>

แต่ app.js ไม่อยู่ใน Resource Files ที่ต้องส่ง Client UI อาจโหลดไม่ครบ

㊲ เพิ่มรูปภาพ NUI

สมมติมี

html/images/logo.png

เพิ่ม

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

หรือระบุ File ตรง ๆ

'html/images/logo.png'

㊳ เพิ่ม Font หรือ Audio NUI

หลักเดียวกัน

เช่น

files {
    'html/index.html',
    'html/style.css',
    'html/app.js',
    'html/fonts/*.woff2',
    'html/audio/*.ogg'
}

ใส่เฉพาะ Assets ที่ UI ใช้จริง

㊴ Resource ไม่มี NUI ต้องใส่ files ไหม

ไม่จำเป็น หากไม่มี Client Assets ที่ต้องเพิ่มเข้า Packfile ผ่าน Directive นี้

Resource Lua ง่าย ๆ อาจมีเพียง

fx_version 'cerulean'
game 'gta5'

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

ไม่ต้องสร้าง files {} เปล่า ๆ

㊵ วิธีทำ Server-only Resource

ถ้า Resource ทำงานเฉพาะ Server

fx_version 'cerulean'
game 'gta5'

server_only 'yes'

server_script 'server.lua'

เหมาะกับ Backend Logic ที่ไม่มี Client Code หรือ Client Assets

㊶ server_only มีข้อดีอะไร

ช่วยบอก Resource System ว่า Content ของ Resource นี้ไม่ต้องส่งให้ Clients

เหมาะกับ

Database Worker
Server Scheduler
Logging
Server-only API

แต่ Secrets ควรยังถูกจัดการด้วย Server Configuration ที่เหมาะสม

㊷ วิธีเขียน Resource ที่มี Export

สำหรับ Code ใหม่สามารถประกาศ Runtime Export ใน Script

server.lua

exports(
    'GetValue',
    function()

        return 100
    end
)

Resource อื่นเรียก

local value =
    exports['my_resource']
        :GetValue()

ไม่จำเป็นต้องประกาศ Export ใน Manifest ในกรณี Runtime Export แบบนี้

㊸ Manifest Export ยังมีไหม

มี

เช่น

export 'GetValue'

หรือ

server_export 'GetValue'

แต่ Runtime Export ทำให้ API Definition อยู่ใกล้ Implementation และมักอ่านง่ายกว่าสำหรับ Resource ใหม่

㊹ วิธีเพิ่ม Streaming Assets

สมมติ Vehicle Resource

my_vehicle/
├── fxmanifest.lua
├── handling.meta
└── stream/
    ├── mycar.yft
    └── mycar.ytd

Manifest อาจต้องประกาศ Data File ตาม Asset Type

ตัวอย่าง Concept

files {
    'handling.meta'
}

data_file 'HANDLING_FILE'
    'handling.meta'

แต่ Vehicle Resource จริงมักมี .meta หลายประเภท ต้องประกาศให้ตรงกับไฟล์จริง

㊺ อย่า Copy Vehicle Manifest ทั้งชุด

บาง Manifest บน Internet มี

handling.meta
vehicles.meta
carcols.meta
carvariations.meta
vehiclelayouts.meta

แต่ Resource ของคุณอาจไม่มีทุกไฟล์

ถ้าประกาศ File ที่ไม่มีหรือ Data Type ไม่ตรง อาจเกิด Warning/Error

ใส่เฉพาะ Assets ที่ Resource ใช้จริง

㊻ Map Resource เขียน Manifest อย่างไร

Map Resource ก็ใช้

fx_version 'cerulean'
game 'gta5'

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

แต่จะมี Streaming Assets และ Metadata ตามประเภท Map

หลักคือ Resource System เดียวกัน

ไม่ว่าคุณกำลังเขียน Script, Vehicle หรือ Map

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

ไม่ต้อง

Manifest ปัจจุบันไม่จำเป็นต้องเขียน

lua54 'yes'

Cfx.re ระบุ Directive นี้ Deprecated แล้ว เพราะตั้งแต่เดือนมิถุนายน 2025 Lua Scripts ทั้งหมดใช้ Lua 5.4

ดังนั้น Manifest ใหม่ควรตัดบรรทัดนี้ออก

㊽ ตัวอย่าง Manifest เก่าที่ควรปรับ

เก่า

fx_version 'cerulean'
game 'gta5'

lua54 'yes'

client_script 'client.lua'

ปัจจุบัน

fx_version 'cerulean'
game 'gta5'

client_script 'client.lua'

สั้นกว่าและไม่ใช้ Deprecated Directive

㊾ __resource.lua ควรทำอย่างไร

หาก Resource เก่ายังมี

__resource.lua

ควรพิจารณา Migration เป็น

fxmanifest.lua

และเปลี่ยนจาก Manifest Version GUID เก่าไปใช้

fx_version 'cerulean'

โดยต้องตรวจ Directives เดิมของ Resource ว่ายังรองรับหรือจำเป็นต้องปรับหรือไม่

㊿ use_experimental_fxv2_oal คืออะไร

Manifest ปัจจุบันมี Directive

use_experimental_fxv2_oal 'yes'

สำหรับ OAL ซึ่งมีเป้าหมายด้าน Native Call Performance และ Return Types

แต่มีคำว่า experimental ชัดเจน

Resource ทั่วไปไม่ควรเปิดเพียงเพราะคิดว่าจะทำให้ FPS สูงขึ้น

ต้องทดสอบ Compatibility โดยเฉพาะ Native Arguments บางรูปแบบ

51 อย่าใส่ Experimental Directive โดยไม่จำเป็น

Manifest ที่ดีที่สุดไม่ใช่ Manifest ที่ยาวที่สุด

แนวคิดควรเป็น

Resource ต้องการอะไร
↓
ประกาศเท่านั้น

ไม่ใช่

เห็น Directive อะไรใน Internet
↓
ใส่ทั้งหมด

ยิ่ง Configuration น้อยและตรง Requirement ยิ่ง Debug ง่าย

52 ตัวอย่าง Manifest สำหรับ Standalone Script

fx_version 'cerulean'
game 'gta5'

author 'Your Name'
description 'Standalone FiveM script'
version '1.0.0'

shared_script 'config.lua'

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

เหมาะกับ Resource เล็กและตรงไปตรงมา

53 ตัวอย่าง Manifest สำหรับ Resource ที่ใช้ OneSync

fx_version 'cerulean'
game 'gta5'

author 'Your Name'
description 'OneSync entity system'
version '1.0.0'

dependency '/onesync'

shared_script 'shared/config.lua'

client_script 'client/main.lua'
server_script 'server/main.lua'

ถ้า OneSync State Awareness ไม่พร้อม Resource มี Requirement ที่ชัดเจนตั้งแต่ Manifest

54 ตัวอย่าง Manifest สำหรับ Database Resource

fx_version 'cerulean'
game 'gta5'

author 'Your Name'
description 'Database-backed garage'
version '1.0.0'

dependencies {
    'oxmysql'
}

shared_script 'shared/config.lua'

client_script 'client/main.lua'

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

สิ่งสำคัญคือให้ Database Layer อยู่ Server-side

อย่านำ SQL Credentials หรือ Server-only Database Logic ไป Shared/Client

55 ตัวอย่าง Manifest สำหรับ NUI + Database

fx_version 'cerulean'
game 'gta5'

author 'Your Name'
description 'Garage with NUI'
version '1.0.0'

dependencies {
    'oxmysql'
}

shared_script 'shared/config.lua'

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

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

ui_page 'html/index.html'

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

นี่เป็นโครงสร้างใกล้เคียง Resource จริงจำนวนมาก

56 ตัวอย่าง Manifest สำหรับ Resource ใหญ่

fx_version 'cerulean'
game 'gta5'

author 'comsiam'
description 'Complete FiveM garage system'
version '1.0.0'

dependencies {
    '/onesync',
    'ox_lib',
    'oxmysql'
}

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

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

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

ui_page 'html/index.html'

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

Manifest นี้อ่านแล้วมองเห็น Architecture ของ Resource ได้ทันที

57 Resource ไม่ Start เพราะ Manifest แก้อย่างไร

ตรวจจาก Server Console ก่อน

ปัญหาที่พบบ่อยคือ

fxmanifest.lua ไม่มี
ชื่อไฟล์ผิด
Path ผิด
Syntax Lua ผิด
ประกาศ File ที่ไม่มี
Dependency ไม่มี
Dependency ยังไม่ Start
Server Build ต่ำเกิน Constraint
OneSync Requirement ไม่ผ่าน

อย่าเดา

อ่านข้อความ Error จาก Console ก่อนเสมอ

58 File Path ตัวพิมพ์ใหญ่เล็กสำคัญไหม

สำคัญ โดยเฉพาะ Linux Server

สมมติไฟล์จริง

client/Main.lua

แต่ Manifest

client_script 'client/main.lua'

Windows Development Environment อาจไม่แสดงปัญหาชัดเหมือน Linux

Production Server จึงควรรักษาชื่อ Files ให้ตรงกันทุกตัวอักษร

59 Checklist ก่อนใช้งาน fxmanifest.lua

ตรวจ

① ชื่อไฟล์คือ fxmanifest.lua หรือไม่?
② อยู่ Root Resource หรือไม่?
③ fx_version เป็น cerulean หรือไม่?
④ game เป็น gta5 หรือไม่?
⑤ author/description/version เหมาะสมหรือไม่?
⑥ Shared Files โหลดก่อน Files ที่ต้องใช้หรือไม่?
⑦ Client Paths ถูกหรือไม่?
⑧ Server Paths ถูกหรือไม่?
⑨ มี File ประกาศแต่ไม่มีจริงหรือไม่?
⑩ Case ของ Path ตรงหรือไม่?
⑪ Shared Script มี Secret หรือไม่?
⑫ Database Logic อยู่ Server หรือไม่?
⑬ Dependencies ถูกหรือไม่?
⑭ OneSync Requirement จำเป็นไหม?
⑮ Minimum Server Build จำเป็นไหม?
⑯ NUI มี ui_page หรือไม่?
⑰ NUI Assets อยู่ files ครบหรือไม่?
⑱ Wildcard กว้างเกินไปหรือไม่?
⑲ Load Order ชัดเจนหรือไม่?
⑳ ยังมี lua54 'yes' หรือไม่?
㉑ ยังมี resource_manifest_version เก่าหรือไม่?
㉒ มี Experimental Directive โดยไม่จำเป็นหรือไม่?
㉓ Server Console มี Manifest Warning หรือไม่?

⑥⓪ วิธีเขียน fxmanifest.lua ที่เหมาะสำหรับ Production

สำหรับ Resource ที่มี Client, Server, Shared, OneSync, Database และ NUI สามารถใช้เป็นต้นแบบได้ดังนี้

โครงสร้าง Folder

com_garage/
├── fxmanifest.lua
│
├── shared/
│   ├── config.lua
│   └── constants.lua
│
├── client/
│   ├── main.lua
│   ├── garage.lua
│   └── ui.lua
│
├── server/
│   ├── main.lua
│   ├── garage.lua
│   └── database.lua
│
└── html/
    ├── index.html
    ├── app.js
    ├── style.css
    └── images/
        └── logo.png

fxmanifest.lua

fx_version 'cerulean'
game 'gta5'

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

dependencies {
    '/onesync',
    'ox_lib',
    'oxmysql'
}

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

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

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

ui_page 'html/index.html'

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

server.cfg

Resource Dependencies ควรถูก Start ก่อน Resource หลัก

ensure ox_lib
ensure oxmysql
ensure com_garage

แนวคิดคือ

FXServer
↓
พบ com_garage
↓
อ่าน fxmanifest.lua
↓
ตรวจ OneSync
↓
ตรวจ ox_lib
↓
ตรวจ oxmysql
↓
โหลด Shared
↓
โหลด Client
↓
โหลด Server
↓
เตรียม NUI
↓
Resource Running

Manifest จึงเป็น Contract ระหว่าง Resource กับ FXServer

คำถามที่พบบ่อยเกี่ยวกับการเขียน fxmanifest.lua

fxmanifest.lua ขั้นต่ำเขียนอย่างไร

fx_version 'cerulean'
game 'gta5'

แล้วเพิ่ม Script ตาม Resource

Client Script เขียนอย่างไร

client_script 'client.lua'

Server Script เขียนอย่างไร

server_script 'server.lua'

Shared Script เขียนอย่างไร

shared_script 'config.lua'

หลาย Client Files ทำอย่างไร

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

หลาย Server Files ทำอย่างไร

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

ใช้ Wildcard ได้ไหม

ได้ใน Directives ที่รองรับ เช่น

client_scripts {
    'client/*.lua'
}

Resource ใช้ oxmysql ต้องใส่ dependency ไหม

แนะนำให้ประกาศ Requirement ให้ชัดหาก Resource พึ่ง oxmysql

dependency 'oxmysql'

Resource ใช้ OneSync เขียนอย่างไร

dependency '/onesync'

/onesync เปิด OneSync หรือไม่

ไม่ เป็น Runtime Requirement เท่านั้น

NUI เขียน Manifest อย่างไร

ui_page 'html/index.html'

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

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

ไม่ Cfx.re ระบุว่า Deprecated แล้ว และ Lua Scripts ใช้ Lua 5.4

JavaScript ใช้ Manifest แบบเดียวกันไหม

ใช่ เพียงเปลี่ยน Script Files เป็น .js

Node 22 ตั้งอย่างไร

Server JavaScript Resource สามารถใช้

node_version '22'

ตาม Runtime ที่รองรับ

C# ต้องใช้ fxmanifest.lua ไหม

ใช้

server_only คืออะไร

ใช้บอกว่า Resource ทำงานเฉพาะ Server และ Content ไม่ต้องส่ง Client

Dependency ช่วยอะไร

ช่วยประกาศว่า Resource อื่นหรือ Runtime Requirement ต้องพร้อมก่อน Resource ปัจจุบัน

Manifest แก้ Start Order ได้ทั้งหมดไหม

Dependency ช่วย Resource-level Ordering แต่ภายใน Resource ยังต้องจัด Initialization และ Script Load Order ให้ถูก

Resource ไม่ Start ควรดูตรงไหนก่อน

Server Console

Error มักบอก File, Line, Dependency หรือ Manifest ที่มีปัญหา

ใช้ refresh เมื่อไร

เมื่อเพิ่งเพิ่ม Resource ใหม่ระหว่าง FXServer กำลังทำงาน สามารถ refresh เพื่อ Scan Resources ใหม่ แล้ว ensure Resource

Manifest ยิ่งยาวยิ่งดีไหม

ไม่ ควรมีเฉพาะ Entries และ Requirements ที่ Resource ใช้จริง

สรุปวิธีเขียน fxmanifest.lua สำหรับ FiveM

การเขียน fxmanifest.lua ที่ดีเริ่มจากโครงสร้างง่ายที่สุด

fx_version 'cerulean'
game 'gta5'

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

ถ้ามี Configuration ที่ใช้ทั้งสองฝั่ง

shared_script 'config.lua'

ถ้ามีหลาย Files

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

ถ้ามี Dependencies

dependencies {
    'ox_lib',
    'oxmysql'
}

ถ้าต้องใช้ OneSync

dependency '/onesync'

ถ้ามี NUI

ui_page 'html/index.html'

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

และ Resource Lua ปัจจุบันไม่จำเป็นต้องใส่

lua54 'yes'

อีกแล้ว เพราะ Directive นี้ Deprecated และ Lua Scripts ใช้ Lua 5.4 อยู่แล้ว

วิธีคิดที่สำคัญคือ

fxmanifest.lua
↓
บอกว่า Resource ต้องการอะไร
↓
ไม่ใช่ใส่ทุกอย่างที่ FiveM รองรับ

สำหรับ Developer ที่เรียนกับ comsiam Manifest ที่ดีที่สุดไม่จำเป็นต้องซับซ้อน แต่ต้องเปิดแล้วตอบได้ทันทีว่า Resource ใช้ Client Files อะไร, Server Files อะไร, Shared Files อะไร และพึ่ง Resource ไหนบ้าง

อีกหลักสำคัญจาก comsiam คือ อย่าแก้ปัญหา Dependency ด้วยการเพิ่ม Wait(5000) และอย่าแก้ปัญหา Manifest ด้วยการ Copy Configuration จาก Script อื่นมาทั้งชุด เพราะวิธีที่ถูกต้องคือกำหนด Dependencies, Paths และ Load Order ให้ตรงกับ Architecture ของ Resource จริง

หัวข้อถัดไปคือ FiveM fx_version cerulean คืออะไร ซึ่งจะเจาะว่า cerulean มีหน้าที่อะไร ต่างจาก FX Versions รุ่นเก่าอย่าง adamant และ bodacious อย่างไร และทำไม Resource FiveM ปัจจุบันจึงนิยมใช้ cerulean

Comments

Popular posts from this blog

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

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

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