FiveM Entity Ownership คืออะไร? Network Control ทำงานอย่างไร และทำไม Entity บางตัวควบคุมไม่ได้
FiveM Entity Ownership คือแนวคิดเรื่อง Client หรือ Server ฝั่งใดกำลังมีอำนาจควบคุม Networked Entity ในช่วงเวลาหนึ่ง เช่น Vehicle, Ped หรือ Object ภายใต้ OneSync โดย Ownership สามารถเปลี่ยนได้ตาม Scope, การเคลื่อนที่ของ Entity และระบบ Network Synchronization ของ FiveM.
เรื่องนี้เกี่ยวข้องโดยตรงกับปัญหายอดนิยม เช่น Entity มีอยู่แต่สั่งงานไม่ได้, Network Control ไม่ได้, Vehicle เปลี่ยนตำแหน่งไม่สำเร็จ, State ไม่ Sync หรือ Client คนหนึ่งควบคุมได้แต่อีกคนควบคุมไม่ได้
Meta SEO
Meta Title: FiveM Entity Ownership คืออะไร? Network Control และ OneSync ทำงานอย่างไร
Meta Description: อธิบาย FiveM Entity Ownership, Network Control, Owner Migration, NetworkGetEntityOwner, NetworkRequestControlOfEntity, State Bags และวิธีแก้ Entity ควบคุมไม่ได้
Focus Keyword: FiveM Entity Ownership
Related Keywords: FiveM Network Control, NetworkGetEntityOwner, NetworkRequestControlOfEntity, NetworkHasControlOfEntity, FiveM OneSync, FiveM Entity Owner
สารบัญ
① FiveM Entity Ownership คืออะไร
Networked Entity ใน FiveM ไม่ได้หมายความว่า Client ทุกเครื่องสามารถควบคุม Entity นั้นได้อย่างอิสระพร้อมกัน
OneSync มีระบบ Synchronization สำหรับกำหนดว่า Entity อยู่ใน Scope ของใคร และข้อมูลของ Entity จะถูกส่งไปยัง Clients ที่เกี่ยวข้องอย่างไร.
แนวคิดง่ายๆ:
Vehicle A
↓
Network ID 145
↓
Current Network Owner
↓
Client A
Client B อาจมองเห็นรถคันเดียวกัน แต่ไม่ได้หมายความว่า Client B เป็น Owner
② Network Owner คืออะไร
Network Owner คือ Client ที่ระบบ Network กำลังมอบความรับผิดชอบในการ Synchronize Entity บางส่วนให้ในขณะนั้น
State Bags Documentation ของ Cfx.re แสดงหลักการเดียวกัน โดยระบุว่า Entity State สามารถถูกเขียนได้โดย Entity Owner หรือ Server ภายใต้ Policy ปกติ.
จึงเห็นได้ว่า Ownership มีผลต่อสิ่งที่ Client สามารถเปลี่ยนได้
③ Owner กับผู้สร้าง Entity เหมือนกันไหม
ไม่จำเป็นต้องเหมือนกันตลอดเวลา
Client ที่สร้าง Entity อาจเป็น Owner ช่วงแรก แต่ Ownership สามารถเปลี่ยนเมื่อ Network Conditions และ Scope เปลี่ยน
OneSync ใช้ Player/Entity Culling และ Focus Zone เพื่อจัดการสิ่งที่ Client แต่ละเครื่องต้อง Synchronize.
ดังนั้นอย่าออกแบบ Script โดยสมมติว่า:
Client A สร้าง Entity
=
Client A จะเป็น Owner ตลอดไป
④ Entity Ownership เปลี่ยนได้ไหม
ได้
OneSync ถูกออกแบบให้ Entity Synchronization สามารถเปลี่ยนตามบริบทของ Players และ Entity ใน Network
เมื่อ Owner เดิมไม่เหมาะสมอีกต่อไป Ownership สามารถย้ายไปยัง Client อื่นตามระบบ Networking
นี่เรียกว่า Ownership Migration
⑤ ทำไม Ownership ต้องย้าย
ตัวอย่าง:
Player A อยู่ใกล้ Vehicle
↓
Player A เป็น Owner
Player A ขับออกไปไกล
↓
Player B อยู่ใกล้ Vehicle มากกว่า
↓
Network System อาจเปลี่ยน Owner
OneSync ใช้ Focus Zone/Culling เพื่อลดการสร้างและ Synchronize Entities ที่อยู่ไกลจาก Client.
ระบบจึงไม่ควรผูก Entity กับ Client คนเดิมตลอดไป
⑥ Ownership Migration เป็น Error หรือไม่
ไม่จำเป็น
สำหรับ Networked Entity การเปลี่ยน Owner สามารถเป็น Behavior ปกติของ Synchronization System
Resource ที่เขียนดีควรรองรับ:
Owner เดิม
↓
Ownership เปลี่ยน
↓
Entity ยังทำงานต่อ
แทนการ Cache Owner แล้วคิดว่าจะไม่มีวันเปลี่ยน
⑦ Entity Ownership กับ Network ID เกี่ยวข้องกันอย่างไร
Network ID ใช้อ้าง Entity ผ่าน Network ส่วน Ownership บอกว่าใครกำลังควบคุม Entity นั้น
ดังนั้น:
Network ID
= Entity ตัวไหน
Network Owner
= ใครกำลังควบคุม
Network ID ไม่ได้เปลี่ยนเพียงเพราะ Ownership เปลี่ยนระหว่าง Lifetime เดียวกันของ Entity
⑧ อย่าสับสน Owner กับ NetID
ตัวอย่าง:
Vehicle NetID = 145
Owner = Player 8
ต่อมา:
Vehicle NetID = 145
Owner = Player 21
Entity ยังเป็น Network Entity เดิม แต่ Owner เปลี่ยน
นี่เป็นเหตุผลที่ NetID เหมาะกับการอ้าง Entity มากกว่าการจำว่าใครเป็น Owner
⑨ ดู Entity Owner จาก Server อย่างไร
FiveM มี Native:
NetworkGetEntityOwner(entity)
สำหรับดู Owner ของ Entity.
ตัวอย่าง:
local owner = NetworkGetEntityOwner(entity)
print(('Entity owner: %s'):format(owner))
เหมาะสำหรับ Debug ว่า Server มองว่า Player คนใดกำลังเป็น Owner
⑩ NetworkGetFirstEntityOwner คืออะไร
FiveM ยังมี Native สำหรับดู First Entity Owner แยกจาก Current Owner ตาม Native Reference ปัจจุบัน.
แนวคิดคือ:
First Owner
≠
Current Owner เสมอไป
เพราะ Ownership สามารถ Migration ได้
⑪ Current Owner สำคัญกว่า First Owner เมื่อไหร่
หากกำลัง Debug ว่า:
“ตอนนี้ Client คนไหนควบคุม Entity?”
ต้องดู Current Owner
First Owner มีประโยชน์สำหรับ Tracking ต้นกำเนิดบางประเภท แต่ไม่ควรนำมาใช้แทน Current Ownership ใน Runtime Logic
⑫ Owner ID เป็น Persistent Account ID ไหม
ไม่
Owner ที่ได้จาก Networking ใช้อ้าง Player Connection ใน Session ปัจจุบัน
ถ้าต้องการระบุตัว Account ถาวรต้องใช้ Player Identifier เช่น license, license2 หรือ fivem ตาม Architecture ของ Server
⑬ Network Control คืออะไร
ใน Client Context การ “มี Network Control” หมายถึง Client สามารถควบคุม Network Entity นั้นในระดับที่ Network System อนุญาต
Native ที่เกี่ยวข้องได้แก่:
NetworkHasControlOfEntity(entity)
และ:
NetworkRequestControlOfEntity(entity)
Cfx.re มี Native References สำหรับการตรวจและ Request Network Control โดยตรง.
⑭ NetworkHasControlOfEntity ใช้ทำอะไร
ใช้ตรวจว่า Client ปัจจุบันมี Control ของ Entity หรือไม่
แนวคิด:
if NetworkHasControlOfEntity(entity) then
print('We have network control')
end
ก่อนทำ Client-side Operation ที่พึ่ง Network Ownership สามารถตรวจ Control ก่อน
⑮ ทำไม Entity มีอยู่แต่แก้ไม่ได้
เพราะ:
Entity Exists
ไม่ได้แปลว่า:
Client มี Network Control
Client อาจเห็น Entity เพราะ Entity อยู่ใน Scope แต่ Owner เป็น Client คนอื่น
นี่เป็นหนึ่งในสาเหตุสำคัญที่ Script ทำงานกับ Local Entity ได้ แต่ไม่ทำงานกับ Networked Entity ของ Player อื่น
⑯ NetworkRequestControlOfEntity คืออะไร
Native:
NetworkRequestControlOfEntity(entity)
ใช้ส่งคำขอ Network Control สำหรับ Entity.
ตัวอย่าง:
NetworkRequestControlOfEntity(entity)
แต่ต้องเข้าใจว่า Request ไม่ได้แปลว่าจะได้รับ Control สำเร็จทันที
⑰ Request Control แล้วต้องตรวจอะไรต่อ
ควรตรวจ:
NetworkHasControlOfEntity(entity)
ไม่ควรทำ:
NetworkRequestControlOfEntity(entity)
-- สมมติว่ามี control ทันที
DoSomething(entity)
Architecture ที่เหมาะกว่าคือ Request แล้วตรวจผลภายในช่วงเวลาที่จำกัด
⑱ ตัวอย่าง Request Control แบบมี Timeout
local function requestEntityControl(entity, timeoutMs)
if not DoesEntityExist(entity) then
return false
end
if NetworkHasControlOfEntity(entity) then
return true
end
local timeout = GetGameTimer() + timeoutMs
NetworkRequestControlOfEntity(entity)
while not NetworkHasControlOfEntity(entity) do
if GetGameTimer() >= timeout then
return false
end
Wait(50)
NetworkRequestControlOfEntity(entity)
end
return true
end
แนวคิดสำคัญคือ มี Timeout เพื่อไม่ให้ Resource Loop อย่างไม่มีจุดสิ้นสุด
⑲ อย่า Request Control ทุก Frame
ตัวอย่างที่ควรหลีกเลี่ยง:
while true do
NetworkRequestControlOfEntity(entity)
Wait(0)
end
เพราะเป็นการร้องขอซ้ำต่อเนื่องโดยไม่รู้ว่า Entity ยังมีอยู่หรือจำเป็นต้องควบคุมหรือไม่
ใช้ Request เฉพาะเมื่อ Action ต้องการจริงและกำหนด Timeout
⑳ Request Control ไม่สำเร็จเกิดจากอะไร
สาเหตุที่ควรตรวจ ได้แก่:
Entity ไม่มีแล้ว
Entity อยู่นอก Scope
Current Owner เป็น Client อื่น
Ownership กำลัง Migration
Entity อยู่ Routing Bucket อื่น
Script ใช้ Entity Handle ผิด
Network Entity ยังไม่พร้อม
Architecture ควรทำ Action ฝั่ง Server
OneSync ใช้ Scope/Culling และ Server-determined Entity Routing จึงไม่ควรคิดว่า Control Request จะสำเร็จทุกกรณี.
㉑ Request Control แล้ว Entity หาย
ให้ตรวจก่อนว่า Entity ยัง Exist:
if not DoesEntityExist(entity) then
return
end
และหากมาจาก NetID ให้ตรวจ Network Entity ด้วย
อย่า Cache Entity Handle ระยะยาวโดยไม่มี Lifecycle Check
㉒ Entity อยู่นอก Scope ขอ Control ได้ไหม
หาก Client ไม่มี Local Entity นั้นอยู่ใน Scope ก็ไม่มี Entity Handle ที่เหมาะสมให้ควบคุม
OneSync Infinity ใช้ Focus Zone และไม่สร้าง Entities บน Client ที่อยู่นอกพื้นที่ที่เกี่ยวข้อง.
ดังนั้นต้องแยก:
Server รู้จัก Entity
กับ:
Client มี Entity อยู่ใน Scope
㉓ อย่า Force Ownership เพราะคิดว่าเป็นวิธีแก้ทุกปัญหา
ปัญหาบางอย่างไม่ต้อง Request Control เลย
หาก Server สามารถทำ Action ด้วย Server-side Native ได้โดยตรง การย้าย Logic ไปฝั่ง Serverอาจเหมาะกว่า
OneSync มี Server-side Synchronization State และรองรับ Server-side Entity Operations มากขึ้นกว่าระบบ Networking รุ่นเก่า.
㉔ Server-side Entity Logic มีข้อดีอะไร
Architecture:
Client ขอ Action
↓
Server ตรวจ Permission/State
↓
Server ทำ Action
↓
OneSync Sync ผล
ช่วยลดการพึ่งว่า Client คนใดกำลังเป็น Entity Owner
และทำให้ Authority ของระบบชัดเจนขึ้น
㉕ State Bags กับ Entity Owner เกี่ยวข้องอย่างไร
Cfx.re ระบุ Policy ปกติว่า Entity State สามารถเขียนได้โดย:
Entity Owner
หรือ
Server
ส่วน Global State เขียนได้จาก Server.
นี่เป็นตัวอย่างชัดเจนว่า Ownership มีผลกับ Replicated State
㉖ Client ที่ไม่ใช่ Owner แก้ Entity State ได้ไหม
ตาม Default Policy เจ้าของ Entityและ Server เป็นผู้เขียน Entity State ได้.
หาก Client อื่นพยายามเขียน State โดยไม่ได้เป็น Owner ไม่ควรออกแบบ Resource โดยสมมติว่าจะ Replicate ได้
㉗ Server ควรเป็นผู้ Set State สำคัญหรือไม่
สำหรับ State ที่มีผลต่อ Gameplay หรือ Permission ควรพิจารณา Server-authoritative Architecture
เช่น:
Client ขอเปลี่ยนสถานะ
↓
Server ตรวจ
↓
Server Set State
↓
State Replicate
เพราะ State ที่ Server Set จะ Replicate โดย Default.
㉘ sv_stateBagStrictMode เกี่ยวข้องกับ Ownership อย่างไร
Server Commands ปัจจุบันมี:
setr sv_stateBagStrictMode true
เมื่อเป็น false ซึ่งเป็น Default Network Owner สามารถแก้ State ของ Entity ที่ตัวเองเป็น Owner และ Player State ได้
เมื่อเป็น true จะอนุญาตให้ เฉพาะ Server แก้ State ของ Networked Entities และ Player State.
㉙ Strict Mode ช่วยอะไร
ช่วยให้ State Bag Architecture เป็น Server-authoritative มากขึ้น
ตัวอย่าง:
Client Owner
ไม่สามารถเปลี่ยน Replicated Entity State เอง
↓
Server ตรวจ Logic
↓
Server เปลี่ยน State
Resource ที่เดิมให้ Client Owner Set State ต้องทดสอบ Compatibility ก่อนเปิด Strict Mode.
㉚ Server-created Entity คืออะไร
OneSync รองรับการสร้าง Entities เช่น Ped, Vehicle และ Object จาก Server และ Documentation ยก Server-created Entities เป็นแนวทางสำคัญสำหรับ Server-side Synchronization.
แนวคิด:
Client ขอ Entity
↓
Server Validate
↓
Server Create Entity
↓
OneSync Route Entity
↓
Client ที่เกี่ยวข้องเห็น Entity
㉛ Server-created Entity ยังมี Network Owner ไหม
Entity ยังทำงานภายใต้ Network Synchronization และ Clients อาจมี Ownership/Control ตามระบบในช่วง Runtime
ความแตกต่างคือ Entity Creation และ Authority หลักสามารถเริ่มจาก Server
จึงไม่ควรตีความคำว่า “Server-created” ว่า Entity จะไม่มี Client Ownership ใดๆ ตลอด Lifetime
㉜ Server-created Entity ช่วยลด Ownership Bug ได้ไหม
ช่วยลด Dependency ต่อ Client ที่ต้องเป็นคนสร้าง Entity
โดยเฉพาะ Entity สำคัญที่ Server ต้องควบคุม Lifecycle
แต่ Developer ยังต้องเข้าใจ:
Scope
NetID
Owner
Routing Bucket
State
Cleanup
เพราะทั้งหมดทำงานร่วมกันภายใต้ OneSync.
㉝ SetEntityOrphanMode คืออะไร
FiveM มี Native:
SetEntityOrphanMode(entity, orphanMode)
สำหรับกำหนดว่า Server จะตัดสินการลบ Orphaned Entity อย่างไร.
ใช้กับ Server-side Entity Lifecycle ใน Use Case ที่เหมาะสม
㉞ Orphan Mode ไม่ใช่ Database Persistence
ต้องแยก:
Entity Persistence ระหว่าง Runtime
ออกจาก:
Persistent Data หลัง Server Restart
ถ้า Server Restart Entity จะต้องถูกสร้างกลับจาก Persistent Storage หากระบบต้องการให้มันกลับมา
NetID และ Runtime Entity State ไม่ควรถูกใช้แทน Database
㉟ KeepEntity ใช้ทำอะไร
OneSync Documentation ใช้ SetEntityOrphanMode(entity, 2) กับ Server-created Entity เพื่อกำหนด Persistence Behavior ของ Entity ใน Runtime.
แต่ต้อง Cleanup Entity เมื่อระบบไม่ต้องการแล้ว ไม่ควรสร้าง Entities แบบถาวรโดยไม่มี Lifecycle Management
㊱ Routing Bucket มีผลกับ Entity Ownership ไหม
Routing Bucket แยก Players และ Entities ออกเป็น Game State/Instance ต่างกัน
หาก Player และ Entity อยู่คนละ Bucket Player อาจไม่เห็น Entity นั้นเลย
ดังนั้นก่อน Debug Ownership ต้องตรวจ:
Player Bucket
=
Entity Bucket ?
OneSync รองรับ Player และ Entity Routing Bucket โดยตรง.
㊲ Entity อยู่ Bucket อื่นแต่ยังมี NetID ได้ไหม
Server อาจยังรู้จัก Network Entity แต่ Client ที่อยู่อีก Bucket อาจไม่มี Local Representation
ดังนั้นมี NetID ไม่ได้แปลว่า Client สามารถ Resolve หรือควบคุม Entity ได้ทันที
㊳ ย้าย Player แล้ว Entity หาย
ตรวจว่า Player ถูกย้าย Bucket แต่ Entity ไม่ได้ย้ายตาม
ตัวอย่าง:
SetPlayerRoutingBucket(source, 10)
แต่ Entity ยังอยู่ Bucket 0
ผลคือ Client อาจไม่เห็น Entity ตาม Routing Isolation
㊴ FiveM Entity ควบคุมไม่ได้ แก้อย่างไร
ใช้ลำดับ:
Entity Exists?
↓
Networked?
↓
NetID ถูก?
↓
อยู่ใน Scope?
↓
Routing Bucket ถูก?
↓
Current Owner คือใคร?
↓
Client มี Control?
↓
ควร Request Control หรือทำฝั่ง Server?
อย่าเริ่มจาก Request Control ซ้ำๆ ทันที
㊵ วิธี Debug Entity Owner
Server:
local owner = NetworkGetEntityOwner(entity)
print(('Owner=%s'):format(owner))
Native นี้คืน Owner ของ Entity สำหรับการตรวจ Current Ownership.
จากนั้นเทียบกับ Server ID ของ Players ที่เกี่ยวข้อง
㊶ Client ดู Control อย่างไร
local hasControl =
NetworkHasControlOfEntity(entity)
print(('Has control: %s')
:format(tostring(hasControl)))
หาก false อย่าทำ Operation ที่ต้องพึ่ง Ownership โดยสมมติว่าจะ Sync
㊷ Entity Client A ใช้ได้ แต่ Client B ใช้ไม่ได้
ตรวจ:
Client B เห็น Entity หรือไม่
NetID อยู่ใน Scope หรือไม่
B เป็น Owner หรือไม่
Action ต้องมี Network Control หรือไม่
Routing Bucket ตรงหรือไม่
อาการนี้ไม่ได้พิสูจน์ว่า Entity เสีย
อาจเป็นผลจาก Ownership/Scope ตาม OneSync Architecture.
㊸ Request Control แล้วไม่เคยได้ Control
อย่า Loop ไม่สิ้นสุด
ใช้ Timeout เช่น:
local expires = GetGameTimer() + 2000
หากหมดเวลาให้ยกเลิก Action หรือส่ง Request ไป Server เพื่อจัดการด้วย Architecture ที่เหมาะสม
㊹ Entity Control หายหลัง Player เดินออกไป
นี่สามารถเกิดจาก Ownership/Scope Migration
Resource ต้องไม่ Cache:
Player A = Owner forever
ให้ตรวจ Current Owner หรือออกแบบ State/Action ให้ไม่พึ่ง Static Ownership
㊺ Vehicle เปลี่ยน Owner แล้ว State หายไหม
State Bags ถูกออกแบบให้เป็น State ที่ผูกกับ Entity ไม่ใช่ Variable Local ของ Client Owner
จึงเหมาะกับสถานะที่ต้องคงอยู่กับ Entityขณะ Ownership เปลี่ยน โดย Policy การเขียนยังขึ้นกับ Owner/Server.
นี่เป็นหนึ่งในเหตุผลที่ State Bags มีประโยชน์กับ OneSync Resources
㊻ อย่าเก็บ State สำคัญไว้ใน Local Variable ของ Owner อย่างเดียว
ถ้า Client A มี:
local vehicleLocked = true
แล้ว Ownership ย้ายไป Client B
Client B ไม่รู้ Local Variable ของ Client A
สำหรับ Runtime State ที่ต้องแชร์ควรใช้ State Bag หรือ Server-side State ตาม Use Case
㊼ Entity Ownership กับ Network Events ใช้ร่วมกันอย่างไร
Client สามารถส่ง:
Action Request + NetID
ไป Server
จากนั้น Server:
ตรวจ Entity
ตรวจ Owner
ตรวจ Player
ตรวจ Permission
ทำ Action
การส่ง NetID ไม่ได้ให้สิทธิ์ Player โดยอัตโนมัติ
㊽ อย่าเชื่อ Owner ที่ Client ส่งมา
ไม่ควรให้ Clientส่ง:
owner = me
แล้ว Server เชื่อทันที
Server สามารถตรวจ Current Entity Owner เองด้วย NetworkGetEntityOwner.
ข้อมูล Authority ควรมาจาก Server-side State เมื่อเป็นไปได้
㊾ Entity Ownership กับ Performance เกี่ยวข้องไหม
Resource ที่พยายาม:
Request Control ทุก Tick
Scan Entities ทุก Frame
Force Ownership ซ้ำ
Trigger Network Events ต่อเนื่อง
สามารถสร้าง Load ที่ไม่จำเป็น
ควรใช้ Event-driven Logic, State Bags และ Server-side Entity Management ตาม Use Case มากกว่า Polling/Request แบบต่อเนื่อง
㊿ Checklist FiveM Entity Ownership
ก่อนเปิด Resource Production ตรวจว่า:
เข้าใจ Entity Handle
เข้าใจ Network ID
เข้าใจ Current Owner
ไม่คิด Creator = Owner ตลอดไป
รองรับ Ownership Migration
ตรวจ
DoesEntityExistตรวจ Entity อยู่ใน Scope
ตรวจ Routing Bucket
ใช้
NetworkGetEntityOwnerเมื่อ Debugใช้
NetworkHasControlOfEntityก่อน Client Operation ที่ต้องการ Controlใช้
NetworkRequestControlOfEntityเฉพาะเมื่อจำเป็นRequest Control มี Timeout
ไม่ Request ทุก Tick
ไม่ Cache Entity Handle ระยะยาวแบบไม่ตรวจ
ไม่ Cache Owner แบบถาวร
ใช้ NetID สำหรับอ้าง Entity ข้าม Network
ใช้ State Bags สำหรับ Shared Runtime State
ให้ Server Set State สำคัญ
พิจารณา State Bag Strict Mode
ใช้ Server-created Entities เมื่อเหมาะสม
Cleanup Entities
ไม่ใช้ NetID เป็น Database ID
ตรวจ Owner/Permission ฝั่ง Server
ทดสอบ Player หลายคน
ทดสอบ Entity เข้าและออก Scope
ตาราง Entity Ownership ที่ควรรู้
| เรื่อง | ความหมาย |
|---|---|
| Entity Handle | Local Entity Reference |
| Network ID | Network Entity Reference |
| Network Owner | Client ที่กำลังควบคุม Entity |
| Ownership Migration | การเปลี่ยน Owner |
| Network Control | สิทธิ์ควบคุม Entity ใน Client Context |
| State Bag | Runtime State ของ Entity |
| Routing Bucket | Instance ของ Player/Entity |
| Orphan Mode | Entity Lifecycle Policy ฝั่ง Server |
ระบบเหล่านี้ทำงานร่วมกันภายใต้ OneSync และ State Awareness.
ตัวอย่างตรวจ Entity Owner ฝั่ง Server
RegisterNetEvent('example:checkEntityOwner', function(netId)
local src = source
local entity =
NetworkGetEntityFromNetworkId(netId)
if entity == 0 then
print('Entity does not exist')
return
end
local owner =
NetworkGetEntityOwner(entity)
print((
'Requester=%s Entity=%s Owner=%s'
):format(
src,
entity,
owner
))
end)
NetworkGetEntityOwner เป็น Native สำหรับดู Current Entity Owner.
ตัวอย่าง Request Control ฝั่ง Client
local function getControl(entity)
if not DoesEntityExist(entity) then
return false
end
if NetworkHasControlOfEntity(entity) then
return true
end
local expires =
GetGameTimer() + 2000
while GetGameTimer() < expires do
NetworkRequestControlOfEntity(entity)
if NetworkHasControlOfEntity(entity) then
return true
end
Wait(50)
end
return false
end
Function นี้มี Timeout เพื่อป้องกันการรอ Entity Control แบบไม่สิ้นสุด
ตัวอย่างใช้ State Bag แทน Local Owner State
Server:
Entity(vehicle).state:set(
'garage:locked',
true,
true
)
Client:
local locked =
Entity(vehicle).state['garage:locked']
State Bags รองรับ Entity State และ Default Policy อนุญาต Server รวมถึง Entity Owner ให้เขียน State โดย Server-set State จะ Replicate โดย Default.
FiveM NetworkRequestControlOfEntity ไม่ทำงาน แก้อย่างไร
ตรวจ:
Entity Exists
↓
Network Entity
↓
In Scope
↓
Routing Bucket
↓
Current Owner
↓
Request Control
↓
Has Control?
หากยังไม่ได้ Control หลัง Timeout อย่าร้องขอแบบไม่สิ้นสุด ให้พิจารณาว่า Action นั้นควรย้ายไป Server-side หรือให้ Current Owner เป็นผู้ทำงานแทน
FiveM NetworkHasControlOfEntity เป็น false
แปลว่า Client ปัจจุบันไม่มี Network Control ของ Entity ในขณะนั้น
ไม่ได้แปลว่า Entity ไม่มีอยู่
ตรวจ Current Owner, Scope และ Architecture ต่อ
FiveM NetworkGetEntityOwner ใช้ทำอะไร
ใช้หาว่า Entity ปัจจุบันมี Owner เป็น Player ใดจากฝั่งที่ Native รองรับ โดยเหมาะมากกับการ Debug OneSync Entity Ownership.
FiveM Entity Owner เปลี่ยนเองได้ไหม
ได้
Resource จึงไม่ควรสร้าง Logic เช่น:
ตอน Spawn Owner = Player A
↓
จำ Player A ไปตลอด
ต้องออกแบบให้รองรับ Migration ของ Network Ownership
FiveM Entity State แก้ไม่ได้
ตรวจว่าใครเป็นคนแก้
Policy ปกติของ State Bags คือ Entity State เขียนได้โดย Owning Player และ Server และสามารถเปิด sv_stateBagStrictMode true เพื่อให้เฉพาะ Server แก้ State ของ Networked Entities และ Player State ได้.
FiveM Entity มี NetID แต่ควบคุมไม่ได้
NetID บอกว่า Entity ไหน ไม่ได้บอกว่า Client นี้มี Control
ต้องตรวจ:
NetworkHasControlOfEntity(entity)
เพิ่มเติม
และอาจ Request Control เมื่อ Use Case เหมาะสม
FiveM Entity Owner หลุดออก Server จะเกิดอะไรขึ้น
OneSync Networking ถูกออกแบบให้จัดการ Entity Routing/Ownership ตาม State และ Clients ที่ยังเกี่ยวข้อง
Resource ไม่ควรผูก Entity Lifecycle ทั้งหมดกับ Local Variable ของ Owner คนเดียว
หาก Entity ต้องคงอยู่ใน Runtime ให้ใช้ Server-side Entity Lifecycle และ Orphan Mode ตามความเหมาะสม.
FiveM Entity Ownership กับ sv_stateBagStrictMode ต่างกันอย่างไร
Ownership บอกว่า Client ใดเป็น Network Owner ของ Entity
sv_stateBagStrictMode ควบคุม Permission สำหรับการเขียน Replicated State Bags
เมื่อเปิด Strict Mode ต่อให้ Client เป็น Owner ก็ไม่สามารถแก้ Replicated Entity State ได้ เพราะเฉพาะ Server ถูกอนุญาต.
FAQ FiveM Entity Ownership
FiveM Entity Owner คืออะไร
คือ Client ที่ Network System กำลังให้ความรับผิดชอบต่อ Networked Entity ในช่วงเวลานั้น โดย Ownership สามารถเปลี่ยนตาม Networking/Scope ได้
Entity Owner ดูอย่างไร
สามารถใช้:
NetworkGetEntityOwner(entity)
เพื่อดู Current Owner.
NetworkHasControlOfEntity คืออะไร
ใช้ตรวจว่า Client ปัจจุบันมี Network Control ของ Entity หรือไม่
NetworkRequestControlOfEntity คืออะไร
ใช้ Request Network Control ของ Entity แต่การเรียก Function ไม่ควรถูกตีความว่าจะได้รับ Control ทันที.
Entity Owner เปลี่ยนได้หรือไม่
ได้ Resource ต้องรองรับ Ownership Migration แทนการสมมติว่า Creator จะเป็น Owner ตลอดไป
Entity มี NetID แต่ทำไมควบคุมไม่ได้
เพราะ NetID เป็นเพียง Network Reference ส่วน Control ขึ้นกับ Current Ownership, Scope และ Networking State
State Bag ใครแก้ได้
Default Policy อนุญาต Entity Owner และ Server แก้ Entity State ส่วน sv_stateBagStrictMode true สามารถจำกัดให้เฉพาะ Server แก้ Replicated State.
Server-created Entity ยังมี Owner ไหม
ยังอยู่ภายใต้ Network Synchronization; Server-created หมายถึง Entity ถูกสร้างและจัดการต้นทางจาก Server ไม่ได้หมายความว่าจะไม่มี Network Ownership/Client Synchronization
ประเด็นสำคัญ
FiveM Entity Ownership เป็นส่วนสำคัญของ OneSync เพราะ Networked Entity ไม่ได้ถูกควบคุมโดย Client ทุกคนพร้อมกัน และ Current Owner สามารถเปลี่ยนตาม Scope และ Network Synchronization ได้.
สิ่งที่ควรแยกให้ชัดคือ:
Network ID
= Entity ตัวไหน
Network Owner
= ใครกำลังควบคุม
Network Control
= Client นี้ควบคุมได้หรือไม่
State Bag
= Entity มี State อะไร
หาก Client ต้องทำ Action กับ Networked Entity ให้ตรวจ NetworkHasControlOfEntity() ก่อน และหากจำเป็นจึงใช้ NetworkRequestControlOfEntity() พร้อม Timeout ไม่ควร Request ซ้ำทุก Frameหรือสมมติว่า Request แล้วจะได้ Control ทันที.
สำหรับ State Bags Cfx.re ระบุว่า Default Policy ให้ Entity Owner และ Server เขียน Entity State ได้ และ Server สามารถเปิด sv_stateBagStrictMode true เพื่อเปลี่ยนเป็น Server-only Replicated State Modification ได้.
สำหรับผู้อ่าน comsiam ให้จำสูตร “NetID = ตัวไหน, Owner = ใครควบคุม, Control = ทำได้ไหม” และ comsiam แนะนำให้ Resource สำคัญลดการพึ่ง Static Client Ownership โดยใช้ Server-side Validation, Server-created Entities และ State Bags ตามหน้าที่ จะรองรับ OneSync และผู้เล่นหลายคนได้ดีกว่า
Comments
Post a Comment