Skip to content

Manager & Events — DM.Manager

Class defined in sources/DynamicMission.lua:3330-4995 (full section, header included: 3324-4996).

DCS events listened to

Exhaustive list from the onEvent() dispatcher (:4108-4128) — no other event id is ever tested.

Event Handler Role
S_EVENT_BIRTH _handlePlayerBirth
_syncDynamicGroupToDB
Restricts the F10 regions menu to the designated player (see below); syncs any dynamically-spawned group into groupsByName, otherwise invisible to makeUnitTable()
S_EVENT_LAND _handleLanding Spawns defenses for the landing player's coalition (see Airbases)
S_EVENT_BASE_CAPTURED _handleBaseCaptured Coalition update + CLEARED status re-check (no spawn)
S_EVENT_CRASH _handleCrash Diagnostic logging + bookkeeping cleanup
S_EVENT_PILOT_DEAD _handlePilotDead Same
S_EVENT_UNIT_LOST _handleUnitLost Same

The three cleanup handlers (_handleCrash/_handlePilotDead/_handleUnitLost) converge on _cleanupUnitFromActiveGroups(), which doesn't destroy anything itself: it logs which the destroyed unit belonged to (a DM-managed region group, or a base defense group — in the latter case, an immediate purge of airbase.defenseGroups). The actual removal from region.activeGroups happens lazily, on the next runCycle(), not synchronously on the event.

Restricting the F10 regions menu to a designated player

_handlePlayerBirth() is short-circuited if DM.Config.DEBUG_MODE is active (the regions menu is then built globally for everyone).

DM.Config.DESIGNATED_PLAYER_NAME (default "") controls who has access to the F10 → DM → RG submenu (see Regions). Access follows the player's name, not a fixed slot or group — it's re-evaluated on every S_EVENT_BIRTH via DM.Manager:_handlePlayerBirth().

  • If DEBUG_MODE is active, this restriction is entirely bypassed: the regions menu is built globally for everyone.
  • Outside debug, on every player birth: immediate exit if the unit has no player name (AI) or isn't one (e.g. a static Jerrycan); otherwise the {"DM"} menu is removed from its group then, only if the player's name exactly matches DESIGNATED_PLAYER_NAME, rebuilt via _buildRegionsMenuTree() — that specific player gets the menu.
  • For any other player (or if DESIGNATED_PLAYER_NAME == ""), the {"DM"} menu is simply removed from the group, with no rebuild — no regions menu visible.
  • Rebuilt on every birth of the designated player regardless of slot or coalition, and removed from any group taken over by another player — prevents a player who inherits the designated player's old slot from accidentally keeping the menu.

With the default value (""), nobody sees this menu outside DEBUG_MODE.

Startup sequence

DM.Manager:start() runs automatically at the bottom of the file — with no guard, so the script self-initializes the moment it's loaded — in 10 steps: config validation → mission scan (rebuilding zonesByName/groupsByName, instantiating RG_* regions, scanning bases and AD_* templates) → coherence check (polygon overlaps via SAT, MG_/SZ_ pairs per tag) → bidirectional base↔region linking → residual Jerrycan cleanup → neutral base anchoring → coalition resync → initial activation → starting the schedulers, registering the event handler, building the F10 menus.

Blocking point

A polygon overlap or a missing MG_/SZ_ pair is treated as critical and stops the entire initialization — nothing else runs, DM.Manager._initialized stays false.

Schedulers

  • Proximity (30s) — always started.
  • Auto-activation (AUTO_ACTIVATION_CHECK_INTERVAL, 60s by default) — only started if TYPE_CONTROL == "TERRAIN"; self-terminates if the value changes at runtime.