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 ต้องทดสอบอะไร?
ตรวจว่า
State ของ Entity เก่าหายจาก Context ที่ควรหาย
Entity ใหม่ Stream เข้า
Handler ทำงาน
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
Post a Comment