Skip to content

feat: add variable name exclusion for objects#121

Open
fank wants to merge 1 commit into
mainfrom
feat/variable-name-exclusions
Open

feat: add variable name exclusion for objects#121
fank wants to merge 1 commit into
mainfrom
feat/variable-name-exclusions

Conversation

@fank

@fank fank commented Jul 10, 2026

Copy link
Copy Markdown
Member

Summary

Adds the ability to exclude objects from OCAP recording by their editor variable name (vehicleVarName), complementing the existing classname, KindOf, and marker-prefix exclusions. This addresses a long-standing gap — mission makers previously had no way to hide specific objects from recording while keeping visible others of the same class.

Changes

Three files modified:

addons/recorder/XEH_preInit.sqf

  • Registers new CBA setting OCAP_settings_excludeVarNameFromRecord under the existing Exclusions category
  • Stringified array of vehicleVarName values, default []

addons/recorder/fnc_init.sqf

  • Parses the new setting into GVAR(excludeVarNameList) at init

addons/recorder/fnc_captureLoop.sqf

  • Adds two pre-initialization checks in both the unit and vehicle capture paths, before any data is sent to the extension:

    1. Per-object control — honors this setVariable ["OCAP_main_exclude", true, true] pre-set in an object's editor init field. Objects with this variable set before OCAP encounters them are skipped entirely.
    2. Centralized setting — checks vehicleVarName _x against OCAP_settings_excludeVarNameFromRecord. Matching objects are fully excluded.

    Both checks exit early by marking OCAP_main_isInitialized = true (which prevents OCAP from re-processing them) and, for the centralized path, also mark OCAP_main_exclude = true for consistency with the rest of the exclusion system.

How to Use

Option A — Centralized (in description.ext or server CBA settings):

OCAP_settings_excludeVarNameFromRecord = "['hideout_alpha','cache_west']";

Option B — Per-object (in 3DEN init field):

this setVariable ["OCAP_main_exclude", true, true];

Use Case

Hidden insurgency hideouts that should not appear in AAR playback until later in a campaign. Place the object in the editor with a variable name, add it to the exclude list, then reconfigure or script the removal of the exclusion when the hideout should be revealed.

Adds OCAP_settings_excludeVarNameFromRecord CBA setting and pre-initialization
checks for vehicleVarName and pre-set OCAP_main_exclude on objects.

Mission makers can now:
- Exclude objects by editor variable name via centralized setting
- Exclude objects per-object via setVariable ['OCAP_main_exclude', true]
  in the 3DEN init field

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new CBA setting to exclude specific vehicle variable names from recording, parsing this setting into a centralized list, and checking both units and vehicles against it during initialization. The review feedback highlights a critical bug where player units could be incorrectly excluded, leading to missing creation events and database errors. Additionally, the feedback points out that empty variable names could trigger unintended exclusions if the exclusion list contains an empty string, suggesting a check to ensure the variable name is not empty before performing the lookup.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +97 to +99
if (_x getVariable [QGVARMAIN(exclude), false]) exitWith {
_x setVariable [QGVARMAIN(isInitialized), true, true];
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Exiting early here for excluded units without sending the :SOLDIER:CREATE: event introduces a critical bug when players are involved.

OCAP's design forces player units to always be tracked (lines 135-139 un-exclude any unit where isPlayer _x is true). If a player unit (or a playable AI unit that a player slots into later) is excluded at initialization, it will be marked as isInitialized = true but :SOLDIER:CREATE: will never be sent. When the player is un-excluded, OCAP will start sending :SOLDIER:STATE: updates for an ID that was never created, leading to database errors or broken AAR playbacks.

To fix this:

  1. Ensure player units are never excluded during initialization by adding !isPlayer _x to the exclusion checks.
  2. For playable AI units that players slot into later, reset isInitialized to false when they are un-excluded so they can be properly initialized on the next frame.

Since lines 135-139 are outside this diff hunk, you should update them manually as follows:

private _isExcluded = _x getVariable [QGVARMAIN(exclude), false];
if (_isExcluded && {isPlayer _x}) then {
  _x setVariable [QGVARMAIN(exclude), false];
  _x setVariable [QGVARMAIN(isInitialized), false, true];
  _isExcluded = true; // Keep it excluded for this frame until initialized on the next frame
};
        if (!isPlayer _x && {_x getVariable [QGVARMAIN(exclude), false]}) exitWith {
          _x setVariable [QGVARMAIN(isInitialized), true, true];
        };

Comment on lines +101 to 104
if (GVAR(excludeVarNameList) isNotEqualTo [] && {vehicleVarName _x in GVAR(excludeVarNameList)}) exitWith {
_x setVariable [QGVARMAIN(exclude), true, true];
_x setVariable [QGVARMAIN(isInitialized), true, true];
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

If vehicleVarName _x returns "" (which is the case for almost all objects without an editor-assigned variable name), and GVAR(excludeVarNameList) contains an empty string "" (due to a user typo or empty setting element), then every single unit without a variable name will be excluded from the recording.

Additionally, calling in on an array for every unit initialization when the variable name is empty is an unnecessary performance cost.

We should check _varName isNotEqualTo "" first, and also ensure !isPlayer _x is checked to prevent player exclusion.

        private _varName = vehicleVarName _x;
        if (!isPlayer _x && {_varName isNotEqualTo "" && {GVAR(excludeVarNameList) isNotEqualTo [] && {_varName in GVAR(excludeVarNameList)}}}) exitWith {
          _x setVariable [QGVARMAIN(exclude), true, true];
          _x setVariable [QGVARMAIN(isInitialized), true, true];
        };

Comment on lines +219 to +222
if (GVAR(excludeVarNameList) isNotEqualTo [] && {vehicleVarName _x in GVAR(excludeVarNameList)}) exitWith {
_x setVariable [QGVARMAIN(exclude), true, true];
_x setVariable [QGVARMAIN(isInitialized), true, true];
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Similar to the unit loop, if vehicleVarName _x is "" and GVAR(excludeVarNameList) contains "", all vehicles without a variable name will be excluded.

Checking _varName isNotEqualTo "" first prevents this risk and avoids unnecessary array lookups.

        private _varName = vehicleVarName _x;
        if (_varName isNotEqualTo "" && {GVAR(excludeVarNameList) isNotEqualTo [] && {_varName in GVAR(excludeVarNameList)}}) exitWith {
          _x setVariable [QGVARMAIN(exclude), true, true];
          _x setVariable [QGVARMAIN(isInitialized), true, true];
        };

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant