FiveM OneSync คืออะไร? ระบบ Sync ผู้เล่นและ Entity ที่ FiveM Developer ต้องรู้

 FiveM OneSync คือระบบ Synchronization ของ Cfx.re ที่ต่อยอดจากระบบ Network ของ GTA Online เพื่อรองรับผู้เล่นจำนวนมากขึ้น และเพิ่มความสามารถด้าน Server-side Entity State, Entity Synchronization, Scope, State Bags, Routing Buckets และ Server-side Entity Management

พูดง่าย ๆ OneSync คือระบบสำคัญที่ช่วยให้ FiveM Server จัดการว่า

Player คนไหนควรเห็นใคร
Entity ตัวไหนควรถูก Sync
Client ใดกำลังควบคุม Entity
Server รู้ State ของ Entity อะไรบ้าง
Entity อยู่ Instance ไหน
State อะไรต้อง Replicate

ตัวอย่างเช่น Server มีผู้เล่นอยู่คนละด้านของแผนที่

Player A
↓
อยู่ Los Santos

Player B
↓
อยู่ไกลออกไปมาก

Client A ไม่จำเป็นต้องได้รับและสร้าง Entity ของทุก Player, Vehicle, Ped และ Object ที่อยู่ทั่ว Server พร้อมกัน

OneSync จึงใช้แนวคิดอย่าง Scope และ Culling เพื่อส่งเฉพาะสิ่งที่เกี่ยวข้องกับ Player

นอกจากนี้ยังทำให้ Server สามารถทำสิ่งสำคัญ เช่น

local ped =
    GetPlayerPed(source)

local coords =
    GetEntityCoords(ped)

หรือสร้าง Networked Vehicle จาก Server ตาม API ที่รองรับ

local vehicle =
    CreateVehicleServerSetter(
        joaat('sultan'),
        'automobile',
        215.0,
        -810.0,
        30.0,
        157.0
    )

ดังนั้นหากต้องการเขียน FiveM Script ระดับกลางถึงสูง OneSync เป็นพื้นฐานที่ควรเข้าใจอย่างจริงจัง

① FiveM OneSync คืออะไร

OneSync คือ Custom Synchronization System ของ FiveM/Cfx.re

หน้าที่หลักคือจัดการ Synchronization ของ Multiplayer Game State เช่น

  • Players

  • Peds

  • Vehicles

  • Objects

  • Networked Entities

  • Entity State

  • Scope

  • Ownership

  • Routing

ระบบนี้ทำให้ FiveM สามารถรองรับ Server ที่ซับซ้อนและมีผู้เล่นมากกว่าระบบ Synchronization แบบเดิม

② ทำไม FiveM ต้องมี OneSync

Multiplayer Server ต้องตอบคำถามตลอดเวลาว่า

ใครอยู่ที่ไหน?
ใครเห็นใคร?
รถคันไหนอยู่ที่ไหน?
ใครกำลังควบคุมรถ?
Entity ตัวไหนต้องส่งไป Client ไหน?
State อะไรเปลี่ยน?

หากส่ง Entity ทั้งหมดไป Client ทุกคนโดยไม่จำกัด Server ใหญ่จะมีปัญหาด้าน

  • Bandwidth

  • CPU

  • Client Processing

  • Entity Limits

  • Scalability

OneSync จึงเพิ่มระบบ Streaming, Scope และ Server-side Awareness เข้ามาช่วยจัดการปัญหาเหล่านี้

③ OneSync ทำอะไรให้ Developer บ้าง

สิ่งสำคัญที่เกี่ยวข้องกับ OneSync ได้แก่

Server-side State Awareness
Networked Entities
Network IDs
Entity Ownership
Scope
Culling
State Bags
Routing Buckets
Entity Lockdown
Server-created Entities

หลายหัวข้อเหล่านี้ถูกใช้ร่วมกัน

จึงไม่ควรเรียนแยกเป็น Function ทีละตัวโดยไม่เข้าใจภาพรวม OneSync

④ State Awareness คืออะไร

State Awareness หมายถึง Server มีความสามารถรับรู้ State ของ Players และ Networked Entities มากขึ้น

ตัวอย่าง Server สามารถหา Player Ped

local ped =
    GetPlayerPed(source)

แล้วอ่าน Coordinates

local coords =
    GetEntityCoords(ped)

ทำให้ Server-side Validation ทำได้แข็งแรงขึ้น

เช่นตรวจว่า Player อยู่ใกล้จุดส่งงานจริงหรือไม่

⑤ ทำไม State Awareness สำคัญกับ Security

สมมติ Client ส่ง

TriggerServerEvent(
    'job:complete'
)

Server ไม่ควรเชื่อว่า Playerอยู่จุดส่งงานเพียงเพราะ Client Trigger Event

Server สามารถตรวจ

source
↓
Player Ped
↓
Coordinates
↓
Distance
↓
Mission State
↓
Reward

นี่เป็นหนึ่งในเหตุผลที่ OneSync มีความสำคัญกับ Server-authoritative Script Design

