FiveM Population คืออะไร? วิธีควบคุม NPC, Ped และรถที่เกมสร้างเองด้วย OneSync

 FiveM Population คือระบบที่เกี่ยวข้องกับ Ped, NPC และ Vehicle ที่ตัวเกมสร้างขึ้นโดยอัตโนมัติเพื่อทำให้โลก GTA V มีชีวิต เช่น คนเดินถนน รถบนถนน และ Entity จากระบบ Population ต่างๆ สำหรับ FiveM Developer สามารถควบคุม Population ได้ทั้งระดับ Routing Bucket, ระดับ Density ฝั่ง Client และดักการสร้าง Population Ped ผ่าน populationPedCreating.

เรื่องนี้สำคัญโดยเฉพาะ Server ที่ใช้ OneSync และ Routing Buckets เพราะ Cfx.re ระบุว่า แต่ละ Routing Bucket มี world grid ของตัวเองสำหรับกำหนด Population Owners และสามารถเปิดหรือปิด Automatically-created Population แยกเป็นราย Bucket ได้.

① FiveM Population คืออะไร

คำว่า Population ในบริบท FiveM หมายถึง Entity ที่ระบบเกมสร้างขึ้นเพื่อเติมโลกของ GTA V โดยอัตโนมัติ แทนที่จะเป็น Entity ที่ Resource ของเราสร้างโดยตรง

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

FiveM World
│
├── Script-created Entities
│   ├── Vehicle
│   ├── Ped
│   └── Object
│
└── Game Population
    ├── Pedestrians
    ├── Scenario Peds
    ├── Traffic Vehicles
    └── Parked Vehicles

FiveM มีทั้ง APIs สำหรับตรวจ Population Type และ APIs สำหรับควบคุม Population ในระดับต่างๆ.

② Population ต่างจาก Server-created Entity อย่างไร

Server-created Entity คือ Entity ที่ Resource ฝั่ง Server สร้างขึ้นโดยตั้งใจ

ตัวอย่าง:

local vehicle = CreateVehicleServerSetter(
    GetHashKey('blista'),
    'automobile',
    x,
    y,
    z,
    heading
)

ส่วน Population คือ Entity ที่ Game Population System เป็นผู้สร้างตาม Environment และ Gameplay ของ GTA V

OneSync Documentation แยกแนวคิด Server-created Entities ออกจาก Population และยังเปิดให้กำหนด Population Policy ของ Routing Bucket ได้.

③ Routing Bucket มี Population แยกกันหรือไม่

มี

Cfx.re ระบุว่าแต่ละ Routing Bucket มี world grid ของตัวเองสำหรับ determining population owners.

ตัวอย่าง:

Bucket 0
├── Player A
└── Population A

Bucket 100
├── Player B
└── Population B

Bucket 200
├── Player C
└── Population C

Population ของแต่ละ Bucket จึงทำงานภายใต้ Game State ของ Bucket นั้น

④ ปิด Population ใน Routing Bucket ได้ไหม

ได้

Cfx.re มี:

SetRoutingBucketPopulationEnabled(
    bucketId,
    false
)

และ OneSync Documentation ใช้ Native นี้ในตัวอย่างเพื่อปิด Population ภายใน Routing Bucket.

⑤ ตัวอย่างปิด Population ใน Bucket

local bucketId = 100

SetRoutingBucketPopulationEnabled(
    bucketId,
    false
)

ผลคือ Automatically-created Population ของ Bucket นั้นถูกปิดตาม Routing Bucket Population Policy.

⑥ เปิด Population กลับอย่างไร

ใช้:

SetRoutingBucketPopulationEnabled(
    bucketId,
    true
)

ดังนั้น Resource สามารถควบคุม Population ของแต่ละ Instance ได้โดยไม่จำเป็นต้องใช้ Policy เดียวกันทั้ง Server.

⑦ Bucket 0 ปิด Population ได้ไหม

ได้เช่นเดียวกับ Bucket อื่น หาก Architecture ของ Server ต้องการ

ตัวอย่าง:

SetRoutingBucketPopulationEnabled(
    0,
    false
)

แต่ควรเข้าใจก่อนว่า Bucket 0 มักเป็น Main Game State ดังนั้นการปิด Population จะกระทบโลกหลักของ Server ตามที่ Resource ออกแบบไว้.

⑧ Character Selection ควรปิด Population ไหม

กรณี Character Selection แบบ Private Instance การปิด Population มักเป็น Architecture ที่เหมาะสม เพราะไม่ต้องการให้ NPC หรือ Traffic ของ Game Population ปรากฏใน Scene

Cfx.re ระบุ Character Screen แบบ Instanced เป็นหนึ่งใน Use Cases ของ Routing Buckets และตัวอย่าง OneSync ยังแสดงการใช้ Population Disabled ร่วมกับ Bucket.

ตัวอย่าง:

local bucket = 100

SetRoutingBucketEntityLockdownMode(
    bucket,
    'strict'
)

SetRoutingBucketPopulationEnabled(
    bucket,
    false
)

