FiveM start, ensure, restart และ stop ต่างกันอย่างไร? ใช้ Resource Commands ให้ถูกต้อง

คำสั่ง start, ensure, restart และ stop ใน FiveM ใช้ควบคุมสถานะของ Resource บน FXServer แต่แต่ละคำสั่งมีพฤติกรรมต่างกัน โดยเฉพาะ start กับ ensure ที่มือใหม่มักเข้าใจว่าเหมือนกัน

สรุปสั้นที่สุดคือ

start
→ Start Resource ถ้ากำลังหยุดอยู่

ensure
→ ถ้าหยุดอยู่ให้ Start
→ ถ้ากำลังทำงานอยู่ให้ Restart

restart
→ Restart Resource ถ้ากำลัง Started

stop
→ Stop Resource ถ้ากำลัง Started

ตัวอย่าง

start my_garage
ensure my_garage
restart my_garage
stop my_garage

สำหรับ server.cfg มักพบ ensure มากที่สุด เช่น

ensure ox_lib
ensure oxmysql
ensure my_core
ensure my_garage

เพราะเป็นการบอก FXServer ในเชิง Desired State ว่า

Resource นี้ควรอยู่ในสถานะ Started

และถ้า Resource กำลังทำงานอยู่แล้ว การสั่ง ensure ซ้ำจะ Restart Resource นั้น

① FiveM Resource Commands คืออะไร

FXServer มีคำสั่งสำหรับจัดการ Resource โดยตรง

Resource หนึ่งสามารถ

Start
Stop
Restart

ได้โดยไม่ต้อง Restart FXServer ทั้งเครื่อง

นี่เป็นพื้นฐานสำคัญของ FiveM Development เพราะเวลาแก้ Script เราไม่จำเป็นต้อง

ปิดเกม
↓
ปิด Server
↓
เปิด Server ใหม่
↓
เข้าเกมใหม่

ทุกครั้ง

ในหลายกรณีเพียง

restart my_resource

ก็เพียงพอ

② start คืออะไร

คำสั่ง

start resource_name

ใช้ Start Resource ที่กำลังอยู่ในสถานะ Stopped

ตัวอย่าง

start my_garage

ถ้า my_garage ยังไม่ได้ทำงาน FXServer จะพยายาม Start Resource

③ ตัวอย่าง start

สมมติมี Resource

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

หลัง refresh

สามารถใช้

start my_test

เพื่อเปิด Resource

ถ้า Manifest และ Scripts ถูกต้อง Resource จะเข้าสู่สถานะ Started

④ start ใช้ใน server.cfg ได้ไหม

ได้

เช่น

start mapmanager
start chat
start my_resource

แต่ Server Configuration สมัยใหม่มักพบ

ensure my_resource

มากกว่า เพราะ ensure มี Behavior ที่ครอบคลุมทั้ง Start และ Restart ตามสถานะปัจจุบัน

⑤ ensure คืออะไร

ensure เป็นคำสั่งที่สำคัญมาก

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

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

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

ตัวอย่าง

ensure my_garage

จึงไม่เหมือน start ทุกกรณี

⑥ start กับ ensure ต่างกันตรงไหน

สมมติ Resource อยู่ในสถานะ

Stopped

สั่ง

start my_resource

ผลคือ

Started

สั่ง

ensure my_resource

ผลก็เป็น

Started

ตรงนี้ดูเหมือนกัน

แต่ถ้า Resource กำลัง Started อยู่แล้ว

start my_resource

ไม่ได้มีความหมายแบบ Restart

ในขณะที่

ensure my_resource

จะทำ

Restart Resource

นี่คือความแตกต่างสำคัญ

⑦ ตาราง start กับ ensure

สถานะก่อนสั่งstartensure
StoppedStartStart
Startedไม่ทำ Restart แบบ ensureRestart
Resource ไม่มีError/หาไม่พบError/หาไม่พบ

ดังนั้นถ้าต้องการบอกว่า

Resource นี้ต้องทำงานอยู่

ensure เหมาะมาก

⑧ ทำไม server.cfg นิยมใช้ ensure

ตัวอย่าง Vanilla FXServer Configuration ปัจจุบันของ Cfx.re ใช้ Pattern

ensure mapmanager
ensure chat
ensure spawnmanager
ensure sessionmanager

เหตุผลคือ Configuration กำลังบอก Desired State ว่า Resource เหล่านี้ต้องทำงาน

อ่านแล้วเข้าใจง่าย