⑥ OneSync เกี่ยวกับ Entity อย่างไร

Vehicle, Ped และ Object ที่ Networked ต้องถูก Synchronize ระหว่างผู้เล่น

OneSync ช่วยจัดการ

Entity
↓
Network ID
↓
Scope
↓
Ownership
↓
Synchronization

ตัวอย่างรถคันหนึ่งไม่จำเป็นต้องมี Local Entity Handle เดียวกันใน Client ทุกเครื่อง

แต่สามารถอ้างถึง Network Entity เดียวกันด้วย Network ID

⑦ Entity Handle กับ OneSync

Entity Handle เป็น Local Runtime Reference

ตัวอย่าง

local vehicle =
    GetVehiclePedIsIn(
        PlayerPedId(),
        false
    )

เลข Handle ของรถคันเดียวกันสามารถแตกต่างกันใน Client แต่ละเครื่อง

OneSync Networking จึงใช้ Network Representation สำหรับการ Sync ระหว่าง Machines

⑧ Network ID เกี่ยวกับ OneSync อย่างไร

Network ID ใช้อ้าง Networked Entity ข้าม Client และ Server

Concept คือ

Client A
Entity Handle 154
↓
Network ID 82
↓
OneSync
↓
Client B
Entity Handle 731

Entity Handle ต่างกัน

แต่ Network ID ใช้ระบุ Network Entity เดียวกันในช่วง Lifetime ของ Entity

⑨ OneSync Scope คืออะไร

Scope คือชุด Players/Entities ที่เกี่ยวข้องกับ Client หนึ่งในช่วงเวลานั้น

ตัวอย่าง

Player A อยู่ใกล้ Player B
↓
B อยู่ใน Scope ของ A

เมื่ออยู่ไกลมาก

Player B
↓
ออกนอก Scope

Client A ไม่จำเป็นต้องมี Local Representation ของ B ต่อไปตามระบบ Culling

⑩ ทำไมไม่ Sync ทุกคนให้ทุกคน

สมมติมีผู้เล่น 1,000 คน

ถ้า Player ทุกคนต้องรับ

999 Players
+
Vehicles
+
Peds
+
Objects

ทั้งหมดตลอดเวลา Network และ Client Processing จะหนักมาก

OneSync จึงใช้ Culling เพื่อลดข้อมูลที่ไม่เกี่ยวข้อง

นี่เป็นพื้นฐานสำคัญของ Scalability

⑪ Culling คืออะไร

Culling คือการลดการ Synchronize Entity ที่อยู่นอกพื้นที่ความสนใจของ Client

แนวคิด

อยู่ใกล้
→ Sync

อยู่ไกล
→ Cull

เอกสาร Cfx.re ปัจจุบันระบุ Focus Zone เริ่มต้นประมาณ 424 game units ในบริบท OneSync Infinity

แต่ Developer ไม่ควรเขียน Gameplay Logic โดยสมมติว่า Entity ทุกตัวอยู่ใน Client เสมอ

⑫ Entity ออกจาก Scope แล้วเกิดอะไรขึ้น

เมื่อ Entity ออกจาก Range

Client อาจไม่มี Local Entity นั้นอีก

และ Network Ownership สามารถ

Migrate
หรือ
Disown

ได้

นี่เป็นเหตุผลที่ Script ต้องตรวจ Entity Lifecycle

เช่น

if not DoesEntityExist(entity) then
    return
end

ก่อนใช้ Handle ที่เก็บไว้นาน

⑬ playerEnteredScope คืออะไร

OneSync มี Event สำหรับตรวจ Player เข้า Scope

AddEventHandler(
    'playerEnteredScope',
    function(data)

        local playerEntered =
            data.player

        local player =
            data['for']

    end
)

แต่ Cfx.re มี Performance Warning สำหรับ Events กลุ่มนี้

เพราะ Cost Scale ตามจำนวน Players ที่เข้า/ออก Scope

⑭ playerLeftScope คืออะไร

ทำงานเมื่อ Player ออกจาก Scope ของอีก Player

แต่มีข้อควรระวังด้าน Scaling เช่นเดียวกับ playerEnteredScope

Cfx.re แนะนำว่า หาก Use Case สามารถใช้ State Bags เพื่อจัดการ Scoped State ได้ ควรพิจารณา State Bags แทน

⑮ ทำไม State Bags ถึงเกี่ยวกับ OneSync

State Bags เป็นระบบ Replicated Key/Value State ใน State Awareness Mode

เช่น Vehicle

fuel = 70
locked = true
mission = 15

สามารถเขียน

Entity(vehicle).state:set(
    'fuel',
    70,
    true
)

แล้ว Clients ที่เกี่ยวข้องสามารถรับ State ตาม Replication Policy

⑯ Player State ก็เป็นส่วนหนึ่งของระบบนี้

Player มี State Bag เช่นกัน

Player(source).state:set(
    'job:onDuty',
    true,
    true
)

