Repository navigation
fix(recorder): evaluate __EVAL display names instead of recording their source - #131
Conversation
…ir source getTextRaw returns the unevaluated source of a displayName written as __EVAL(...), so recordings showed e.g. 'format ["%1 [BLUE]", getText (...)]' as an item name. Add OCAP_recorder_fnc_getConfigDisplayName as the single rule for locale-safe config names, use it at every server site, and ship it to clients for gear and Zeus module names.
|
Ratatoskr reviewed this pull request. Approved on Finished 2026-10-20 17:25 UTC. |
fank
left a comment
There was a problem hiding this comment.
APPROVE — 0 blocking findings.
Review details
Reviewed head 6e09fde00d498a6a556971057490bec091cfefe7 against base 61269ee60f9a40bbd166365d95a554b3af0a2716, including the shared helper, server callers, and client bootstrap. No concrete correctness or safety blocker found. The helper is registered before use, retains stringtable-reference fallback, and the client bootstrap supplies it before installing its consumers. The documented ASCII heuristic remains a limitation, not a language guarantee.
Checks and limitations
git diff --check 61269ee60f9a40bbd166365d95a554b3af0a2716 HEADpassed.- GitHub's
Build / buildcheck completed successfully. command -v hemtt,command -v arma3server, andcommand -v sqfvmfound no local executables. I did not run HEMTT or multiplayer regression tests.tests/README.mdrequires an Arma multiplayer mission with two connected players.- In-game evaluation of expression entries (
addons/recorder/fnc_getConfigDisplayName.sqf:56–63) and normal/JIP client installation (addons/recorder/fnc_installPlayerTrackingClients.sqf:75–81,1907) remain unverified; static review and CI do not establish these engine behaviours.
Optional, non-blocking: Add an engine-backed display-name fixture covering literal, stringtable, array, ASCII-expression and non-ASCII-expression entries, plus ordinary/JIP bootstrap checks. The existing regression scripts do not pin these new paths.
Earlier discussions: GitHub GraphQL returned no review threads (hasNextPage: false), so none required replies or resolution; resolved/still-open/skipped: 0/0/0. Authenticated reviewer: fank.
Problem
Some mods build an item's
displayNamewith a config expression, for example VTGM's per-side radio backpacks:Recordings showed the raw expression as the item's name. In the replay's unit tab, the player's backpack read:
instead of
[US] MOLLE Sturmgepak (OCP/Rajio) [BLUE], which is what the game shows.Cause. HEMTT does not evaluate
__EVALat build time. It writes the entry intoconfig.binas an expression value (rap value subtype 4), and the engine runs it only when the entry is read withgetText. OCAP deliberately reads names withgetTextRaw, so a stringtable reference never gets resolved in the recording server's language. For an expression entry,getTextRawreturns the expression's source. It does not start with$, so the recorder treated it as an English literal and stored it.The same pattern was copied across the recorder, so vehicle, magazine, explosion, static-weapon, fortification and Zeus-module names had the same bug.
Fix
OCAP_recorder_fnc_getConfigDisplayName, the one rule for a locale-safe config name. It returns""when no safe name exists, and the caller falls back to the class name.getTextequalsgetTextRaw, so nothing changes here.$STR_...:"", as before.__EVAL(...): detected becausegetTextdiffers fromgetTextRaw. The evaluated name is returned, unless it is non-ASCII, which means the expression pulled in a localized name.getTextRaw (... >> "displayName"):fnc_recordExplosion,fnc_submitStaticWeapon,fnc_trackServicing(vehicle and rearm magazine names) andfnc_trackConstructions(two places).fnc_trackTrenches: the fallback for trench classes not intrenchTypesused plaingetText, so it stored the server's localized name. It now uses the shared rule too.fnc_installPlayerTrackingClientsnow passes the compiled function as the argument of the existingremoteExec ["call", ...]bootstrap and stores it inOCAP_recorder_client_getConfigDisplayName. Gear and Zeus-module names use it, so the rule exists only once. Zeus modules still apply their stricterisEnglishTextfilter on top, as before.docs/player-detail-tracking.mdand the comments in the sampler now describe the expression case.Behaviour changes
$STR_reference now tries its default magazine's name before it falls back to the ammo class. Before, it went straight to the class name.displayName[]entry written as an array is handled at every place on the server, not only in the client gear code.Known limits
Only expression values are checked for non-ASCII characters, and that check is a heuristic:
Gewehr [BLUE]), still gets through. SQF cannot tell it apart from English. Cyrillic, Czech, Polish and similar names are caught.×,–) is rejected and falls back to the class name.These limits are documented in the function header.
Testing
hemtt check: no errors or warnings in the changed files.getTextevaluates an expression entry whilegetTextRawreturns its source. That matches the observed replay and the bytes in the builtconfig.bin, but it should be confirmed on a mission with VTGM's radio backpacks. Also check that clients and JIP clients still install the sampler with the new bootstrap argument.tests/*_regressions.sqfcover neither display names nor this path. They need a multiplayer mission, and I did not run them.