FiveM Enhanced State Bags เปลี่ยนอะไรบ้าง

FiveM Enhanced ปรับระบบ State Bags ครั้งสำคัญ โดยเน้นลด Network Overhead, ทำ Replication ให้ชัดเจนขึ้น และแก้ปัญหา Change Handler ทำงานก่อน Entity พร้อมใช้งาน

การเปลี่ยนแปลงหลักที่ Cfx.re ระบุ ได้แก่

  • ส่งผ่าน Network เฉพาะ State ที่มี Replication Intent

  • Change Listener จะทำงานเมื่อ Entity มีอยู่ฝั่งรับแล้ว

  • การ Set State Bags เร็วขึ้นโดยเฉลี่ยประมาณ 10 เท่าในการทดสอบของ Cfx.re

  • ลด Networking Overhead

  • ลด Hitch ที่เกี่ยวข้องกับ State Bag

  • ยังรองรับ Player State, Entity State และ Global State

  • สามารถกำหนด Replication แบบ Explicit ผ่าน state:set()

  • มี sv_stateBagStrictMode สำหรับจำกัดการเขียน State ให้ Server เท่านั้น

จุดสำคัญคือ Resource Legacy ที่ใช้ State Bags อาจยัง Start ได้ตามปกติ แต่ Behavior ด้าน Replication และ Timing บางส่วนเปลี่ยนไป

ดังนั้น Resource ประเภท

  • Vehicle State

  • Door

  • Job/Duty

  • Housing

  • Police

  • Inventory Integration

  • Target

  • Entity Metadata

ควรได้รับ Multiplayer Test ก่อนขึ้น Enhanced Production

บทความนี้จาก comsiam จะอธิบายตั้งแต่ State Bags คืออะไร ไปจนถึงสิ่งที่ Developer ต้องแก้เมื่อย้ายจาก Legacy ไป Enhanced

① FiveM State Bags คืออะไร?

State Bags คือระบบสำหรับผูกข้อมูล Key/Value เข้ากับ Object ใน FiveM Networking

เช่น

Entity
Player
Global State

ตัวอย่างรถหนึ่งคันอาจมี State

locked = true
fuel = 72
owner = 15

Resource อื่นสามารถอ่าน State เหล่านี้ได้โดยไม่ต้องสร้าง Custom Network Event สำหรับทุกค่า

② State Bag มีประโยชน์อะไร?

ใช้กับข้อมูลที่ต้องการให้หลาย Resource หรือหลาย Client เข้าใจ State เดียวกัน

เช่น

  • รถล็อกหรือไม่

  • Player เข้าเวรหรือไม่

  • Entity ถูกใช้งานหรือไม่

  • Door เปิดหรือปิด

  • Mission Object อยู่สถานะไหน

จึงเหมาะกับ State-driven Gameplay

③ State Bags มีประเภทอะไร?

หลัก ๆ มี

Entity State

ผูกกับ Entity

Entity(vehicle).state

Player State

ผูกกับ Player

Player(source).state

หรือ Client

LocalPlayer.state

Global State

State ระดับ Server ที่ Client อ่านได้

GlobalState

แต่แต่ละประเภทมี Policy การเขียนแตกต่างกัน

④ ตัวอย่าง Entity State

ตัวอย่าง

local state = Entity(vehicle).state
state.locked = true

ใช้เก็บ State ของ Vehicle

แต่ต้องเข้าใจเรื่อง Ownership และ Replication ก่อนนำไปใช้จริง

⑤ ตัวอย่าง Player State

ฝั่ง Server

Player(source).state.duty = true

จากนั้น Client ที่ได้รับ State สามารถอ่านสถานะ Duty ของ Player ตาม Scope/Replication ที่เกี่ยวข้อง

เหมาะกับ

  • Job

  • Duty

  • Status

  • Gameplay Flag

⑥ GlobalState คืออะไร?

เป็น State ระดับ Global ที่ Server เป็นผู้กำหนดและ Client สามารถอ่านได้

ตัวอย่าง

GlobalState.weatherMode = 'normal'

เหมาะกับข้อมูลที่ Client หลายคนต้องรู้เหมือนกัน

แต่ไม่ควรใส่ Sensitive Data ลง GlobalState

⑦ FiveM Enhanced เปลี่ยน State Bags ตรงไหนใหญ่ที่สุด?

จุดใหญ่คือ Replication Intent

Cfx.re ระบุว่าใน Legacy มีการ Replicate Values โดยไม่คำนึงถึง Intent มากเท่าปัจจุบัน