Client สามารถตอบสนองต่อ State ตาม Architecture

เหมาะกับข้อมูล Runtime ที่ต้อง Sync ระหว่างระบบ

⑰ GlobalState คืออะไร

Server สามารถกำหนด Global State

GlobalState.doubleXP =
    true

Clients สามารถอ่านค่าได้

เหมาะกับ State ระดับ Server เช่น

Event Active
Double XP
Server Mode
Global Feature Flag

ทั้งหมดนี้สัมพันธ์กับ State Awareness ของ OneSync

⑱ OneSync กับ State Bag Change Handler

State เปลี่ยนแล้ว Resource สามารถฟังด้วย

AddStateBagChangeHandler(
    'vehicle:locked',
    nil,
    function(
        bagName,
        key,
        value
    )

        -- react

    end
)

ช่วยสร้าง Architecture แบบ Reactive

แทนการ Polling State ซ้ำตลอดเวลา

⑲ OneSync กับ Routing Bucket

Routing Bucket เป็น Dimension/Instance System ที่อยู่ใน OneSync Architecture

ตัวอย่าง

Bucket 0
→ Main World

Bucket 100
→ Mission A

Bucket 200
→ Mission B

Server ย้าย Player ด้วย

SetPlayerRoutingBucket(
    source,
    100
)

และ Entity ด้วย

SetEntityRoutingBucket(
    entity,
    100
)

⑳ Routing Bucket ใช้ทำอะไร

เหมาะกับ

  • Party Instance

  • Mission Session

  • Character Selection

  • Lobby

  • Match

  • Multi-mode Server

Cfx.re ระบุ Use Cases เหล่านี้โดยตรง

แต่ไม่ได้แนะนำ Routing Buckets เป็น Default Solution สำหรับ Interior ทั่วไป

㉑ OneSync กับ Entity Ownership

Networked Entity มี Network Ownership

หมายถึง Client ใดกำลังรับผิดชอบ Network Simulation ของ Entity

ตัวอย่าง

Vehicle
Net ID = 50
↓
Owner A

ต่อมา

A ออกนอก Scope
↓
Ownership Migration
↓
Owner B

Ownership สามารถเปลี่ยนได้

㉒ คน Spawn Entity เป็น Owner ตลอดไหม

ไม่

นี่เป็นข้อผิดพลาดที่ Developer มือใหม่มักคิด

Client A สร้าง Vehicle
=
A จะ Own ตลอดไป

ไม่จริง

Ownership สามารถ Migration ตาม Scope และ Networking State

Business Logic จึงไม่ควรผูกกับ Owner คนเดิมถาวร

㉓ Network Owner คือเจ้าของรถไหม

ไม่

ต้องแยก

Network Owner
→ ผู้ควบคุม Network Simulation

ออกจาก

Database Owner
→ เจ้าของรถในระบบ Garage

Player ที่ขับรถคนอื่นสามารถเป็น Network Owner ได้ในบางช่วง

ไม่ได้หมายความว่ามีสิทธิ์ขายรถ

㉔ Server-created Entity คืออะไร

OneSync รองรับการสร้าง Entities ฝั่ง Server

เช่น Vehicle

local vehicle =
    CreateVehicleServerSetter(
        joaat('blista'),
        'automobile',
        2204.795,
        -887.9213,
        1461.224,
        90.0
    )

ช่วยให้ Server เป็นผู้ควบคุม Entity Creation ได้มากขึ้น

㉕ ทำไม Cfx.re แนะนำ Server-created Entities

สำหรับระบบที่สำคัญ การให้ Client เป็นผู้สร้าง Entity อาจเพิ่ม Complexity และ Attack Surface

Architecture ที่ดีกว่าในหลายกรณีคือ

Client
↓
ขอ Spawn
↓
Server Validate
↓
Server Create
↓
OneSync
↓
Clients

โดยเฉพาะ Mission Vehicles, Peds หรือ Objects ที่ Server ต้องควบคุม

㉖ Client-created Entity ยังใช้ได้ไหม

ใช้ได้ตาม Configuration และ Use Case

แต่ต้องเข้าใจ

  • Entity Lockdown

  • Network Ownership

  • Security

  • Lifecycle

  • Scope

Server ที่ต้องการควบคุมเข้มสามารถใช้ Entity Lockdown จำกัด Client Creation ได้

㉗ Entity Lockdown คืออะไร

Routing Bucket สามารถกำหนด Lockdown Mode

เช่น

SetRoutingBucketEntityLockdownMode(
    bucket,
    'strict'
)

strict หมายถึงไม่อนุญาต Clients สร้าง Entities ใน Bucket นั้น

เหมาะกับ Server-authoritative Entity Creation

㉘ Lockdown Modes มีอะไร

เอกสาร OneSync ปัจจุบันระบุ Mode เช่น

strict
relaxed
inactive

และ full สำหรับ GTAV Enhanced ตามข้อกำหนดของเอกสารปัจจุบัน

ความหมายโดยย่อ:

