FiveM Routing Bucket คืออะไร? วิธีสร้าง Instance แยกผู้เล่นและ Entity อย่างถูกต้อง
FiveM Routing Bucket คือระบบสำหรับแยก Players และ Networked Entities ออกเป็นคนละ Game State หรือ Instance ภายใน Server เดียวกัน คล้ายแนวคิด Dimension / Virtual World โดยผู้เล่นที่อยู่คนละ Routing Bucket จะไม่เห็น Players และ Entities ของอีก Bucket ตามระบบ Routing ของ OneSync.
Routing Bucket เหมาะมากกับระบบประเภท Character Selection, Party/Session, Multi-mode Server และ Instance Gameplay แต่ Cfx.re ระบุชัดว่า ไม่ควรใช้ Routing Bucket เป็นวิธีหลักสำหรับ Interiors เพราะ Interior มีแนวทาง Scoped/Conceal ที่เหมาะกว่า.
Meta SEO
Meta Title: FiveM Routing Bucket คืออะไร? วิธีสร้าง Instance แยก Player และ Entity
Meta Description: อธิบาย FiveM Routing Bucket แบบละเอียด วิธีใช้ SetPlayerRoutingBucket, SetEntityRoutingBucket, Population, Entity Lockdown และแก้ปัญหา Player หรือ Vehicle หายหลังเปลี่ยน Bucket
Focus Keyword: FiveM Routing Bucket
Related Keywords: FiveM Instance, FiveM Dimension, SetPlayerRoutingBucket, SetEntityRoutingBucket, FiveM OneSync, Routing Bucket FiveM
สารบัญ
① FiveM Routing Bucket คืออะไร
Routing Bucket คือระบบ Instance ของ FiveM
แนวคิด:
FiveM Server
Bucket 0
├── Player A
├── Player B
└── Vehicle A
Bucket 10
├── Player C
├── Player D
└── Vehicle B
Bucket 20
├── Player E
└── Vehicle C
Player ใน Bucket 10 จะอยู่ใน Game State แยกจาก Player ใน Bucket 0 หรือ 20
Cfx.re ระบุว่าสามารถ Assign ทั้ง Player และ Entity ไปยัง Routing Bucket และแต่ละฝ่ายจะมองเห็น Players/Entities ที่อยู่ใน Bucket เดียวกัน.
② Routing Bucket เหมือน Dimension หรือไม่
แนวคิดใกล้เคียงกันมาก
Cfx.re ระบุว่า Routing Buckets เป็นระบบ Dimension ของ FiveM และสามารถเทียบได้กับ Dimension หรือ Instance System จากแพลตฟอร์ม Multiplayer อื่น แม้รายละเอียดการทำงานภายในจะแตกต่างกัน.
จำง่ายๆ:
Routing Bucket
≈ Dimension
≈ Virtual World
≈ Instance
แต่ควรใช้คำว่า Routing Bucket เมื่อเขียน Resource FiveM ปัจจุบัน
③ Routing Bucket ทำงานอย่างไร
หลักคือ:
Player Bucket
+
Entity Bucket
=
Visibility
ถ้า Player และ Vehicle อยู่ Bucket เดียวกัน Player สามารถมองเห็น Entity นั้นตาม Scope และ Networking ปกติ
แต่ถ้าอยู่คนละ Bucket Entity อาจไม่ปรากฏให้ Client คนนั้นเห็นเลย.
④ Routing Bucket เกี่ยวกับ OneSync หรือไม่
เกี่ยวข้องโดยตรง
Routing Buckets เป็นส่วนหนึ่งของระบบ OneSync และ Cfx.re ระบุ Native สำหรับจัดการ Player, Entity, Population และ Lockdown ของแต่ละ Bucket ภายใน OneSync Documentation.
Resource ที่ใช้ Routing Buckets จึงควรออกแบบตาม OneSync Networking ไม่ใช่แนวทาง Client-only แบบเก่า
⑤ แต่ละ Bucket มี World Grid แยกกันหรือไม่
Cfx.re ระบุว่าแต่ละ Routing Bucket มี World Grid ของตัวเองสำหรับ Population Owners.
ดังนั้น Bucket ไม่ได้เป็นเพียง Filter ว่าใครเห็นใคร แต่ยังมี Behavior ระดับ World/Population ที่แยกจาก Bucket อื่นด้วย
⑥ Bucket 0 คืออะไร
โดยทั่วไป Bucket 0 สามารถมองเป็น Main/Default World ของ Server
ตัวอย่าง:
Bucket 0
= Gameplay หลัก
Bucket 100
= Character Selection
Bucket 200
= Party Instance
เมื่อระบบ Instance จบ มักย้าย Player กลับ:
SetPlayerRoutingBucket(source, 0)
อย่าให้ Player ค้างอยู่ Instance เก่าโดยไม่ตั้งใจ
⑦ Bucket ID ต้องเป็นเลขหรือไม่
Routing Bucket ใช้ Bucket ID เป็น Integer
ตัวอย่าง:
SetPlayerRoutingBucket(source, 10)
Cfx.re มี Native SET_PLAYER_ROUTING_BUCKET สำหรับกำหนด Bucket ของ Player และ SET_ENTITY_ROUTING_BUCKET สำหรับ Entity.
⑧ ควรใช้ Bucket ID แบบไหน
ควรสร้าง Convention ของ Server เช่น:
0 = Main World
100-199 = Character Instances
200-299 = Party Sessions
300-399 = Game Modes
หรือใช้ Dynamic Bucket Allocator
เป้าหมายคือไม่ให้ Resource หลายตัวเลือก Bucket ID ชนกันโดยไม่รู้ตัว
⑨ ย้าย Player เข้า Routing Bucket อย่างไร
ใช้:
SetPlayerRoutingBucket(source, bucketId)
ตัวอย่าง:
local bucketId = 100
SetPlayerRoutingBucket(
source,
bucketId
)
Cfx.re มี Native สำหรับกำหนด Routing Bucket ของ Player โดยตรง และ OneSync Documentation ใช้ Native นี้ในตัวอย่าง Entity Lockdown.
⑩ ย้าย Player กลับโลกหลักอย่างไร
ใช้:
SetPlayerRoutingBucket(source, 0)
ตัวอย่าง:
RegisterNetEvent(
'instance:leave',
function()
local src = source
SetPlayerRoutingBucket(
src,
0
)
end
)
สำหรับ Production Resource ต้องตรวจว่า Player มีสิทธิ์ออก Instance ณ จุดนั้นหรือไม่
⑪ อย่าให้ Client กำหนด Bucket ID เองโดยตรง
ตัวอย่างที่ควรหลีกเลี่ยง:
TriggerServerEvent(
'instance:setBucket',
999999
)
แล้ว Server นำเลขที่ Client ส่งมาใช้ทันที
ควรเป็น:
Client ขอเข้า Session
↓
Server ตรวจ Session
↓
Server หา Bucket ID
↓
Server ย้าย Player
เพราะ Bucket Assignment เป็น Server Gameplay State ที่ควรถูกควบคุมจาก Server
⑫ Server ควรเป็นผู้เลือก Bucket
ตัวอย่าง:
RegisterNetEvent(
'party:joinInstance',
function(partyId)
local src = source
local bucket =
GetBucketForParty(partyId)
if not bucket then
return
end
SetPlayerRoutingBucket(
src,
bucket
)
end
)
GetBucketForParty() เป็น Function สมมติ
หลักคือ Client ส่ง Request แต่ Server เป็นผู้ตัดสิน Instance
⑬ Entity ก็มี Routing Bucket ได้
ใช่
Cfx.re รองรับ:
SetEntityRoutingBucket(
entity,
bucketId
)
และระบุว่า Player กับ Entity ที่อยู่ Bucket เดียวกันสามารถถูก Route ให้อยู่ใน Game State เดียวกัน.
⑭ Player เข้า Instance แต่ Vehicle หายเพราะอะไร
สาเหตุที่พบบ่อยคือ:
Player Bucket = 10
Vehicle Bucket = 0
Player ถูกย้ายออกจากโลกหลัก แต่ Vehicle ไม่ได้ย้ายตาม
แก้โดยจัด Entity ที่ต้องอยู่ใน Instance ให้ Bucket ตรงกับ Player
SetEntityRoutingBucket(
vehicle,
10
)
⑮ ตัวอย่างย้าย Player และ Vehicle พร้อมกัน
local bucketId = 10
SetPlayerRoutingBucket(
source,
bucketId
)
SetEntityRoutingBucket(
vehicle,
bucketId
)
นี่เป็น Pattern เดียวกับตัวอย่าง OneSync ของ Cfx.re ที่ย้าย Player และ Vehicle ไป Bucket เดียวกัน.
⑯ Ped และ Object ใช้ Bucket ได้ไหม
Routing Bucket ทำงานกับ Networked Entities ไม่ได้จำกัดเฉพาะ Vehicle
OneSync Documentation กล่าวถึง Player หรือ Entity โดยทั่วไป และรองรับ Server-created Peds, Vehicles และ Objects ภายในระบบ Entity Synchronization.
⑰ Entity สร้างหลัง Player เข้า Bucket ควรทำอย่างไร
Resource ควรรู้ว่า Entity นั้นเป็นของ Session ไหน
ตัวอย่าง:
Create Entity
↓
หา Session Bucket
↓
SetEntityRoutingBucket
↓
Set State ที่จำเป็น
ไม่ควรสร้าง Entity แล้วปล่อยไว้ Bucket 0 หาก Intended Gameplay อยู่ใน Instance อื่น
⑱ ตรวจว่า Player อยู่ Bucket ไหนอย่างไร
FiveM มี:
GetPlayerRoutingBucket(source)
Native นี้คืน Routing Bucket ปัจจุบันของ Player.
ตัวอย่าง:
local bucket =
GetPlayerRoutingBucket(source)
print(
('Player bucket: %s')
:format(bucket)
)
⑲ ตรวจ Entity Bucket อย่างไร
ใช้:
GetEntityRoutingBucket(entity)
Cfx.re มี Native สำหรับอ่าน Bucket ของ Entity.
ตัวอย่าง:
local bucket =
GetEntityRoutingBucket(vehicle)
print(
('Vehicle bucket: %s')
:format(bucket)
)
⑳ Debug Player ไม่เห็น Entity ให้เทียบสองค่า
ใช้:
local playerBucket =
GetPlayerRoutingBucket(source)
local entityBucket =
GetEntityRoutingBucket(entity)
แล้วตรวจ:
Player Bucket == Entity Bucket ?
ถ้าไม่เท่ากัน นี่เป็นจุดแรกที่ควรแก้ก่อน Debug Network ID หรือ Entity Ownership ต่อ
㉑ Routing Bucket ใช้ทำ Character Selection ได้ไหม
ได้ และเป็น Use Case ที่ Cfx.re ระบุโดยตรง
Cfx.re ยกตัวอย่าง Character Screen ที่ถูก Instance แยกจาก Gameplay เป็นหนึ่งใน Use Cases ของ Routing Buckets.
Flow:
Player Connecting
↓
Player Joining
↓
ย้ายเข้า Character Bucket
↓
เลือก Character
↓
โหลดข้อมูลเสร็จ
↓
ย้ายกลับ Bucket 0
㉒ ทำ Character Bucket ต่อ Player หรือรวมกันดี
ขึ้นกับ UI และ Gameplay
Shared Character Bucket
ผู้เล่นหลายคนอยู่ Instance เดียวกัน
Private Character Bucket
หนึ่ง Player ต่อหนึ่ง Bucket
หากต้องการให้ Character Screen เป็น Private ควรมี Bucket Allocator ที่สร้าง/คืน Bucket IDs อย่างเป็นระบบ
㉓ Private Instance ควร Cleanup เมื่อ Player ออก
ถ้า Player Disconnect ขณะอยู่ Bucket 125
Resource ควร Cleanup:
Session Mapping
Temporary Entities
Bucket Allocation
Temporary State
โดยใช้ playerDropped หรือ Lifecycle ที่เหมาะสม
ไม่ควรปล่อย Session Table เก่าค้างอยู่
㉔ Routing Bucket ใช้ทำ Party หรือ Session ได้ไหม
ได้
Cfx.re ระบุ Session/Party Systems เป็น Use Case โดยตรง.
ตัวอย่าง:
Party A
→ Bucket 201
Party B
→ Bucket 202
Party C
→ Bucket 203
แต่ละ Party สามารถเล่นบนพิกัดเดียวกันโดยไม่เห็น Entity/Player ของ Party อื่น
㉕ Multi-mode Server ใช้ได้ไหม
ได้
Cfx.re ระบุ Multi-mode Servers เป็นอีก Use Case เช่นแต่ละ Game Mode ทำงานแยก Game State โดยไม่รบกวนกัน.
ตัวอย่าง:
Bucket 0 = Main Lobby
Bucket 10 = Mode A
Bucket 20 = Mode B
Bucket 30 = Mode C
㉖ Interiors ควรใช้ Routing Bucket ไหม
Cfx.re ระบุชัดว่า Interiors ไม่ใช่ Use Case ที่แนะนำสำหรับ Routing Buckets.
หากต้องการซ่อน/แยกพื้นที่ Interior ควรตรวจระบบ Conceal หรือ Scoped Routing ที่เหมาะสมมากกว่า
อย่าใช้ Bucket กับทุกห้องเพียงเพราะทำง่าย
㉗ ทำไม Interior ไม่เหมาะ
เพราะ Routing Bucket แยก Game State ทั้ง Bucket
แต่ Interior หลายกรณีต้องการเพียงการควบคุม Visibility ภายในพื้นที่หนึ่งโดยที่ Player ยังควรรับรู้สิ่งที่เกิดขึ้นนอกพื้นที่บางส่วน
Cfx.re จึงแยก Use Case นี้ออกจาก Routing Buckets.
㉘ แต่ละ Bucket มี Population แยกไหม
Cfx.re ระบุว่าแต่ละ Bucket มี World Grid ของตัวเองสำหรับ Population Owners และมี Native สำหรับเปิดหรือปิด Population ภายใน Bucket.
ใช้:
SetRoutingBucketPopulationEnabled(
bucketId,
false
)
㉙ ปิด Population เมื่อไหร่
เหมาะกับ Instance ที่ต้องการ Environment ควบคุมเอง เช่น:
Character Selection
Private Session
Controlled Game Mode
ตัวอย่าง Cfx.re:
SetRoutingBucketPopulationEnabled(
1,
false
)
เพื่อปิด Population ใน Bucket นั้น.
㉚ เปิด Population กลับอย่างไร
ใช้:
SetRoutingBucketPopulationEnabled(
bucketId,
true
)
ควรเลือกตาม Gameplay Design ไม่จำเป็นต้องปิด Population ทุก Bucket
㉛ Entity Lockdown คืออะไร
Routing Bucket สามารถมี Entity Lockdown Mode ของตัวเอง เพื่อกำหนดว่า Client สามารถสร้าง Entity ภายใน Bucket ได้มากน้อยแค่ไหน.
ใช้:
SetRoutingBucketEntityLockdownMode(
bucketId,
mode
)
㉜ Lockdown Mode มีอะไรบ้าง
Documentation ปัจจุบันของ Cfx.re ระบุ:
| Mode | ความหมาย |
|---|---|
full | ปิด Dummy Object Creation เพิ่มเติม ใช้กับ FiveM for GTAV Enhanced |
strict | Client สร้าง Entity ไม่ได้ |
relaxed | Block Script-owned Entity ที่ Client สร้าง |
inactive | Client สร้าง Entity ได้ |
㉝ strict เหมาะกับอะไร
strict เหมาะกับ Instance ที่ Server ต้องการควบคุม Entity Creation อย่างมาก
ตัวอย่าง:
SetRoutingBucketEntityLockdownMode(
bucketId,
'strict'
)
Cfx.re ระบุว่าใน Mode นี้ Clients ไม่สามารถสร้าง Entities ได้.
㉞ inactive คืออะไร
inactive คือ Mode ที่เปิดให้ Clients สามารถสร้าง Entities ได้
ถ้า Resource ไม่ต้องการ Lockdown Behavior สามารถใช้ Mode นี้ตาม Architecture ของ Server.
㉟ full ใช้ได้ทุก Server ไหม
ไม่
Cfx.re ระบุว่า full เป็น Lockdown Mode ที่ใช้เฉพาะ FiveM for GTAV Enhanced และเพิ่มการป้องกัน Dummy Object Creation.
Resource ที่ต้องรองรับทั้ง Legacy และ Enhanced ต้องตรวจ Environment ก่อนใช้
㊱ ตัวอย่าง Private Bucket แบบควบคุม Entity
local bucketId = 100
SetRoutingBucketEntityLockdownMode(
bucketId,
'strict'
)
SetRoutingBucketPopulationEnabled(
bucketId,
false
)
SetPlayerRoutingBucket(
source,
bucketId
)
โครงสร้างนี้ตรงกับแนวทางตัวอย่างของ OneSync Documentation: ตั้ง Lockdown → ปิด Population → ย้าย Player เข้า Bucket.
㊲ Strict Lockdown แล้ว Client Resource พัง
เป็นไปได้หาก Resource เดิมคาดหวังว่า Client จะสร้าง Networked Entity เอง
เมื่อใช้ strict Cfx.re ระบุว่า Client ไม่สามารถสร้าง Entities ใน Bucket นั้นได้.
จึงควรย้าย Entity Creation ที่สำคัญไป Server หรือปรับ Resource Architecture
㊳ Entity Lockdown กับ sv_stateBagStrictMode เหมือนกันไหม
ไม่
Entity Lockdown
ควบคุมการสร้าง Entity
sv_stateBagStrictMode
ควบคุมการแก้ Replicated State Bag
จึงเป็นคนละ Layer ของ OneSync Security/Authority
㊴ Network Event ข้าม Routing Bucket ได้ไหม
อย่าสมมติว่า Routing Bucket เป็น Security Boundary สำหรับ Custom Network Events ทั้งหมด
Bucket มีหน้าที่หลักด้าน Game State/Entity Routing
Resource ที่รับ Client Network Event ยังต้องตรวจเองว่า Player อยู่ Session/Bucket ที่ถูกต้องก่อนทำ Action
ตัวอย่าง:
local bucket =
GetPlayerRoutingBucket(source)
if bucket ~= expectedBucket then
return
end
㊵ Event ของ Instance ควรตรวจ Bucket
ตัวอย่าง:
RegisterNetEvent(
'session:finish',
function(sessionId)
local src = source
local session =
Sessions[sessionId]
if not session then
return
end
local currentBucket =
GetPlayerRoutingBucket(src)
if currentBucket ~=
session.bucket then
return
end
-- ทำ Logic ต่อ
end
)
Client ไม่ควรสามารถ Trigger Action ของ Session อื่นเพียงเพราะรู้ Event Name
㊶ Control Request ข้าม Bucket มีข้อจำกัด
Server Commands ปัจจุบันระบุว่าเมื่อเปิด sv_filterRequestControl ใน Mode ที่ไม่ใช่ Off จะมี Check เพิ่มเติม และ Control Request Events ไม่สามารถ Route ข้าม Routing Buckets.
นี่สำคัญมากเมื่อตรวจปัญหา Network Control หลังย้าย Player หรือ Entity เข้า Instance
㊷ strict Lockdown มีผลกับ Control Request ด้วย
Cfx.re ระบุว่าเมื่อใช้ sv_filterRequestControl Mode ที่ไม่ใช่ Off Control Request จะถูก Block หาก Sender อยู่ใน strict Entity Lockdown Mode.
ดังนั้นอาการ:
NetworkRequestControlOfEntity
ไม่สำเร็จ
อาจไม่ได้เกิดจาก Entity Ownership อย่างเดียว ต้องตรวจ Bucket Lockdown และ Server Control Policy ด้วย
㊸ Routing Bucket มีต้นทุน Memory หรือไม่
มี
Cfx.re ระบุว่า แต่ละ Routing Bucket มี Memory Cost และ Behavior ไม่ได้เหมือน Dimension System จากแพลตฟอร์มอื่นแบบหนึ่งต่อหนึ่ง.
ดังนั้นไม่ควรสร้าง Bucket ใหม่จำนวนมากแบบไม่มี Lifecycle Management
㊹ ไม่ควรสร้าง Bucket ใหม่ทุก Action
ตัวอย่างที่ไม่ดี:
Player เปิด Menu
→ สร้าง Bucket ใหม่
ปิด Menu
→ ไม่ Cleanup
เปิดใหม่
→ Bucket ใหม่อีก
ควรมี Bucket Allocator/Session Manager ที่ Reuse หรือ Cleanup Bucket IDs ตาม Architecture
㊺ Bucket ID หายเองไหม
Bucket ID เป็นค่าที่ Resource เลือกใช้ แต่ State/Entities/Players ภายในต้องถูกจัด Lifecycle เอง
Resource ควรเก็บ Mapping เช่น:
Sessions[sessionId] = {
bucket = bucketId,
players = {},
entities = {}
}
แล้ว Cleanup เมื่อ Session สิ้นสุด
㊻ Player Disconnect ควรคืน Bucket หรือไม่
Player Connection หายไปเอง แต่ Resource ยังควร Cleanup Session Mapping
ใช้ playerDropped:
AddEventHandler(
'playerDropped',
function()
local src = source
RemovePlayerFromSession(src)
end
)
เพื่อไม่ให้ข้อมูล Party/Instance เก่าค้างอยู่
㊼ Resource Restart ระหว่างมี Instances ทำอย่างไร
ต้องมี Recovery Strategy
เมื่อ Resource Restart:
Session Table ใน Memory
→ หาย
Players
→ อาจยังอยู่ใน Bucket ที่ตั้งไว้
จึงควรพิจารณา onResourceStop / onResourceStart และ Restore/Reset Players ตาม Architecture
อย่าคิดว่า Restart Resource แล้ว Instance State จะจัดตัวเองทั้งหมด
㊽ ควร Reset Players กลับ Bucket 0 เมื่อ Resource Stop ไหม
สำหรับ Resource ที่เป็นเจ้าของ Instance เหล่านั้น อาจเป็นแนวทางที่เหมาะสม
ตัวอย่างเชิงแนวคิด:
AddEventHandler(
'onResourceStop',
function(resourceName)
if resourceName ~=
GetCurrentResourceName() then
return
end
-- Reset players ที่ resource นี้จัดการ
end
)
แต่ต้องระวังไม่ย้าย Player ที่ถูก Resource อื่นจัดการอยู่
㊾ FiveM Routing Bucket Player ไม่เห็นกัน แก้อย่างไร
ตรวจ:
Player A Bucket = ?
Player B Bucket = ?
ด้วย:
GetPlayerRoutingBucket(playerId)
ถ้าอยู่คนละ Bucket การไม่เห็นกันสามารถเป็น Behavior ที่ถูกต้องของระบบ.
㊿ FiveM Routing Bucket Entity หาย แก้อย่างไร
ใช้ Checklist:
Player Bucket เท่าไร
Entity Bucket เท่าไร
Entity ยัง Exist หรือไม่
Entity มี Network ID หรือไม่
Entity อยู่ใน Scope หรือไม่
Resource ย้าย Player แต่ไม่ได้ย้าย Entityหรือไม่
Entity ถูก Cleanup แล้วหรือไม่
Routing Bucket ถูก Reset โดย Resource อื่นหรือไม่
เริ่มจากเปรียบเทียบ:
GetPlayerRoutingBucket(source)
GetEntityRoutingBucket(entity)
ก่อน Debug OneSync ขั้นลึก.
ตาราง Routing Bucket Functions สำคัญ
| Native | หน้าที่ |
|---|---|
SetPlayerRoutingBucket | ย้าย Player เข้า Bucket |
GetPlayerRoutingBucket | ดู Bucket ของ Player |
SetEntityRoutingBucket | ย้าย Entity เข้า Bucket |
GetEntityRoutingBucket | ดู Bucket ของ Entity |
SetRoutingBucketPopulationEnabled | เปิด/ปิด Population |
SetRoutingBucketEntityLockdownMode | ตั้ง Entity Lockdown |
Native กลุ่มนี้ถูกรวมไว้ใน OneSync Routing Bucket Documentation ของ Cfx.re.
ตัวอย่างสร้าง Private Instance แบบพื้นฐาน
local nextBucket = 1000
local playerBuckets = {}
local function createPrivateBucket(src)
local bucket = nextBucket
nextBucket = nextBucket + 1
playerBuckets[src] = bucket
SetRoutingBucketEntityLockdownMode(
bucket,
'strict'
)
SetRoutingBucketPopulationEnabled(
bucket,
false
)
SetPlayerRoutingBucket(
src,
bucket
)
return bucket
end
นี่เป็น Architecture ตัวอย่างสำหรับอธิบายการจัด Bucket ไม่ใช่ระบบ Allocation Production ที่สมบูรณ์
ตัวอย่างออกจาก Private Instance
local function leavePrivateBucket(src)
SetPlayerRoutingBucket(
src,
0
)
playerBuckets[src] = nil
end
หาก Instance มี Entities Resource ต้อง Cleanup หรือย้าย Entities เหล่านั้นด้วย
ตัวอย่าง Party Instance
local parties = {
[25] = {
bucket = 525,
players = {}
}
}
local function joinPartyInstance(
src,
partyId
)
local party = parties[partyId]
if not party then
return false
end
SetPlayerRoutingBucket(
src,
party.bucket
)
party.players[src] = true
return true
end
Server เป็นผู้เลือก Bucket จาก Party Data ไม่ใช่ให้ Clientกำหนด Bucket ID ตามใจ
ตัวอย่างย้าย Vehicle ตาม Player
local playerBucket =
GetPlayerRoutingBucket(source)
SetEntityRoutingBucket(
vehicle,
playerBucket
)
เหมาะเมื่อ Vehicle ถูกสร้างมาเพื่อใช้งานเฉพาะ Session ของ Player นั้น
ตัวอย่าง Debug Bucket
RegisterCommand(
'debugbucket',
function(source)
if source == 0 then
return
end
local bucket =
GetPlayerRoutingBucket(source)
print((
'Player %s is in bucket %s'
):format(
source,
bucket
))
end,
false
)
สำหรับ Production ควรจำกัด Debug Command ด้วย Permission ที่เหมาะสม
FiveM SetPlayerRoutingBucket ไม่ทำงาน
ตรวจ:
OneSync
↓
Server-side Script
↓
Player ID ถูก?
↓
Bucket ID ถูก?
↓
Script Error?
↓
Resource Running?
และใช้ GetPlayerRoutingBucket() หลัง Set เพื่อตรวจค่าที่ Server เห็นจริง.
FiveM SetEntityRoutingBucket ไม่ทำงาน
ตรวจว่า:
Entity มีอยู่จริง
Entity Handle ถูกต้องฝั่ง Server
Entity เป็น Networked Entity ตาม Use Case
Resource ไม่ได้ลบ Entity
Bucket ID ถูก
Player ที่ต้องเห็น Entity อยู่ Bucket เดียวกัน
จากนั้นใช้:
GetEntityRoutingBucket(entity)
ตรวจผลจริง.
FiveM Routing Bucket Vehicle ไม่ตาม Player
Routing Bucket ไม่ได้หมายความว่า Entity ทุกตัวที่ Player เคยใช้จะถูกย้ายตาม Player อัตโนมัติ
ถ้า Gameplay ต้องการรถคันหนึ่งติดตาม Player เข้า Instance ต้องกำหนด Bucket ของรถให้ตรงด้วย
SetPlayerRoutingBucket(
source,
bucket
)
SetEntityRoutingBucket(
vehicle,
bucket
)
FiveM Routing Bucket Voice Chat แยกอัตโนมัติไหม
อย่าคิดว่า Routing Bucket ควรเป็นตัวจัด Voice Routing ของ Resource ทุกระบบโดยอัตโนมัติ
Voice Resource อาจมี Channel, Proximity หรือ Routing Logic ของตัวเอง
ดังนั้นหาก Player คนละ Bucket ยังได้ยินกัน ให้ตรวจ Voice Resource Configuration เพิ่ม ไม่ควรแก้ Entity Bucket แบบสุ่ม
FiveM Routing Bucket กับ State Bags ใช้ร่วมกันได้ไหม
ได้
Cfx.re แนะนำ State Bags สำหรับแนบ Attributes ให้ Entities ซึ่ง Clients ที่เกี่ยวข้องสามารถอ่านได้ตาม State Awareness/Scope.
ตัวอย่าง:
Bucket 500
↓
Vehicle
↓
State Bag
session:id = 123
vehicle:locked = true
ช่วยให้ Resource รู้ทั้ง Instance และ Runtime State ของ Entity
FiveM Routing Bucket กับ Network ID ต่างกันอย่างไร
Routing Bucket บอกว่า:
Entity อยู่ Game State ไหน
Network ID บอกว่า:
Entity ตัวไหนใน Network
ดังนั้น:
Entity
├── NetID = 145
└── Bucket = 500
เป็นข้อมูลคนละหน้าที่
FiveM Routing Bucket กับ Entity Ownership ต่างกันอย่างไร
Routing Bucket กำหนด Visibility/Game State
Entity Ownership กำหนดว่า Client ใดกำลังควบคุม Networked Entity
Player อาจอยู่ Bucket เดียวกับ Vehicleและเห็นรถ แต่ไม่ได้หมายความว่า Player นั้นเป็น Current Network Owner เสมอไป
FiveM Routing Bucket ใช้จำนวนมากได้ไหม
ใช้ได้ตาม Architecture แต่ Cfx.re ระบุว่า แต่ละ Routing Bucket มี Memory Cost จึงไม่ควรสร้าง Bucket จำนวนมหาศาลโดยไม่จำเป็นหรือไม่ Cleanup.
ออกแบบ Bucket Allocation ให้เหมาะกับจำนวน Concurrent Sessions จริง
FiveM Routing Bucket ควรใช้กับ Interior ไหม
Cfx.re ระบุว่าไม่ควรใช้ Routing Bucket เป็น Use Case หลักสำหรับ Interiors.
Routing Bucket เหมาะกับ:
Character Selection
Party
Session
Multi-mode
Private Instance
มากกว่า
Checklist FiveM Routing Bucket สำหรับ Production
ตรวจว่า:
OneSync ทำงาน
Bucket IDs มี Convention
Server เป็นผู้ Assign Bucket
ไม่เชื่อ Bucket ID จาก Client
Player Bucket ถูก
Entity Bucket ถูก
Player และ Entity อยู่ Bucket เดียวกันเมื่อควรเห็นกัน
Character Instance ถูก Cleanup
Party Instance ถูก Cleanup
Player Disconnect ถูกลบจาก Session
Resource Restart มี Recovery
Entity Lockdown ถูก Mode
Population ถูกเปิด/ปิดตาม Design
ไม่ใช้ Interior เป็น Bucket แบบสุ่ม
Event ตรวจ Session/Bucket ฝั่ง Server
NetID ไม่ถูกใช้แทน Bucket
Entity Ownership ไม่ถูกสับสนกับ Bucket
ไม่สร้าง Buckets จำนวนมากโดยไม่มี Cleanup
ทดสอบ Player หลายคน
ทดสอบผู้เล่นออก Instance
ทดสอบ Disconnect ใน Instance
ทดสอบ Resource Restart
ทดสอบ Vehicle/Ped/Object ใน Instance
ตรวจ Server Console
ตรวจ Performance เมื่อมี Concurrent Instances จำนวนมาก
FAQ FiveM Routing Bucket
FiveM Routing Bucket คืออะไร
เป็นระบบ Instance/Dimension ของ FiveM ที่สามารถ Assign Players และ Entities ไปยัง Game State แยกกัน โดยผู้ที่อยู่ Bucket เดียวกันจะเห็น Players/Entities ภายใน Bucket เดียวกัน.
Routing Bucket ใช้ทำ Character Selection ได้ไหม
ได้ Cfx.re ระบุ Character Screen แบบ Instanced เป็น Use Case โดยตรง.
Routing Bucket ใช้ทำ Party ได้ไหม
ได้ Session/Party System เป็นหนึ่งใน Use Cases ที่ Cfx.re แนะนำ.
ย้าย Player เข้า Bucket ใช้คำสั่งอะไร
ใช้:
SetPlayerRoutingBucket(
source,
bucketId
)
ดูว่า Player อยู่ Bucket ไหนอย่างไร
ใช้:
GetPlayerRoutingBucket(source)
ย้าย Entity เข้า Bucket อย่างไร
ใช้:
SetEntityRoutingBucket(
entity,
bucketId
)
Cfx.re รวม Native นี้ไว้ใน Routing Bucket API ของ OneSync.
Player เข้า Bucket แล้วรถหายเพราะอะไร
สาเหตุหนึ่งที่พบบ่อยคือ Player และ Vehicle อยู่คนละ Routing Bucket ให้ตรวจ GetPlayerRoutingBucket() กับ GetEntityRoutingBucket() ก่อน.
Routing Bucket ใช้ทำ Interior ได้ไหม
Cfx.re ระบุชัดว่า Interiors ไม่ใช่ Use Case ที่แนะนำสำหรับ Routing Buckets.
Routing Bucket มีผลต่อ Memory ไหม
มี Cfx.re ระบุว่าแต่ละ Routing Bucket มี Memory Cost ดังนั้นควรสร้างและจัด Lifecycle อย่างเป็นระบบ.
strict Entity Lockdown คืออะไร
เป็น Mode ที่ไม่อนุญาตให้ Clients สร้าง Entities ภายใน Bucket นั้น.
ประเด็นสำคัญ
FiveM Routing Bucket เป็นระบบ Instance ของ OneSync ที่ใช้แยก Players และ Entities เป็น Game State คนละชุด โดย Cfx.re ระบุ Use Cases หลักอย่าง Multi-mode Server, Party/Session และ Character Selection พร้อมทั้งระบุว่า Interior ไม่ใช่ Use Case ที่ควรใช้ Routing Bucket เป็นวิธีหลัก.
สิ่งที่ต้องจำให้แม่นคือ:
SetPlayerRoutingBucket
= ย้าย Player
SetEntityRoutingBucket
= ย้าย Entity
GetPlayerRoutingBucket
= ดู Player Bucket
GetEntityRoutingBucket
= ดู Entity Bucket
หาก Player เข้า Instance แล้วรถหรือ Entity หาย ให้ตรวจ Player Bucket เทียบกับ Entity Bucket ก่อน เพราะ Entity จะต้องถูก Route ไปยัง Game State ที่เหมาะสมเช่นเดียวกับ Player.
แต่ละ Bucket ยังสามารถกำหนด Population และ Entity Lockdown ของตัวเอง โดยปัจจุบันมี strict, relaxed, inactive และสำหรับ GTAV Enhanced มี full เพิ่มเข้ามา.
Server ที่ใช้ Instances จำนวนมากควรมี Bucket Allocator + Session Manager + Cleanup เนื่องจาก Cfx.re ระบุว่า Routing Buckets มี Memory Cost และไม่ควรสร้าง Bucket จำนวนมากโดยไม่มี Lifecycle Management.
สำหรับผู้อ่าน comsiam ให้จำสูตร “Player Bucket + Entity Bucket = Instance ที่มองเห็น” และ comsiam แนะนำให้ Server เป็นผู้เลือก Bucket ID ตรวจ Bucket ทุกครั้งก่อนทำ Session Action และ Cleanup Player/Entity เมื่อ Instance จบ เพื่อป้องกันปัญหาผู้เล่นหาย รถหาย หรือค้างอยู่คนละโลกหลัง Resource Restart
Comments
Post a Comment