ส่วน Enhanced จะส่งค่าผ่าน Network เฉพาะ State ที่ถูกกำหนดให้ Replicate

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

⑧ Replication คืออะไร?

Replication คือการส่ง State จากฝั่งหนึ่งไปยังอีกฝั่ง

ตัวอย่าง

Server
↓
locked = true
↓
Client A
Client B

ถ้า State ไม่จำเป็นต้องออกจาก Local Context ก็ไม่ควรถูกส่งผ่าน Network

⑨ Legacy Replication มี Overhead อย่างไร?

ถ้า State จำนวนมากถูกส่งแม้ไม่ได้มีความตั้งใจให้ Replicate

จะเกิด Network Traffic เพิ่มโดยไม่จำเป็น

Server ที่มี

  • Player มาก

  • Entity มาก

  • State Bags มาก

จะเห็นผลชัดขึ้น

Enhanced จึงทำ Replication Intent ให้มีความสำคัญมากขึ้น

⑩ Enhanced ส่ง State ทุกตัวหรือไม่?

ไม่

Enhanced เปลี่ยนไปส่งเฉพาะค่าที่ถูกกำหนดเป็น Replicated ตาม Behavior ของระบบ

นี่ช่วยลด Network Overhead

และทำให้ Developer ต้องคิดให้ชัดว่า State ไหนควร

  • Local

  • Replicated

⑪ Default Replication ปัจจุบันทำงานอย่างไร?

เอกสาร State Bags ระบุว่า

Set จาก Server

โดย Default จะ Replicate

Set จาก Client

โดย Default จะไม่ Replicate

และสามารถ Override เป็นรายค่าได้ผ่าน

state:set(key, value, replicate)

⑫ ตัวอย่าง Server State ที่ไม่ต้อง Replicate

ถ้าต้องการเก็บ State บน Server เท่านั้น

ใช้

Entity(vehicle).state:set('internalOwner', 25, false)

ค่า false คือไม่ส่ง State นี้ผ่าน Network

เหมาะกับข้อมูล Internal Logic

⑬ ตัวอย่าง Client State ที่ต้องส่ง Server

Client อาจใช้

Entity(entity).state:set('taskAck', 'done', true)

ค่า true คือขอ Replicate State

แต่ Server Developer ไม่ควร Trust ข้อมูลสำคัญจาก Client โดยไม่มี Validation

⑭ ทำไม Explicit Replication ถึงสำคัญ?

เพราะช่วยแยกให้ชัดว่า

State A → ใช้เฉพาะ Local
State B → ต้องส่ง Network

ยิ่ง Server มี Entity จำนวนมาก การไม่ส่งข้อมูลที่ไม่จำเป็นช่วยลด Network Load

⑮ State Bag Set เร็วขึ้นจริงไหม?

Cfx.re ระบุว่าในการทดสอบของ Enhanced

State Bag Sets เร็วขึ้นโดยเฉลี่ยประมาณ 10 เท่า

พร้อมลด Network Overhead และ Hitch

แต่ตัวเลขนี้เป็นผลทดสอบของ Platform ไม่ใช่การรับประกันว่า Resource ทุกตัวจะเร็วขึ้น 10 เท่า

⑯ ทำไม State Bags เร็วขึ้นจึงสำคัญ?

Resource Server ใหญ่สามารถ Set State จำนวนมาก เช่น

  • Vehicles

  • Doors

  • Players

  • Mission Entities

ถ้าการ Set State มี Overhead สูง อาจเกิด

  • Frame Hitch

  • Server Hitch

  • Networking Delay

Optimization ตรงนี้จึงมีประโยชน์มาก

⑰ Change Handler เปลี่ยนอะไร?

นี่เป็น Breaking Behavior ที่สำคัญ

ใน Legacy Change Listener สามารถถูกเรียกตอนที่ Entity ฝั่งรับยังไม่มีอยู่

Enhanced เปลี่ยนให้ Handler ทำงานเมื่อ Entity มีอยู่แล้ว

ช่วยลด Race Condition

⑱ Race Condition แบบเก่าเป็นอย่างไร?

สมมติ State ถูกส่งมา

vehicle.locked = true

แต่ Client ยังไม่ได้ Stream Vehicle Entity เข้ามา

Handler อาจทำงานก่อนแล้วเรียก Native กับ Entity ที่ยังไม่มี

ผลคือ

  • Entity ID = 0

  • Native Error

  • Logic ไม่ทำงาน

  • ต้อง Retry เอง

Enhanced ช่วยลดกรณีนี้

⑲ Enhanced Change Handler ดีกว่าอย่างไร?

