FiveM Job Script คืออะไร ระบบอาชีพทำงานอย่างไร

FiveM Job Script คือระบบที่กำหนดว่า ตัวละครของผู้เล่นทำอาชีพอะไร มีตำแหน่งระดับไหน อยู่ระหว่างปฏิบัติงานหรือไม่ ได้รับเงินเดือนเท่าไร และสามารถเข้าถึงระบบใดของ Server ได้บ้าง

ตัวอย่างอาชีพยอดนิยม เช่น

Police
EMS
Mechanic
Taxi
Real Estate
Car Dealer
Restaurant
Trucker
Garbage
Tow

ระบบ Job ใน Server RP ไม่ได้จบแค่การตั้งค่า

job = police

แต่สามารถเชื่อมต่อกับ

Grade
Duty
Salary
Boss Menu
Inventory
Stash
Garage
Vehicle
Radio
Target
Billing
Banking
Crafting
Permissions

ได้ทั้งหมด

ดังนั้น Job System ถือเป็นหนึ่งในแกนหลักของ FiveM Roleplay Server

① Job Script คืออะไรแบบง่ายที่สุด

สมมติผู้เล่นสมัครเป็นตำรวจ

Framework อาจเก็บข้อมูลประมาณ

Job: police
Grade: 1
Duty: true

จากนั้น Scripts อื่นใช้ข้อมูลนี้ตรวจว่า Player ทำอะไรได้

เช่น

Police Job
↓
เปิด Locker
↓
เบิกรถตำรวจ
↓
ใช้ Radio ตำรวจ
↓
เข้าห้อง Evidence
↓
ใส่กุญแจมือ
↓
รับเงินเดือน

ดังนั้น Framework เก็บ สถานะอาชีพ

ขณะที่ Job Script สร้าง Gameplay ของอาชีพ

② Framework Job กับ Job Script ต่างกันอย่างไร

ต้องแยกสองอย่างนี้ออกจากกัน

Framework Job

เก็บข้อมูล เช่น

job name
grade
duty
salary
boss

Job Script

สร้าง Gameplay เช่น

จับผู้ต้องหา
ซ่อมรถ
รักษาผู้ป่วย
ส่งสินค้า
ขายรถ
ขับแท็กซี่

ดังนั้น

Framework Job Data
+
Job Script
=
ระบบอาชีพที่เล่นได้จริง

③ Job Name คืออะไร

เป็นชื่อภายในระบบ

เช่น

police
ambulance
mechanic
taxi

ควรใช้ชื่อสั้น ตัวพิมพ์เล็ก และคงที่

ตัวอย่าง Qbox ปัจจุบันมีคำเตือนว่า Job Names ระดับบนสุดควรเป็นตัวพิมพ์เล็ก

เช่น

['police'] = {
    ...
}

ดีกว่า

['Police'] = {
    ...
}

④ Job Label คืออะไร

Label คือชื่อที่แสดงให้ผู้เล่นเห็น

ตัวอย่าง

Name:
police

Label:
LSPD

Script ใช้

police

สำหรับ Logic

แต่ UI สามารถแสดง

Los Santos Police Department

ได้

จึงไม่ควรใช้ Label เป็น Identifier ของระบบ

⑤ Grade คืออะไร

Grade คือระดับของ Player ภายใน Job

เช่น

Police

Grade 0 → Recruit
Grade 1 → Officer
Grade 2 → Sergeant
Grade 3 → Lieutenant
Grade 4 → Chief

Grade สามารถกำหนด

ตำแหน่ง
เงินเดือน
สิทธิ์
Boss Permission
Bank Permission

ต่างกันได้

⑥ Grade Number สำคัญอย่างไร

Script จำนวนมากตรวจ

job = police
grade >= 2

เพื่อให้เฉพาะ Sergeant ขึ้นไปทำบาง Action

เช่น

เข้าห้องอาวุธพิเศษ
ดู Evidence
อนุมัติรถ
จัดการพนักงาน

จึงไม่ควรเปลี่ยน Grade Numbers ของ Production Server โดยไม่ตรวจ Scripts ที่อ้างค่าเดิม

⑦ Boss Grade คืออะไร

ตำแหน่งระดับสูงสามารถกำหนด

isboss = true

ได้

ตัวอย่าง QBCore/Qbox ปัจจุบันใช้แนวคิดนี้

[4] = {
    name = 'Chief',
    isboss = true,
    payment = 150
}

Framework/Management Script จึงรู้ว่าตำแหน่งนี้เข้าถึง Boss Functions ได้

⑧ Boss ทำอะไรได้บ้าง

ขึ้นกับ Management Resource

ตัวอย่าง

Hire
Fire
Promote
Demote
View Employees
Company Account
Boss Stash

แต่ต้องตรวจสิทธิ์บน Server เสมอ

ไม่ควรให้ Client ส่งว่า

ฉันคือ Boss

แล้ว Server เชื่อทันที

⑨ Salary หรือ Payment คืออะไร

แต่ละ Grade สามารถมีเงินเดือนต่างกัน

ตัวอย่าง

Recruit → $50
Officer → $75
Sergeant → $100
Chief → $150

Current QBCore และ Qbox Job Definitions มี payment อยู่ใน Grade Data

