feat: add variable name exclusion for objects#121
Conversation
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
There was a problem hiding this comment.
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.
| if (_x getVariable [QGVARMAIN(exclude), false]) exitWith { | ||
| _x setVariable [QGVARMAIN(isInitialized), true, true]; | ||
| }; |
There was a problem hiding this comment.
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:
- Ensure player units are never excluded during initialization by adding
!isPlayer _xto the exclusion checks. - For playable AI units that players slot into later, reset
isInitializedtofalsewhen 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];
};
| if (GVAR(excludeVarNameList) isNotEqualTo [] && {vehicleVarName _x in GVAR(excludeVarNameList)}) exitWith { | ||
| _x setVariable [QGVARMAIN(exclude), true, true]; | ||
| _x setVariable [QGVARMAIN(isInitialized), true, true]; | ||
| }; |
There was a problem hiding this comment.
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];
};
| if (GVAR(excludeVarNameList) isNotEqualTo [] && {vehicleVarName _x in GVAR(excludeVarNameList)}) exitWith { | ||
| _x setVariable [QGVARMAIN(exclude), true, true]; | ||
| _x setVariable [QGVARMAIN(isInitialized), true, true]; | ||
| }; |
There was a problem hiding this comment.
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];
};
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.sqfOCAP_settings_excludeVarNameFromRecordunder the existing Exclusions categoryvehicleVarNamevalues, default[]addons/recorder/fnc_init.sqfGVAR(excludeVarNameList)at initaddons/recorder/fnc_captureLoop.sqfAdds two pre-initialization checks in both the unit and vehicle capture paths, before any data is sent to the extension:
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.vehicleVarName _xagainstOCAP_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 markOCAP_main_exclude = truefor consistency with the rest of the exclusion system.How to Use
Option A — Centralized (in
description.extor server CBA settings):Option B — Per-object (in 3DEN init field):
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.