เมื่อ Change Handler ทำงานหลัง Entity พร้อม

Developer สามารถเขียน Logic ที่เกี่ยวกับ Entity ได้ง่ายขึ้น

เช่น

State Update
↓
Entity Exists
↓
Handler
↓
Apply Native

แทนการสร้าง Retry Loop จำนวนมาก

⑳ Resource Legacy ที่มี Wait Loop ยังต้องใช้ไหม?

ต้องตรวจเป็นราย Resource

Script เดิมอาจมี

while not DoesEntityExist(entity) do
    Wait(100)
end

เพื่อรอ Entity ก่อนประมวลผล State

บน Enhanced บาง Workaround อาจไม่จำเป็นแล้ว

แต่ไม่ควรลบทิ้งทุกตัวโดยไม่ Test

㉑ AddStateBagChangeHandler คืออะไร?

เป็นระบบสำหรับ Listen การเปลี่ยน State Bag

ตัวอย่างแนวคิด

AddStateBagChangeHandler('locked', nil, function(...)
    -- state changed
end)

เหมาะกับ Resource ที่ต้องตอบสนองทันทีเมื่อ State เปลี่ยน

㉒ State Change Handler ควรใช้กับอะไร?

เช่น

  • Vehicle Lock

  • Door

  • Player Duty

  • Entity Status

  • Mission State

แทนการ Poll State ทุก Frame

ช่วยลด Resource CPU Usage

㉓ Polling กับ Handler อะไรดีกว่า?

ถ้า State เปลี่ยนไม่บ่อย Handler มักเหมาะกว่า

หลีกเลี่ยง

while true do
    Wait(0)
    local state = Entity(vehicle).state.locked
end

ถ้าเพียงต้องตอบสนองตอน State เปลี่ยน

Event-driven Approach มีประสิทธิภาพกว่า

㉔ State Get มีข้อจำกัดอะไร?

เอกสาร Cfx.re ระบุว่า State Get/Set ยังมี Shallow Limitations

ทุกครั้งที่อ่าน State อาจเกี่ยวข้องกับการ Deserialize State Bag

ดังนั้นการอ่าน Nested Object ซ้ำ ๆ ไม่ใช่ Pattern ที่ดี

㉕ ตัวอย่าง Pattern ที่ไม่ควรใช้

เช่น

local y = Entity(x).state.position.y
local z = Entity(x).state.position.z

อาจทำให้ State ถูก Deserialize ซ้ำ

ถ้า State ใหญ่จะเพิ่ม Cost โดยไม่จำเป็น

㉖ Nested State Set ทำไมไม่ Replicate?

ตัวอย่างที่เอกสารเตือน

Entity(x).state.data.value = true

การแก้ Nested Property แบบนี้จะไม่ทำให้ State Bag เข้าใจว่า Key หลักถูก Set ใหม่ตามที่คาดหวัง

จึงไม่ควรใช้ Pattern นี้

㉗ วิธีที่แนะนำคืออะไร?

ใช้ Flat/Granular Keys

เช่น

Entity(x).state['vehicle:locked'] = true
Entity(x).state['vehicle:fuel'] = 70

แทนการใส่ Object ใหญ่แล้วแก้ Nested Property ภายใน

㉘ ทำไม Flat Key ดีกว่า?

ช่วยลด

  • Serialization

  • Deserialization

  • Replication Size

  • Complexity

และทำให้ Change Handler จับเฉพาะ Key ที่ต้องการได้ง่ายกว่า

㉙ ควรใส่ Table ใหญ่มากใน State Bag ไหม?

ไม่ควร

State Bags เหมาะกับ State ขนาดเล็กถึงปานกลาง

ไม่ควรใช้เป็น Database หรือส่งข้อมูลขนาดใหญ่

เช่น Player Inventory ทั้งชุดจำนวนหลายพันรายการไม่ควร Broadcast ผ่าน State Bag ทุกครั้งที่ Item เปลี่ยน

㉚ State Bag ใช้แทน Database ได้ไหม?

ไม่ได้

State Bags เป็น Runtime Synchronization

Database ใช้ Persistent Storage

เมื่อ Server Restart State Bag ไม่ได้กลายเป็นข้อมูลถาวรให้อัตโนมัติ

ถ้าต้องเก็บ Vehicle Ownership ต้องใช้ Database ตามระบบเดิม

㉛ State Bag ใช้แทน Event ได้ทุกอย่างไหม?

ไม่

เลือกตาม Use Case

State Bag

เหมาะกับ สถานะปัจจุบัน

Event

เหมาะกับ เหตุการณ์ที่เกิดขึ้น