จำนวนเงินจริงควรปรับตาม Economy ของ Server ไม่ควร Copy Default มาใช้โดยไม่ Balance

⑩ เงินเดือนสูงเกินไปส่งผลอะไร

ถ้า

Police Salary = $10,000
ทุก 10 นาที

แต่สินค้าทั่วเมืองราคาเพียงหลักร้อย

จะเกิด Inflation อย่างรวดเร็ว

Job Salary ต้องสัมพันธ์กับ

Food
Vehicle
Housing
Business
Fuel
Repair
Items
Fines

ทั้งหมด

ระบบอาชีพจึงเกี่ยวข้องกับ Economy Design โดยตรง

⑪ Duty คืออะไร

Duty คือสถานะ

On Duty
หรือ
Off Duty

Player อาจยังเป็นตำรวจ แต่ตอนนั้นไม่ได้ปฏิบัติงาน

ตัวอย่าง

Job = police
Duty = false

หมายถึง

ยังเป็นตำรวจ
แต่ไม่ได้เข้าเวร

⑫ On Duty ใช้ทำอะไร

เมื่อ

onduty = true

Scripts สามารถเปิดสิทธิ์ เช่น

Police Radio
Police Garage
Dispatch
Evidence
Armory
Cuff
Billing
Job Salary

ส่วน Off Duty อาจปิด Feature เหล่านี้

ช่วยแยกชีวิตส่วนตัวกับงานใน RP

⑬ QBCore มี Duty State หรือไม่

มี

Current QBCore Player Job Data มี

onduty

และ Player Function

Player.Functions.SetJobDuty(true)

หรือ

Player.Functions.SetJobDuty(false)

เพื่อเปลี่ยน Duty State

⑭ Qbox มี Duty State หรือไม่

มีเช่นกัน

Current Qbox มี Export

exports.qbx_core:SetJobDuty(source, true)

และ Player Job Data มี

onduty

Qbox ยัง Trigger Events สำหรับ Duty Update เพื่อให้ Resources อื่น Sync ตามได้

⑮ defaultDuty คืออะไร

Job Definition สามารถกำหนด

defaultDuty = true

หรือ

defaultDuty = false

เพื่อกำหนดสถานะพื้นฐานของ Job

ตัวอย่างตำรวจอาจให้เข้า Server แล้ว On Duty ตาม Configuration

หรือบาง Server ต้องให้ Player ไป Clock In ก่อน

⑯ offDutyPay คืออะไร

Current QBCore/Qbox Job Definitions มี

offDutyPay

ใช้กำหนดว่าผู้เล่นยังได้รับ Paycheck ตอน Off Duty หรือไม่

ตัวอย่าง

offDutyPay = false

หมายความว่าโดย Design จะไม่จ่ายเงินเดือนตอน Off Duty

เหมาะกับ Economy ที่ต้องการให้ Player ทำงานจริง

⑰ Job Type คืออะไร

Framework รุ่นใหม่สามารถมี

type

เพื่อจัด Job หลายตัวเป็นประเภทเดียวกัน

ตัวอย่าง

police
sheriff
statepolice

อาจมี

type = leo

ทำให้ Script ไม่ต้องตรวจชื่อ Job ทีละตัวเสมอไป

⑱ ทำไม Job Type มีประโยชน์

สมมติ Server มีตำรวจ 3 หน่วย

ถ้าเขียนแบบเก่า

if job == 'police'
or job == 'sheriff'
or job == 'statepolice' then

ทุก Script จะต้องรู้ชื่อทุก Job

แต่ถ้า Architecture รองรับ Type

type = leo

สามารถออกแบบ Feature บางอย่างให้ใช้ร่วมกันตาม Role Category ได้ง่ายขึ้น

⑲ Qbox Job Definition ปัจจุบันมีอะไรบ้าง

Current Type Definition มีข้อมูลสำคัญประมาณ

label
type
defaultDuty
offDutyPay
grades

และแต่ละ Grade มี

name
isboss
bankAuth
payment

จึงสามารถกำหนด Organization Structure ได้ใน Job Definition โดยตรง

⑳ bankAuth คืออะไร

Current Qbox Job Grade รองรับ

bankAuth

เพื่อระบุสิทธิ์ด้าน Organization/Banking ตาม Integration

ตัวอย่าง

[4] = {
    name = 'Chief',
    isboss = true,
    bankAuth = true,
    payment = 150
}

Boss Grade จึงอาจมีสิทธิ์เข้าถึงบัญชีองค์กรได้

㉑ QBCore Job Data เป็นอย่างไร

Current QBCore PlayerData Job มีข้อมูล เช่น

name
label
payment
onduty
isboss
grade

โดย Grade มี

name
level
payment
isboss

ทำให้ Resources ลูกตรวจ Job State ของ Player ได้โดยไม่ต้อง Query Database ทุกครั้ง

㉒ วิธีตั้ง Job ใน QBCore

Current API ใช้

local Player = QBCore.Functions.GetPlayer(source)

if not Player then
    return
end

Player.Functions.SetJob('police', 1)

Job ต้องมีอยู่ใน

QBCore.Shared.Jobs

ก่อน

ถ้าไม่มี Function จะไม่สามารถตั้ง Job ที่ถูกต้องได้

㉓ วิธีตั้ง Duty ใน QBCore

local Player = QBCore.Functions.GetPlayer(source)