SetPlayerRoutingBucket(
    source,
    bucket
)

⑨ Population กับ Entity Lockdown เหมือนกันไหม

ไม่เหมือนกัน

Population

ควบคุม Automatically-created Population

Entity Lockdown

ควบคุมการสร้าง Entity จาก Client

ตัวอย่าง:

Population Disabled
≠
Client สร้าง Entity ไม่ได้

ถ้าต้องการทั้งสองอย่างต้องกำหนด Policy แยกกัน.

⑩ strict Lockdown + Population Off คืออะไร

Architecture:

Routing Bucket
↓
Entity Lockdown = strict
↓
Client สร้าง Entity ไม่ได้

+

Population = false
↓
Game Population ไม่ถูกสร้างอัตโนมัติ

Server จึงสามารถควบคุม Entity หลักภายใน Instance ได้มากขึ้น และสร้าง Entity ที่ต้องการจาก Server เอง.

⑪ populationPedCreating คืออะไร

populationPedCreating เป็น Client Core Event ของ FiveM ที่เกิดก่อน Game Population System จะสร้าง Ped

Cfx.re ระบุว่า Event นี้สามารถ:

  • อ่านตำแหน่งที่ Ped กำลังจะ Spawn

  • อ่าน Model

  • เปลี่ยน Model

  • เปลี่ยนตำแหน่ง

  • Cancel การสร้าง Ped

ได้.

⑫ populationPedCreating ใช้ฝั่งไหน

ใช้ฝั่ง:

Client

ไม่ใช่ Server Event

Cfx.re จัด populationPedCreating ไว้ใน Client Core Events โดยตรง.

ดังนั้นโดยทั่วไปใส่ Code ใน:

client.lua

⑬ Syntax ของ populationPedCreating

รูปแบบ Lua:

AddEventHandler(
    'populationPedCreating',
    function(x, y, z, model, setters)

    end
)

Parameters ปัจจุบันคือ Position x, y, z, Model และ setters สำหรับ Override Model/Position.

⑭ Cancel Population Ped ได้อย่างไร

ใช้:

AddEventHandler(
    'populationPedCreating',
    function(x, y, z, model, setters)
        CancelEvent()
    end
)

Cfx.re ระบุชัดว่า CancelEvent() สามารถใช้หยุด Population Ped ไม่ให้ถูกสร้างได้.

⑮ อย่า Cancel Population Ped ทุกตัวโดยไม่มีเหตุผล

แม้สามารถเขียน:

AddEventHandler(
    'populationPedCreating',
    function()
        CancelEvent()
    end
)

ได้ แต่จะเป็นการปิด Population Ped ผ่าน Event ฝั่ง Clientในลักษณะกว้างมาก

ถ้าเป้าหมายคือปิด Population ทั้ง Routing Bucket อยู่แล้ว Native ฝั่ง Server:

SetRoutingBucketPopulationEnabled(...)

มักตรงหน้าที่กว่า เพราะควบคุม Automatically-created Population ระดับ Bucket โดยตรง.

⑯ เปลี่ยน Model ของ Population Ped ได้ไหม

ได้

setters มี:

setters.setModel(...)

Cfx.re ระบุว่าสามารถใช้ชื่อ Model หรือ Model Hash ได้.

ตัวอย่างเชิงโครงสร้าง:

AddEventHandler(
    'populationPedCreating',
    function(x, y, z, model, setters)

        setters.setModel(
            'a_m_y_business_01'
        )

    end
)

Resource ควรเตรียม Model ให้พร้อมตามระบบ Streaming/Model Loading ของ Script ที่ใช้

⑰ เปลี่ยนตำแหน่ง Spawn ได้ไหม

ได้

ใช้:

setters.setPosition(
    x,
    y,
    z
)

Cfx.re ระบุว่า Setter นี้ใช้ Override ตำแหน่งที่ Population Ped จะ Spawn.

⑱ ตัวอย่างเปลี่ยน Position

AddEventHandler(
    'populationPedCreating',
    function(x, y, z, model, setters)

        setters.setPosition(
            x,
            y,
            z + 2.0
        )

    end
)

ตัวอย่างนี้แสดงวิธีใช้ API ไม่ได้หมายความว่าควรเลื่อน Population Ped ทุกตัวใน Production

⑲ ใช้ populationPedCreating ตรวจพื้นที่ได้ไหม

ได้ในแง่ที่ Event ส่ง Position ที่ Ped กำลังจะ Spawn มาให้ Script.

จึงสามารถทำ Logic เช่น:

Ped กำลังจะ Spawn
↓
ตรวจ Position
↓
อยู่ในพื้นที่ที่ Resource จัดการ?
↓
Allow / Cancel / Override

ตัวอย่าง:

local blockedArea =
    vector3(100.0, 200.0, 30.0)

AddEventHandler(
    'populationPedCreating',
    function(x, y, z, model, setters)

        local pos =
            vector3(x, y, z)

        if #(pos - blockedArea) < 30.0 then
            CancelEvent()
        end

    end
)