ensure
=
ทำให้แน่ใจว่า Resource อยู่ในสถานะ Started

⑨ restart คืออะไร

คำสั่ง

restart my_resource

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

Concept คือ

Resource Running
↓
Stop
↓
Start
↓
Resource Running ใหม่

มีประโยชน์มากตอน Development

⑩ เมื่อไรควรใช้ restart

ตัวอย่างคุณแก้

client.lua

หรือ

server.lua

แล้วต้องการ Reload Resource

ใช้

restart my_resource

ไม่จำเป็นต้อง Restart FXServer ทั้งหมด

นี่ช่วยให้เขียน Script ได้เร็วขึ้นมาก

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

ถ้า Resource กำลัง Started

restart my_resource

และ

ensure my_resource

ต่างก็ทำให้เกิด Restart ตาม Behavior ปัจจุบัน

แต่ถ้า Resource Stopped

restart

ไม่ได้มีพฤติกรรมเหมือน ensure

ขณะที่

ensure

จะ Start Resource ให้

จำง่าย ๆ ว่า

ensure
→ Start หรือ Restart ตามสถานะ

⑫ stop คืออะไร

ใช้

stop my_resource

เพื่อหยุด Resource ที่กำลัง Started อยู่

เมื่อ Resource Stop

Client Runtime ของ Resource
Server Runtime ของ Resource

จะถูกหยุดตาม Lifecycle

Resource ที่เขียนดีควรออกแบบให้รับมือกับการ Stop ได้

⑬ stop ใช้ตอนไหน

ตัวอย่าง

  • ปิด Script ชั่วคราว

  • Debug ปัญหา

  • ปิด Resource ที่กิน CPU

  • ทดสอบ Dependency

  • ปิด Feature

  • เตรียม Update Resource

เช่น

stop my_garage

Garage Resource จะหยุดทำงานโดยไม่ต้องปิด FXServer

⑭ stop Resource แล้วผู้เล่นหลุดไหม

โดยทั่วไปการ Stop Resource หนึ่งไม่ได้หมายความว่า Player ทุกคนจะ Disconnect

แต่ผลกระทบขึ้นกับ Resource นั้น

ถ้าหยุด

garage

อาจมีเพียง Garage ใช้ไม่ได้

แต่ถ้าหยุด

framework core

Resource จำนวนมากอาจทำงานผิดปกติ

ดังนั้นผลกระทบขึ้นกับ Dependency Architecture

⑮ restart Resource ทำให้ Player หลุดไหม

โดยทั่วไปไม่จำเป็นต้อง Disconnect Player

แต่ Resource ที่กำลังจัดการ

  • Character

  • Inventory

  • Session

  • NUI

  • Vehicle

  • Voice

  • Framework State

อาจมีผลกระทบกับ Player

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

⑯ restart Resource แล้ว Variable จะเกิดอะไร

ตัวแปร Runtime จะถูกสร้างใหม่

สมมติ server.lua

local Players = {}

ระหว่าง Resource ทำงาน Table มีข้อมูล

Players
├── 1
├── 7
└── 24

เมื่อ Resource Restart

Runtime เดิมถูกหยุด
↓
Variable เดิมหาย
↓
Script โหลดใหม่
↓
Players = {}

ดังนั้น Runtime Variables ไม่ใช่ Persistence

⑰ ข้อมูลไหนควรอยู่ Database

ถ้าข้อมูลต้องอยู่หลัง

Resource Restart
Server Restart

ควรพิจารณา Persistent Storage เช่น Database

เช่น

Player Money
Vehicle Ownership
House Ownership
Inventory
Account Data

ไม่ควรเก็บเฉพาะ Local Table แล้วหวังว่าจะไม่ Restart Resource

⑱ State อะไรเก็บใน Memory ได้

ข้อมูลชั่วคราว เช่น

Active Mission
Temporary Cooldown
Cached Query
Current Lobby
Runtime Handler
Temporary Instance

อาจเก็บใน Memory ได้

แต่ต้องออกแบบว่า Resource Restart แล้ว State เหล่านี้ควรถูก Restore หรือ Reset อย่างไร

⑲ restart กับ Resource Lifecycle

เมื่อ Restart จะมี Lifecycle ประมาณ

Resource Running
↓
Resource Stop
↓
Cleanup
↓
Resource Start
↓
Initialization
↓
Running

ดังนั้น Resource ควรมี Initialization และ Cleanup ที่ทำซ้ำได้

⑳ onResourceStart คืออะไร

Server Resource สามารถตรวจ Start

