Skip to content

fix(recorder): migrate FiredMan EH to new owner on locality transfer#118

Open
fank wants to merge 2 commits into
mainfrom
fix/firedman-locality-transfer
Open

fix(recorder): migrate FiredMan EH to new owner on locality transfer#118
fank wants to merge 2 commits into
mainfrom
fix/firedman-locality-transfer

Conversation

@fank
Copy link
Copy Markdown
Member

@fank fank commented May 13, 2026

Summary

  • Fix shots/hits not being recorded when a player slots into a pre-placed AI unit.
  • Refactor the FiredMan/HandleDamage install/remove logic into reusable code values and trigger an install on the new owner whenever the server loses locality.

Root cause

Per BIS wiki, addEventHandler "Local" only fires on machines where it was added. OCAP is server-side only, so the Local EH lives on the server. The previous logic assumed the EH would fire on both old and new owners, but in practice:

  1. Mission start: all pre-placed AI are server-local → FiredMan EH installed on server, Local EH installed on server.
  2. Player joins and slots into AI: locality transfers server → player.
  3. Server's Local EH fires with _isLocal=false → removes its own FiredMan EH.
  4. Player's machine never had a Local EH → never installs FiredMan EH.
  5. Player fires → no FiredMan EH → no :EVENT:PROJECTILE: ever reaches the extension.

This matched a user report where vehicle kills (server-side EntityKilled) and ACE3 medical events (server-local AI dying) were captured, but zero shots/hits were recorded across a 7-minute session with 10 confirmed kills.

Fix

  • Extract the install code into GVAR(ownerInstallBlock) and cleanup into GVAR(ownerRemoveBlock) to eliminate three near-duplicate copies.
  • In the server's Local EH _isLocal=false branch, after cleaning up server EHs, remoteExec the install block to owner _entity (which is the new owner at that point).
  • Update the misleading "Local EH is global (ironically)" comment to reflect actual semantics.

Delivery pattern is unchanged — install code is still shipped as an inline code block via remoteExec ["call", target], just sourced from a GVAR instead of being inlined three times. No new CfgRemoteExec whitelisting required.

Test plan

  • In-game: player slots into a pre-placed AI unit, fires several rounds — verify :EVENT:PROJECTILE: events appear in the extension log at loglevel: debug.
  • In-game: fresh player-owned unit (no AI takeover) fires — verify still works (regression check).
  • In-game: kill a player, server takes locality back — verify FiredMan EH installs on server (existing path).
  • In-game: AI hand-off between server and an HC — verify EH migrates.

When a player slotted into a pre-placed AI unit, their shots were never
recorded. Per BIS wiki, addEventHandler "Local" only fires on machines
where it was added; OCAP is server-side only, so the Local EH lives on
the server. When locality transferred from server to a client, the
server's EH fired with _isLocal=false (removing its own FiredMan EH),
but the new owner never installed one — so FiredMan never triggered
for the player.

Refactor the install/remove blocks into reusable code values and, when
the server loses locality, remoteExec the install to the new owner.
Copy link
Copy Markdown

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

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 refactors the event handler management for unit locality changes in fnc_eh_fired_server.sqf, introducing dedicated blocks for installing and removing FiredMan and HandleDamage handlers. This ensures that recording follows the unit's owner, particularly when players take control of AI. A review comment points out that the installation block is not idempotent, which could lead to duplicate event handlers if a unit's ownership changes multiple times, and suggests incorporating a check to remove existing handlers before adding new ones.

Comment thread addons/recorder/fnc_eh_fired_server.sqf
The server's Local EH cleanup only runs on the server, so a client that
previously owned a unit retains its FiredMan/HandleDamage handlers
indefinitely. If the unit later returns to that client (S→A→S→A), the
install block stacked a second EH on A and emitted duplicate
:EVENT:PROJECTILE: records on every shot.

Clear any pre-existing EH at the start of the install block.
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