⑳ populationPedCreating ใช้แทน Routing Bucket Population ได้ไหม

ไม่ควรมองว่าแทนกันทั้งหมด

populationPedCreating

ดัก Population Ped ฝั่ง Clientเป็นราย Creation

SetRoutingBucketPopulationEnabled

เปิดหรือปิด Automatically-created Population ระดับ Routing Bucket

ดังนั้นควรเลือกเครื่องมือให้ตรงกับ Use Case.

㉑ ถ้าต้องการไม่มี NPC ใน Private Instance ใช้อะไรดี

กรณีต้องการปิด Automatically-created Population ทั้ง Instance:

SetRoutingBucketPopulationEnabled(
    bucket,
    false
)

เหมาะกว่า Loop ลบ NPC หลัง Spawn เพราะเป็น Population Policy ของ Routing Bucket โดยตรง.

㉒ GetEntityPopulationType คืออะไร

FiveM มี Native:

GetEntityPopulationType(entity)

สำหรับอ่าน Population Type ID ของ Entity.

เหมาะกับ Debug หรือ Logic ที่ต้องการแยก Entity ตาม Population Classification

㉓ GetEntityPopulationType ใช้ทำอะไร

ตัวอย่าง:

local popType =
    GetEntityPopulationType(entity)

print(
    ('Population type: %s')
    :format(popType)
)

Native จะคืน Population Type ID ของ Entity ที่กำหนด.

㉔ อย่าใช้ Population Type เป็น Security Check เพียงอย่างเดียว

Population Type เป็นข้อมูลเกี่ยวกับ Entity Classification ไม่ใช่ Permission ของ Player

ถ้าฝั่ง Serverได้รับ Action จาก Client ยังต้องตรวจ:

Player
Permission
Session
Position
Entity
State

ตาม Use Case

Cfx.re แนะนำให้ Networked Events ตรวจข้อมูลสำคัญด้วย Server-side Methods แทนการเชื่อ Client Input.

㉕ Ped Density คืออะไร

FiveM Native:

SetPedDensityMultiplierThisFrame(
    multiplier
)

ใช้ปรับ Density ของ Ped บนถนน โดย Official Native Reference ระบุช่วงแนวคิดจาก 0.0 ซึ่งไม่มี Ped บนถนน ไปถึง 1.0 ซึ่งเป็นจำนวนปกติ.

㉖ ตัวอย่างลด Ped Density

CreateThread(function()
    while true do
        SetPedDensityMultiplierThisFrame(
            0.5
        )

        Wait(0)
    end
end)

Native มีชื่อว่า ThisFrame และต้องใช้ตาม Frame/Tick Pattern ที่เหมาะสมหากต้องการให้ค่ามีผลต่อเนื่อง.

㉗ ปิด Ped Density ด้วย 0.0 ได้ไหม

Native Reference ระบุว่า:

0.0

เป็นค่าต่ำสุดซึ่งหมายถึงไม่มี Pedestrians บนถนนสำหรับ Multiplier นี้.

ตัวอย่าง:

CreateThread(function()
    while true do
        SetPedDensityMultiplierThisFrame(
            0.0
        )

        Wait(0)
    end
end)

㉘ Vehicle Density คืออะไร

FiveM มี:

SetVehicleDensityMultiplierThisFrame(
    multiplier
)

Official Native Reference ระบุ:

0.0 = ไม่มี Vehicles บนถนน
1.0 = จำนวนปกติ

และควรเรียกภายใน Loop เพื่อให้ผลต่อเนื่อง.

㉙ ตัวอย่างลด Traffic Vehicle

CreateThread(function()
    while true do
        SetVehicleDensityMultiplierThisFrame(
            0.5
        )

        Wait(0)
    end
end)

ใช้เมื่อ Server ต้องการลด Traffic Density โดยไม่ปิด Population ทั้งหมด

㉚ Ped Density กับ Population Off ต่างกันอย่างไร

Density Multiplier

ปรับระดับความหนาแน่น

0.0 → ต่ำสุด
0.5 → ลดลง
1.0 → ปกติ

Routing Bucket Population

เปิดหรือปิด Automatically-created Population ของ Bucket

เป็นคนละระดับการควบคุม.

㉛ Scenario Ped Density คืออะไร

FiveM มี:

SetScenarioPedDensityMultiplierThisFrame(
    interiorMult,
    exteriorMult
)

Native Reference ระบุว่าใช้ปรับจำนวน Scenario Peds โดยมี Multiplier สำหรับ Interior และ Exterior.

㉜ Scenario Ped ต่างจาก Ped Density ทั่วไปอย่างไร

ตัวหนึ่งเน้น Ped Density ทั่วไปบนถนน ส่วน SetScenarioPedDensityMultiplierThisFrame ใช้กับ Scenario Peds ตามระบบ Scenario ของ GTA V.

ดังนั้น Resource ที่ต้องการ Fine-tune Population อาจต้องพิจารณาหลาย Multiplier ไม่ใช่เพียง Ped Density ตัวเดียว