strict
→ Client สร้าง Entity ไม่ได้

relaxed
→ จำกัด Script-owned Client Entities

inactive
→ Client สร้าง Entity ได้ตามปกติ

ต้องเลือกให้เหมาะกับ Resources

㉙ OneSync กับ Population

Routing Bucket สามารถควบคุม Population

SetRoutingBucketPopulationEnabled(
    bucket,
    false
)

เช่น Character Selection หรือ Private Mission อาจไม่ต้องการ

  • NPC

  • Traffic

  • Ambient Population

จึงปิดได้เฉพาะ Bucket

㉚ Server-created Entity และ Orphan Mode

Cfx.re แนะนำให้ใช้

SetEntityOrphanMode(
    entity,
    2
)

กับ Server-created Entity ที่ต้องการให้ Serverเก็บ Entity ไว้แม้ไม่มี Client Owner

Mode 2 คือ KeepEntity ในบริบทนี้

แต่ไม่ใช่ Persistence ข้าม Server Restart

㉛ Orphan Entity คืออะไร

Server-created Entity อาจเกิดก่อนมี Client อยู่ใน Scope

Concept:

Server Create Entity
↓
ไม่มี Client ใกล้
↓
ยังไม่มี Client Owner
↓
Orphaned

เมื่อ Client เข้า Scope ระบบจึงสามารถมี Client มารับ Simulation Ownership

㉜ Server-created หมายถึง Server Simulate Physics เองไหม

ไม่ควรเข้าใจแบบนั้น

FiveM ไม่ได้ใช้ Server-based Authoritative Entity Ownership แบบเดียวกับ Multiplayer Engine บางระบบ

Cfx.re ระบุว่า Ownership ยังอาศัย Client Forwarding และ Ownership Mechanisms

ดังนั้น

Server-created
≠
Server physics simulation ทุกอย่าง

㉝ RPC Native คืออะไรใน OneSync

Native บางตัวที่ Server เรียกเป็น RPC Native

หมายความว่า Operation จริงอาจถูก Execute บน Client ซึ่งโดยทั่วไปคือ Client ที่ Own Entity

Concept:

Server
↓
RPC Native
↓
Owner Client
↓
Native Execute

Cfx.re เตือนว่า RPC Calls เหล่านี้ อาจล้มเหลวและไม่รับประกันว่าจะถูก Execute

㉞ ทำไม RPC Native ถึง Fallible

เพราะ Network Conditions และ Ownership สามารถเปลี่ยนได้

เช่น

Server เรียก Native
↓
Owner เปลี่ยน
↓
Client Disconnect
↓
Entity ออกจาก Scope

ดังนั้น Critical System ไม่ควรสมมติว่า RPC Native ทุก Call สำเร็จเสมอ

㉟ Server Setter ต่างจาก RPC Native อย่างไร

Server Setter บางตัว Update/Create State จาก Server-side โดยตรงมากกว่า RPC Pattern

ตัวอย่างที่ Cfx.re แนะนำคือ

CreateVehicleServerSetter(...)

เมื่อมี Server Setter ที่เหมาะสม มักน่าสนใจกว่าสำหรับ Server-created Entity Architecture

แต่ต้องดู Native Reference ของแต่ละ Function

㊱ OneSync กับ Network Control

Client สามารถมี Concept

NetworkHasControlOfEntity(
    entity
)

และ Request Control

NetworkRequestControlOfEntity(
    entity
)

แต่ Request ไม่ได้แปลว่าจะได้รับ Control แน่นอน

Server สามารถควบคุม Requests ผ่าน sv_filterRequestControl

㊲ sv_filterRequestControl คืออะไร

เป็น Server Setting ที่จำกัด Client Requests เพื่อขอ Control Entity

เอกสารปัจจุบันมีระดับ

0
1
2
3
4

โดย

0
→ ไม่ Filter

4
→ ไม่อนุญาต Control Requests ทั้งหมด

และระดับกลางจะเพิ่มข้อจำกัดตาม Entity Ownership/Settled State

㊳ ทำไม Developer ต้องรู้ Setting นี้

เพราะ Script เก่าบางตัวใช้ Pattern

หา Entity
↓
Request Control
↓
Delete/Modify

แล้วสมมติว่าจะสำเร็จ

แต่ Server ที่เปิด Filtering เข้มขึ้นอาจทำให้ Resource แบบนี้ทำงานต่างออกไป

จึงไม่ควรพึ่ง Network Control Request อย่าง Aggressive

㊴ อย่า Loop Request Control ตลอดไป

ตัวอย่างที่ควรหลีกเลี่ยง

while not NetworkHasControlOfEntity(
    entity
) do

    NetworkRequestControlOfEntity(
        entity
    )

    Wait(0)
end

ถ้า Server ไม่ให้ Control Loop อาจทำงานไม่จบ

ควรมี Timeout และ Failure Path

㊵ OneSync ทำให้ Server ตรวจ Position ได้อย่างไร

หนึ่งในประโยชน์สำคัญคือ Server-side Entity Awareness

