5.2 KiB

title, description
title description
ICOM Usage Guide ICOM is the Forge inter-server communication helper. It lets multiple Arma 3 servers exchange generic JSON events through a central TCP hub instead of connecting directly to each other.

Runtime Shape

Arma server SQF
  -> forge_server extension icom:* command
  -> ICOM client inside the extension
  -> forge-icom TCP hub
  -> target server extension
  -> forge_icom_event CBA server event

The ICOM hub lives in bin/icom. The Arma server extension integrates with it through arma/server/extension/src/icom.rs.

Components

Component Path Role
ICOM hub binary bin/icom Standalone TCP router for connected servers.
ICOM client library bin/icom/src/client.rs Rust client used by the Forge server extension and examples.
Extension command group arma/server/extension/src/icom.rs Exposes icom:* commands to SQF and forwards inbound events to Arma.
SQF callback bridge arma/server/addons/main/XEH_preInit.sqf Receives extension callbacks and re-emits forge_icom_event through CBA.

Build and Run the Hub

Build the release binary:

cargo build --release -p forge-icom

Run it during development:

cargo run -p forge-icom

The default bind address is 0.0.0.0:9090.

Hub Configuration

Copy bin/icom/config.example.toml to config.toml beside the forge-icom executable or into the working directory used to launch it.

[server]
host = "0.0.0.0"
port = 9090

Use 127.0.0.1 for same-machine testing. Use 0.0.0.0 when remote Arma servers need to connect, and secure the port at the firewall or host network layer.

Extension Commands

ICOM commands are exposed through the icom command group in forge_server.

Command Arguments Returns
icom:connect address, server_id Connection initiated or ERROR: Already connected.
icom:send_event target_server, event_name, data_json OK or ERROR: <reason>.
icom:broadcast event_name, data_json OK or ERROR: <reason>.

The current extension connects when icom:connect is called. Start the ICOM hub first, then connect each Arma server with a unique server_id.

private _result = "forge_server" callExtension [
    "icom:connect",
    ["127.0.0.1:9090", "server_1"]
];
diag_log format ["[ICOM] Connect result: %1", _result select 0];

Send an Event

Send a targeted event to one connected server:

private _data = createHashMapFromArray [
    ["coords", [1234, 5678, 0]],
    ["supplies", ["ammo_box", "medical_supplies"]]
];

"forge_server" callExtension [
    "icom:send_event",
    ["server_2", "supply_drop", toJSON _data]
];

Broadcast to every connected server except the sender:

private _alert = createHashMapFromArray [
    ["message", "Server restart in 5 minutes"],
    ["severity", "warning"]
];

"forge_server" callExtension [
    "icom:broadcast",
    ["global_alert", toJSON _alert]
];

Receive Events

Inbound ICOM events are forwarded to SQF as the CBA server event forge_icom_event.

["forge_icom_event", {
    params ["_eventName", "_data"];

    switch (_eventName) do {
        case "supply_drop": {
            private _coords = _data getOrDefault ["coords", []];
            private _supplies = _data getOrDefault ["supplies", []];
            diag_log format ["[ICOM] Supply drop at %1: %2", _coords, _supplies];
        };
        case "global_alert": {
            private _message = _data getOrDefault ["message", ""];
            if (_message isNotEqualTo "") then {
                [_message] remoteExec ["hint", 0];
            };
        };
        default {
            diag_log format ["[ICOM] Unhandled event: %1 | %2", _eventName, _data];
        };
    };
}] call CBA_fnc_addEventHandler;

Message Protocol

The hub uses newline-delimited JSON. The first message from each client is a registration payload:

{
  "type": "register",
  "server_id": "server_1"
}

Targeted events use type: "event":

{
  "type": "event",
  "target_server": "server_2",
  "event_name": "supply_drop",
  "data": {
    "coords": [1234, 5678, 0]
  }
}

Broadcasts use type: "broadcast" and are routed to all connected servers except the sender.

Operational Notes

  • Server IDs must be unique. If the same ID reconnects, the hub replaces the old connection.
  • Event names are mission/application contracts. ICOM only routes them; it does not validate gameplay meaning.
  • Always send valid JSON in the data_json argument.
  • icom:send_event and icom:broadcast return quickly after scheduling async work in the extension. Check extension and ICOM hub logs for delivery errors.
  • Keep event payloads small and stable. Use IDs or compact data where possible.

Testing

Start the hub:

cargo run -p forge-icom

Run example clients in separate terminals:

cargo run -p forge-icom --example server_1_client
cargo run -p forge-icom --example server_2_client

For Arma testing, start the hub, connect the server with icom:connect, register a forge_icom_event handler, then send an event from another connected server.