- Add shared `bin/host/config.example.toml` and remove the old host example - Split Arma config creation between `server.cfg` and `basic.cfg` - Update docs and examples to reflect shared host-managed config
5.8 KiB
Framework Architecture
Forge is organized around domain modules. A domain usually has SQF addon entry points, Rust models, repository traits, service logic, extension command handlers, and optional browser UI.
Runtime Flow
Arma client UI or SQF action
-> shared config classes from @forge_mod
-> client addon bridge
-> server addon function
-> forge_server callExtension command
-> extension command group
-> forge-services domain service
-> forge-repositories trait
-> SurrealDB repository implementation
-> SurrealDB
For small payloads, server SQF calls forge_server directly through the
extension bridge. For large payloads, arma/server/addons/extension stages
request and response chunks through the extension transport module.
Main Layers
Shared Mod
The shared mod lives under arma/mod and builds to @forge_mod. It contains
mission-facing config classes that must exist on both clients and servers, such
as Forge task Eden modules and shared vehicle definitions. Missions should
depend on these forge_mod_* addons when placing Forge modules.
@forge_mod does not own server runtime behavior. Task module config can point
at server-owned functions, but those functions still live in @forge_server
and execute only where the server mod is loaded.
Client Addons
Client addons live under arma/client/addons. They own local player UX,
keybinds, browser UI dialogs, and UI-to-SQF event handling. When a client needs
durable or authoritative state, it routes work to the matching server addon
instead of touching persistence directly.
Server Addons
Server addons live under arma/server/addons. They own server-side SQF
initialization, game-object integration, validation near the Arma runtime, and
calls into the Rust extension. The extension addon is the shared bridge for
callExtension and transport handling.
Server addons may require forge_mod_* addons for shared class definitions.
They should keep authoritative logic in @forge_server so clients only need
shared config and client UX packages.
Rust Extension
The server extension lives under arma/server/extension. It registers the
forge_server command groups, loads configuration, initializes SurrealDB, and
maps SQF command inputs into service calls.
The extension should stay thin:
- Parse and validate command arguments that arrive from SQF.
- Resolve Arma-specific context such as player UID when required.
- Call the matching service.
- Serialize the service result back to JSON or a simple string.
Shared Rust Crates
The lib workspace contains reusable Rust crates:
forge-models: shared domain structs and serialization rules.forge-repositories: storage-agnostic repository traits and in-memory implementations used by tests and hot-state services.forge-services: domain behavior, validation, and mutation workflows.forge-shared: cross-crate helpers.
Persistence
Durable storage is SurrealDB. Schema modules live under
arma/server/extension/src/schema, and concrete SurrealDB repository
implementations live under arma/server/extension/src/storage.
Repository traits stay in lib/repositories so service logic remains testable
without a database.
Hot State
Several domains have hot command groups. Hot state keeps a runtime copy of
frequently accessed data in memory, then saves it back to durable storage when
requested. This is useful for player state that changes often during a session.
Typical hot-state flow:
actor:hot:init
actor:hot:get
actor:hot:override
actor:hot:save
actor:hot:remove
Use hot state for session workflows. Use normal domain commands for direct durable CRUD operations.
Transport Layer
The transport layer exists because Arma extension calls have practical payload size limits. It provides chunked request and response handling while still routing to the same domain command groups.
Common direct command:
"forge_server" callExtension ["status", []];
Common transport path:
server addon fnc_extCall
-> transport:request:append
-> transport:invoke_stored
-> transport:response:get
Configuration
The server extension reads config.toml from the server working directory,
@forge_server/config.toml, or beside the extension DLL. When Forge Host is
used during development, the repo-root config.toml can be shared across Forge
Host, ICOM, and the extension. The extension reads the [surreal] section and
ignores the host-only sections. The current persistence section is:
[surreal]
endpoint = "127.0.0.1:8000"
namespace = "forge"
database = "main"
username = "root"
password = "root"
connect_timeout_ms = 5000
config.toml is a launch prerequisite for server owners and developers. Use
arma/server/extension/config.example.toml for an extension-only config, or
bin/host/config.example.toml for the shared host-managed config. SurrealDB must
already be running at the configured endpoint before starting a Forge-enabled
dedicated server or local multiplayer test. Clients and mission designers do not
run this configuration unless they are hosting locally, but the server they
connect to must have it in place.
Arma's own dedicated server files remain separate from Forge's TOML config.
Launch server.cfg with -config for server rules, mission rotation, passwords,
and admin settings. Launch basic.cfg with -cfg for network and performance
tuning. Forge Host exposes both paths in the Arma Server settings view and can
create them from bin/host/server.example.cfg and
bin/host/basic.example.cfg.
For install links and role-based setup guidance, see SurrealDB Setup.
Check persistence readiness before issuing commands that require storage:
"forge_server" callExtension ["status", []];
"forge_server" callExtension ["surreal:status", []];