Server สามารถใช้

local ped =
    GetPlayerPed(source)

local coords =
    GetEntityCoords(ped)

แล้วตรวจ

อยู่ใกล้ Shop?
อยู่จุด Mission?
อยู่ใกล้ Vehicle?

แทนเชื่อ Coordinates ที่ Client ส่ง

ช่วย Secure Network Events ได้มาก

㊶ ตัวอย่าง Secure Mission ด้วย OneSync

Client

TriggerServerEvent(
    'delivery:complete'
)

Server

RegisterNetEvent(
    'delivery:complete',
    function()

        local src =
            source

        local ped =
            GetPlayerPed(src)

        if ped == 0 then
            return
        end

        local coords =
            GetEntityCoords(ped)

        if #(coords - finishCoords)
            > 10.0 then
            return
        end

        -- validate mission state
        -- calculate reward server-side

    end
)

OneSync ช่วยให้ Server ตรวจ Game State ที่เกี่ยวข้องได้มากขึ้น

㊷ OneSync ทำให้ Client Trusted ไหม

ไม่

แม้ OneSync จะเพิ่ม Server-side Awareness แต่ Client ยังถือเป็น Untrusted Environment สำหรับข้อมูลสำคัญ

Server ยังต้องตรวจ

  • Money

  • Inventory

  • Permission

  • Job

  • Reward

  • Mission State

  • Input Range

OneSync เป็นเครื่องมือช่วยสร้าง Authority

ไม่ใช่ Anti-cheat สำเร็จรูป

㊸ OneSync เป็น Anti-Cheat ไหม

ไม่

OneSync เป็น Synchronization และ State Awareness System

Entity Lockdown และ Server-created Entities สามารถลด Attack Surface ได้

แต่ Security ยังต้องประกอบด้วย

Secure Events
Server Validation
Permissions
Rate Limits
Entity Validation
Database Validation
Anti-Cheat

ตามระบบ

㊹ OneSync กับ ESX

ESX Server สามารถใช้ OneSync Features ได้เหมือน FiveM Resource อื่น

ตัวอย่าง

ESX Player Data
+
OneSync Player Ped
+
Server Position
+
State Bags

ใช้ร่วมกันได้

Framework ไม่ได้แทน OneSync

㊺ OneSync กับ QBCore

เหมือนกัน

QBCore จัดการ Framework Layer เช่น

  • Player Data

  • Economy

  • Jobs

OneSync จัดการ Multiplayer Entity/Networking Layer

Resource ที่ดีสามารถใช้ทั้งคู่ร่วมกัน

㊻ OneSync กับ Qbox

Qbox/ox ecosystem ก็ยังอยู่บน FiveM Networking เหมือนเดิม

State Bags, Routing Buckets, Entity Ownership และ Server-side Entity APIs ยังคงเป็น Core Concepts

ดังนั้นการเข้าใจ OneSync ช่วยให้ Developer ไม่ผูกความรู้ไว้กับ Framework เดียว

㊼ OneSync ใช้ภาษาอะไรได้

OneSync ไม่ใช่ Feature เฉพาะ Lua

Resource สามารถเข้าถึง APIs ตาม Runtime ที่รองรับ เช่น

Lua
JavaScript
C#

Syntax เปลี่ยนตามภาษา

แต่ Networking Concepts เหมือนกัน

㊽ เปิด OneSync อย่างไร

เอกสารตั้งค่า Vanilla FXServer ปัจจุบันแสดง

set onesync on

ใน server.cfg

โดย OneSync เป็น Requirement สำหรับ Server-side State Awareness ที่เอกสารดังกล่าวกล่าวถึง

หัวข้อ 438 — วิธีเปิด OneSync FiveM จะลงรายละเอียดการตั้งค่าและตรวจสอบโดยเฉพาะ

㊾ fxmanifest ระบุ Requirement ได้ไหม

ได้

Resource ที่ต้องการ OneSync สามารถใช้ Runtime Constraint ใน fxmanifest.lua

เช่น

dependencies {
    '/onesync'
}

เพื่อระบุว่า Resource ต้องการ State Awareness ที่ไม่ถูก Disable

ช่วย Fail เร็วหาก Environment ไม่รองรับ Resource

㊿ OneSync Infinity คืออะไร

OneSync Infinity เป็น Mode/Architecture ของ OneSync ที่ออกแบบเพื่อ Scale จำนวน Players มากขึ้นผ่านการเปลี่ยนแปลงหลายส่วน เช่น

  • Object ID Space ใหญ่ขึ้น

  • Player/Entity Culling

  • Focus Zone

  • Player Culling

เอกสารปัจจุบันกล่าวถึงความสามารถระดับสูงสุดถึง 2048 Players ในระบบนี้

แต่เรื่อง Infinity จะอธิบายเต็มในหัวข้อ 437

51 Infinity ทำไมต้องใช้ Culling

ถ้ามี Player จำนวนมาก Client ไม่ควรสร้าง Player Ped ของทุกคนทั่ว Server

