27/09/2026

ทำไม fxmanifest.lua ต้องมี fx_version 'cerulean' และ lua54 'yes' (ไม่ใส่แล้วเป็นอะไร พร้อม template)

อธิบายสองบรรทัดที่ทุก resource FiveM ยุคนี้ต้องมี: fx_version 'cerulean' คือเวอร์ชันของ manifest ที่กำหนดพฤติกรรม runtime และ NUI ส่วน lua54 'yes' เปิด Lua 5.4 ให้ resource นั้น ทำไม ox_lib และ ESX Legacy บังคับ error ที่เจอเมื่อลืมใส่ ความต่างจาก adamant/bodacious และ __resource.lua พร้อม fxmanifest.lua ตัวอย่างที่ใช้ได้จริง

เปิด fxmanifest.lua ของสคริปยุคนี้จะเจอสองบรรทัดแรกเหมือนกันแทบทุกตัว:

fx_version 'cerulean'
lua54 'yes'

คนเขียนสคริปใหม่มักก๊อปตามโดยไม่รู้ว่าทำอะไร แล้วพอลืมใส่ในสคริปตัวเองก็เจอ error ที่อ่านไม่ออก บทความนี้อธิบายทีละบรรทัด: มันคืออะไร ทำไมต้องมี ไม่มีแล้วพังยังไง และ manifest ที่ถูกต้องสำหรับสคริป ESX ควรหน้าตาเป็นแบบไหน

fxmanifest.lua คืออะไรก่อน

ไฟล์นี้คือ "ใบสั่งโหลด" ที่ FXServer อ่านก่อนสตาร์ท resource: ไฟล์ไหนรันฝั่ง client ไฟล์ไหนฝั่ง server หน้า NUI อยู่ที่ไหน ต้องพึ่ง resource อะไร และ จะรันด้วยกติกาเวอร์ชันไหน สองบรรทัดที่ถามคือส่วน "กติกา" นั่นเอง ก่อนปี 2019 ไฟล์นี้ชื่อ __resource.lua และระบุเวอร์ชันด้วย resource_manifest_version ตามด้วย GUID ยาว ๆ ที่จำไม่ได้ fxmanifest.lua กับ fx_version มาแทนเพื่อให้คนอ่านออก

fx_version 'cerulean' คืออะไร

fx_version บอก FXServer ว่า resource นี้เขียนตาม กติกา manifest รุ่นไหน เพราะ FiveM ปรับพฤติกรรม runtime เป็นระยะ และไม่อยากให้สคริปเก่าพังเมื่ออัปเดต จึงล็อกพฤติกรรมไว้ที่เวอร์ชันที่ผู้เขียนประกาศ ชื่อรุ่นเรียงตามตัวอักษร:

fx_version ช่วงเวลา ความหมาย
adamant ปลาย 2019 รุ่นแรกของรูปแบบ fxmanifest.lua แทน __resource.lua
bodacious ต้น 2020 รุ่นกลาง ปรับพฤติกรรม runtime บางส่วนระหว่างทาง
cerulean กลาง 2020 ถึงปัจจุบัน รุ่นล่าสุด NUI โหลดจาก origin https://cfx-nui-<resource>/ แทน nui:// ทำให้หน้า NUI เป็น secure context ใช้ fetch ไปหา callback และโหลดทรัพยากร https ได้ตรง ๆ

ไม่มีรุ่นใหม่กว่า cerulean ตั้งแต่ 2020 ทุก resource ที่เขียนใหม่ใช้ค่านี้ค่าเดียว ไม่ต้องคิด

ถ้าไม่ใส่ fx_version เลย FXServer ไม่รู้ว่าจะโหลดด้วยกติกาไหน resource จะไม่สตาร์ทและ console จะฟ้องว่า manifest ไม่ถูกต้อง ถ้าใส่ adamant กับสคริปที่มี NUI ยุคใหม่ หน้า UI ที่ใช้ fetch หรือโหลดฟอนต์/รูปจาก https จะทำงานผิดเพราะ origin ยังเป็น nui://

lua54 'yes' คืออะไร

FiveM รัน Lua ด้วย runtime ของตัวเอง (CfxLua) ที่ค่าเริ่มต้นเป็น Lua 5.3 ตั้งแต่ปี 2021 มี runtime Lua 5.4 ให้เลือก แต่เปิดให้ ทีละ resource ด้วยบรรทัด lua54 'yes' เพราะ 5.4 เปลี่ยนพฤติกรรมบางอย่าง (เช่นการแปลงสตริงเป็นตัวเลข การล้นของ integer ใน for loop) สคริปเก่าบางตัวจะพังถ้าถูกบังคับทั้งเซิฟ

สิ่งที่ได้จาก Lua 5.4:

  • เร็วกว่า garbage collector แบบ generational และการเรียกฟังก์ชันที่เบากว่า สคริปที่มี loop ถี่ ๆ (HUD, ระยะ, ตรวจโซน) ได้ประโยชน์ชัด
  • ไวยากรณ์ใหม่ local x <const> = 1 (ค่าคงที่ แก้แล้ว error ตอนคอมไพล์) และ local f <close> = ... (ปิดทรัพยากรอัตโนมัติเมื่อออกจาก scope)
  • ฟังก์ชันใหม่เช่น coroutine.close, warn, math.tointeger และ utf8 ที่เข้มงวดขึ้น

ทำไม "ต้องมี" ไม่ใช่แค่ "ควรมี": library ที่สคริปยุคนี้พึ่งพาเขียนด้วยไวยากรณ์ 5.4 และเช็กจริง ตัวอย่างที่เจอบ่อยที่สุดคือ ox_lib บรรทัดแรก ๆ ของ @ox_lib/init.lua คือ