㉝ Parked Vehicle Density มีไหม

มี

FiveM Native Reference มี:

SetParkedVehicleDensityMultiplierThisFrame(
    multiplier
)

สำหรับควบคุม Density ของ Parked Vehicles ฝั่ง Client.

จึงแยกได้ว่า:

รถวิ่งบนถนน
≠
รถจอด

ใน Population Control

㉞ ทำไมปิด Vehicle Density แล้วรถยังมีอยู่

เพราะ Population ของรถไม่ได้มีเพียง Density Category เดียว

ตัวอย่างเช่น Parked Vehicles มี Multiplier ของตัวเอง และ Scenario/Population Systems อื่นอาจยังเกี่ยวข้อง

จึงไม่ควรคิดว่า:

SetVehicleDensityMultiplierThisFrame(0.0)

จะเท่ากับ “ลบ Entity รถทุกคันในเกม” เพราะ Native นี้เป็น Density Control ไม่ใช่ Generic Entity Deletion API.

㉟ Density Multiplier ต้องเรียกทุก Frame ไหม

สำหรับ SetVehicleDensityMultiplierThisFrame Official Native Reference ระบุชัดว่าควรใช้ใน Looped Function และค่ามีลักษณะ This Frame.

ดังนั้น Pattern:

CreateThread(function()
    while true do
        SetVehicleDensityMultiplierThisFrame(
            0.5
        )

        Wait(0)
    end
end)

เป็นรูปแบบที่เหมาะกับ Native ประเภทนี้

㊱ อย่าใส่ Logic หนักใน Loop Density

ถ้ามี Thread:

while true do
    ...
    Wait(0)
end

ควรให้สิ่งที่ทำใน Loop เบาที่สุดเท่าที่เป็นไปได้

อย่าเพิ่ม:

Database Query
HTTP Request
Table Scan ใหญ่
Complex Calculation

ทุก Frame เพราะ Density Native เองต้องการ Update ต่อเนื่อง แต่ Business Logic หนักไม่จำเป็นต้องทำพร้อมกัน

㊲ แยก Configuration ออกจาก Frame Loop

รูปแบบที่ดีกว่า:

local pedDensity = 0.5
local vehicleDensity = 0.5

CreateThread(function()
    while true do
        SetPedDensityMultiplierThisFrame(
            pedDensity
        )

        SetVehicleDensityMultiplierThisFrame(
            vehicleDensity
        )

        Wait(0)
    end
end)

ทำให้ Config เปลี่ยนได้โดยไม่ต้องคำนวณใหม่ทุก Frame

㊳ Population Control ช่วย Performance หรือไม่

การลดจำนวน Entities ที่ถูกสร้างและ Simulate อาจลดงานบางส่วนของ Client/Network Environment แต่ไม่ควรสรุปว่า “ปิด NPC แล้ว Server จะหาย Lag” โดยอัตโนมัติ

Performance ของ FiveM ยังขึ้นกับ:

Resources
Script loops
Entity count
Network events
State updates
Streaming
Player count

จึงควรวัดจริงแทนการเดา

㊴ Population ปิดแล้ว FPS ดีขึ้นแน่นอนไหม

ไม่สามารถรับประกันได้

เครื่องของผู้เล่น, Resources, Graphics Settings และจำนวน Entity อื่นยังมีผล

ถ้ากำลังแก้ปัญหา Performance ควรใช้ Profiler/Resmon และวัดก่อนกับหลังการเปลี่ยน Population Settings แทนการสรุปจากความรู้สึก

㊵ Server RP ควรปิด Population ทั้งหมดไหม

ไม่มีคำตอบเดียว

Server ที่ต้องการโลกมีชีวิต

อาจคง Population บางส่วน

Server ที่สร้าง NPC/Vehicle เอง

อาจลดหรือปิด Game Population

Private Instance

มักเหมาะกับ Population Off

จึงต้องเลือกจาก Gameplay Design ไม่ใช่ตามสูตรตายตัว

㊶ Population Off กับ Server-created NPC ใช้ร่วมกันได้ไหม

ได้

การปิด Automatically-created Population ไม่ได้หมายความว่า Server ไม่สามารถสร้าง Managed Entities ของตัวเอง

OneSync รองรับ Server-created Peds, Vehicles และ Objects แยกจาก Population Policy.

Architecture:

Population Off
↓
ไม่มี Game-generated Population

Server
↓
สร้างเฉพาะ NPC/Vehicle ที่ต้องใช้

㊷ Population Off กับ strict Lockdown ใช้ร่วมกันได้ไหม

ได้

ตัวอย่างใน OneSync Documentation ใช้:

SetRoutingBucketEntityLockdownMode(
    1,
    'strict'
)

SetRoutingBucketPopulationEnabled(
    1,
    false
)

พร้อมย้าย Player เข้า Bucket ดังกล่าว.

㊸ Population Ped Cancel กับ Server-created Ped เกี่ยวกันไหม

populationPedCreating ถูก Trigger เมื่อ Ped กำลังถูกสร้างโดย Game Population System.