AddEventHandler(
    'onResourceStart',
    function(resourceName)

        if resourceName ~=
            GetCurrentResourceName() then
            return
        end

        print(
            'Resource started'
        )
    end
)

เหมาะกับ

  • Initialize Cache

  • Load Database Data

  • Setup State

  • Debug Startup

㉑ onResourceStop คืออะไร

ใช้จับ Resource Stop

AddEventHandler(
    'onResourceStop',
    function(resourceName)

        if resourceName ~=
            GetCurrentResourceName() then
            return
        end

        print(
            'Resource stopped'
        )
    end
)

เป็นจุดสำคัญสำหรับ Cleanup

㉒ Client มี Resource Lifecycle ไหม

มี Event อย่าง

onClientResourceStart

และ

onClientResourceStop

ตัวอย่าง

AddEventHandler(
    'onClientResourceStop',
    function(resourceName)

        if resourceName ~=
            GetCurrentResourceName() then
            return
        end

        SetNuiFocus(
            false,
            false
        )
    end
)

ช่วยป้องกัน NUI Focus ค้างหลัง Resource Stop

㉓ NUI ต้อง Cleanup ตอน stop ไหม

ควร

สมมติ Resource เปิด Inventory NUI

SetNuiFocus(
    true,
    true
)

แล้ว Resource ถูก Stop

ถ้าไม่ Cleanup ผู้เล่นอาจเจอ

Mouse ค้าง
Keyboard ค้าง
Focus ผิด
UI State แปลก

จึงควรคืน Focus

SetNuiFocus(
    false,
    false
)

ตอน Resource Stop ตาม Architecture

㉔ Camera ต้อง Cleanup ไหม

ถ้า Resource สร้าง Script Camera

Character Creator
Vehicle Preview
Housing Camera

แล้วถูก Restart

ควร Destroy Camera และ Restore Gameplay Camera

ไม่เช่นนั้น Player อาจติดอยู่ใน Camera State ที่ผิด

㉕ Blip ต้อง Cleanup ไหม

ถ้า Resource สร้าง Blips Runtime

ควรเก็บ Handles แล้ว Remove ตอน Resource Stop

ตัวอย่าง Concept

for _, blip in ipairs(Blips) do

    if DoesBlipExist(blip) then
        RemoveBlip(blip)
    end
end

ช่วยให้ Restart Resource ไม่สร้าง Blip ซ้ำ

㉖ Entity ต้อง Cleanup ไหม

ถ้า Resource เป็นผู้สร้าง Temporary

  • Vehicle

  • Ped

  • Object

ควรออกแบบ Lifecycle

Create
↓
Track
↓
Use
↓
Stop/Complete
↓
Delete

ไม่ควรสมมติว่า Restart แล้วทุก Entity จะหายอย่างที่ต้องการเสมอ

㉗ ตัวอย่าง Entity Cleanup

local entities = {}

AddEventHandler(
    'onResourceStop',
    function(resourceName)

        if resourceName ~=
            GetCurrentResourceName() then
            return
        end

        for _, entity in ipairs(
            entities
        ) do

            if DoesEntityExist(
                entity
            ) then

                DeleteEntity(
                    entity
                )
            end
        end
    end
)

Resource จริงต้องพิจารณา Client/Server Ownership และ Entity Type เพิ่มเติม

㉘ Resource Restart แล้ว Thread เก่าทำต่อไหม

Runtime ของ Resource ถูกหยุด

Threads ของ Resource เดิมจึงไม่ควรถูกมองว่าจะทำงานต่อเหมือนเดิม

หลัง Start ใหม่ Code จะสร้าง Threads ใหม่ตาม Script

นี่เป็นอีกเหตุผลที่ Initialization ต้องไม่สร้าง Duplicate State ภายนอก Resource

㉙ Timer ต้องออกแบบ Restart-safe ไหม

ควร

เช่น Resource มี

Daily Reward Timer
Mission Timer
Cooldown Timer

ถ้าใช้เพียง Memory

restart resource
↓
timer reset

อาจทำให้ Player Abuse ได้

Security-sensitive Cooldown อาจต้องเก็บ Timestamp ใน Server State หรือ Database ตามระดับความสำคัญ

㉚ restart Database Resource ต้องระวังอะไร

มาก

สมมติ Resources จำนวนมากพึ่ง

oxmysql

ถ้า Restart Database Dependency ขณะ Server ทำงาน อาจกระทบ

  • Queries

  • Transactions

  • Resource Initialization

  • Pending Operations

