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

12 KiB

Organization Usage Guide

The organization module stores organization records, members, assets, fleet entries, and credit lines. Durable commands manage persisted records directly. Hot-state commands support the active organization UI workflows.

Storage Model

Core organization:

{
  "id": "default",
  "owner": "server",
  "name": "Default Organization",
  "funds": 0.0,
  "reputation": 0,
  "credit_lines": {}
}

Hot organization:

{
  "id": "default",
  "owner": "server",
  "name": "Default Organization",
  "funds": 0.0,
  "reputation": 0,
  "credit_lines": {},
  "assets": {},
  "fleet": {},
  "members": {},
  "pending_invites": {}
}

Rules validated by the Rust service:

  • id must be non-empty and contain only alphanumeric characters or _.
  • owner must be server or a 17-digit Steam UID.
  • name cannot be empty, cannot exceed 100 characters, and cannot contain control characters.
  • funds, reputation, and credit line amounts cannot be negative.
  • Player registration is rejected when the player already belongs to a non-default organization.

Durable Commands

<th>
  Arguments
</th>

<th>
  Returns
</th>
<td>
  <code>
    org_id
  </code>
  
  , <code>
    org_json
  </code>
</td>

<td>
  Organization JSON.
</td>
<td>
  <code>
    org_id
  </code>
</td>

<td>
  Organization JSON.
</td>
<td>
  <code>
    org_id
  </code>
  
  , <code>
    patch_json
  </code>
</td>

<td>
  Updated organization JSON.
</td>
<td>
  <code>
    org_id
  </code>
</td>

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

<td>
  <code>
    OK
  </code>
  
  .
</td>
<td>
  <code>
    org_id
  </code>
</td>

<td>
  Asset map JSON.
</td>
<td>
  <code>
    org_id
  </code>
  
  , <code>
    assets_json
  </code>
</td>

<td>
  Updated asset map JSON.
</td>
<td>
  <code>
    org_id
  </code>
</td>

<td>
  Fleet map JSON.
</td>
<td>
  <code>
    org_id
  </code>
  
  , <code>
    fleet_json
  </code>
</td>

<td>
  Updated fleet map JSON.
</td>
<td>
  <code>
    org_id
  </code>
</td>

<td>
  Member array JSON.
</td>
<td>
  <code>
    org_id
  </code>
  
  , <code>
    member_uid
  </code>
</td>

<td>
  <code>
    OK
  </code>
  
  .
</td>
<td>
  <code>
    org_id
  </code>
  
  , <code>
    member_uid
  </code>
</td>

<td>
  <code>
    OK
  </code>
  
  .
</td>
Command
org:create
org:get
org:update
org:exists
org:delete
org:assets:get
org:assets:update
org:fleet:get
org:fleet:update
org:members:get
org:members:add
org:members:remove

Create an Organization

The command key is authoritative for id.

private _org = createHashMapFromArray [
    ["id", _orgId],
    ["owner", getPlayerUID player],
    ["name", "Spearnet Logistics"],
    ["funds", 0],
    ["reputation", 0],
    ["credit_lines", createHashMap]
];

private _result = "forge_server" callExtension ["org:create", [
    _orgId,
    toJSON _org
]];

Update Organization Funds

private _patch = createHashMapFromArray [
    ["funds", 5000],
    ["reputation", 10]
];

private _result = "forge_server" callExtension ["org:update", [
    _orgId,
    toJSON _patch
]];

Supported durable patch fields are id, owner, name, funds, reputation, and credit_lines.

Assets and Fleet

Assets are grouped by category, then classname.

private _assets = createHashMapFromArray [
    ["ammo", createHashMapFromArray [
        ["ACE_30Rnd_65x39_caseless_mag", createHashMapFromArray [
            ["classname", "ACE_30Rnd_65x39_caseless_mag"],
            ["type", "ammo"],
            ["quantity", 20]
        ]]
    ]]
];

"forge_server" callExtension ["org:assets:update", [_orgId, toJSON _assets]];

Fleet is keyed by an internal fleet entry ID.

private _fleet = createHashMapFromArray [
    ["B_Truck_01_transport_F_0", createHashMapFromArray [
        ["classname", "B_Truck_01_transport_F"],
        ["name", "Transport Truck"],
        ["type", "cars"],
        ["status", "Ready"],
        ["damage", "0%"]
    ]]
];

"forge_server" callExtension ["org:fleet:update", [_orgId, toJSON _fleet]];