if not Player then
    return
end

Player.Functions.SetJobDuty(true)

เมื่อเปลี่ยน Duty Framework จะ Update Player Data ไปยัง Client ตามระบบปัจจุบัน

㉔ Qbox ใช้ SetJob อย่างไร

Current Qbox แนะนำ Server Export

exports.qbx_core:SetJob(source, 'police', 1)

หรือสามารถใช้ citizenid ตาม API

Current Qbox กำลังผลัก Developer ไปใช้ Public Exports แทน Deprecated QBCore-style Player Functions สำหรับ Native Qbox Development

㉕ Qbox รองรับหลาย Job หรือไม่

Current Qbox รองรับโครงสร้างหลาย Jobs ต่อ Player

PlayerData มี

jobs

เป็น Table ของ Jobs ที่ Player ถืออยู่

และมี

job

เป็น Primary Job ที่กำลัง Active

นี่แตกต่างจาก QBCore Traditional Architecture ที่เน้น Current Job หลักหนึ่งตัว

㉖ Qbox จำกัดจำนวน Job ได้หรือไม่

ได้

Current Source ใช้ Convar

qbx:max_jobs_per_player

โดย Default ใน Source ปัจจุบันคือ

1

Server สามารถปรับเพื่อรองรับ Multi-job Architecture

แต่ยิ่ง Player มีหลาย Job ยิ่งต้องออกแบบ Duty, Permissions และ UI ให้ชัดเจน

㉗ Qbox มี Primary Job คืออะไร

สมมติ Player มี

police
mechanic

ใน Job Memberships

แต่ Active Job อาจเป็น

police

Current Qbox มี

exports.qbx_core:SetPlayerPrimaryJob(...)

สำหรับเลือก Job หลักจาก Jobs ที่ Player มีอยู่แล้ว

㉘ AddPlayerToJob คืออะไร

Current Qbox มี

exports.qbx_core:AddPlayerToJob(
    citizenid,
    'mechanic',
    1
)

สำหรับเพิ่ม Job ให้ Player หรือ Update Grade หากมี Job นั้นอยู่แล้ว

ต่างจาก SetJob ซึ่งตาม Current Behavior สามารถ Replace Primary Job ตาม Configuration ได้

㉙ Qbox เก็บ Multi-job ที่ไหน

Current Source ใช้ Persistence Table

player_groups

สำหรับ Job/Gang Membership

โดยข้อมูลมีแนวคิด

citizenid
type
group
grade

จึงรองรับ Group Membership มากกว่าการเก็บ Job เพียง Field เดียว

㉚ QBCore รองรับ Job แบบไหน

Current QBCore Traditional Player Data ใช้

PlayerData.job

เป็น Current Job หลัก

ตัวอย่าง

name = police
grade = Officer
onduty = true

หาก Server ต้องการ Multi-job อาจใช้ Resource เสริมหรือเปลี่ยน Architecture ตาม Framework ที่เลือก

㉛ ESX Job ทำงานอย่างไร

ESX ใช้ Job Data ที่ผูกกับ xPlayer

สามารถอ่าน

local job = xPlayer.getJob()

และเปลี่ยนด้วย

xPlayer.setJob(jobName, grade)

Current ESX Admin Command /setjob ยังตรวจด้วยว่า Job/Grade มีอยู่ก่อนแล้วจึงเรียก setJob

㉜ ESX เก็บ Job ใน Database หรือไม่

ESX ใช้ Persistent Database สำหรับข้อมูล Player และ Jobs

Job Ecosystem แบบดั้งเดิมของ ESX มี Tables อย่าง

jobs
job_grades

และ Player มีค่า

job
job_grade

ตาม Schema/Version ที่ใช้

จึงต่างจาก Qbox ที่ Current Multi-job Architecture ใช้ player_groups

㉝ ESX Grade มี Salary หรือไม่

มี

Current esx_society ยังมีระบบจัดการ Salary ของ Job Grade และสามารถ Update

job_grades.salary

จาก Boss Functions ภายใต้ Permission Rules

จากนั้น Refresh Jobs ให้ Player Data สอดคล้องกับข้อมูลใหม่

㉞ ESX Boss Menu ทำอย่างไร

esx_society เป็น Resource สำคัญใน ESX Ecosystem สำหรับองค์กร

รองรับแนวคิด เช่น

Employees
Hire
Fire
Promote
Salary
Society

Current Source ตรวจ Boss Grade ก่อนทำ Management Actions บน Server

นี่เป็นตัวอย่างที่ดีของ Server-side Authorization

㉟ Job Script ควรเชื่อ Framework อย่างไร

Architecture ที่ดีคือ

Job Script
↓
Public Framework API
↓
Job Data

ไม่ใช่

Job Script
↓
แก้ Framework Core

ตัวอย่าง Qbox ควรใช้

qbx_core exports

QBCore ใช้

Player Functions / Framework APIs

ESX ใช้

xPlayer APIs

㊱ อย่า Query Database เพื่อเช็ก Job ทุกครั้ง

ถ้า Player Online และ Framework มี Job State อยู่ใน Memory แล้ว

ไม่ควรทำ

SELECT job
FROM players
WHERE citizenid = ?

ทุกครั้งที่ Player เปิด Locker

ควรใช้ Runtime Framework Data

เช่น

