5.1 KiB
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_jsonargument. icom:send_eventandicom:broadcastreturn 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.