ไม่ควร Restart Critical Dependency บน Production โดยไม่มีเหตุผล

㉛ restart Framework Core ต้องระวังอะไร

เช่น

es_extended
qb-core
custom_core

อาจมี Resources จำนวนมากพึ่ง

  • Player Objects

  • Exports

  • Events

  • Shared State

เมื่อ Core Restart Consumer Resources อาจไม่ได้ Reinitialize อย่างสมบูรณ์

บาง Server จึงเลือก Restart Server ทั้ง Instance สำหรับ Core Update สำคัญแทน Restart Resource เดียว

㉜ ensure Dependency ซ้ำจะเกิดอะไร

นี่เป็นจุดที่ต้องเข้าใจ Behavior

ถ้า

oxmysql

Started อยู่แล้ว แล้วคุณพิมพ์

ensure oxmysql

Cfx.re ระบุว่า ensure จะ Restart Resource ที่กำลัง Started

ดังนั้นอย่าสั่ง ensure Critical Dependency ซ้ำเพียงเพราะคิดว่า

แค่ตรวจว่ามันทำงานอยู่

เพราะอาจทำให้มัน Restart จริง

㉝ ensure ไม่ใช่ read-only check

นี่สำคัญมาก

ชื่อ ensure อาจทำให้คิดว่า

ตรวจเฉย ๆ ว่าทำงานไหม

แต่ Behavior คือ

Stopped
→ Start

Started
→ Restart

ดังนั้นบน Production ต้องใช้ด้วยความเข้าใจ

㉞ ถ้าอยากเช็กว่า Resource ทำงานอยู่ทำอย่างไร

อย่าใช้ ensure เป็นเครื่องมือตรวจเฉย ๆ

สามารถดู

  • Server Console

  • txAdmin Resource Management

  • Resource State APIs ใน Script

  • Logs

ตาม Use Case

ใน Script ยังมี Native สำหรับอ่าน Resource State ตาม API ที่รองรับ

㉟ start Resource ที่ Started อยู่ใช้แทน check ได้ไหม

ไม่ควรใช้ Commands ที่เปลี่ยน State เป็น Monitoring Mechanism

Resource State ควรถูกตรวจด้วยเครื่องมือหรือ API สำหรับ Inspection

Command start, stop, restart, ensure มีไว้เปลี่ยน State

㊱ refresh คืออะไร

แม้ไม่อยู่ใน 4 คำสั่งหลักของหัวข้อนี้ แต่เกี่ยวข้องโดยตรง

refresh

ใช้ Rescan Folder

resources/

และโหลด Resource Manifests ใหม่

ทำให้ Resource ที่เพิ่ง Copy เข้ามาพร้อมถูก Start

㊲ เพิ่ม Resource ใหม่ต้องทำอย่างไร

สมมติ Copy

resources/[local]/new_script/

เข้ามาระหว่าง FXServer ทำงาน

ใช้

refresh

แล้ว

ensure new_script

Flow คือ

Copy Resource
↓
refresh
↓
FXServer พบ Manifest
↓
ensure
↓
Resource Start

㊳ แก้ Code ใน Resource เดิมต้อง refresh ไหม

โดยทั่วไปถ้าเพียงแก้ Script ภายใน Resource ที่ FXServer รู้จักอยู่แล้ว มักใช้

restart resource_name

เพื่อ Reload

refresh เหมาะโดยเฉพาะกับการเพิ่ม Resource หรือ Manifest Discovery

หากเปลี่ยน Resource Structure/Manifest อาจใช้ refresh ตามสถานการณ์

㊴ เปลี่ยน fxmanifest.lua แล้วทำอย่างไร

เพื่อความชัดเจนระหว่าง Development สามารถ

refresh
restart resource_name

หรือ Workflow ที่เหมาะสมกับการเปลี่ยน Manifest

โดยเฉพาะเมื่อเพิ่ม/ลบ Resource หรือ Dependencies

อย่าพึ่ง Runtime เดิมหลัง Manifest เปลี่ยนอย่างมีนัยสำคัญ

㊵ Category Start ได้ไหม

Cfx.re รองรับ Category Name

เช่น Folder

resources/
└── [cars]/
    ├── car_a/
    ├── car_b/
    └── car_c/

สามารถใช้

start [cars]

ได้

และ Resource Commands หลายตัวรองรับ Category ตาม Documentation

㊶ ensure Category ได้ไหม

ได้ตาม Server Commands Documentation

เช่น

ensure [cars]