PlayerData.job

หรือ Group API

ช่วยลด SQL Queries และลด Runtime/Database State Mismatch

㊲ อย่าเปลี่ยน Job ด้วย Direct SQL ขณะ Player Online

ไม่ควรทำ

UPDATE players
SET job = 'police'
WHERE citizenid = ?

เพื่อเปลี่ยนงานของ Player Online

เพราะอาจเกิด

Database = police
Runtime = mechanic

จนกว่า Player จะ Reconnect

ควรใช้ Public Framework API แล้วให้ Framework จัด Persistence

㊳ Job Script ควรมี Duty System หรือไม่

สำหรับ Whitelist Jobs เช่น

Police
EMS
Mechanic
Government

ควรมี

Clock In
Clock Out

ชัดเจน

เพื่อให้ Scripts อื่นสามารถถามว่า

เป็นตำรวจ?
และ
On Duty?

ได้

㊴ Job กับ Duty ต้องตรวจแยกกัน

ตัวอย่าง Player

job = police
onduty = false

ไม่ควรใช้ Police Actions ที่สงวนสำหรับการทำงาน

ดังนั้น Logic ควรเป็นประมาณ

Job ถูก
+
Duty ถูก

ตาม Gameplay Design

ไม่ใช่ตรวจเพียง Job Name

㊵ Qbox HasGroup ไม่ตรวจ Duty

จุดนี้สำคัญ

Current Qbox Documentation ระบุว่า

HasGroup

และ

HasPrimaryGroup

ตรวจ Group/Grade แต่ ไม่ได้ตรวจว่า Player On Duty หรือ Off Duty

ดังนั้นถ้า Feature ต้องการตำรวจ On Duty ต้องตรวจ Duty เพิ่มเอง

㊶ ตัวอย่าง Permission ที่ผิด

if exports.qbx_core:HasGroup(source, 'police') then
    GivePoliceWeapon(source)
end

ถ้า Design ต้องการเฉพาะ On Duty การตรวจแค่นี้ยังไม่พอ

เพราะ HasGroup ไม่เช็ก Duty

ต้องตรวจ

Group
+
Duty

ตาม Player Data/API ที่ใช้อยู่

㊷ Job Grade Permission ควรทำอย่างไร

เช่นเฉพาะ Sergeant ขึ้นไปเข้าห้อง Evidence

แนวคิด

Job = police
Grade >= 2
Duty = true

แต่ Server-side Validation ต้องเป็นผู้ตัดสิน

Target/UI ฝั่ง Client ใช้ซ่อน Option ได้ แต่ไม่ใช่ Security Boundary

㊸ ox_target เชื่อม Job ได้อย่างไร

Target Option รองรับ

groups

เช่น

groups = {
    police = 2
}

ช่วยให้เฉพาะ Group/Grade ที่เหมาะเห็น Option

ตัวอย่าง

Evidence
Armory
Boss Office
Mechanic Bench

แต่ Action ฝั่ง Server ควรตรวจ Permission ซ้ำ

㊹ ox_inventory เชื่อม Job ได้อย่างไร

Stash, Shop และ Inventory Systems สามารถจำกัด

Groups
Grades

ได้

ตัวอย่าง

Police Armory
→ police grade 1+

หรือ

EMS Storage
→ ambulance

ทำให้ Job + Inventory Integration แข็งแรงขึ้น

㊺ Radio เชื่อม Job อย่างไร

ตำรวจอาจเข้าถึง Radio Frequency เฉพาะ

เช่น

Channel 1
→ police

แต่ pma-voice เป็น Voice Layer

ควรให้ Radio/Framework Script เป็นผู้ตรวจ

Job
Duty
Radio Item
Permission

ก่อนตั้ง Voice Channel

㊻ Garage เชื่อม Job อย่างไร

Job Garage สามารถตรวจ

Job
Grade
Duty

ก่อน Spawn Vehicle

ตัวอย่าง

Police Recruit
→ Cruiser

Sergeant
→ Cruiser + SUV

Command
→ Additional Vehicles

ช่วยทำ Progression ตาม Grade

㊼ Uniform เชื่อม Job อย่างไร

Clothing Script สามารถใช้ Job Data เปิด Uniform ตาม

Job
Grade
Gender
Duty

เช่น

Recruit Uniform
Officer Uniform
Command Uniform

ไม่ควร Hardcode Character ID รายคนหากระบบ Grade ทำได้อยู่แล้ว

㊽ Job Stash คืออะไร

พื้นที่เก็บของของอาชีพ

ตัวอย่าง

Police Evidence
Mechanic Parts
Restaurant Ingredients
EMS Medical Storage

อาจเป็น

Shared
Personal
Grade-restricted

ตาม Job Script

㊾ Job Shop คืออะไร

เป็น Shop เฉพาะอาชีพ

เช่น

Police Armory
EMS Pharmacy
Mechanic Parts Shop

ระบบควรตรวจ

Job
Grade
Duty

และ Server-side transaction ก่อนจ่าย Item

㊿ Job Crafting คืออะไร

บางอาชีพมี Production Loop

ตัวอย่างร้านอาหาร

วัตถุดิบ
↓
เตรียมอาหาร
↓
ปรุง
↓
แพ็ก
↓
ขาย

Mechanic