ตัวอย่าง

Door is locked → State
Player pressed button → Event

ใช้ให้ตรงประเภท

㉜ State Bag เหมาะกับ Vehicle Lock ไหม?

เหมาะ

เช่น

Entity(vehicle).state:set('locked', true, true)

จากนั้น Client ที่เห็น Vehicle สามารถใช้ Handler ปรับ Door Lock State ตามค่าที่ Replicate มา

㉝ Fuel ควร Replicate ทุก Frame ไหม?

ไม่ควร

Fuel สามารถเปลี่ยนบ่อยมาก

การ Set State ทุก Frame เช่น

60 FPS × รถจำนวนมาก

จะสร้าง Network/Serialization Work ที่ไม่จำเป็น

ควร Update เป็น Interval ที่เหมาะสมหรือเมื่อค่ามีการเปลี่ยนอย่างมีนัยสำคัญ

㉞ Vehicle Speed ควรใส่ State Bag ไหม?

โดยทั่วไปไม่จำเป็นถ้า Game Networking Sync Speed/Entity State ให้อยู่แล้ว

อย่าสร้าง State ซ้ำกับข้อมูลที่ Engine Sync อยู่แล้วโดยไม่มีเหตุผล

State Bags ควรใช้กับ Custom Gameplay Metadata

㉟ Door State เหมาะไหม?

เหมาะถ้า Resource ต้อง Sync

  • Locked

  • Unlocked

  • Broken

  • Disabled

แต่ต้องออกแบบ Permission และ Authority ให้เหมาะสม

โดยเฉพาะถ้า Client สามารถเขียน State

㊱ ใครสามารถเขียน Entity State ได้?

Policy ปัจจุบันระบุว่าโดย Default

Entity State

สามารถเขียนได้โดย

  • Entity Owner

  • Server

ดังนั้น Resource Security ต้องคิดเรื่อง Ownership ด้วย

㊲ Player State ใครเขียนได้?

โดย Default

Player State สามารถเขียนได้โดย

  • Player เจ้าของ State

  • Server

ดังนั้นข้อมูล Critical ไม่ควร Trust เพียงเพราะอยู่ใน Player State

㊳ GlobalState ใครเขียนได้?

GlobalState ถูกกำหนดจาก Server

และ Client ใช้สำหรับอ่าน

จึงเหมาะกับ Global Configuration/Status ที่ไม่ Sensitive

㊴ State Bags ปลอดภัยอัตโนมัติไหม?

ไม่

ถ้า Client มีสิทธิ์เขียน State บางชนิด Developer ยังต้อง Validate Gameplay Logic

ตัวอย่างไม่ควรเชื่อ

LocalPlayer.state.money = 999999

แล้ว Serverใช้เป็นจำนวนเงินจริง

Money ต้องมาจาก Server-authoritative Data

㊵ sv_stateBagStrictMode คืออะไร?

เป็น Server ConVar สำหรับเพิ่มความเข้มงวดของ State Bag Write Policy

เมื่อเปิด

sv_stateBagStrictMode true

จะกำหนดให้ Server เท่านั้นที่สามารถแก้ State Bags

ตามเอกสารปัจจุบัน

㊶ Strict Mode เหมาะกับ Server ทุกแห่งไหม?

ไม่ควรเปิด Production ทันทีโดยไม่ทดสอบ

เพราะ Resource บางตัวอาจออกแบบให้ Client Set State แล้ว Replicate ไป Server

ถ้าเปิด Strict Mode Resource เหล่านั้นสามารถหยุดทำงานได้

ควร Audit ก่อน

㊷ Resource แบบไหนอาจพังเมื่อเปิด Strict Mode?

เช่น Resource ที่ Client ทำ

LocalPlayer.state:set('something', true, true)

หรือ Set Entity State เพื่อแจ้ง Server

ถ้า Strict Mode Block การเขียนจาก Client Logic ต้องถูกย้ายไป Server

㊸ Strict Mode มีข้อดีอะไร?

ช่วยสร้าง Server-authoritative Model ที่เข้มงวดขึ้น

ลด Surface ที่ Client สามารถแก้ State Bag ได้

เหมาะกับ Server ที่ต้องการควบคุม

  • Anti-cheat

  • Economy

  • Job

  • Entity State

อย่างรัดกุม

㊹ ควรเก็บ Security State อะไรฝั่ง Server?

เช่น

  • Money

  • Permissions

  • Job Authorization

  • Item Ownership

  • Admin State

  • Purchase Validation

Client State ควรใช้สำหรับ Display หรือ Request เท่านั้นเมื่อเป็นไปได้