แต่ต้องระวังว่า Resource ที่กำลัง Started ภายใน Category อาจถูก Restart ตาม Behavior ของ ensure

ดังนั้นอย่าใช้กับ Category ใหญ่บน Production โดยไม่เข้าใจผลกระทบ

㊷ restart Category ได้ไหม

เอกสาร Cfx.re ระบุว่า restart รองรับ Category Names

เช่น

restart [vehicles]

อาจ Restart Resources จำนวนมากพร้อมกัน

เหมาะสำหรับ Development บางกรณี

แต่ Production ต้องระวัง Load Spike และ Dependencies

㊸ stop Category ได้ไหม

stop รองรับ Category เช่นเดียวกัน

ตัวอย่าง

stop [test]

ทำให้ Resources ใน Category ถูกหยุด

อย่าใช้กับ Category ที่มี Core Resource โดยไม่ตรวจสิ่งที่พึ่งพาอยู่

㊹ Resource Category ไม่ใช่ Dependency Group

Folder

[jobs]

เพียงจัด Resources เป็น Category

ไม่ได้หมายความว่า Resources ภายในมี Dependency กันอัตโนมัติ

เช่น

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

แต่ละ Resource ยังต้องประกาศ Dependencies ของตัวเองผ่าน Manifest

㊺ server.cfg ควรใช้ start หรือ ensure

สำหรับ Resources ที่ต้องทำงานทุกครั้งที่ Server Start ปัจจุบันมักใช้

ensure resource_name

ตัวอย่าง

ensure ox_lib
ensure oxmysql
ensure my_core
ensure my_inventory
ensure my_garage

ตรงกับตัวอย่าง Vanilla Configuration ของ Cfx.re

㊻ server.cfg ควรจัดลำดับอย่างไร

จัดตาม Dependency

# Libraries
ensure ox_lib
ensure oxmysql

# Framework/Core
ensure my_core

# Systems
ensure my_inventory
ensure my_garage

# Jobs
ensure police_job
ensure ambulance_job

ทำให้เปิด Config แล้วเข้าใจ Architecture ทันที

㊼ ensure แก้ Dependency ได้ทั้งหมดไหม

ไม่

แม้จะจัด

ensure oxmysql
ensure garage

Resource garage ก็ควรประกาศ Dependency ใน Manifest หากมันจำเป็นจริง

เช่น

dependency 'oxmysql'

Server Configuration กับ Resource Dependency ทำงานคนละระดับ

㊽ stop Dependency แล้ว Consumer หยุดด้วยไหม

ไม่ควรสมมติว่า Resource Consumer จะถูก Stop ตามแบบอัตโนมัติทุกกรณี

ตัวอย่าง

garage
→ พึ่ง core

คุณสั่ง

stop core

Garage อาจยังอยู่ในสถานะ Started แต่ APIs ที่ต้องใช้จาก Core ใช้งานไม่ได้

จึงอาจเกิด

No such export
nil state
callbacks fail

ขึ้นกับ Architecture

㊾ ทำไม Stop Core อันตราย

เพราะระบบอาจอยู่ในสถานะ

Resource Started
แต่ Dependency ไม่พร้อม

ถ้า Resource ไม่มี Runtime Recovery Logic มันอาจไม่กลับมาทำงานสมบูรณ์แม้ Core Start ใหม่

นี่เป็นเหตุผลที่ Critical Dependency Restart ต้องวางแผน

㊿ ถ้า Dependency Restart ควร Restart Consumer ด้วยไหม

ขึ้นกับ Resource

บาง Resource สามารถ Detect/Reinitialize ได้

บาง Resource Initialize Dependency เพียงครั้งเดียวตอน Start

กรณีหลังอาจต้อง Restart Consumer ตามลำดับ

เช่น

restart my_core
↓
restart my_inventory
↓
restart my_garage

แต่ Production ควรทดสอบ Architecture ของ Server จริงก่อน

51 ตัวอย่าง Development Workflow

หลังแก้ my_garage/server/main.lua

ใช้

restart my_garage

จากนั้นตรวจ

Server Console
Client F8
Garage feature

ไม่จำเป็นต้อง

restart oxmysql
restart my_core

หากไม่ได้แก้ Dependencies เหล่านั้น

Restart ให้น้อยที่สุด

52 อย่า Restart ทุก Resource หลังแก้ไฟล์เดียว

วิธีที่ไม่ดี

แก้ garage
↓
restart oxmysql
↓
restart core
↓
restart inventory
↓
restart garage
↓
restart jobs

สร้าง Side Effects มากเกินไป