ดังนั้นอย่าคิดว่า Event นี้คือ Generic Event สำหรับ Ped ทุกประเภท

สำหรับ Script-created Entity มี Entity Lifecycle/Resource Logic ของตัวเอง

㊹ populationPedCreating กับ entityCreating ต่างกันอย่างไร

populationPedCreating

Client Event

Game Population Ped กำลังจะเกิด

entityCreating

Server-side Entity Lifecycle Event

Network Entity กำลังถูกสร้าง

จึงเป็นคนละ Event และทำงานคนละ Context

㊺ AddEventHandler ใช้กับ populationPedCreating ได้ไหม

ได้

Official Example ใช้:

AddEventHandler(
    'populationPedCreating',
    function(x, y, z, model, setters)
        -- logic
    end
)

โดยไม่ต้องใช้ RegisterNetEvent เพราะเป็น Core Client Event ภายใน Context ฝั่ง Client.

㊻ ไม่ควร RegisterNetEvent ให้ populationPedCreating ใช่ไหม

ไม่จำเป็น

Cfx.re แนะนำ AddEventHandler สำหรับ Event ที่ทำงานภายใน Context เดียวกัน และใช้ RegisterNetEvent เมื่อ Event ต้องเดินทางข้าม Client/Server Context.

ดังนั้น:

AddEventHandler(
    'populationPedCreating',
    function(...)
    end
)

เพียงพอ

㊼ Population Configuration ควรอยู่ Client หรือ Server

ขึ้นกับเครื่องมือ

Server

SetRoutingBucketPopulationEnabled
Routing Bucket Policy

Client

populationPedCreating
Ped Density
Vehicle Density
Scenario Ped Density
Parked Vehicle Density

ดังนั้น Population Resource หนึ่งตัวสามารถมีทั้ง:

server.lua
client.lua

ตามหน้าที่

㊽ ตัวอย่าง fxmanifest.lua

fx_version 'cerulean'
game 'gta5'

client_script 'client.lua'
server_script 'server.lua'

จากนั้นแยก Population Control ระดับ Client และ Bucket Control ระดับ Server ให้ชัดเจน

㊾ ตัวอย่าง server.lua สำหรับ Instance

local INSTANCE_BUCKET = 100

SetRoutingBucketEntityLockdownMode(
    INSTANCE_BUCKET,
    'strict'
)

SetRoutingBucketPopulationEnabled(
    INSTANCE_BUCKET,
    false
)

RegisterCommand(
    'enterinstance',
    function(source)

        if source == 0 then
            return
        end

        SetPlayerRoutingBucket(
            source,
            INSTANCE_BUCKET
        )

    end,
    false
)

Routing Bucket, Lockdown และ Population Policy เป็นความสามารถใน OneSync.

สำหรับ Production ควรจำกัด Command ด้วย Permission/Gameplay Logic ที่เหมาะสม

㊿ ตัวอย่าง client.lua ลด Population

local pedDensity = 0.5
local vehicleDensity = 0.5
local parkedVehicleDensity = 0.5
local scenarioPedDensity = 0.5

CreateThread(function()
    while true do

        SetPedDensityMultiplierThisFrame(
            pedDensity
        )

        SetVehicleDensityMultiplierThisFrame(
            vehicleDensity
        )

        SetParkedVehicleDensityMultiplierThisFrame(
            parkedVehicleDensity
        )

        SetScenarioPedDensityMultiplierThisFrame(
            scenarioPedDensity,
            scenarioPedDensity
        )

        Wait(0)
    end
end)

FiveM มี Native แยกสำหรับ Ped, Vehicle, Parked Vehicle และ Scenario Ped Density.

51. ตัวอย่าง Cancel Population Ped ในพื้นที่

local center =
    vector3(
        100.0,
        200.0,
        30.0
    )

local radius = 50.0

AddEventHandler(
    'populationPedCreating',
    function(x, y, z, model, setters)

        local position =
            vector3(x, y, z)

        if #(position - center) <= radius then
            CancelEvent()
        end

    end
)

เนื่องจาก Event ให้ Position ของ Ped ที่กำลังจะ Spawn และรองรับ CancelEvent() จึงสามารถสร้าง Area-based Population Logic ได้.

52. ตัวอย่างเปลี่ยน Population Ped เฉพาะบางพื้นที่

local center =
    vector3(
        100.0,
        200.0,
        30.0
    )

AddEventHandler(
    'populationPedCreating',
    function(x, y, z, model, setters)

        local pos =
            vector3(x, y, z)

        if #(pos - center) <= 30.0 then

            setters.setModel(
                'a_m_y_business_01'
            )

        end

    end
)

setModel เป็น Setter ที่ Cfx.re รองรับใน populationPedCreating.

53. Population Ped ยังเกิดทั้งที่ Density เป็น 0 เพราะอะไร

ตรวจหลายจุด:

Ped Density
Scenario Ped Density
Population Ped Event
Script-created Peds
Server-created Peds
Routing Bucket Population