㊺ State Bag กับ OneSync เกี่ยวกันอย่างไร?

State Bags เป็น Feature ของ State Awareness/OneSync

Entity State จะ Replicate ตาม Networking Scope ที่เกี่ยวข้อง

ดังนั้น OneSync และ State Bags ต้องออกแบบร่วมกัน

㊻ Player อยู่นอก Scope จะได้รับ Entity State ไหม?

Entity ที่ Client ยังไม่ได้มีอยู่ใน Scope ย่อมไม่ได้มี Local Entity ให้ Resource ใช้งานแบบปกติ

Enhanced ยังปรับ Listener ให้ทำงานเมื่อ Entity มีอยู่แล้ว

จึงสอดคล้องกับ Entity Culling Architecture มากขึ้น

㊼ รถเข้ามาใน Scope แล้ว State ยังอยู่ไหม?

ถ้า State เป็น Replicated State ของ Network Entity ที่ยังมีอยู่ ระบบจะสามารถส่ง State ที่เกี่ยวข้องเมื่อ Entity พร้อมใน Scope ตาม Networking Behavior

นี่เป็นเหตุผลที่ State Bags เหมาะกับ Entity Metadata

㊽ Entity ถูกลบแล้ว State Bag เป็นอย่างไร?

State Bag ผูกกับ Entity Lifecycle

ถ้า Entity ถูกลบ State ของ Entity นั้นก็ไม่ควรถูกใช้เหมือน Persistent Database Record

ถ้าต้อง Restore State หลัง Spawn ใหม่ ให้เก็บ Persistent Data แยก

㊾ Routing Bucket มีผลกับ State Bags ไหม?

มีในแง่ Entity Scope

Entity ในคนละ Routing Bucket สามารถถูกแยกจากกัน

Resource ที่ใช้

  • Housing

  • Missions

  • Character Selection

ควรทดสอบว่า State Replication เป็นไปตาม Bucket ที่ต้องการ

㊿ Player ย้าย Bucket ต้องทดสอบอะไร?

ตรวจว่า

  1. State ของ Entity เก่าหายจาก Context ที่ควรหาย

  2. Entity ใหม่ Stream เข้า

  3. Handler ทำงาน

  4. State ถูก Apply ถูกต้อง

โดยเฉพาะ Housing หรือ Instance Systems

51. Vehicle State ต้อง Multiplayer Test อย่างไร?

ใช้ผู้เล่นอย่างน้อย 2 คน

Player A

Set Vehicle State

Player B

ตรวจว่าได้รับค่าที่ควร Replicate

จากนั้น

  • ขับรถออกนอก Scope

  • กลับเข้ามา

  • Reconnect

ตรวจ State อีกครั้ง

52. ตัวอย่าง Test Vehicle Lock

Scenario:

Player A ล็อกรถ
↓
Server Set locked=true
↓
Player B เห็นรถล็อก
↓
Player B ออกจาก Scope
↓
กลับมา
↓
รถยังแสดง State ถูกต้อง

ถ้าผ่านจึงถือว่า Resource มี Behavior ที่ดีขึ้น

53. Player State ต้องทดสอบอะไร?

เช่น Duty

Player A duty=true

ตรวจว่า

  • Client ตัวเองเห็น

  • Server เห็น

  • Player ที่เกี่ยวข้องเห็น

  • Reconnect แล้ว Framework Restore ถูกต้อง

แต่ Persistent Duty หลัง Restart ต้องมาจาก Framework/Database หากต้องการเก็บถาวร

54. GlobalState ต้องระวังอะไร?

GlobalState ถูกส่งในระดับ Global

อย่าใส่ข้อมูลจำนวนมากหรือข้อมูล Sensitive เช่น

  • Password

  • Secret Token

  • API Key

เพราะ Client สามารถอ่าน GlobalState ได้

55. State Bag Name ควรตั้งอย่างไร?

ใช้ Key ที่ชัดเจน เช่น

vehicle:locked
vehicle:fuel
job:duty
door:locked

ช่วยลดการชนกับ Resource อื่นและทำ Debug ง่ายกว่า Key เช่น

state
data
value

56. Resource Name Prefix ดีไหม?

ดี

เช่น

mygarage:stored
mydoor:locked
myjob:duty

ลดโอกาสสอง Resource ใช้ Key เดียวกันโดยไม่ตั้งใจ

57. State Bag Key Collision เกิดได้ไหม?

ได้

State Bags ของ Entity เดียวกันสามารถถูก Resource หลายตัวใช้

ถ้าสอง Resource ใช้ Key