Infinity จึงใช้ Player/Entity Culling

Concept:

อยู่ใน Focus Zone
→ Create/Sync

อยู่นอก
→ ไม่สร้าง Local Entity

ช่วยให้จำนวนผู้เล่น Server เพิ่มขึ้นโดยไม่บังคับให้แต่ละ Clientจำลองทุกคนพร้อมกัน

52 Player Iteration เปลี่ยนอย่างไรใน OneSync Infinity

เอกสาร Cfx.re ระบุว่า Player Culling ทำให้ Players ที่อยู่นอก Focus Zone อาจไม่ถูกสร้าง Local บน Client

ดังนั้นระบบที่ต้อง Iterate ผู้เล่นทั้งหมดควรทำ Server-side

อย่าเขียน Client Script แล้วสมมติว่า Client รู้จัก Player ทุกคนบน Server

53 ตัวอย่าง Bug จากการคิดว่า Client เห็นทุก Player

สมมติ Client Script ทำ

GetActivePlayers()
↓
คิดว่านี่คือ Player ทั้ง Server

ใน OneSync/Infinity Context นั่นอาจไม่ใช่ Player ทุกคน

เพราะ Players นอก Scope ไม่จำเป็นต้องมี Local Player Representation

Global Player Logic ควรอยู่ Server-side

54 OneSync กับ Performance

OneSync ช่วย Scalability แต่ไม่ได้หมายความว่า Resource จะ Optimize ให้อัตโนมัติ

Script ที่ทำ

Loop Players ทั้งหมดทุก Tick
Loop Entities จำนวนมาก
Broadcast Event ทุกคน
Query Database ทุก Frame
State Bag Update ทุก Tick

ยังสามารถสร้าง Performance Problems ได้

Developer ต้อง Optimize Application Logic ด้วย

55 OneSync ไม่ได้ลบ Entity Limits ทุกชนิด

แม้ Server-side Streaming Architecture ช่วยขยายระบบ แต่ Client/Game Engine ยังมีข้อจำกัดด้าน Entities ที่อยู่ใน Range/Streaming Context

เอกสาร Migration ปัจจุบันเตือนว่า หากมี Entities ใน Range มากเกินกว่าที่เกมรองรับ Client สามารถมีปัญหาหรือ Timeout ได้

ดังนั้นอย่า Spawn Entity จำนวนมหาศาลในพื้นที่เล็ก ๆ เพียงเพราะเปิด OneSync

56 OneSync Persistent Entity หมายถึงอะไร

SetEntityOrphanMode(entity, 2) ช่วยให้ Runtime Entity ไม่ถูก Server ลบเพียงเพราะไม่มี Owner

แต่ไม่ได้หมายถึง

Server Restart
↓
Entity ยังอยู่

ถ้าต้องการ Persistence ข้าม Restart ต้องใช้

  • Database

  • KVP

  • Persistent Storage

แล้วสร้าง Entity ใหม่เมื่อ Serverกลับมา

57 วิธี Debug OneSync

เริ่มจากตรวจ

OneSync เปิดหรือยัง?
Player Ped หา Server-side ได้ไหม?
Entity เป็น Networked หรือไม่?
Network ID ถูกไหม?
Routing Bucket ถูกไหม?
Entity อยู่ Scope หรือไม่?
Owner คือใคร?
State Bag Replicate หรือไม่?

แล้วดู Server Console/F8 ตาม Context

อย่าแก้ Networking Bug ด้วยการเพิ่ม Wait() อย่างเดียว

58 OneSync Problem ที่พบบ่อย

ตัวอย่าง

Entity หาไม่เจอ
→ อาจอยู่นอก Scope

Player ไม่เห็น Vehicle
→ Bucket ต่างกัน

Client สั่ง Entity ไม่ได้
→ ไม่มี Control / Owner เปลี่ยน

State ไม่มา
→ Replication/Ownership/Strict Mode

Server Event ถูกโกง
→ Validation ไม่พอ

Mission Vehicle หาย
→ Lifecycle/Orphan/Persistence

OneSync ช่วยอธิบาย Bug หลายประเภทที่ดูเหมือนไม่เกี่ยวกัน

59 Checklist สำหรับ Resource ที่ใช้ OneSync

ก่อนเปิดใช้งาน Production ตรวจอย่างน้อย