Ped ที่ Resource สร้างเองไม่ได้กลายเป็น Game Population Ped เพียงเพราะอยู่ในโลกเดียวกัน

จึงต้องแยกว่า Entity มาจากระบบไหนก่อนแก้

54. NPC ยังมีหลัง SetRoutingBucketPopulationEnabled false

ตรวจว่า NPC นั้นเป็น:

Game-generated Population
หรือ
Script-created Ped

SetRoutingBucketPopulationEnabled(false) มีหน้าที่ปิด Automatically-created Population ภายใน Bucket ไม่ใช่ Generic DeleteEntity() สำหรับ Entity ที่ Resource สร้างไว้แล้ว.

55. Vehicle ยังมีหลัง Population Off

อาจเป็น Vehicle ที่:

  • Resource สร้างเอง

  • Server-created

  • มีอยู่ก่อนเปลี่ยน Policy

  • ถูกระบบอื่นจัดการ

ดังนั้นควรตรวจ Entity Origin แทนการสรุปว่า Population Native ไม่ทำงาน

56. ตรวจ Population Type ตอน Debug

ตัวอย่าง:

local popType =
    GetEntityPopulationType(entity)

print(
    ('entity=%s populationType=%s')
    :format(
        entity,
        popType
    )
)

GetEntityPopulationType() คืน Population Type ID ของ Entity.

ใช้ร่วมกับ:

Entity Type
Model
Owner
Routing Bucket
Resource Registry

เพื่อหา Origin ได้แม่นขึ้น

57. Population Resource ควรมี Debug Mode

ตัวอย่าง:

local DEBUG_POPULATION = false

แล้วค่อย Log เมื่อ:

if DEBUG_POPULATION then
    print(
        ('Population ped model=%s')
        :format(model)
    )
end

อย่า Print ทุก Population Creation ใน Production เพราะ Console/Client Log จะมีข้อมูลจำนวนมากโดยไม่จำเป็น

58. อย่าใช้ Wait(0) หลาย Thread หากรวมกันได้

ถ้ามี:

Thread Ped Density
Thread Vehicle Density
Thread Parked Density
Thread Scenario Density

สามารถรวม Density Natives ไว้ Thread เดียวเพื่อลดความซ้ำซ้อนของ Resource Structure

ตัวอย่างในข้อก่อนเป็นรูปแบบหนึ่งที่ทำได้

59. แยก Server Population กับ Client Density ให้ชัด

Architecture ที่อ่านง่าย:

server.lua
├── Routing Bucket
├── Population Enabled
└── Instance Policy

client.lua
├── Population Ped Creating
├── Ped Density
├── Vehicle Density
└── Scenario Density

จะ Debug ง่ายกว่าการปนทุกอย่างไว้ใน Script เดียว

60. Population Control กับ Network Events

ไม่ควรเปิด Event ให้ Client ส่งค่าเช่น:

population = false
bucket = 999

แล้ว Server ใช้ทันที

หาก Client ขอเข้า Instance:

Client Request
↓
Server ตรวจ Session
↓
Server เลือก Bucket
↓
Server ตั้ง Population Policy ที่ Server กำหนด

Cfx.re แนะนำให้ข้อมูลสำคัญของ Network Events ถูกตรวจจาก Server-side Methods.

61. Population Off ควรตั้งครั้งเดียวหรือทุก Frame

SetRoutingBucketPopulationEnabled() เป็น Routing Bucket Policy ฝั่ง Server ไม่ใช่ Native แบบ ThisFrame ในชื่อ API

ส่วน Client Density Natives เช่น SetVehicleDensityMultiplierThisFrame() ถูกออกแบบให้เรียกแบบต่อเนื่องใน Loop.

นี่เป็นความแตกต่างสำคัญ

62. Population กับ Routing Bucket Memory

Cfx.re ระบุว่า Routing Bucket เป็น Dimension System ของ FiveM และแต่ละ Bucket มี Behavior/World Grid ของตัวเองสำหรับ Population Owners.

ดังนั้นอย่าสร้าง Bucket จำนวนมากเพียงเพื่อแก้ Population ถ้าไม่ต้องการ Instance จริง

63. Population กับ OneSync Scope

OneSync จัดการ Entity Synchronization ตาม Scope และ Routing State ขณะที่ Population World Grid ใช้กำหนด Population Ownership ภายใน Bucket.

Resource จึงควรแยก:

Population Creation
↓
Entity Exists

OneSync Scope
↓
Client ไหนเห็น Entity

เป็นคนละขั้นตอนของ Networking

64. Population Owner กับ Gameplay Owner ต่างกันไหม

ควรคิดว่า Population Ownership เป็นส่วนหนึ่งของระบบที่กำหนดการสร้าง/ดูแล Population ของ World Grid ส่วน Network Entity Ownership เป็นเรื่อง Client ใดกำลังควบคุม Networked Entity

ไม่ควรนำคำว่า Owner ไปใช้แทนกันโดยไม่ดู Context

65. Checklist FiveM Population