locked

ด้วยความหมายต่างกัน อาจเกิด Conflict

จึงควรกำหนด Namespace ที่ชัดเจน

58. ควร Set State ค่าเดิมซ้ำไหม?

ถ้าไม่มีเหตุผลไม่ควร Set ค่าเดิมซ้ำถี่ ๆ

ตัวอย่าง

locked=true
locked=true
locked=true

ทุก Tick ไม่เกิดประโยชน์

ควรตรวจค่าก่อนเปลี่ยนหรือตั้งเฉพาะเมื่อ State Change

59. State Bag Spam ยังสร้างปัญหาได้ไหม?

ได้

แม้ Enhanced จะทำ Sets เร็วขึ้นและ Network Efficient ขึ้น แต่ Script สามารถ Abuse ระบบได้ถ้า Set State หลายพันครั้งโดยไม่จำเป็น

Optimization Platform ไม่แทน Resource Design

60. จำนวน State Bags ตรวจได้ไหม?

Enhanced เพิ่ม Prometheus-compatible Metrics จำนวนมาก

รวมถึง Metrics ที่เกี่ยวกับ

  • State Bag Counts

  • OneSync Entities

  • Sync Trees

ช่วย Server Owner ตรวจว่าระบบมี State จำนวนผิดปกติหรือไม่

61. ทำไม Metrics สำคัญ?

หาก Server เริ่ม Hitch หลังเพิ่ม Resource ใหม่

สามารถดูว่า

  • State Bag Count เพิ่มหรือไม่

  • Entity Count เพิ่มหรือไม่

  • Network Load เพิ่มหรือไม่

แทนการเดาว่า Framework เป็นสาเหตุ

62. Profiler ใช้กับ Resource State Bag ได้ไหม?

ได้

ถ้า Resource Set/Get State Bags หนักมาก สามารถใช้ Profiler ตรวจ

  • Script Time

  • Tick

  • Hitch

ร่วมกับ Metrics

Enhanced ใช้ Perfetto เป็น Profiler Backend ใหม่

63. Resource ใช้ State Bag ทุก Frame ควรแก้ไหม?

ควรตรวจ

ตัวอย่าง

while true do
    Wait(0)
    Entity(vehicle).state.speed = GetEntitySpeed(vehicle)
end

เป็น Pattern ที่ไม่ดีในหลายกรณี

เพราะทั้ง Game Network และ Scriptมีข้อมูลบางส่วนอยู่แล้ว

อย่า Sync Custom State โดยไม่จำเป็น

64. ควรใช้ Debounce ไหม?

สำหรับ State ที่เปลี่ยนถี่สามารถใช้

  • Debounce

  • Throttle

  • Interval

  • Threshold

เช่น Fuel เปลี่ยน 0.001 ไม่จำเป็นต้องส่งทุกครั้ง

อาจส่งเมื่อเปลี่ยนอย่างน้อย 1 หน่วย เป็นต้น

65. Large Table ควรแยก Keys ไหม?

ควร

แทน

vehicleData = {
 fuel,
 locked,
 owner,
 class,
 mode
}

ที่ต้อง Serialize ทั้ง Object เมื่อแก้หนึ่งค่า

สามารถใช้

vehicle:fuel
vehicle:locked
vehicle:mode

แยกตามข้อมูลที่เปลี่ยน

66. State Bag กับ Inventory Metadata ต่างกันอย่างไร?

Inventory Metadata เป็นข้อมูล Item ภายใน Inventory System

State Bags เป็น Network Runtime State

ไม่ควรเอา Inventory Data จำนวนมากออกมา Replicateผ่าน Entity State โดยไม่มีเหตุผล

แต่สามารถใช้ State เล็ก ๆ เช่น

player:isCarryingObject = true

เพื่อ Gameplay Visualization

67. Door Resource ควรใช้ State Bags ไหม?

เหมาะในหลายกรณี

Server Set

door:locked = true

แล้ว Client Apply Door Native เมื่อ Entity/Area พร้อม

Enhanced Change Handler Timing ใหม่ช่วยลดปัญหาที่ Handler ทำงานก่อน Entity มีอยู่

68. Police Resource ใช้ State อะไรได้บ้าง?

เช่น

  • Duty

  • Cuffed

  • Escorted

  • Vehicle Status

แต่ค่าที่เกี่ยวกับ Authorization ต้องควบคุมฝั่ง Server

อย่าให้ Clientสามารถ Set ตัวเองเป็นตำรวจผ่าน State แล้ว Server เชื่อทันที

69. Housing ใช้ State Bags ได้อย่างไร?