Materials
↓
Craft Repair Kit
↓
ใช้ซ่อมรถ

Crafting ทำให้อาชีพมี Gameplay มากกว่ายืนจุดแล้วกดรับเงิน

51. Job Script ที่ดีต้องมี Gameplay Loop

ตัวอย่าง Taxi

รับงาน
↓
ไปรับลูกค้า
↓
ส่งปลายทาง
↓
คำนวณค่าโดยสาร
↓
รับเงิน
↓
งานใหม่

ไม่ควรเป็น

กด E
↓
ได้เงิน

ซ้ำ ๆ

Gameplay Loop ที่ดีทำให้ผู้เล่นมีเหตุผลใช้เวลาอยู่ในอาชีพ

52. Whitelist Job คืออะไร

อาชีพที่ไม่ใช่ใครก็สมัครได้ทันที

เช่น

Police
EMS
Government
Staff-managed Businesses

อาจต้องผ่าน

Application
Interview
Training
Boss Hire

ก่อน Framework เปลี่ยน Job ให้ Player

53. Public Job คืออะไร

ผู้เล่นทั่วไปสามารถเริ่มได้

เช่น

Taxi
Trucker
Garbage
Delivery
Mining
Fishing

บางระบบไม่จำเป็นต้องเปลี่ยน Framework Job จริง

สามารถเป็น Activity Job ได้

54. ทุกงานจำเป็นต้องเป็น Framework Job ไหม

ไม่

นี่เป็น Architecture Point ที่สำคัญ

สมมติ Player เป็น

mechanic

ใน Framework แต่ช่วงว่างไปทำ

Fishing
Mining
Delivery

ไม่จำเป็นต้องเปลี่ยน Primary Job ทุกครั้ง

Public Activities สามารถเก็บ State แยกจาก Employment Job ได้

ช่วยลดปัญหา Jobs ถูกเปลี่ยนไปมาโดยไม่จำเป็น

55. Employment กับ Activity ควรแยกกัน

แนวคิด

Employment:
Police

Side Activity:
Fishing

ดีกว่า

Fishing เริ่ม
→ SetJob fishing

Fishing จบ
→ SetJob police

เพราะระบบหลังอาจทำลาย Duty/Grade/Multi-job Data

โดยเฉพาะ Framework ที่มี Employment State จริงจัง

56. Job Reputation คืออะไร

บาง Framework/Job Scripts มี

Job Reputation

เพื่อวัด Progression นอกเหนือจาก Grade

ตัวอย่าง

Taxi Rep 0
↓
ทำงาน
↓
Taxi Rep 100
↓
ปลดล็อกรถใหม่

QBCore/Qbox Player Metadata ปัจจุบันยังมีแนวคิด Job Reputation สำหรับงานบางประเภท

57. Grade กับ Reputation ต่างกันอย่างไร

Grade

เป็นตำแหน่งองค์กร

Recruit
Officer
Sergeant
Chief

Reputation

เป็น Experience/Progress

0
100
500
1000

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

ตัวอย่าง

Grade = Taxi Driver
Rep = 850

แล้วปลดล็อก Job Route ที่ยากขึ้น

58. Job Payment แบบ Salary กับ Per-task ต่างกัน

Salary

จ่ายตามเวลา

ทุก X นาที

Per-task

จ่ายตามผลงาน

ส่งของ 1 เที่ยว
→ ได้ $500

Server ที่ดีอาจใช้ทั้งคู่

เช่นตำรวจมี Salary แต่ Taxi/Delivery เน้น Per-task

59. Reward ต้องคำนวณฝั่ง Server

ห้ามให้ Client ส่งว่า

ฉันส่งของสำเร็จ
Reward = 100000

แล้ว Server เพิ่มเงินตามตัวเลขนั้น

ควรเป็น

Client แจ้ง Action
↓
Server ตรวจ Route
↓
Server ตรวจ Position
↓
Server ตรวจ State
↓
Server คำนวณ Reward
↓
จ่ายเงิน

นี่สำคัญต่อ Anti-cheat มาก

60. Job Script เป็นเป้าหมาย Exploit ใหญ่

เพราะ Job Scripts แจก

Money
Items
Weapons
Vehicles

จึงมักเป็นเป้าของ Event Abuse

ต้อง Validate

Player
Job
Duty
Position
Item
Cooldown
Mission State
Reward

บน Server

อย่าเชื่อ Job ที่ Client ส่งมา

ผิด

Client:
job = police

Server:
โอเค คุณเป็นตำรวจ

ถูกกว่า

Client:
ขอทำ Police Action

Server:
อ่าน Job จาก Framework
↓
ตรวจ Duty
↓
ตรวจ Grade
↓
อนุญาต

Server ต้องเป็น Authority

อย่าเชื่อ Grade จาก Client

เหมือนกัน

ห้ามใช้

clientGrade = 4

เพื่อเปิด Boss Action

Server ต้องอ่าน

Framework Player Job

ของ Player ตัวจริง

Boss Menu ต้องตรวจ Server-side

แม้ UI แสดงเฉพาะ Boss

Event

promote employee

ต้องตรวจว่า Caller ยังเป็น Boss อยู่จริง

Current esx_society เป็นตัวอย่างที่ตรวจ Boss Grade ก่อนการ Hire/Promote/Salary Management

Job Count มีประโยชน์อย่างไร

