FF SUITEArma 3 addons

Architecture

Load order and ownership

The rules that keep seven PBOs from turning into one tangle: what loads when, which machine decides, and which names you may not rename.

Seven PBOs, one contract. This page is the map you need before you change anything: what loads when, which machine owns which state, and how components talk without creating a dependency cycle.

1. Component map

ComponentPBO prefixRequiresOwns
FF_corex\FF\addons\coreCBAEditor categories, module bases, shared UI contracts
FF_utilsx\FF\addons\utilsCore, CBA, ACEWardrobe, circuits, faulty optics, documents, generic items, balancing, recovery, UAVs, ready room, weapon faults, terminals, power, solar
FF_cinematicx\FF\addons\cinematicCore, CBACameras, overlays, pulses, music playback and the music director
FF_cbrnx\FF\addons\cbrnCore, CBA, ACE medicalHazard simulation, filters, supplies, detector
FF_zeus_suitex\FF\addons\zeus_suiteCore, Utils, CBAFooter, FPS, look orders, volunteer service, feature dialogs
FF_spectatorx\FF\addons\spectatorCore, Cinematic, CBASpectator presets, command broker, camera driver, UI rendering, radio integration
FF_horrorx\FF\addons\horrorAll of the aboveSoul, skulls, hordes, atmosphere, scares, themed content, alias entry points

The dependency direction is one-way: feature components never depend on Horror. Horror depends on them and keeps the same entry points under its own prefix. That is what allows Utils, CBRN, Cinematic or Zeus to be used without Horror installed.

2. Lifecycle

Config

Patches, required addons, editor categories, item classes, modules, respawn template, faulty optic classes, system CfgFunctions.

PreInit

PREP() compiles every function into a global. CBA events, settings and the Zeus footer registry are installed. No gameplay starts here.

PostInit

Server loops (spawn scheduler, AI balancing, footer server state) and client bootstrap (wardrobe handlers, shield actions, FPS reporter).

Atmosphere, persistence and scare are not started by postInit. A mission executes their entry scripts. That keeps a server that merely loads the PBOs free of loops it does not use.

3. Function registration

StyleUsed byResult
PREP(name) in XEH_preInit.sqfAll component functionsFF_<component>_fnc_name global, compiled once per machine
CfgFunctions with file =Horror systems (FFATM, FFPP, FFSC)Same naming pattern, callable by remoteExec name
Alias functionsHorrorHorror-prefixed name that calls EFUNC(component,fn)

Because everything is a compiled global, a mission can call any documented function directly. Remote execution needs the function to be allowed in CfgRemoteExec; the Zeus-facing system functions already are.

4. Events

CBA events carry request/response traffic. Names are FF_<component>_<event>; Horror keeps FF_horror_* names for its own systems.

// client requests a shield application
[QGVAR(soulShieldRequest), [_body, _actor]] call CBA_fnc_serverEvent;

// server answers the owner only
[QGVAR(soulShieldResult), [_ok, _message]] call CBA_fnc_ownerEvent;

Use global-JIP events for state a later player must receive (skull registration, active flights, soul-shield results). Use public mission variables for read-mostly shared configuration; never as a high-frequency tick channel.

5. Authority table

DecisionDecided byPublished as
Shield consumedServerOwner event + corpse receipt
Circuit completedServerBroadcast object variable + animation
Arrival and horde schedulingServerJIP events and controller state
AI ownershipServerEngine group ownership + reveal event
Atmosphere mood and trackServerShared state + client playback
Scare audienceServerController logic + client binding
Reconnect snapshotServerOwner event with restore plan
Wardrobe policyServerPublic mission variable + reset event
Faulty optic conversionUnit ownerLocal loadout rewrite
CBRN exposureEach clientLocal unit variables

6. Stable names

Three names are part of the public contract and do not change:

  • FF_Horror_* item classes — mission scripts and loadouts reference them.
  • FF_horror_fnc_* public functions — mission code calls them.
  • Object state keys such as FF_horror_cbrnMinutes and FFPP_* — missions read and write them directly. They are a naming contract, not a dependency.

The name is the API and the implementation behind it is free to change: keep the entry point, change what it calls.

7. Failure philosophy

  • Validate inputs, then fail closed: an invalid circuit stays closed, a bad config value falls back to the default.
  • Every long-running sequence has a recovery path (corpse deleted, unit replaced, controller stopped, HC gone).
  • Cleanup is idempotent: UI, cameras, handlers, particles and JIP events can be cleared twice.
  • Cap the work: 32 controllers, 128 jobs, 2 AI moves per pass, 10 Hz gaze tests.