สามารถใช้กับ

  • Door State

  • Furniture State เล็ก ๆ

  • Interaction Status

แต่ข้อมูลบ้านทั้งหมด เช่น Ownership และ Furniture Database หลายร้อยรายการควรเก็บใน Database แล้วส่งตามความจำเป็น

70. QBCore/Qbox/ESX ได้รับผลไหม?

Framework Core อาจไม่ได้รับผลโดยตรงทุกตัว

แต่ Third-party Resource รอบ Framework ที่ใช้ State Bags ต้องทดสอบ

โดยเฉพาะ

  • Inventory

  • Target

  • Vehicles

  • Police

  • Housing

  • Phone Integration

อย่าใช้ Framework Name เป็นตัวตัดสิน Compatibility

71. OX Resources ต้องทดสอบไหม?

Resource ใน OX Ecosystem และ Third-party ที่เชื่อม OX สามารถใช้ State Bags ในหลายจุด

จึงควรใช้ Version ปัจจุบันและทำ Multiplayer Test

โดยเฉพาะ Resource ที่ทำงานกับ Entity State และ Networked Objects

72. Resource Legacy ต้อง Rewrite State Bags ทั้งหมดไหม?

ไม่

เริ่มจาก Test Resource เดิมก่อน

ถ้าใช้

Entity(entity).state.key = value

ตาม Standard API อาจทำงานต่อได้

ให้แก้เฉพาะ Resource ที่พึ่ง Legacy-specific Replication/Callback Behavior

73. วิธีหา Resource เสี่ยง

ค้นหา Source สำหรับคำ เช่น

.state
state:set
AddStateBagChangeHandler
LocalPlayer.state
Player(source).state
GlobalState

แล้วทำรายชื่อ Resource ที่ใช้ State Bags

จากนั้น Test กลุ่มนี้ก่อน

74. ต้องตรวจ Replication Intent อย่างไร?

สำหรับ State แต่ละตัวถามว่า

State นี้ต้องให้ใครเห็น?

Server Only

ใช้ non-replicated

Client → Server

ใช้ Explicit Replication เมื่อเหมาะ พร้อม Validate Server-side

Server → Clients

Server-side State ที่ Replicate

อย่าส่งทุก State โดย Default ถ้าไม่จำเป็น

75. Migration Checklist

ตรวจ Source

  • State Bag Keys

  • Nested State

  • Change Handlers

  • Client Writes

  • Server Writes

ตรวจ Replication

  • Local

  • Replicated

  • Server-only

Multiplayer

  • Player A/B

  • เข้า/ออก Scope

  • Routing Bucket

  • Reconnect

Performance

  • State Count

  • Set Frequency

  • Profiler

  • Metrics

ผ่านครบก่อน Production

76. ตัวอย่าง State Bag Architecture ที่ดี

Database
↓
Server Logic
↓
State Bag เฉพาะข้อมูลที่ Client ต้องรู้
↓
OneSync
↓
Relevant Clients
↓
Change Handler
↓
Apply Gameplay/Visual

Server ยังคงเป็น Source of Truth สำหรับ Critical Data

State Bag เป็น Synchronization Layer

77. สิ่งที่ไม่ควรทำ

หลีกเลี่ยง

  • ใส่ข้อมูลใหญ่ทุกอย่างใน State Bag

  • Set State ทุก Frame

  • ใช้ Nested Mutation แล้วคิดว่าจะ Replicate

  • Trust Client State สำหรับเงิน/สิทธิ์

  • ใส่ Secret ใน GlobalState

  • เปิด Strict Mode โดยไม่ทดสอบ Resource

  • Poll State ทุก Frameถ้า Handler ใช้ได้

  • คิดว่า Enhanced เร็วขึ้นแล้ว Spam State ได้

  • ไม่ทดสอบ Scope/Entity Lifecycle

State Bags ที่ออกแบบดีจะช่วยลด Event Spam และทำ Resource อ่านง่ายขึ้นมาก

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

FiveM Enhanced State Bags เปลี่ยนอะไร?

เปลี่ยน Replication ให้ส่งเฉพาะค่าที่มี Replication Intent, Change Handler ทำงานเมื่อ Entity มีอยู่ และการ Set State เร็วขึ้นอย่างมากตามผลทดสอบของ Cfx.re

State Bag Set เร็วขึ้นเท่าไร?

Cfx.re ระบุประมาณ 10 เท่าโดยเฉลี่ยในการทดสอบ

Server Set State Replicate ไหม?

Current API ระบุว่า Server-side Set Replicate โดย Default

Client Set State Replicate ไหม?