Server อาจต้องรู้ว่า

Police Online = 5
EMS Online = 2

เพื่อระบบ เช่น

Robbery requirement
Dispatch
Status UI
Heist
Hospital

Current ESX Core ยัง Track จำนวน Players ของแต่ละ Job และ Sync ผ่าน GlobalState

แต่ควรพิจารณาว่าจะนับ

Job Members
หรือ
On-duty Members

ตาม Gameplay

Heist ควรเช็กตำรวจอย่างไร

ไม่ควรเช็กเพียง

มี police job 3 คน

ถ้า 2 คน Off Duty

Game Design อาจต้องการ

On Duty Police >= 3

จึงควรใช้ Count ที่ตรงกับ Gameplay Rule

Job Script ไม่ควรผูกกับชื่อ police ตัวเดียว

ถ้า Server อาจมี

police
sheriff
statepolice

ควรออกแบบ Abstraction เช่น

LEO Group/Type

เมื่อ Framework รองรับ

ลดการแก้ Code หลายสิบ Resources ในอนาคต

Job Script ไม่ควรแก้ Framework Core

ถ้า Custom Job ต้องการ

Locker
Boss Menu
Garage
Crafting

ให้สร้าง Resource

my_police

แล้วเรียก Public APIs ของ

Framework
Inventory
Target
Garage

แทนการแก้

qbx_core
qb-core
es_extended

โดยตรง

ทำไมการแก้ Core ถึงไม่ดี

เพราะ Update Framework รอบต่อไปจะเกิด

Git Conflict
Custom Code หาย
Bug ตาม Version
Update ยาก

Custom Gameplay ควรอยู่ใน Resource แยก

ทำให้ Framework Core สามารถ Update ได้สะอาดกว่า

Job Definition กับ Job Gameplay ควรแยก

ตัวอย่าง

qbx_core/shared/jobs.lua
→ กำหนด police มี Grade อะไร

ส่วน

my_police/
→ Gameplay ของตำรวจ

การแยกแบบนี้ช่วยให้ Responsibility ชัดเจน

Runtime Job Creation ใน Qbox

Current Qbox มี Exports

CreateJob
CreateJobs
RemoveJob

แต่ Documentation เตือนว่า Changes เหล่านี้เป็น

runtime-only

ไม่ Persist หลัง Restart และไม่แก้ Files

ดังนั้นอย่าสร้าง Job ผ่าน Runtime API แล้วคาดว่าจะอยู่ถาวรหลัง Server Restart

Permanent Job ต้องอยู่ Configuration/Persistence ที่เหมาะสม

ถ้าต้องการ Job ถาวร

ควรเพิ่มตาม Framework Workflow

เช่น

shared/jobs.lua

หรือ Configuration/Database ที่ Framework กำหนด

ไม่ควรพึ่ง Runtime Creation เพียงอย่างเดียว

Qbox GetJobs ใช้ทำอะไร

Current Shared Export

exports.qbx_core:GetJobs()

คืน Jobs Table

หรือ

exports.qbx_core:GetJob('police')

คืน Job Definition เฉพาะตัว

มีประโยชน์กับ Scripts ที่ต้องอ่าน Config โดยไม่ Import Core Table แบบเก่า

Qbox HasGroup ใช้เมื่อไร

ใช้ตรวจว่า Player มี Group ที่ต้องการหรือไม่

เช่น

exports.qbx_core:HasGroup(source, {
    police = 2
})

สำหรับ Grade Requirement

แต่จำอีกครั้งว่า Current Documentation ระบุว่า Function นี้ ไม่ตรวจ Duty

QBCore SetJob ทำอะไรภายใน

Current QBCore Source จะ

ตรวจ Job มีอยู่
↓
สร้าง PlayerData.job
↓
กำหนด label
↓
defaultDuty
↓
type
↓
grade
↓
payment
↓
isboss
↓
Update Client

จึงไม่ควรสร้าง PlayerData.job เองด้วย Table แบบ Manual

ใช้ SetJob ดีกว่า

Qbox SetJob ต่างจาก QBCore ปัจจุบันอย่างไร

Qbox มี Multi-job Architecture เพิ่มขึ้น

Current SetJob สามารถ

Remove Current Primary Job
↓
Add New Job
↓
Set New Primary Job

ตาม qbx:setjob_replaces

และมี APIs แยกสำหรับ

AddPlayerToJob
SetPlayerPrimaryJob

Developer ที่เขียน Native Qbox ควรใช้ APIs เหล่านี้ตรง ๆ

เลือก Job Framework ไหนง่ายที่สุด

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

ESX

เหมาะกับ

ESX Ecosystem
Society Jobs
Resources จำนวนมาก

QBCore

เหมาะกับ

QB Ecosystem
Single-current-job style
Existing QB Server

Qbox

เหมาะกับ

Modern Qbox
Multiple jobs/groups
OX ecosystem
Public exports

เลือกตาม Server Architecture ไม่ใช่แค่ Job Script ตัวเดียว

Job Script ที่ดีควรรองรับอะไร

อย่างน้อยควรมี

Framework Integration
Duty
Grades
Permissions
Server Validation
Inventory Integration
Target Integration
Garage Integration
Localization
Configurable Rewards

และไม่ควร Hardcode ทุกอย่างใน Client