if not _VERSION:find('5.4') then
    error('Lua 5.4 must be enabled in the resource manifest!', 2)
end

และเพราะ runtime เป็นของ แต่ละ resource การที่ ox_lib เองมี lua54 'yes' ไม่ช่วยอะไร สคริปของคุณที่ shared_script '@ox_lib/init.lua' ต้องมี lua54 'yes' ในไฟล์ manifest ของตัวเองด้วย ไม่งั้นเจอ error ข้างบนตอนสตาร์ท เช่นเดียวกับ ox_inventory, ox_target, qbx_core และ ESX Legacy รุ่นใหม่ที่ manifest ของ es_extended ประกาศ lua54 'yes' มาตั้งแต่ต้น

อาการเมื่อลืมใส่แต่โค้ดใช้ไวยากรณ์ 5.4: error ตอนโหลดไฟล์แบบ '=' expected near '<' ชี้ไปบรรทัดที่มี <const> หรือ <close> หรือ error attempt to call a nil value (field 'close') เมื่อเรียก coroutine.close

แล้ว use_experimental_fxv2_oal 'yes' ล่ะ

บรรทัดที่สามที่มักเห็นคู่กันใน ESX Legacy คือ

use_experimental_fxv2_oal 'yes'

เปิดวิธีเรียก native แบบใหม่ที่เร็วกว่า (one-argument-list) ไม่บังคับ แต่ปลอดภัยกับสคริปที่เขียนใหม่และให้ประสิทธิภาพเพิ่มในสคริปที่เรียก native ถี่ ถ้าเจอพฤติกรรมแปลกกับ native ที่คืนค่าหลายตัว ลองปิดบรรทัดนี้ก่อน

fxmanifest.lua ตัวอย่างสำหรับสคริป ESX

fx_version 'cerulean'
game 'gta5'
lua54 'yes'
use_experimental_fxv2_oal 'yes'

author 'X3D Developer'
description 'x3d_example: ตัวอย่างโครง manifest'
version '1.0.0'

shared_scripts {
  '@es_extended/imports.lua',
  '@ox_lib/init.lua',
  'config/config.lua',
}

client_scripts {
  'client/*.lua',
}

server_scripts {
  '@oxmysql/lib/MySQL.lua',
  'config/config.license.lua',
  'server/*.lua',
}

ui_page 'html/index.html'

files {
  'html/index.html',
  'html/**/*',
  'locales/*.json',
}

dependencies {
  '/server:7290',
  '/onesync',
  'es_extended',
  'ox_lib',
}

จุดที่คนพลาดบ่อย:

  • game 'gta5' จำเป็น ถ้าทำ RedM ใช้ game 'rdr3' และเพิ่ม rdr3_warning ตามที่ FXServer บอก
  • ไฟล์ที่ต้องเปิดจาก NUI (รูป ฟอนต์ เสียง) ต้องอยู่ใน files ไม่งั้นโหลดไม่ขึ้นแม้ไฟล์มีอยู่จริง (html/**/* ครอบให้หมดในโฟลเดอร์)
  • ไฟล์ที่มีความลับฝั่ง server เช่น config/config.license.lua ห้าม อยู่ใน shared_scripts เพราะ shared ส่งไปให้ทุกไคลเอนต์ ต้องอยู่ใน server_scripts เท่านั้น (สคริป X3D ทุกตัววาง license config ไว้ใน server_scripts เป็นบรรทัดแรก)
  • dependencies แบบ /server:7290 บังคับเวอร์ชัน FXServer ขั้นต่ำ และ /onesync บังคับให้เปิด OneSync ถ้าไม่ครบ resource จะไม่สตาร์ทพร้อมข้อความบอกชัด ดีกว่าพังเงียบ ๆ ทีหลัง
  • ลำดับใน server.cfg ยังสำคัญ: es_extended และ ox_lib ต้อง ensure ก่อนสคริปที่ import จากมัน

คำถามที่พบบ่อย

สคริปเก่าที่ยังเป็น __resource.lua ต้องแปลงไหม — ยังรันได้ แต่ควรเปลี่ยนชื่อไฟล์เป็น fxmanifest.lua และแทน resource_manifest_version '...' ด้วย fx_version 'cerulean' แล้วทดสอบ NUI อีกรอบ

ใส่ lua54 'yes' กับสคริปเก่าแล้วจะพังไหม — ส่วนใหญ่ไม่ ที่เจอคือโค้ดที่พึ่งการแปลง "10" + 5 โดยอัตโนมัติ (5.4 ยังทำได้ผ่าน string metamethod) และ integer overflow ใน for loop ที่ 5.4 หยุด loop แทนที่จะวนต่อ ทดสอบก่อนขึ้น prod

ใส่ lua54 'yes' ที่ es_extended ตัวเดียวพอไหม — ไม่พอ ค่านี้เป็นรายตัว ทุก resource ที่ใช้ไวยากรณ์ 5.4 หรือ import ox_lib ต้องใส่เอง

เห็น fx_version 'bodacious' ในสคริปที่ซื้อมา — ทำงานได้ แต่เป็นสัญญาณว่าโค้ดไม่ได้อัปเดตตั้งแต่ 2020 ตรวจ NUI และความเข้ากันได้กับ ESX Legacy รุ่นปัจจุบันก่อนใช้

สคริปฟรีของ X3D ทุกตัว (เช่น ESX Legacy Core — X3D Build และ X3D Phone) ใช้โครง manifest แบบข้างบน ดูไฟล์จริงได้จากบทความแจกสคริป FiveM ฟรี อยากให้ทีมช่วยเขียนสคริปตามโจทย์: รับเขียนสคริป FiveM