ควร Restart เฉพาะ Resource ที่เปลี่ยนและ Dependencies/Consumers ที่จำเป็นจริง

53 Production Update ควรทำอย่างไร

สำหรับ Resource สำคัญควรมีขั้นตอน

Backup
↓
Update Files
↓
ตรวจ Dependency
↓
กำหนด Maintenance Window ถ้าจำเป็น
↓
Restart Resource/Server ตาม Impact
↓
ตรวจ Console
↓
Test Feature

ไม่ควร Upload แล้วพิมพ์ ensure หลาย Resource แบบสุ่ม

54 Resource Restart แล้ว Event Handler ซ้ำไหม

Runtime เก่าถูกหยุดและ Runtime ใหม่ Register Handlers ใหม่

ภายใน Resource เดียวจึงไม่ควรคง Handler เก่าต่อเหมือน Code ถูก Execute ซ้ำใน Runtime เดียว

แต่ External State ที่ Resource สร้างไว้ เช่น Entity หรือ Database State ยังต้องออกแบบ Cleanup แยก

55 Resource Restart แล้ว NUI Browser เกิดอะไร

Resource/NUI Context สามารถถูก Reload ตาม Resource Lifecycle

Resource ที่ดีควรทำให้ UI สามารถ

Start
↓
Initialize
↓
Stop
↓
Clean
↓
Start ใหม่

ได้โดยไม่ต้องให้ Player Reconnect

ถ้าต้อง Reconnect ทุกครั้งที่ Restart UI Resource แสดงว่า Lifecycle Design อาจยังไม่ดี

56 Resource Restart แล้ว Cache หายไหม

ถ้า Cache อยู่ใน Lua Table เช่น

local VehicleCache = {}

จะหายเมื่อ Resource Runtime Restart

ถ้าต้องการ Cache ใหม่ ต้องสร้าง Initialization

local function loadCache()

    -- query database
    -- rebuild cache

end

AddEventHandler(
    'onResourceStart',
    function(resourceName)

        if resourceName ~=
            GetCurrentResourceName() then
            return
        end

        loadCache()
    end
)

57 Resource Stop กับ Database Data

การ Stop Resource ไม่ได้หมายความว่าข้อมูลใน Database ถูกลบ

Database เป็น External Persistent Storage

ดังนั้น

Runtime Tables
→ หาย

แต่

Database Records
→ ยังอยู่

ตาม Transaction/Query ที่บันทึกเสร็จแล้ว

58 ตัวอย่าง Resource ที่ Restart-safe

server.lua

local Cache = {}

local function initialize()

    Cache = {}

    print(
        '[my_resource] initialized'
    )
end

local function cleanup()

    Cache = {}

    print(
        '[my_resource] cleaned'
    )
end

AddEventHandler(
    'onResourceStart',
    function(resourceName)

        if resourceName ~=
            GetCurrentResourceName() then
            return
        end

        initialize()
    end
)

AddEventHandler(
    'onResourceStop',
    function(resourceName)

        if resourceName ~=
            GetCurrentResourceName() then
            return
        end

        cleanup()
    end
)

Resource นี้มี Lifecycle ที่ชัดกว่า Code ที่สมมติว่าจะ Start เพียงครั้งเดียวตลอดอายุ Server

59 Checklist ก่อน start, ensure, restart หรือ stop

ตรวจ

① Resource Name ถูกไหม?
② Resource มี Manifest หรือไม่?
③ FXServer รู้จัก Resource หรือยัง?
④ ถ้าเพิ่งเพิ่ม ใช้ refresh หรือยัง?
⑤ Resource มี Dependency อะไร?
⑥ Dependency Start อยู่หรือไม่?
⑦ Resource เป็น Critical Core หรือไม่?
⑧ Player กำลังใช้ Feature อยู่หรือไม่?
⑨ Restart แล้ว Runtime State หายอะไร?
⑩ Database Data ปลอดภัยหรือไม่?
⑪ Temporary Entities จะถูก Cleanup หรือไม่?
⑫ NUI Focus จะถูก Reset หรือไม่?
⑬ Camera จะถูก Destroy หรือไม่?
⑭ Blips จะถูก Remove หรือไม่?
⑮ Consumer Resource พึ่ง Resource นี้หรือไม่?
⑯ Resource รองรับ Restart กลางเกมหรือไม่?
⑰ ต้อง Restart Consumer ต่อหรือไม่?
⑱ Production หรือ Development?
⑲ Console มี Error หลัง Start หรือไม่?
⑳ Client F8 มี Error หรือไม่?