Job Script แบบ Paid ควรตรวจอะไร

ก่อนซื้อให้ดู

Framework
Inventory
Target
Garage
Billing
Banking
Boss Menu
Voice
Database
Escrow
Source Access
Updates

โดยเฉพาะคำว่า

QBCore compatible

ไม่ได้หมายความว่า Native Qbox Compatible ทุกครั้ง

ต้องดู Documentation จริง

Job Script แบบ Standalone คืออะไร

บาง Job ไม่พึ่ง Framework โดยตรง

เช่น Activity

Fishing
Mining
Delivery
Trucking

สามารถจัด State เองและใช้ Framework Adapter สำหรับ Reward

ข้อดีคือ Port Framework ง่ายกว่า

แต่ถ้าเป็น Organization เช่น Police/EMS มักต้อง Integration กับ Job/Groups จริง

Server ใหม่ควรเริ่ม Job อะไรก่อน

สำหรับ RP Server ไม่ควรติดตั้ง 50 Jobs วันแรก

เริ่มจาก Core Jobs

Police
EMS
Mechanic
Taxi/Delivery

ให้ระบบ

Duty
Salary
Garage
Inventory
Boss
Billing

เสถียรก่อน

จากนั้นค่อยเพิ่ม Businesses

ทำไม Job เยอะเกินไปไม่ดี

ถ้ามี Player Online 30 คน แต่มี 40 Businesses

ผลอาจเป็น

แต่ละอาชีพไม่มีคน
เมืองดูว่าง
Economy แตก
Staff ดูแลยาก

จำนวน Jobs ควรสัมพันธ์กับ Concurrent Players

ไม่ใช่จำนวน Scripts ที่ซื้อมา

Checklist สร้าง Job ใหม่

Job Definition

  • Name

  • Label

  • Type

  • Grades

  • Payment

  • Boss

  • Duty

Gameplay

  • Clock In

  • Garage

  • Stash

  • Shop

  • Crafting

  • Uniform

  • Missions

Integration

  • Framework

  • Inventory

  • Target

  • Voice

  • Phone

  • Banking

Security

Server ตรวจ

Job
Grade
Duty
Position
Item
Reward

Economy

  • Salary

  • Item Cost

  • Revenue

  • Company Account

  • Money Sink

ตัวอย่าง Qbox Job Definition

แนวคิด

['mechanic'] = {
    label = 'Mechanic',
    type = 'mechanic',
    defaultDuty = false,
    offDutyPay = false,

    grades = {
        [0] = {
            name = 'Trainee',
            payment = 50
        },

        [1] = {
            name = 'Mechanic',
            payment = 75
        },

        [2] = {
            name = 'Manager',
            isboss = true,
            bankAuth = true,
            payment = 100
        }
    }
}

ค่าจริงควร Balance ตาม Server

ตัวอย่าง QBCore Job Definition

แนวคิด

mechanic = {
    label = 'Mechanic',
    type = 'mechanic',
    defaultDuty = false,
    offDutyPay = false,

    grades = {
        ['0'] = {
            name = 'Trainee',
            payment = 50
        },

        ['1'] = {
            name = 'Mechanic',
            payment = 75
        },

        ['2'] = {
            name = 'Manager',
            isboss = true,
            payment = 100
        }
    }
}

จะเห็นว่า Structure มีความคล้ายกัน แต่ไม่ควร Copy APIs ระหว่าง QBCore/Qbox แบบเดา

ตัวอย่างตรวจ Job Server-side

แนวคิด QBCore

local Player = QBCore.Functions.GetPlayer(source)

if not Player then
    return
end

if Player.PlayerData.job.name ~= 'police' then
    return
end

if not Player.PlayerData.job.onduty then
    return
end

-- ทำ Police Action

แนวคิดนี้ปลอดภัยกว่าการให้ Client ตัดสินเอง

ตัวอย่างตรวจ Grade

local grade = Player.PlayerData.job.grade.level

if grade < 2 then
    return
end

จากนั้นจึงทำ Action ที่ต้องการ

แต่ Code จริงต้องตรวจ Framework/API Version ที่ใช้ด้วย

Boss Action ต้องตรวจทุกครั้ง

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

Boss กด Promote
↓
Server รับ Request
↓
อ่าน Job ของ Caller
↓
ตรวจ isboss
↓
ตรวจ Target
↓
ตรวจ Grade ใหม่
↓
Set Job

ไม่ใช่

Client ส่ง isboss = true
↓
Promote

Salary ไม่ควร Hardcode หลาย Script

ถ้า Framework Job Definition มี

payment

ควรใช้ Source of Truth เดียว

ไม่ควรให้

jobs.lua = 100
paycheck.lua = 500
bossmenu.lua = 200

เพราะจะเกิดข้อมูลไม่ตรงกัน

Job Permissions ควรมี Source of Truth

เช่น

Grade 4 = Boss

ควรให้ Framework/Organization System เป็นคนกำหนด

แล้ว Resources อื่นอ่านจาก API

ลด Hardcode แบบ

if grade == 4

ทั่ว Server เมื่อทำได้

Job Script ควรรองรับ Offline Employees ไหม

Boss Management บางระบบรองรับจัดการ Player ที่ Offline

Current qb-management ระบุว่ารองรับ Employees Online และ Offline