① Resource ต้องใช้ OneSync หรือไม่?
② Server เปิด OneSync แล้วหรือยัง?
③ Entity เป็น Local หรือ Networked?
④ ใช้ Entity Handle กับ Network ID ถูกหรือไม่?
⑤ Client อยู่ใน Scope หรือไม่?
⑥ Logic ต้องรู้ Player ทุกคนหรือไม่?
⑦ ถ้าต้องรู้ทั้งหมด ทำ Server-side หรือยัง?
⑧ Entity Owner สามารถเปลี่ยนได้หรือไม่?
⑨ Resource พึ่ง Request Control มากไปหรือไม่?
⑩ Server-created Entity เหมาะกว่าหรือไม่?
⑪ Entity ต้อง KeepEntity หรือไม่?
⑫ State ควรใช้ State Bag หรือ Event?
⑬ State Bag ถูก Set ถี่เกินไปหรือไม่?
⑭ Routing Bucket ถูกต้องหรือไม่?
⑮ Population Policy ถูกต้องหรือไม่?
⑯ Entity Lockdown Mode เหมาะสมหรือไม่?
⑰ Network Event Validate Server-side หรือไม่?
⑱ Position ตรวจ Server-side หรือไม่?
⑲ Entity Cleanup ถูกออกแบบหรือไม่?
⑳ Persistence ใช้ Database หรือไม่?
㉑ Client Script สมมติว่าเห็นทุก Player หรือไม่?
㉒ Resource วัด Performance จริงแล้วหรือยัง?

⑥⓪ ภาพรวม Architecture ของ OneSync

สามารถมอง OneSync แบบนี้

                    FXServer
                       │
         ┌─────────────┼─────────────┐
         │             │             │
      Players       Entities       State
         │             │             │
      source        Net ID       State Bags
         │             │             │
         └─────── OneSync ──────────┘
                       │
              Scope / Culling
                       │
              Entity Ownership
                       │
             Routing Buckets
                       │
                Relevant Clients

หรือมองจาก Client

Client
↓
อยู่ใน Bucket ไหน?
↓
มี Entity ไหนอยู่ใน Scope?
↓
Entity ไหนถูก Stream เข้ามา?
↓
Network ID อะไร?
↓
ใครเป็น Owner?
↓
State Bag เป็นอะไร?
↓
Script ตอบสนอง

นี่คือภาพรวมของ Multiplayer Networking ที่ FiveM Developer ต้องเข้าใจ

ตัวอย่าง OneSync Server-side Vehicle

server.lua

RegisterCommand(
    'spawnservercar',
    function(source)

        if source <= 0 then
            return
        end

        local ped =
            GetPlayerPed(source)

        if ped == 0 then
            return
        end

        local coords =
            GetEntityCoords(ped)

        local bucket =
            GetPlayerRoutingBucket(
                source
            )

        local vehicle =
            CreateVehicleServerSetter(
                joaat('sultan'),
                'automobile',
                coords.x + 5.0,
                coords.y,
                coords.z,
                0.0
            )

        if vehicle == 0 then
            return
        end

        SetEntityRoutingBucket(
            vehicle,
            bucket
        )

        SetEntityOrphanMode(
            vehicle,
            2
        )

        Entity(vehicle).state:set(
            'example:serverVehicle',
            true,
            true
        )
    end,
    false
)

ตัวอย่างเดียวนี้รวมแนวคิดหลายอย่าง

Player source
↓
Server Player Ped
↓
Server Coordinates
↓
Player Routing Bucket
↓
Server-created Vehicle
↓
Entity Routing Bucket
↓
Orphan Mode
↓
State Bag
↓
OneSync Replication

นี่คือเหตุผลที่การเข้าใจ OneSync ทำให้การเขียน FiveM Resource ขั้นสูงง่ายขึ้นมาก

คำถามที่พบบ่อยเกี่ยวกับ FiveM OneSync

FiveM OneSync คืออะไร

คือ Custom Synchronization System ของ FiveM ที่เพิ่ม Scalability และ Server-side State Awareness สำหรับ Players และ Networked Entities

OneSync มีไว้เพิ่มจำนวนผู้เล่นอย่างเดียวไหม

ไม่ นอกจาก Scaling แล้ว ยังมี Developer Features สำคัญ เช่น Server-side Entity State, State Bags, Routing Buckets และ Server-created Entities

OneSync เกี่ยวกับ Network ID ไหม

เกี่ยวโดยตรง เพราะ Network IDs ใช้อ้าง Networked Entities ระหว่าง Client และ Server

OneSync เกี่ยวกับ Entity Ownership ไหม

เกี่ยว เพราะ Network Entity Ownership และ Migration เป็นส่วนหนึ่งของ Synchronization Model

OneSync เกี่ยวกับ State Bags ไหม

เกี่ยว State Bags ทำงานใน State Awareness Mode และใช้ Replicate Custom State

OneSync เกี่ยวกับ Routing Bucket ไหม

เกี่ยว Routing Buckets เป็นระบบ Dimension/Instance ใน OneSync

OneSync ทำให้ Server ดู Player Coordinates ได้ไหม

OneSync State Awareness รองรับ Server-side Player/Entity APIs ที่ทำให้ Server ตรวจ State เช่น Player Ped และ Coordinates ได้

OneSync ทำให้ Server ปลอดภัยจาก Cheat ไหม

ไม่ แต่ช่วยให้ Server Validate Gameplay State ได้ดีขึ้น

OneSync สร้าง Vehicle ฝั่ง Server ได้ไหม

ได้ผ่าน Server-side APIs ที่รองรับ เช่น CreateVehicleServerSetter()