ก่อนใช้ Production ตรวจว่า:

  1. รู้ว่า Population คืออะไร

  2. แยก Population กับ Script-created Entity

  3. แยก Population กับ Server-created Entity

  4. ตรวจ Routing Bucket

  5. ใช้ SetRoutingBucketPopulationEnabled ตาม Instance

  6. ไม่สร้าง Bucket เพียงเพื่อปิด NPC โดยไม่มีเหตุผล

  7. เข้าใจ populationPedCreating

  8. ใช้ AddEventHandler

  9. ไม่ Register Event เป็น Network Event โดยไม่จำเป็น

  10. ใช้ CancelEvent() เฉพาะเมื่อจำเป็น

  11. ตรวจ Position ก่อน Area-based Cancel

  12. ใช้ setModel อย่างถูกต้อง

  13. ใช้ setPosition อย่างถูกต้อง

  14. เข้าใจ Ped Density

  15. เข้าใจ Vehicle Density

  16. เข้าใจ Scenario Ped Density

  17. เข้าใจ Parked Vehicle Density

  18. Density ThisFrame อยู่ใน Loop ที่เหมาะสม

  19. ไม่ใส่ Heavy Logic ทุก Frame

  20. Config แยกจาก Loop

  21. ตรวจ GetEntityPopulationType เมื่อ Debug

  22. ไม่ใช้ Population Type เป็น Security Permission

  23. Server Validate Network Events

  24. ไม่เชื่อ Bucket ID จาก Client

  25. แยก Population Off กับ Entity Lockdown

  26. แยก Population Off กับ DeleteEntity

  27. ตรวจ Script-created NPC

  28. ตรวจ Server-created NPC

  29. มี Debug Mode

  30. วัด Performance ก่อนและหลังการปรับ

ตาราง FiveM Population Tools ที่ควรรู้

ระบบใช้ทำอะไร
SetRoutingBucketPopulationEnabledเปิด/ปิด Population ระดับ Bucket
populationPedCreatingดัก Population Ped ก่อนสร้าง
CancelEventยกเลิก Population Ped Creation
setters.setModelเปลี่ยน Ped Model
setters.setPositionเปลี่ยน Spawn Position
GetEntityPopulationTypeดู Population Type ID
SetPedDensityMultiplierThisFrameปรับ Ped Density
SetVehicleDensityMultiplierThisFrameปรับ Traffic Vehicle Density
SetParkedVehicleDensityMultiplierThisFrameปรับ Parked Vehicle Density
SetScenarioPedDensityMultiplierThisFrameปรับ Scenario Ped Density

ความสามารถเหล่านี้มีอยู่ใน Cfx.re Client Events, OneSync และ Native References ปัจจุบัน.

FiveM ปิด NPC ทั้งหมดทำอย่างไร

ถ้าเป้าหมายคือ Private Routing Bucket ที่ไม่ต้องการ Automatically-created Population ให้เริ่มจาก:

SetRoutingBucketPopulationEnabled(
    bucket,
    false
)

ซึ่งเป็น Population Policy โดยตรงของ Routing Bucket.

ถ้าต้องการปรับ Density ของโลกหลักแทนการปิดทั้งหมด ให้พิจารณา Density Multipliers ฝั่ง Client

FiveM ลด NPC ครึ่งหนึ่งทำอย่างไร

ตัวอย่าง:

CreateThread(function()
    while true do

        SetPedDensityMultiplierThisFrame(
            0.5
        )

        Wait(0)

    end
end)

Official Native Reference ระบุ Multiplier ตั้งแต่ 0.0 ถึง 1.0 สำหรับ Ped Density โดย 1.0 คือจำนวนปกติ.

FiveM ลดรถบนถนนทำอย่างไร

ตัวอย่าง:

CreateThread(function()
    while true do

        SetVehicleDensityMultiplierThisFrame(
            0.5
        )

        Wait(0)

    end
end)

Native Reference ระบุ 0.0 เป็นไม่มี Vehicles บนถนนและ 1.0 เป็นจำนวนปกติ.

FiveM ปิด NPC เฉพาะพื้นที่ทำอย่างไร

หนึ่งในวิธีคือใช้ populationPedCreating ตรวจตำแหน่งก่อน Ped ถูกสร้าง แล้ว CancelEvent() เฉพาะพื้นที่ที่กำหนด

เพราะ Event ส่ง Coordinates ของ Ped ที่กำลังจะ Spawnมาให้ Script และรองรับการ Cancel.

FiveM Population Ped เปลี่ยน Model ได้ไหม

ได้ผ่าน:

setters.setModel(...)

ใน Event populationPedCreating.

FiveM NPC ยังเกิดแม้ปิด Ped Density

ตรวจ Scenario Ped Density, Script-created Peds และ Server-created Peds เพิ่ม เพราะ SetPedDensityMultiplierThisFrame เป็นเพียงเครื่องมือสำหรับ Ped Density ประเภทที่ Native ควบคุม ไม่ใช่ Generic Removal สำหรับ Ped ทุกตัวใน Server.