Current ESX Society ก็มี Logic สำหรับแก้ Job ของ Offline Player ผ่าน Database ในบาง Operations

Feature นี้สะดวก แต่ต้องออกแบบ Persistence ให้ถูก

Offline Job Change ต้องระวังอะไร

ถ้า Player Offline การแก้ Database อาจเหมาะสมตาม Framework API

แต่ถ้า Player Online ควรเปลี่ยน Runtime State ผ่าน Framework

จึงควรให้ Management Resource แยก

Online Player
→ Framework API

Offline Player
→ Framework Offline API / Supported DB Workflow

ไม่ใช่ Direct SQL ทุกกรณี

Job Data ต้อง Save เมื่อ Reconnect

ทดสอบ

ตั้ง police grade 2
↓
Disconnect
↓
Reconnect

แล้วต้องยังเป็น Job/Grade ที่ถูกต้อง

ถ้า Runtime เปลี่ยนแต่เข้าใหม่กลับ Job เก่า แสดงว่า Persistence มีปัญหา

Duty ต้อง Persist ไหม

ขึ้นกับ Framework Configuration

บาง Serverต้องการ

Reconnect
→ defaultDuty

บาง Serverต้องการจำ Duty ล่าสุด

Current QBCore มี Config

ForceJobDefaultDutyAtLogin

สำหรับควบคุม Behavior นี้

จึงควรกำหนดให้ตรง RP Design

Multi-job ต้องวาง UX ให้ดี

ถ้า Player มี

Police
Mechanic
Taxi

ควรมีวิธีเลือก

Primary Job

ที่ชัดเจน

และควรป้องกัน

On Duty หลายองค์กรพร้อมกัน

ถ้า Gameplay ไม่อนุญาต

ไม่เช่นนั้น Permissions จะซับซ้อนมาก

Job กับ Gang ควรแยกกัน

Framework จำนวนมากแยก

Job

กับ

Gang

ตัวอย่าง

Job = mechanic
Gang = ballas

ดังนั้น Police Script ไม่ควรอ่าน Gang Field แทน Job

และ Gang Systems ไม่ควรเปลี่ยน Employment Job โดยไม่จำเป็น

สรุป FiveM Job Script คืออะไร ระบบอาชีพทำงานอย่างไร

FiveM Job Script คือระบบ Gameplay ที่ใช้ข้อมูลอาชีพจาก Framework เพื่อกำหนดว่า Player สามารถทำอะไรได้บ้าง

แกนหลักของระบบคือ

Job Name
↓
Grade
↓
Duty
↓
Permissions
↓
Salary
↓
Gameplay

แล้วเชื่อมต่อกับ

Boss Menu
Garage
Inventory
Stash
Shop
Crafting
Target
Radio
Phone
Banking

QBCore ปัจจุบันมี PlayerData.job ซึ่งเก็บ Job Name, Label, Payment, Duty, Boss และ Grade และมี SetJob กับ SetJobDuty สำหรับเปลี่ยน State ของ Player

Qbox ปัจจุบันขยายแนวคิดนี้ไปถึง Multi-job โดย Player มี jobs หลายรายการและ Primary job หนึ่งตัว พร้อม APIs เช่น

SetJob
AddPlayerToJob
SetPlayerPrimaryJob
SetJobDuty
HasGroup
GetGroups

และสามารถจำกัดจำนวน Jobs ต่อ Player ผ่าน qbx:max_jobs_per_player

ESX ยังคงใช้ xPlayer.getJob() และ xPlayer.setJob() เป็น Core Job APIs และ esx_society ใช้ Job/Grade ในระบบ Hire, Promote, Fire และ Salary Management

สิ่งสำคัญที่สุดในการเขียน Job Script คือ อย่าเชื่อ Job, Grade หรือ Reward ที่ Client ส่งมาเอง Server ต้องอ่านข้อมูลจาก Framework และตรวจ Job, Grade, Duty, Position, Mission State และ Reward ก่อนให้เงินหรือ Item

อีกหลักหนึ่งคือไม่ควรใช้ Framework Job สำหรับทุกกิจกรรมในเมือง หาก Player มีอาชีพตำรวจแต่ต้องการไปตกปลาในเวลาว่าง Fishing สามารถเป็น Activity State แยกได้ ไม่จำเป็นต้อง SetJob('fishing') แล้วเปลี่ยนกลับทุกครั้ง

แนวทางของ comsiam คือให้ Framework เป็น Source of Truth ของ Job/Grade/Duty ส่วน Police, EMS, Mechanic หรือ Business Scripts เป็น Gameplay Layer และใช้ Public APIs เชื่อม Inventory, Target, Garage และ Banking แทนการแก้ Framework Core

สำหรับ Server RP ขนาดใหญ่ comsiam แนะนำให้เริ่มจาก Job หลักไม่กี่อาชีพ แล้วทำ Duty → Grade → Garage → Stash → Salary → Boss → Security ให้สมบูรณ์ก่อนเพิ่ม Jobs จำนวนมาก เพราะระบบอาชีพที่เชื่อมกันถูกต้อง 5 งานมีคุณค่ากว่า 50 Jobs ที่แจกเงินได้แต่ไม่มี Gameplay หรือ Permission Architecture ที่ชัดเจน

Comments

Popular posts from this blog

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

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

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