Hot-State Commands

<th>
  Arguments
</th>

<th>
  Returns
</th>
<td>
  <code>
    org_id
  </code>
</td>

<td>
  Hot organization JSON.
</td>
<td>
  <code>
    org_id
  </code>
</td>

<td>
  Hot organization JSON.
</td>
<td>
  <code>
    org_id
  </code>
  
  , <code>
    hot_org_json
  </code>
</td>

<td>
  Hot organization JSON.
</td>
<td>
  <code>
    context_json
  </code>
</td>

<td>
  Hot organization JSON.
</td>
<td>
  <code>
    member_uid
  </code>
</td>

<td>
  Invite array JSON.
</td>
<td>
  <code>
    context_json
  </code>
</td>

<td>
  Register result JSON.
</td>
<td>
  <code>
    context_json
  </code>
</td>

<td>
  Invite result JSON.
</td>
<td>
  <code>
    context_json
  </code>
</td>

<td>
  Invite decision result JSON.
</td>
<td>
  <code>
    context_json
  </code>
</td>

<td>
  Invite decision result JSON.
</td>
<td>
  <code>
    context_json
  </code>
</td>

<td>
  Mutation result JSON.
</td>
<td>
  <code>
    context_json
  </code>
</td>

<td>
  Repayment result JSON.
</td>
<td>
  <code>
    context_json
  </code>
</td>

<td>
  Mutation result JSON.
</td>
<td>
  <code>
    context_json
  </code>
  
  , <code>
    assets_json
  </code>
</td>

<td>
  Mutation result JSON.
</td>
<td>
  <code>
    context_json
  </code>
  
  , <code>
    fleet_json
  </code>
</td>

<td>
  Mutation result JSON.
</td>
<td>
  <code>
    context_json
  </code>
</td>

<td>
  Leave result JSON.
</td>
<td>
  <code>
    context_json
  </code>
</td>

<td>
  Disband result JSON.
</td>
<td>
  <code>
    org_id
  </code>
</td>

<td>
  Current hot organization JSON and async durable save.
</td>
<td>
  <code>
    org_id
  </code>
</td>

<td>
  <code>
    OK
  </code>
  
  .
</td>
Command
org:hot:init
org:hot:get
org:hot:override
org:hot:ensure_member
org:hot:member_invites
org:hot:register
org:hot:invite_member
org:hot:accept_invite
org:hot:decline_invite
org:hot:assign_credit_line
org:hot:repay_credit_line
org:hot:charge_checkout
org:hot:add_assets
org:hot:add_fleet
org:hot:leave
org:hot:disband
org:hot:save
org:hot:remove

Register from UI Context

private _context = createHashMapFromArray [
    ["requesterUid", getPlayerUID player],
    ["requesterName", name player],
    ["orgId", _orgId],
    ["orgName", "Spearnet Logistics"],
    ["existingOrgId", "default"]
];

private _result = "forge_server" callExtension ["org:hot:register", [toJSON _context]];

Invite and Accept

private _invite = createHashMapFromArray [
    ["requesterUid", getPlayerUID player],
    ["requesterName", name player],
    ["orgId", _orgId],
    ["requesterIsDefaultOrgCeo", false],
    ["targetUid", _targetUid],
    ["targetName", _targetName],
    ["targetOrgId", "default"]
];

"forge_server" callExtension ["org:hot:invite_member", [toJSON _invite]];

private _decision = createHashMapFromArray [
    ["requesterUid", _targetUid],
    ["requesterName", _targetName],
    ["orgId", _orgId],
    ["existingOrgId", "default"]
];

"forge_server" callExtension ["org:hot:accept_invite", [toJSON _decision]];

Credit Line Checkout

private _credit = createHashMapFromArray [
    ["requesterUid", getPlayerUID player],
    ["orgId", _orgId],
    ["requesterIsDefaultOrgCeo", false],
    ["memberUid", _memberUid],
    ["memberName", _memberName],
    ["amount", 1000]
];

"forge_server" callExtension ["org:hot:assign_credit_line", [toJSON _credit]];

private _charge = createHashMapFromArray [
    ["requesterUid", _memberUid],
    ["orgId", _orgId],
    ["requesterIsDefaultOrgCeo", false],
    ["source", "credit_line"],
    ["amount", 250],
    ["commit", true]
];

"forge_server" callExtension ["org:hot:charge_checkout", [toJSON _charge]];

Error Handling

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