Default ไม่ Replicate เว้นแต่กำหนดผ่าน set(..., true)

Nested State ใช้ได้ไหม?

อ่านได้ แต่การแก้ Nested Property โดยตรงไม่ได้ทำให้เกิด Direct State Set ตามที่ต้องการ จึงควรใช้ Granular Keys

Change Handler ดีกว่า Legacy อย่างไร?

Enhanced จะเรียก Listener เมื่อ Entity ฝั่งรับมีอยู่แล้ว ช่วยลด Race Condition

State Bags ใช้แทน Database ได้ไหม?

ไม่ได้

ใช้แทน Events ได้ทุกอย่างไหม?

ไม่ได้ State เหมาะกับ “สถานะ” ส่วน Event เหมาะกับ “เหตุการณ์”

sv_stateBagStrictMode คืออะไร?

เมื่อเปิดจะจำกัดให้ Server เท่านั้นที่แก้ State Bags

ควรเปิด Strict Mode เลยไหม?

ไม่ควรจนกว่าจะตรวจว่า Resource ใดพึ่ง Client-side State Writes

79. สรุป FiveM Enhanced State Bags เปลี่ยนอะไรบ้าง

FiveM Enhanced ปรับ State Bags โดยเน้น Performance, Replication Control และ Reliability

การเปลี่ยนแปลงหลักคือ

Legacy → State หลายค่าถูก Replicate โดยไม่ได้แยก Intent ชัดเท่าปัจจุบัน

Enhanced → ส่งเฉพาะค่าที่ถูกกำหนดให้ Replicate

ทำให้ Network ส่งข้อมูลที่จำเป็นมากขึ้นและลด Overhead

อีกจุดสำคัญคือ Change Listeners

Legacy สามารถเรียก Listener ตอน Entity ยังไม่มีฝั่งรับได้ ทำให้ Developer ต้องสร้าง

  • Retry

  • Wait

  • Entity Check

จำนวนมาก

Enhanced เปลี่ยนให้ Listener ทำงานเมื่อ Entity มีอยู่แล้ว ช่วยลด Race Condition และทำให้ Entity State Logic มีความคาดเดาได้มากขึ้น

Cfx.re ยังรายงานว่า State Bag Sets เร็วขึ้นโดยเฉลี่ยประมาณ 10 เท่า ในการทดสอบ พร้อมลด Networking Overhead และ Hitch

อย่างไรก็ตาม Developer ยังต้องเข้าใจ State Bags API เดิมให้ถูกต้อง

  • Server-side State → Replicate โดย Default

  • Client-side State → Local โดย Default

  • state:set(key, value, true/false) → ควบคุม Replication เป็นรายค่า

  • Nested Mutation → ไม่ใช่ Pattern ที่ควรใช้

  • State Bags → ไม่ใช่ Database

  • GlobalState → ห้ามเก็บ Secret

  • Client State → ห้ามใช้เป็น Source of Truth สำหรับ Critical Data

นอกจากนี้ยังมี sv_stateBagStrictMode ที่สามารถบังคับให้ Server เท่านั้นเป็นผู้แก้ State Bags ซึ่งเหมาะกับ Server-authoritative Architecture แต่ต้อง Test Resource เดิมก่อนเปิด เพราะ Script บางตัวพึ่ง Client State Replication

แนวทางที่ comsiam แนะนำคือ

ค้นหา Resource ที่ใช้ State Bags → ตรวจ Replication Intent → แก้ Nested State → ตรวจ Client Writes → Multiplayer Test → Scope Test → Routing Bucket Test → Monitor Metrics → Production

สรุปสั้นที่สุด:

Replication → Enhanced ส่งข้อมูลเฉพาะที่ควร Replicate

Change Handler → รอ Entity พร้อมก่อน

Set Performance → เร็วขึ้นมากตามผลทดสอบของ Cfx.re

Network Overhead → ลดลง

Nested State → ควรใช้ Flat/Granular Keys

Security → Critical State ต้อง Server-authoritative

Strict Mode → มี แต่ต้อง Audit ก่อนเปิด

Database → ยังต้องใช้สำหรับ Persistent Data

Resource ที่ใช้ State Bags อย่างถูกวิธีจะได้ประโยชน์โดยตรงจาก Enhanced โดยเฉพาะ Server ที่มี Player และ Networked Entities จำนวนมาก เพราะสามารถลด Event Spam และส่งเฉพาะ State ที่ Client จำเป็นต้องใช้ได้อย่างมีประสิทธิภาพมากขึ้น

Comments

Popular posts from this blog

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

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

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