⑥⓪ ตารางสรุป start, ensure, restart และ stop

CommandResource StoppedResource Startedใช้เมื่อ
startStartไม่ได้ทำ Restart แบบ ensureเปิด Resource ที่หยุดอยู่
ensureStartRestartserver.cfg, ทำให้ Resource อยู่ในสถานะ Started
restartไม่ทำหน้าที่ Start แบบ ensureRestartReload Resource ที่กำลังทำงาน
stopไม่มีอะไรต้องหยุดStopปิด Resource

จำแบบง่ายที่สุด

start
= เปิด

stop
= ปิด

restart
= ปิดแล้วเปิดใหม่

ensure
= ทำให้มันทำงาน
  ถ้ายังไม่ทำงาน → Start
  ถ้าทำงานอยู่ → Restart

ตัวอย่าง server.cfg ที่เหมาะสม

# Libraries
ensure ox_lib
ensure oxmysql

# Core
ensure my_core

# Systems
ensure my_inventory
ensure my_garage

# Jobs
ensure police_job
ensure ambulance_job

ใช้ Manifest Dependencies เพิ่มด้วยหาก Resource ต้องพึ่งกันจริง

ตัวอย่าง my_garage/fxmanifest.lua

fx_version 'cerulean'
game 'gta5'

dependencies {
    'oxmysql',
    'my_core'
}

shared_script 'shared/config.lua'

client_script 'client/main.lua'

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

Architecture จึงเป็น

FXServer Start
↓
ox_lib
↓
oxmysql
↓
my_core
↓
inventory / garage
↓
jobs

อ่านง่ายและ Debug ง่ายกว่า Resource Order ที่วางแบบสุ่ม

ตัวอย่างขั้นตอนเพิ่ม Resource ใหม่

สมมติเพิ่งเพิ่ม

resources/[local]/com_garage

ขณะ FXServer ทำงาน

ใช้

refresh

แล้ว

ensure com_garage

หลังจากนั้นเพิ่มใน server.cfg

ensure com_garage

เพื่อให้ Start ตอนเปิด Server ครั้งถัดไปด้วย

ตัวอย่างขั้นตอนแก้ Code Resource เดิม

แก้

com_garage/server/main.lua

บันทึกไฟล์

จากนั้น Server Console

restart com_garage

ทดสอบ Feature

ถ้าไม่มี Dependency/Manifest Changes ก็ไม่ควร Restart Resources อื่นโดยไม่จำเป็น

ตัวอย่างกรณีต้อง stop

สมมติสงสัยว่า custom_hud ทำให้ Client FPS ลด

สามารถทดสอบ

stop custom_hud

แล้วดูผล

เมื่อจะเปิดกลับ

start custom_hud

หรือ

ensure custom_hud

แต่จำว่า ensure หาก Resource Started อยู่จะ Restart

คำถามที่พบบ่อยเกี่ยวกับ start, ensure, restart และ stop

FiveM start คืออะไร

ใช้ Start Resource ที่กำลัง Stopped

start my_resource

FiveM ensure คืออะไร

ถ้า Resource ยังไม่ Started จะ Start และถ้า Started อยู่แล้วจะ Restart

ensure my_resource

FiveM restart คืออะไร

Restart Resource ที่กำลัง Started

restart my_resource

FiveM stop คืออะไร

หยุด Resource ที่กำลัง Started

stop my_resource

start กับ ensure เหมือนกันไหม

ไม่ ถ้า Resource Started อยู่แล้ว ensure จะ Restart Resource

ensure กับ restart เหมือนกันไหม

เฉพาะตอน Resource Started อยู่ ทั้งคู่ทำให้เกิด Restart แต่ถ้า Resource Stopped ensure สามารถ Start ได้

server.cfg ควรใช้ start หรือ ensure

Configuration ปัจจุบันของ Cfx.re นิยมใช้ ensure

แก้ client.lua แล้วต้อง Restart Server ไหม

ส่วนใหญ่ไม่ จำเป็นเพียง Restart Resource ที่เกี่ยวข้อง

แก้ server.lua แล้วทำอย่างไร

ใช้

restart resource_name

แล้วตรวจ Server Console

เพิ่ม Resource ใหม่ต้องทำอะไร

โดยทั่วไป

refresh
ensure resource_name

refresh คืออะไร

Rescan resources/ และโหลด Resource Manifests ใหม่

stop Resource แล้ว Player หลุดไหม