FiveM รถยังเกิดแม้ Vehicle Density เป็น 0

ตรวจ Parked Vehicle Density และ Resource ที่สร้าง Vehicle เองด้วย เพราะ FiveM มี Density Controls แยกสำหรับ Vehicles และ Parked Vehicles.

FiveM Population กับ Entity Events ต่างกันอย่างไร

Population System:

เกมสร้าง Entity อัตโนมัติ

Entity Events:

ติดตาม Lifecycle ของ Network Entity

จึงสามารถใช้ร่วมกันเพื่อ Debug ได้ แต่ไม่ใช่ระบบเดียวกัน

FiveM Population กับ Server-created Entities ต่างกันอย่างไร

Population:

Game-generated

Server-created:

Resource/Server-generated

ถ้า Server ต้องการควบคุม Entity สำคัญ Cfx.re แนะนำ Server-created Entities ภายใต้ OneSync แทนการพึ่ง Client Creation.

FiveM Population กับ Entity Lockdown ต่างกันอย่างไร

จำสูตร:

Population
= Game สร้างอะไรอัตโนมัติ

Entity Lockdown
= Client สร้างอะไรได้

Server-created Entity
= Server สร้างอะไรเอง

เมื่อใช้ร่วมกันจะได้ Architecture ที่ควบคุม Entity ได้ชัดเจนขึ้น.

FAQ FiveM Population

FiveM Population คืออะไร

คือระบบ Game Population ที่สร้าง Ped และ Entity Environment บางประเภทโดยอัตโนมัติ และ OneSync มี Population Policy แยกตาม Routing Bucket.

ปิด Population ใน Routing Bucket อย่างไร

ใช้:

SetRoutingBucketPopulationEnabled(
    bucketId,
    false
)

populationPedCreating คืออะไร

เป็น Client Core Event ที่ถูก Trigger ก่อน Game Population System สร้าง Ped และสามารถเปลี่ยน Model, Position หรือ Cancel Creation ได้.

populationPedCreating ใช้ฝั่ง Server หรือ Client

Client โดย Cfx.re จัด Event นี้อยู่ใน Client Core Events.

ปิด Population Ped ตัวหนึ่งได้ไหม

ได้ด้วย CancelEvent() ภายใน populationPedCreating.

เปลี่ยน Population Ped Model ได้ไหม

ได้ด้วย:

setters.setModel(...)

เปลี่ยนตำแหน่ง Population Ped ได้ไหม

ได้ด้วย:

setters.setPosition(...)

ลด Ped Density อย่างไร

ใช้ SetPedDensityMultiplierThisFrame() โดย Official Native Reference ระบุ 0.0 เป็นไม่มี Pedestrians บนถนนและ 1.0 เป็นจำนวนปกติ.

ลด Traffic Vehicle อย่างไร

ใช้ SetVehicleDensityMultiplierThisFrame() และเรียกใน Looped Function เพื่อให้ค่ามีผลต่อเนื่อง.

ปิด Population แล้ว Server-created NPC ยังเกิดได้ไหม

ได้ เพราะ Population Policy กับ Server-created Entity เป็นคนละระบบ และ OneSync รองรับ Server-created Peds, Vehicles และ Objects.

GetEntityPopulationType คืออะไร

เป็น Native สำหรับคืน Population Type ID ของ Entity ที่กำหนด.

ประเด็นสำคัญ

FiveM Population ควรแยกออกเป็นอย่างน้อย 3 ระดับ:

Routing Bucket Population
= เปิด/ปิด Game Population

Client Density
= ปรับจำนวน Ped/Vehicle

populationPedCreating
= ควบคุม Population Ped ก่อน Spawn

Cfx.re รองรับการปิด Population แยก Routing Bucket และระบุว่าแต่ละ Bucket มี World Grid ของตัวเองสำหรับ Population Owners.

ถ้าต้องการ Fine-tune โลกหลักสามารถใช้ Ped, Vehicle, Parked Vehicle และ Scenario Ped Density Multipliers ฝั่ง Client ส่วน Instance ที่ไม่ต้องการ Population เลยสามารถใช้ SetRoutingBucketPopulationEnabled(bucket, false) จาก Server.

ส่วน populationPedCreating เหมาะเมื่อ Resource ต้องการตรวจ Population Ped เป็นรายตัวก่อน Spawn เพราะสามารถอ่าน Model/Position, เปลี่ยน Model, เปลี่ยนตำแหน่ง หรือ Cancel Creation ได้.

สำหรับผู้อ่าน comsiam ให้จำสูตร “Bucket = เปิดหรือปิด, Density = มากหรือน้อย, populationPedCreating = จัดการก่อนเกิด” และ comsiam แนะนำให้เลือกเครื่องมือ Population ให้ตรงหน้าที่แทนการสร้าง Loop ลบ Entity ทั้งโลก เพราะจะทำให้ Resource อ่านง่าย Debug ง่าย และทำงานร่วมกับ OneSync/Routing Buckets เป็นระบบมากกว่า

Comments

Popular posts from this blog

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

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

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