Server-created Vehicle มี Owner เป็น Server ตลอดไหม

ไม่ควรเข้าใจแบบนั้น Entity Network Ownership ยังมี Client Simulation/Ownership Behavior

Entity Owner เปลี่ยนได้ไหม

ได้

Entity ออกจาก Scope แล้วเกิดอะไร

สามารถถูก Culled และ Ownership สามารถ Migrate/Disown ได้

OneSync ใช้ State Bag แทน Event ได้ไหม

ได้ใน Use Case ที่เป็น Current State แต่ Event ยังคงเหมาะกับ Action/Occurrence

OneSync Routing Bucket ใช้ทำ Instance ได้ไหม

ได้ เหมาะกับ Session, Party, Character Selection และ Multi-mode

Routing Bucket ใช้ทำ Interior ดีไหม

Cfx.re ไม่แนะนำเป็น Default Solution สำหรับ Interiors

OneSync มี Entity Lockdown ไหม

มี โดย Routing Bucket สามารถกำหนด Lockdown Mode เพื่อควบคุม Client-created Entities

OneSync เปิดอย่างไร

เอกสาร FXServer ปัจจุบันใช้

set onesync on

หัวข้อ 438 จะอธิบายการเปิดและตรวจสอบอย่างละเอียด

OneSync Infinity คืออะไร

เป็นรูปแบบ OneSync สำหรับ Scaling จำนวน Players สูงขึ้น โดยใช้แนวคิดอย่าง Player/Entity Culling และ Focus Zones เพิ่มเติม ซึ่งจะอธิบายเต็มในหัวข้อถัดไป

OneSync Infinity รองรับกี่คน

เอกสาร Cfx.re ปัจจุบันระบุความสามารถสูงสุดใน Architecture ถึง 2048 Players แต่จำนวนที่ใช้งานจริงยังขึ้นกับ Server, Resources, Network, Subscription และประสิทธิภาพโดยรวม

Client เห็น Player ทุกคนใน Server ไหม

ไม่จำเป็น โดยเฉพาะใน Infinity Players นอก Focus Zone อาจไม่มี Local Player Representation

Loop Player ทั้ง Server ควรทำ Client ไหม

ไม่ หากต้องการข้อมูล Players ทั้งหมดควรออกแบบ Server-side

เปิด OneSync แล้ว Script จะลื่นอัตโนมัติไหม

ไม่ Resource ยังต้อง Optimize Threads, Events, Database, Entities และ Network Payload เอง

สรุป FiveM OneSync คืออะไร

FiveM OneSync คือหัวใจสำคัญของระบบ Multiplayer Synchronization สมัยใหม่ของ FiveM ซึ่งช่วยทั้งเรื่อง Scalability และเพิ่มความสามารถให้ Developer จัดการ Players, Entities และ State จาก Server ได้ดีขึ้น

ภาพรวมสำคัญคือ

OneSync
├── State Awareness
├── Networked Entities
├── Network IDs
├── Scope
├── Culling
├── Entity Ownership
├── Server-created Entities
├── State Bags
├── Routing Buckets
└── Entity Lockdown

ถ้า Player หรือ Entity อยู่ไกลเกิน Scope

ไม่จำเป็นต้องถูกสร้างบน Client

ช่วยลดข้อมูลที่ Client ต้องจัดการ

หากต้องการเก็บ Custom State

State Bags

หากต้องการสร้าง Dimension

Routing Buckets

หากต้องการควบคุม Entity Creation

Server-created Entities
+
Entity Lockdown

และหากต้องการ Secure Gameplay

Client Request
↓
OneSync Server-side State
↓
Validation
↓
Server Decision

อย่างไรก็ตาม OneSync ไม่ใช่ Anti-cheat และไม่ได้ทำให้ Client กลายเป็น Trusted Environment การตรวจ Money, Inventory, Job, Permission, Reward และ Business State ยังต้องทำ Server-side เช่นเดิม

สำหรับคนที่กำลังเรียน FiveM Developer กับ comsiam การเข้าใจ OneSync จะช่วยเชื่อมหลายหัวข้อที่ดูเหมือนแยกกันให้กลายเป็นภาพเดียว ตั้งแต่ Entity Handle, Network ID, Ownership, State Bags จนถึง Routing Bucket

หลักสำคัญจาก comsiam คือ อย่าคิดว่า OneSync มีไว้แค่เพิ่ม Slot ผู้เล่น เพราะคุณค่าที่สำคัญสำหรับ Developer คือการทำให้ Server เข้าใจและควบคุม Multiplayer State ได้มากขึ้น

หัวข้อถัดไปคือ FiveM OneSync Infinity คืออะไร ซึ่งจะเจาะระบบ Scaling ขนาดใหญ่โดยเฉพาะ ทั้ง 2048-player architecture, 16-bit Object IDs, Focus Zone, Player/Entity Culling และผลกระทบต่อการเขียน Script ฝั่ง Client

Comments

Popular posts from this blog

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

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

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