Skip to content

Characters & money (wf_core) ​

Accounts and identity ​

A player is an account identified by a string:

  • wfx:<username> — the WFX.re account linked in the launcher, verified by the server (lower-case);
  • guest:<name> — only with "identity": "wfx+guest", for LAN servers and bots.

Guests are not authenticated

A guest identifier is derived from the player name. Anyone using the same name gets the same characters and items. Never use wfx+guest on a public server.

The same account cannot be connected twice. Accounts are created on first join.

Account verification is not live yet

Today the launcher does not send a WFX.re proof to game servers. Sending the account's session token would let a server operator steal the account, so the plan is a single-use, per-server ticket issued by the master server and checked by the game server. Until it exists, use wfx+guest for tests; wfx refuses everyone.

Characters ​

Each account has up to maxCharacters characters. One character is played at a time.

FieldRule
firstname, lastname1–24 letters, spaces, ' and -; must start with a letter
dobYYYY-MM-DD, a real date, age 18 to 100
sex"m", "f" or ""

Deleting a character is a soft delete (kept in the database, hidden). A character in use cannot be deleted or loaded by a second player.

When a character is loaded, the server sends its saved position (wf:spawn) so the client can put the player back where they left. Positions come from the server's own player sync, are saved every savePositionSeconds and on leave.

In game (v1, before the character menu exists):

text
/perso                          your character
/perso liste                    list your characters
/perso creer Ana Lopez 1991-02-03
/perso jouer 1
/perso quitter                  back to character selection

Money ​

Two accounts per character: cash and bank. Amounts are positive integers (no cents); 1.5, "10", NaN, negative numbers or values above 2^53 are refused with invalid_amount. A balance can never go below zero (insufficient_funds). Each movement is written to the money_log table with the new balance and a reason.

lua
-- server script (Lua)
local balance, err = exports.wf_core:AddMoney(source, "bank", 250, "fishing")
if not balance then print("refused:", err) end

local ok = exports.wf_core:RemoveMoney(source, "cash", 40, "taxi")
exports.wf_core:TransferBank(source, target, 1000, "rent")   -- atomic: both or nothing

Jobs and grades ​

Jobs are data, in wf_core/data/jobs.json:

json
"police": {
  "label": "Police de Bolivie",
  "grades": [
    { "label": "Cadet", "salary": 200 },
    { "label": "Capitaine", "salary": 550, "boss": true }
  ]
}

A character has one job and a grade (index in grades, from 0). unemployed always exists.

Duty. A character is off duty when loaded (unless the job sets "defaultDuty": true) and goes back off duty when it changes job. Job scripts call exports.wf_core:SetDuty(source, true) (for example at the police station) and listen to wf:dutyChanged. Every paycheckMinutes, each loaded character on duty receives the salary of its grade in the bank; the unemployed allowance is always paid. Set paycheckRequiresDuty to false in config.json to pay everyone.

Needs (hunger, thirst) ​

Each character has needs from 0 to 100, defined in wf_core/config.json:

json
"status": { "hunger": { "decayPerMinute": 0.5 }, "thirst": { "decayPerMinute": 0.8 } }
  • New characters start at 100. Every minute the server lowers each need by decayPerMinute; values are saved per character.
  • Food and drink restore them through the item definition: "use": { "consume": 1, "status": { "thirst": 35 } }.
  • Scripts use GetStatus, SetStatus, AddStatus and listen to wf:statusChanged / wf:statusEmpty (a need reached 0 — what happens then is up to your scripts).
  • The client shows them in the WildM HUD with SetHudStat(id, value): the bar ids in wildm-hud/hud.json (status.items) must match the need names. Add a need ("stress": { "decayPerMinute": 0 }) and a bar with the same id to display it.

Groups (factions) ​

A character can belong to any number of groups, each with a grade: SetGroup(source, "cartel_sb", 2). Group names are lower-case letters, digits and _. Stashes can require a job or group grade (see Inventory).

Permissions ​

Permission groups belong to the account, defined in wf_core/data/groups.json:

json
"mod":   { "inherits": "user", "permissions": ["wf.kick", "wf.inventory.open_any"] },
"admin": { "inherits": "mod",  "permissions": ["*"] }

* matches everything, wf.* matches every permission starting with wf.. Every account is in user. The server console (source 0) has every permission.

One permission system with the server ACE. HasPermission also accepts what the server's ACE allow (add_ace / add_principal, FiveM-style), and each WFramework account group is pushed as an ACE principal: an account in admin makes identifier.wfx:<name> inherit group.admin. So add_ace group.police wf.inventory.open_any allow works for WFramework, and IsPlayerAceAllowed(src, "command.kick") sees WFramework groups.

PermissionUsed by
wf.money.give, wf.money.set/givemoney, /setmoney
wf.job.set/setjob
wf.group.add/addgroup, /removegroup
wf.inventory.give/giveitem
wf.inventory.open_anyopen any inventory, including other players'

Admin commands ​

text
givemoney <id> <cash|bank> <amount>
setmoney  <id> <cash|bank> <amount>
setjob    <id> <job> [grade]
addgroup  <id> <group>        removegroup <id> <group>
giveitem  <id> <item> [count]

WildM is an independent community project. It is not affiliated with or endorsed by Ubisoft. Ghost Recon Wildlands is a trademark of Ubisoft Entertainment.