Server Modules

Bank Usage Guide

The bank module stores player account balances, earnings, PINs, and transaction strings. The hot-state API also owns the active banking workflows used by the UI: deposit, withdraw, transfer, checkout charge, and PIN validation.

Bank Usage Guide

The bank module stores player account balances, earnings, PINs, and transaction strings. The hot-state API also owns the active banking workflows used by the UI: deposit, withdraw, transfer, checkout charge, and PIN validation.

Storage Model

Bank data is persisted through SurrealDB by the server extension.

{
  "uid": "76561198000000000",
  "name": "Player Name",
  "bank": 1000.0,
  "cash": 250.0,
  "earnings": 0.0,
  "pin": 1234,
  "transactions": []
}

Rules validated by the Rust service:

  • uid is authoritative from the command argument.
  • name cannot be empty.
  • bank and cash cannot be negative.
  • pin must be a four-digit number.
  • Durable bank:get requires an existing bank account.

Durable Commands

CommandArgumentsReturns
bank:createuid, bank_jsonPersisted bank JSON.
bank:getuidBank JSON.
bank:updateuid, patch_jsonUpdated bank JSON.
bank:existsuidtrue or false.
bank:deleteuidOK.

Create an Account

The uid field in the JSON is overwritten with the command UID.

private _account = createHashMapFromArray [
    ["uid", getPlayerUID player],
    ["name", name player],
    ["bank", 0],
    ["cash", 0],
    ["earnings", 0],
    ["pin", 1234],
    ["transactions", []]
];

private _result = "forge_server" callExtension ["bank:create", [
    getPlayerUID player,
    toJSON _account
]];

Hot-State Commands

CommandArgumentsReturns
bank:hot:inituidBank JSON loaded into hot state.
bank:hot:getuidBank JSON.
bank:hot:overrideuid, bank_jsonBank JSON.
bank:hot:patchuid, patch_json{ account, patch }.
bank:hot:deposituid, amount, context_json{ account, patch }.
bank:hot:withdrawuid, amount, context_json{ account, patch }.
bank:hot:deposit_earningsuid, amount, context_json{ account, patch }.
bank:hot:transfersource_uid, target_uid, amount, context_jsonTransfer result JSON.
bank:hot:charge_checkoutuid, amount, context_json{ account, patch }.
bank:hot:validate_pinuid, pin, context_json{} on success.
bank:hot:saveuidCurrent hot bank JSON and async durable save.
bank:hot:removeuidOK.

Use hot-state commands for UI workflows. They return patch objects so the UI can update only changed fields.

Deposit and Withdraw

ATM sessions require atmAuthorized: true. Full bank sessions can set mode: "bank".

private _context = createHashMapFromArray [
    ["mode", "atm"],
    ["atmAuthorized", true]
];

private _deposit = "forge_server" callExtension ["bank:hot:deposit", [
    getPlayerUID player,
    "100",
    toJSON _context
]];

private _withdraw = "forge_server" callExtension ["bank:hot:withdraw", [
    getPlayerUID player,
    "50",
    toJSON _context
]];

Transfer

Transfers are only available from the full bank interface. fromField can be bank or cash.

private _context = createHashMapFromArray [
    ["mode", "bank"],
    ["atmAuthorized", false],
    ["fromField", "bank"]
];

private _result = "forge_server" callExtension ["bank:hot:transfer", [
    getPlayerUID player,
    _targetUid,
    "250",
    toJSON _context
]];

Checkout Charge

Checkout charging supports sourceField: "cash" or sourceField: "bank". Set commit to false to preview the patch without saving.

private _context = createHashMapFromArray [
    ["sourceField", "bank"],
    ["commit", true]
];

private _result = "forge_server" callExtension ["bank:hot:charge_checkout", [
    getPlayerUID player,
    "125",
    toJSON _context
]];

PIN Validation

PIN entry is only valid in ATM mode.

private _context = createHashMapFromArray [["mode", "atm"]];

private _result = "forge_server" callExtension ["bank:hot:validate_pin", [
    getPlayerUID player,
    "1234",
    toJSON _context
]];

Error Handling

private _result = "forge_server" callExtension ["bank:hot:get", [getPlayerUID player]];
private _payload = _result select 0;

if (_payload find "Error:" == 0) exitWith {
    systemChat format ["Bank error: %1", _payload];
};

private _bank = fromJSON _payload;
Copyright © 2026