ไม่จำเป็น แต่ขึ้นกับ Resource และระบบที่ Resource นั้นควบคุม

Restart Framework Core ได้ไหม

ได้ในเชิง Command แต่มีความเสี่ยงสูงเพราะ Consumer Resources จำนวนมากอาจพึ่งมัน จึงต้องทดสอบ Architecture ก่อน

Restart oxmysql ได้ไหม

ควรหลีกเลี่ยงการ Restart บน Production โดยไม่มีเหตุผล เพราะ Resources จำนวนมากอาจมี Database Operations พึ่งอยู่

ensure oxmysql ซ้ำเป็นเพียงการเช็กไหม

ไม่ หาก oxmysql Started อยู่ ensure จะ Restart ตาม Behavior ปัจจุบัน

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

Runtime Variables จะถูกสร้างใหม่

Database หายไหม

ข้อมูลที่บันทึกใน Database แล้วไม่หายเพียงเพราะ Resource Restart

NUI ต้อง Cleanup ตอน Stop ไหม

ควร โดยเฉพาะ SetNuiFocus(false, false) และ UI State ที่ Resource สร้าง

Entity ต้อง Cleanup ตอน Resource Stop ไหม

Temporary Entities ที่ Resource เป็นเจ้าของ Lifecycle ควรมี Cleanup Strategy

Category สามารถ start ได้ไหม

ได้ เช่น

start [cars]

ensure Category ได้ไหม

รองรับ แต่ต้องระวัง Resource ที่ Started อยู่จะถูก Restartตาม Behavior ของ ensure

restart Category ได้ไหม

รองรับ

stop Category ได้ไหม

รองรับตาม Resource Commands

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

ดู FXServer Console และตรวจ Manifest/Dependencies ก่อน

Restart แล้ว No such export เกิดขึ้นทำไม

อาจเพราะ Dependency ถูก Restart/Stopped, Export ยังไม่พร้อม, API เปลี่ยน หรือ Client/Server Context ผิด ต้อง Debug Dependency แยก

สรุป FiveM start, ensure, restart และ stop ต่างกันอย่างไร

คำสั่งทั้ง 4 ตัวใช้ควบคุม FiveM Resource แต่ Behavior แตกต่างกันชัดเจน

start
→ Start Resource ที่ Stopped
ensure
→ Stopped = Start
→ Started = Restart
restart
→ Restart Resource ที่ Started
stop
→ Stop Resource ที่ Started

ถ้ากำลังเขียน Script และแก้ Code ของ Resource ที่ทำงานอยู่

restart my_resource

มักตรงวัตถุประสงค์ที่สุด

ถ้าเพิ่งเพิ่ม Resource ใหม่

refresh
ensure my_resource

เป็น Workflow ที่ใช้ได้ดี

และถ้าต้องการให้ Resource เปิดทุกครั้งเมื่อ FXServer Start

ensure my_resource

เหมาะสำหรับ server.cfg

จุดที่ต้องจำมากที่สุดคือ

ensure
≠
แค่ตรวจว่า Resource ทำงานอยู่

เพราะถ้า Resource Started อยู่แล้ว มันจะ Restart Resource

ดังนั้นอย่าใช้

ensure oxmysql
ensure framework_core

ซ้ำบน Production เพียงเพราะต้องการเช็กสถานะ

สำหรับ Developer ที่เรียน FiveM กับ comsiam ควรออกแบบ Resource ให้สามารถ start, stop และ restart ได้อย่างสะอาดตั้งแต่แรก โดยเฉพาะการ Cleanup Entity, NUI Focus, Camera, Blip และ Runtime State

อีกหลักสำคัญจาก comsiam คือ Restart Resource ให้น้อยที่สุดเท่าที่จำเป็น หากแก้ Garage ก็ไม่ควร Restart Database, Framework และ Resource ทั้ง Serverตามไปด้วยโดยไม่มีเหตุผล เพราะยิ่ง Restart Dependency สำคัญมากเท่าไร Side Effects และโอกาสเกิด State ไม่ตรงกันก็ยิ่งสูงขึ้น

หัวข้อถัดไปคือ FiveM Resource ไม่ Start แก้อย่างไร ซึ่งจะรวมสาเหตุจริงที่พบบ่อยตั้งแต่ Couldn't find resource, ไม่มี fxmanifest.lua, Manifest Syntax Error, Missing Dependency, No such export, File Path ผิด, Resource Crash และวิธีไล่ Server Console ทีละขั้น

Comments

Popular posts from this blog

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

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

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