2026-05-23 09:23:12 -05:00

8.1 KiB

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

<th>
  Arguments
</th>

<th>
  Returns
</th>
<td>
  <code>
    uid
  </code>
  
  , <code>
    bank_json
  </code>
</td>

<td>
  Persisted bank JSON.
</td>
<td>
  <code>
    uid
  </code>
</td>

<td>
  Bank JSON.
</td>
<td>
  <code>
    uid
  </code>
  
  , <code>
    patch_json
  </code>
</td>

<td>
  Updated bank JSON.
</td>
<td>
  <code>
    uid
  </code>
</td>

<td>
  <code>
    true
  </code>
  
   or <code>
    false
  </code>
  
  .
</td>
<td>
  <code>
    uid
  </code>
</td>

<td>
  <code>
    OK
  </code>
  
  .
</td>
Command
bank:create
bank:get
bank:update
bank:exists
bank:delete

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

<th>
  Arguments
</th>

<th>
  Returns
</th>
<td>
  <code>
    uid
  </code>
</td>

<td>
  Bank JSON loaded into hot state.
</td>
<td>
  <code>
    uid
  </code>
</td>

<td>
  Bank JSON.
</td>
<td>
  <code>
    uid
  </code>
  
  , <code>
    bank_json
  </code>
</td>

<td>
  Bank JSON.
</td>
<td>
  <code>
    uid
  </code>
  
  , <code>
    patch_json
  </code>
</td>

<td>
  <code>
    { account, patch }
  </code>
  
  .
</td>
<td>
  <code>
    uid
  </code>
  
  , <code>
    amount
  </code>
  
  , <code>
    context_json
  </code>
</td>

<td>
  <code>
    { account, patch }
  </code>
  
  .
</td>
<td>
  <code>
    uid
  </code>
  
  , <code>
    amount
  </code>
  
  , <code>
    context_json
  </code>
</td>

<td>
  <code>
    { account, patch }
  </code>
  
  .
</td>
<td>
  <code>
    uid
  </code>
  
  , <code>
    amount
  </code>
  
  , <code>
    context_json
  </code>
</td>

<td>
  <code>
    { account, patch }
  </code>
  
  .
</td>
<td>
  <code>
    source_uid
  </code>
  
  , <code>
    target_uid
  </code>
  
  , <code>
    amount
  </code>
  
  , <code>
    context_json
  </code>
</td>

<td>
  Transfer result JSON.
</td>
<td>
  <code>
    uid
  </code>
  
  , <code>
    amount
  </code>
  
  , <code>
    context_json
  </code>
</td>

<td>
  <code>
    { account, patch }
  </code>
  
  .
</td>
<td>
  <code>
    uid
  </code>
  
  , <code>
    pin
  </code>
  
  , <code>
    context_json
  </code>
</td>

<td>
  <code>
    {}
  </code>
  
   on success.
</td>
<td>
  <code>
    uid
  </code>
</td>

<td>
  Current hot bank JSON and async durable save.
</td>
<td>
  <code>
    uid
  </code>
</td>

<td>
  <code>
    OK
  </code>
  
  .
</td>
Command
bank:hot:init
bank:hot:get
bank:hot:override
bank:hot:patch
bank:hot:deposit
bank:hot:withdraw
bank:hot:deposit_earnings
bank:hot:transfer
bank:hot:charge_checkout
bank:hot:validate_pin
bank:hot:save
bank:hot:remove

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;