Implementation Plan
June 8, 2026 ยท View on GitHub
Last updated: 2026-06-06
This file now tracks only active repo-level work. Detailed closure narratives
live in the dedicated subsystem audits under docs/reverse-engineering/.
Historical task headings that existing parity gates still check are preserved in
the appendix as compact archival anchors instead of repeated full narratives.
Strategic goal
The long-term parity target remains the same: the reconstructed engine should,
in theory, be able to replace the retail Quake Live engine, load retail
cgamex86.dll, qagamex86.dll, and uix86.dll, present the retail main menu,
and interoperate with the retail Windows host/runtime contracts. Quake
Live-only online services remain behind QL_BUILD_ONLINE_SERVICES, default
disabled, until a documented open replacement path exists.
Current planning baseline
- Treat
AUDIT.mdanddocs/reverse-engineering/repo-wide-parity-audit-2026-04-21.mdas the current cross-subsystem truth. - Treat the 2026-04-10 engine-wide 100% report as the strict-retail Windows closure milestone, not as a whole-repo all-green claim.
- The strict-retail Windows replacement target remains 100% on the current worktree, and the current repo-wide parity estimate is 99% after the non-Windows portability lanes were closed as explicit compatibility-only containment. Remaining repo-wide uncertainty is validation freshness rather than active non-Windows source parity debt.
- The new file-by-file audit campaign now lives in
docs/reverse-engineering/source-file-parity-ledger-2026-04-22.mdanddocs/reverse-engineering/source-file-parity-audit-plan-2026-04-22.md. It tracks567source entries, seeds concrete per-file notes for the documentedRW-G01divergence owners plus the activeRW-G02gap owners, and keeps the older subsystem ledgers as inherited baselines until each file is walked again. - Top-level planning is reopened in this file because the 2026-04-21 repo-wide audit identified active gaps outside the strict-retail score.
- The older broad planning notes under
docs/parity-plan.md,docs/ui_deltas.md, anddocs/ui_followup_issues.mdare historical snapshots, not current gap ledgers. - The ownerdraw index checklists live in
docs/reverse-engineering/ui-ownerdrawtype-parity-index.mdanddocs/reverse-engineering/cg-ownerdrawtype-parity-index.md; use them to pick and close remainingsrc/ui/menudef.hownerdraw IDs.
Active work
Task A334: Pin qagame ai_team modal order and leader dispatcher wiring [COMPLETED]
Priority: High
Primary areas: references/analysis/quakelive_symbol_aliases.json,
tests/test_botlib_qagame_ai_team_modal_order_parity.py,
docs/reverse-engineering/botlib-qagame-ai-team-modal-order-mapping-2026-06-06.md
Parity estimate: before 0% -> after 100% for focused qagame
ai_team.c Obelisk/Harvester/leader/BotTeamAI alias coverage, before 88%
-> after 98% for focused source-owned modal team-order reconstruction
confidence, before 94% -> after 98% for focused
leader/chat/EA/import-wiring confidence, and overall botlib plus qagame AI
wiring confidence 98.3% -> 98.6%.
Completed work:
- Promoted both
FUN_...andsub_...aliases forBotObeliskOrders,BotHarvesterOrders,FindHumanTeamLeader, andBotTeamAIat0x10029df0..0x1002aef0. - Cross-checked the checked-in source against HLIL evidence for
defend/attack/harvest order splits, passive/aggressive caps, human leader
discovery,
whoisteamleader/iamteamleaderchat,startleadervoice emission, and the gametype-specific order dispatcher cadence. - Added a parity regression covering aliases, Ghidra function inventory, symbol-map signatures/comments, source anchors, Binary Ninja HLIL entry/flow anchors, Ghidra top-function anchors, and the configstring/AAS/chat/EA import bridge used by this band.
- Documented that the source reconstruction already matches this retail slice, so no C source edits were required in this round.
Task A333: Pin ZMQ idZMQ host lifecycle and source wiring [COMPLETED]
Priority: High
Primary areas: docs/reverse-engineering/quakelive_steam_mapping_round_420.md,
tests/test_platform_services.py,
src/code/server/sv_zmq.c
Parity estimate: before 76% -> after 95% for focused idZMQ host
lifecycle/publication/RCON wiring confidence, before 94.1% -> after 94.2%
for ZMQ-related source reconstruction confidence, and overall Quake Live
source parity 55.83% -> 55.84%.
Completed work:
- Rechecked the older retail
idZMQhost aliases from Rounds 94 through 97 against current HLIL, function inventory, and the source reconstruction. - Re-pinned the server-facing match-report/player-event wrappers, retained object methods, thin global wrappers, RCON broadcast/pump helpers, shutdown split, and peer-table ownership helpers.
- Tied the retail wrapper and string evidence back to the current
sv_zmq.c,sv_init.c,sv_main.c,sv_game.c, andcommon.ccall sites without changing C source behavior. - Documented the CZMQ/libzmq inference boundary: retail uses embedded helper
bands, while this repository keeps Quake Live's server integration source
and dynamically resolves public
zmq_*symbols for opted-in live transport.
Task A332: Pin qagame ai_team one-flag order and team dispatcher wiring [COMPLETED]
Priority: High
Primary areas: references/analysis/quakelive_symbol_aliases.json,
tests/test_botlib_qagame_ai_team_oneflag_order_parity.py,
docs/reverse-engineering/botlib-qagame-ai-team-oneflag-order-mapping-2026-06-06.md
Parity estimate: before 0% -> after 100% for focused qagame
ai_team.c dispatcher/group/1FCTF alias coverage, before 87% -> after
97% for focused source-owned one-flag and team-order reconstruction
confidence, before 94% -> after 98% for focused
Cvar/configstring/chat/EA import-wiring confidence, and overall botlib plus
qagame AI wiring confidence 98.0% -> 98.3%.
Completed work:
- Promoted both
FUN_...andsub_...aliases forBotCTFOrders,BotCreateGroup,BotTeamOrders, the fourBot1FCTFOrders_*helpers, andBot1FCTFOrdersat0x10027750..0x10029d90. - Cross-checked the checked-in source against HLIL evidence for the CTF
flag-status dispatcher, group leader follow commands, cached
sv_maxclientsteam enumeration, 1FCTF percentage splits, return/getflag voice order quirks, andneutralflagstatusdispatch. - Added a parity regression covering aliases, Ghidra function inventory,
symbol-map signatures/comments, source anchors, Binary Ninja HLIL
entry/flow anchors, Ghidra top-function anchors,
BotTeamAIgametype dispatch, and the Cvar/configstring/chat/EA import bridge used by the band. - Documented that the source reconstruction already matches this retail slice, so no C source edits were required in this round.
Task A331: Pin ZMQ option switch source-constant wiring [COMPLETED]
Priority: High
Primary areas: docs/reverse-engineering/quakelive_steam_mapping_round_419.md,
tests/test_platform_services.py,
src/code/server/sv_zmq.c
Parity estimate: before 68% -> after 93% for focused ZMQ
option-switch/source-constant linkage confidence, before 94.0% -> after
94.1% for ZMQ-related source reconstruction confidence, and overall Quake
Live source parity 55.82% -> 55.83%.
Completed work:
- Rechecked the retail
options_t::setsockopt/options_t::getsockoptswitch tables at0x40E0E0and0x40E690against the committed HLIL. - Pinned the option range, jump/lookup-table shapes,
EINVALrejection path, and the entries for ROUTER mandatory delivery (0x21), PLAIN server mode (0x2c), and ZAP domain strings (0x37). - Tied those retail option ids to the reconstructed
QL_ZMQ_*constants used by the server-owned RCON and stats socket setup insrc/code/server/sv_zmq.c. - Added a focused regression so future ZMQ edits cannot drift the source constants away from the retail option switch evidence.
Task A330: Classify ZMQ dependency ownership boundary [COMPLETED]
Priority: High
Primary areas: docs/reverse-engineering/zmq-dependency-ownership-2026-06-06.md,
tests/test_platform_services.py,
README.md
Parity estimate: before 61% -> after 92% for focused ZMQ dependency
ownership confidence, before 94.0% -> after 94.0% for ZMQ-related source
reconstruction confidence, and overall Quake Live source parity 55.82% ->
55.82%.
Completed work:
- Investigated whether writable source contains actual libzmq implementation
code or only the Quake Live server-owned
idZMQintegration. - Confirmed the only ZMQ-named source file under
src/code/issrc/code/server/sv_zmq.c, and that it dynamically resolves external libzmq symbols for opted-in online-service builds. - Documented the conclusion that no dependency should be installed under
src/libs/in this pass and nosv_zmq.ccode should be cut fromsrc/code/. - Added a regression guard against accidentally treating
src/codeas a vendored libzmq implementation space.
Task A329: Pin qagame ai_team CTF order and botlib wiring [COMPLETED]
Priority: High
Primary areas: references/analysis/quakelive_symbol_aliases.json,
tests/test_botlib_qagame_ai_team_ctf_order_parity.py,
docs/reverse-engineering/botlib-qagame-ai-team-ctf-order-mapping-2026-06-06.md
Parity estimate: before 0% -> after 100% for focused qagame
ai_team.c CTF order-band alias coverage, before 88% -> after 97% for
focused source-owned team-order reconstruction confidence, before 94% ->
after 98% for focused AAS/chat/EA import-wiring confidence, and overall
botlib plus qagame AI wiring confidence 97.6% -> 98.0%.
Completed work:
- Promoted both
FUN_...andsub_...aliases for the retail teammate counting, base travel-time sorting, CTF task-preference, team-order chat, voice-chat, and first four CTF order helpers at0x10025390..0x10026f20. - Cross-checked the source reconstruction against HLIL evidence for
sv_maxclientscaching, player configstring walks, AAS travel-time calls, task-preference name validation, defender/roamer/attacker partitioning,vsay/vtellandvosay/votellEA formatting, and theBotCTFOrdersdispatcher edges. - Added a parity regression covering aliases, Ghidra function sizes, symbol-map signatures/comments, source anchors, Binary Ninja HLIL entry/flow anchors, Ghidra decompiler anchors, and the game/server import bridge for the AAS, chat, and EA calls used by the slice.
- Documented
FUN_100269d0as a medium-high confidence mapping because HLIL reports unresolved stack usage, while the surrounding dispatcher, command-string, sort/preference, and symbol-map evidence still strongly supportBotCTFOrders_EnemyFlagNotAtBase.
Task A328: Pin ZMQ clock and thread runtime wiring [COMPLETED]
Priority: High
Primary areas: references/analysis/quakelive_symbol_aliases.json,
tests/test_platform_services.py,
docs/reverse-engineering/quakelive_steam_mapping_round_418.md
Parity estimate: before 48% -> after 93% for focused ZMQ clock/thread
runtime wiring confidence, before 93.8% -> after 94.0% for ZMQ-related
source reconstruction confidence, and overall Quake Live source parity
55.81% -> 55.82%.
Completed work:
- Rechecked the cached millisecond clock helper, Windows tick-count fallback,
thread trampoline, start wrapper, stop wrapper, and fallback lock atexit
cleanup against HLIL around
0x40B950..0x40BB30and0x52A9E0..0x52B070. - Added aliases for the address-backed clock/thread helpers that connect
socket_base_ttimeout loops,select_t,io_thread_t, andreaper_tto the retail runtime scaffolding. - Documented the
GetTickCount64resolver/fallback path while leavingsub_40B950as supporting evidence because it is not exposed as a normal Ghidra inventory row. - Added a parity regression covering alias rows, clock cache anchors, thread assertion anchors, select/io-thread/reaper callsites, and static initializer evidence for the fallback tick-count lock.
Task A327: Pin qagame ai_main lifecycle and training helper wiring [COMPLETED]
Priority: High
Primary areas: references/analysis/quakelive_symbol_aliases.json,
tests/test_botlib_qagame_ai_main_lifecycle_training_parity.py,
docs/reverse-engineering/botlib-qagame-ai-main-lifecycle-training-mapping-2026-06-06.md
Parity estimate: before 8% -> after 100% for focused qagame
ai_main.c lifecycle and training-helper alias coverage, before 92% ->
after 98% for focused source-owned lifecycle reconstruction confidence,
before 58% -> after 87% for focused retail-only training/dynamic-skill
helper mapping confidence, and overall botlib plus qagame AI execution wiring
confidence 97.1% -> 97.6%.
Completed work:
- Promoted both
FUN_...andsub_...aliases for the source-ownedBotTestAAS, interbreed, team-leader, view-angle, input translation, per-bot think, scheduling, session, setup, shutdown, reset, map-load, botlib setup, and botlib shutdown rows. - Promoted mapped training and tutorial helper aliases for
BotEntityBoundsGap,BotSetIdealViewAnglesToPoint,BotSetTrainingBotState,BotAppendDynamicSkillSample,BotUpdateDynamicSkill,BotApplyBeyondRealityTravelFlags, local/bot client selectors, training cvar helpers, and the training-state tail. - Added a parity regression covering aliases, Ghidra row sizes, symbol-map signatures/comments, reconstructed source anchors, Binary Ninja HLIL entry/flow anchors, Ghidra decompiler anchors for the larger retail-only helpers, and the botlib lifecycle, EA, chat, move, goal, weapon, entity, and user-command import wiring used by the slice.
- Documented the source-reconstruction boundary for the retail-only dynamic-skill island, where names and call sites are now pinned but exact C reconstruction remains open.
Task A326: Pin ZMQ own_t owned pointer-set lifecycle wiring [COMPLETED]
Priority: High
Primary areas: references/analysis/quakelive_symbol_aliases.json,
tests/test_platform_services.py,
docs/reverse-engineering/quakelive_steam_mapping_round_417.md
Parity estimate: before 42% -> after 94% for focused ZMQ own_t
owned pointer-set lifecycle confidence, before 93.6% -> after 93.8% for
ZMQ-related source reconstruction confidence, and overall Quake Live source
parity 55.80% -> 55.81%.
Completed work:
- Rechecked
own_tconstruction, destruction,process_own,process_term_req, andprocess_termagainst HLIL around0x40F050..0x40FAE0. - Added aliases for the pointer-node create/find/predecessor/rightmost,
subtree free, right-rotation, range-erase, and full-tree clear helpers that
back the
ownedchild set. - Preserved the Round 148 shared pointer-set insert/erase/rebalance aliases
while tying the remaining helper surface to the observed
own.cpplifecycle flow. - Documented the reconstructed container-level source shape and the inference
boundary for the inline command opcode
0xBtermination send sequence.
Task A325: Pin ZMQ object default command and poll-event assertion wiring [COMPLETED]
Priority: High
Primary areas: references/analysis/quakelive_symbol_aliases.json,
tests/test_platform_services.py,
docs/reverse-engineering/quakelive_steam_mapping_round_416.md
Parity estimate: before 35% -> after 96% for focused ZMQ object-command
default callback surface confidence, before 93.4% -> after 93.6% for
ZMQ-related source reconstruction confidence, and overall Quake Live source
parity 55.79% -> 55.80%.
Completed work:
- Rechecked
object_t,io_thread_t, andreaper_tdefault callback slots against HLIL around0x40CF60..0x40DF00. - Added aliases for io-thread/reaper
out_eventandtimer_eventassertion callbacks with their source-file-specific assertion anchors. - Added aliases for all 16 base
object_t::process_*fail-fast command handlers, matching thezmq_command_t_processopcode dispatch table and existing command send helpers. - Documented the reconstructed command vtable surface and the inference
boundary for the
process_attachslot.
Task A324: Pin qagame DMQ3 deathmatch setup and ai_main wrapper wiring [COMPLETED]
Priority: High
Primary areas: references/analysis/quakelive_symbol_aliases.json,
references/symbol-maps/qagame.json,
tests/test_botlib_qagame_ai_dmq3_deathmatch_setup_parity.py,
docs/reverse-engineering/botlib-qagame-ai-dmq3-deathmatch-setup-mapping-2026-06-06.md
Parity estimate: before 0% -> after 100% for focused qagame
deathmatch/setup and adjacent ai_main alias coverage, before 91% -> after
98% for focused source-owned deathmatch/setup/wrapper parity confidence,
before 45% -> after 82% for focused retail-only tutorial helper mapping
confidence, and overall botlib plus qagame AI execution wiring confidence
96.7% -> 97.1%.
Completed work:
- Promoted both
FUN_...andsub_...aliases for the source-ownedBotDeathmatchAI,BotSetEntityNumForGoal,BotSetupDeathmatchAI,BotAI_Print,BotAI_Trace,BotAI_GetClientState,BotClientHasNoTargetFlag,BotAI_GetEntityState, andBotAI_BotInitialChatrows. - Promoted mapped-only retail helper aliases for
BotSelectTormentTarget,BotResolveTourPoint,BotAcceptOffscreenEnemyCandidate, andBotCanSpawnTourPoint, without claiming source reconstruction for those retail-only bodies. - Corrected the
BotSetEntityNumForGoalsymbol-map comment to document the retail-preserved classname guard that skips exact classname matches and falls through for absent or non-matching classnames. - Added a parity regression covering aliases, Ghidra row sizes, symbol-map signatures/comments, source-body anchors, Binary Ninja HLIL entry/flow anchors, and the cvar, userinfo, trace, AAS/BSP, EA command, chat, stack dump, and level-item botlib wiring used by the slice.
Task A323: Pin ZMQ socket-base endpoint and pending compact-map wiring [COMPLETED]
Priority: High
Primary areas: references/analysis/quakelive_symbol_aliases.json,
tests/test_platform_services.py,
docs/reverse-engineering/quakelive_steam_mapping_round_415.md
Parity estimate: before 44% -> after 90% for focused ZMQ socket-base
endpoint and pending compact-map helper wiring, before 93.2% -> after
93.4% for ZMQ-related source reconstruction confidence, and overall Quake
Live source parity 55.78% -> 55.79%.
Completed work:
- Rechecked
socket_base_t::bind,socket_base_t::connect, andsocket_base_t::term_endpointagainst HLIL around0x408D90..0x40B360. - Added aliases for the shared
socket_base_t::add_endpointhelper and the compact endpoint/pending node creation, subtree cleanup, iterator, range erase, and rotation helpers. - Preserved the older ctx and socket-base map aliases while distinguishing the
socket-base compact layouts by their
0x30/0x31endpoint and0x2C/0x2Dpending node sentinel offsets. - Documented the inferred source reconstruction shape for endpoint registration and unresolved inproc pending-connection storage.
Task A322: Pin qagame DMQ3 activate-goal, obstacle, snapshot, and alternate-route wiring [COMPLETED]
Priority: High
Primary areas: references/analysis/quakelive_symbol_aliases.json,
tests/test_botlib_qagame_ai_dmq3_activate_obstacle_parity.py,
docs/reverse-engineering/botlib-qagame-ai-dmq3-activate-obstacle-mapping-2026-06-06.md
Parity estimate: before 80% -> after 100% for focused qagame
ai_dmq3.c activate/obstacle/alternate-route alias coverage, before 92% ->
after 98% for focused source-owned activate/obstacle/event parity confidence,
before 91% -> after 98% for focused botlib activation, route, movement,
avoid, and chat import wiring confidence, and overall botlib plus qagame AI
execution wiring confidence 96.0% -> 96.7%.
Completed work:
- Promoted the remaining retail qagame
FUN_...andsub_...names forBotCheckConsoleMessages,BotAlternateRoute,BotGetAlternateRouteGoal, andBotSetupAlternativeRouteGoals. - Added a parity regression covering the contiguous
0x1001BCD0..0x1001EE30qagame band from activate-goal builders through alternate-route setup. - Pinned the source bodies against Binary Ninja HLIL entries and flow anchors, Ghidra function sizes, symbol-map signatures, and representative botlib AAS, chat, movement, avoid, and alternate-route import wiring.
- Documented the observed facts, inferred subsystem role, import wiring, and remaining confidence limits in the reverse-engineering notes.
Task A321: Pin ZMQ ctx endpoint and pending tree helper wiring [COMPLETED]
Priority: High
Primary areas: references/analysis/quakelive_symbol_aliases.json,
tests/test_platform_services.py,
docs/reverse-engineering/quakelive_steam_mapping_round_414.md
Parity estimate: before 46% -> after 91% for focused ZMQ ctx endpoint and
pending tree helper wiring, before 93.0% -> after 93.2% for ZMQ-related
source reconstruction confidence, and overall Quake Live source parity
55.77% -> 55.78%.
Completed work:
- Rechecked the ctx endpoint and pending inproc connection map helper band
against HLIL around
0x404380..0x406820. - Added aliases for endpoint-tree find, get-or-insert, lower-bound, insertion, subtree cleanup, iterator, and rotation helpers.
- Added aliases for pending-connection tree copy, creation, insertion,
iterator, subtree cleanup, and rotation helpers, preserving the retail
0x280/0x281pending-node layout distinction from endpoint nodes. - Re-pinned the
options_taddress-mask vector copy/destruction helpers reached by the ctx endpoint payload copy path.
Task A320: Pin ZMQ ctx runtime and inproc handoff wiring [COMPLETED]
Priority: High
Primary areas: references/analysis/quakelive_symbol_aliases.json,
tests/test_platform_services.py,
docs/reverse-engineering/quakelive_steam_mapping_round_413.md
Parity estimate: before 36% -> after 93% for focused ZMQ ctx runtime and
inproc-pending wiring, before 92.8% -> after 93.0% for ZMQ-related source
reconstruction confidence, and overall Quake Live source parity
55.76% -> 55.77%.
Completed work:
- Rechecked the ctx runtime helper band around
0x403120..0x404010against socket destruction, I/O-thread selection, endpoint map cleanup, and inproc pending-connection call sites. - Added aliases for socket destruction, I/O-thread selection, endpoint-record destruction, options destruction, endpoint bulk-unregistration, and pending-connection delivery.
- Corrected two stale compiler-noise aliases:
sub_4038B0is theoptions_tcopy constructor, andsub_403BB0is the ctx pending inproc connection helper rather than an STL locale helper.
Task A319: Pin qagame DMQ3 aim, attack, and map-script bridge [COMPLETED]
Priority: High
Primary areas: src/code/game/ai_dmq3.c,
references/analysis/quakelive_symbol_aliases.json,
tests/test_botlib_qagame_ai_dmq3_aim_attack_parity.py,
docs/reverse-engineering/botlib-qagame-ai-dmq3-aim-attack-mapping-2026-06-06.md
Parity estimate: before 0% -> after 96% for focused qagame
ai_dmq3.c aim/attack alias coverage, before 88% -> after 97% for
focused source-owned aim/attack/map-script parity confidence, before 92% ->
after 97% for fire-control and prediction import wiring confidence, and
overall botlib plus adjacent qagame AI execution wiring 95% -> 96%.
Completed work:
- Mapped the retail
qagamex86.dll0x10019E00..0x1001BBE0ai_dmq3.cbridge fromBotAimAtEnemythroughBotModelMinsMaxs. - Promoted both
FUN_...andsub_...aliases for the aim controller, attack gate, map-script helper, movedir helper, and model-bounds helper. - Reconstructed the retail
BotMapScriptsfallback branch frommpq3tourney6tobeyondreality, matching HLIL and symbol-map evidence. - Added a parity gate covering aliases, Ghidra row sizes, symbol-map signatures, source-body anchors, Binary Ninja HLIL entry/flow anchors, and the predictive movement, weapon-info, visible-position, characteristic, EA attack, and EA view botlib wiring used by the slice.
Task A318: Pin ZMQ ctx constructor and endpoint-map wiring [COMPLETED]
Priority: High
Primary areas: references/analysis/quakelive_symbol_aliases.json,
tests/test_platform_services.py,
docs/reverse-engineering/quakelive_steam_mapping_round_412.md
Parity estimate: before 41% -> after 94% for focused ZMQ ctx constructor,
endpoint-map, and map-cleanup wiring, before 92.5% -> after 92.8% for ZMQ-related
source reconstruction confidence, and overall Quake Live source parity
55.75% -> 55.76%.
Completed work:
- Rechecked the
ctx_tconstructor body against the publiczmq_ctx_newwrapper, ctx magic constants, mailbox setup, map sentinels, mutex initialization, and default option writes. - Added aliases for the ctx constructor, endpoint registration/removal/lookup, endpoint/pending-connection map constructor-unwind destructors, and the endpoint/pending range-erase helpers.
- Added a static parity guard tying the constructor and cleanup aliases to
ctx.cppstrings, the existing ctx destructor, Ghidra rows, endpoint map errno behavior, map sentinel sizes, and command-mailbox teardown evidence.
Task A317: Pin qagame DMQ3 roaming, visibility, and carrier helpers [COMPLETED]
Priority: High
Primary areas: references/analysis/quakelive_symbol_aliases.json,
tests/test_botlib_qagame_ai_dmq3_visibility_parity.py,
docs/reverse-engineering/botlib-qagame-ai-dmq3-visibility-mapping-2026-06-06.md
Parity estimate: before 0% -> after 95% for focused qagame
ai_dmq3.c visibility-band alias coverage, before 90% -> after 97%
for focused source-owned visibility-band parity confidence, before 91% ->
after 96% for movement/visibility import wiring confidence, and overall
botlib plus adjacent qagame AI execution wiring 94% -> 95%.
Completed work:
- Mapped the retail
qagamex86.dll0x10017D20..0x10019D30ai_dmq3.cslice fromBotRoamGoalthroughBotEnemyCubeCarrierVisible. - Promoted both
FUN_...andsub_...aliases for the roam, attack-movement, same-team, field-of-view, entity-visibility, enemy-acquisition, flag-carrier, and cube-carrier helper rows. - Added a parity gate covering aliases, Ghidra row sizes, symbol-map signatures, source-body anchors, Binary Ninja HLIL entry/flow anchors, and the AAS contents, characteristic, move-to-goal, and move-in-direction botlib import wiring used by the slice.
Task A316: Pin ZMQ Windows err.cpp helper wiring [COMPLETED]
Priority: High
Primary areas: references/analysis/quakelive_symbol_aliases.json,
tests/test_platform_services.py,
docs/reverse-engineering/quakelive_steam_mapping_round_411.md
Parity estimate: before 34% -> after 91% for focused ZMQ Windows
err.cpp helper wiring, before 92.4% -> after 92.5% for ZMQ-related
source reconstruction confidence, and overall Quake Live source parity
55.74% -> 55.75%.
Completed work:
- Rechecked the early ZMQ Windows
err.cpphelper band against HLIL bodies, Ghidra function rows, imports, and source-file string anchors. - Added aliases for the fatal abort helper, WSA last-error string dispatch,
Win32
FormatMessageAformatter, and Winsock-to-errno mapper. - Added a static parity guard tying the helpers to public
zmq_poll, stream-engine send/recv handling, TCP listener setup, and retainederr.cppassertion lines.
Task A315: Pin ZMQ select fd-vector and pollout reset wiring [COMPLETED]
Priority: High
Primary areas: references/analysis/quakelive_symbol_aliases.json,
tests/test_platform_services.py,
docs/reverse-engineering/quakelive_steam_mapping_round_410.md
Parity estimate: before 38% -> after 92% for focused ZMQ select-poller
fd-vector and pollout reset wiring, before 92.3% -> after 92.4% for
ZMQ-related source reconstruction confidence, and overall Quake Live source
parity 55.73% -> 55.74%.
Completed work:
- Rechecked the deferred
select_tfd-entry vector helper slab left by Round 370 againstselect.cppHLIL, Ghidra rows, and the select vtable/ source-file anchors. - Added aliases for the stream-engine-facing pollout reset helper and the fd-entry vector grow/reserve/allocate/copy helpers.
- Added a static parity guard tying the aliases to add/remove fd behavior, select-loop fd-set copies, retired-slot compaction, and stream-engine output backpressure call sites.
Task A314: Pin qagame AI DMQ3 support-band mapping [COMPLETED]
Priority: High
Primary areas: references/analysis/quakelive_symbol_aliases.json,
tests/test_botlib_qagame_ai_dmq3_support_parity.py,
docs/reverse-engineering/botlib-qagame-ai-dmq3-support-mapping-2026-06-06.md,
src/code/game/ai_dmq3.c, src/code/game/g_public.h,
src/code/game/g_syscalls.c, src/code/server/sv_game.c,
src/code/server/ql_game_imports.inc
Parity estimate: before 0% -> after 95% for focused qagame ai_dmq3.c
support-band alias coverage, before 90% -> after 97% for source-owned
support-band parity confidence, before 90% -> after 96% for focused
botlib support import wiring confidence, and overall botlib plus adjacent
qagame AI execution wiring 93% -> 94%.
Completed work:
- Promoted the retail qagame
ai_dmq3.csupport-band identities over0x10015A40..0x10017CD0, covering AAS point-area helpers, client-name helpers, weapon and movement setup, inventory and battle-inventory updates, item use, observer and hazard probes, waypoints, aggression/retreat/chase, rocket-jump, persistent-powerup, camping, avoid-goal, and powerup helpers. - Added a parity gate that checks alias promotion against Ghidra rows, symbol-map names/signatures, Binary Ninja HLIL entry and flow anchors, and direct source-body anchors for every promoted helper.
- Pinned the related AAS, EA, characteristic, avoid-goal, camp-spot,
level-item, movement-state, and weapon botlib import wiring from qagame
syscall constants through native Quake Live import slots and generated
QL_G_trap_*wrappers.
Task A313: Pin ZMQ io_object default callback wiring [COMPLETED]
Priority: High
Primary areas: references/analysis/quakelive_symbol_aliases.json,
tests/test_platform_services.py,
docs/reverse-engineering/quakelive_steam_mapping_round_409.md
Parity estimate: before 45% -> after 94% for focused ZMQ io_object_t
default callback-surface mapping, before 92.2% -> after 92.3% for
ZMQ-related source reconstruction confidence, and overall Quake Live source
parity 55.72% -> 55.73%.
Completed work:
- Rechecked the deferred Round 377 assertion-only
io_object_tcallbacks against retainedio_object.cppHLIL bodies and the sharedi_poll_events/io_object_tvtable order. - Added aliases for the default
in_event,out_event, andtimer_eventfail-fast callback handlers. - Added a static parity guard tying the names to Ghidra rows, HLIL
assert(false)bodies, and reuse by REQ/session, TCP listener, and stream-engine subobject vtables.
Task A312: Pin qagame AI DMQ3 team-goal mapping [COMPLETED]
Priority: High
Primary areas: references/analysis/quakelive_symbol_aliases.json,
tests/test_botlib_qagame_ai_dmq3_team_goal_parity.py,
docs/reverse-engineering/botlib-qagame-ai-dmq3-team-goal-mapping-2026-06-06.md,
src/code/game/ai_dmq3.c, src/code/game/g_public.h,
src/code/game/g_syscalls.c, src/code/server/sv_game.c,
src/code/server/ql_game_imports.inc
Parity estimate: before 0% -> after 95% for focused qagame ai_dmq3.c
team-goal alias coverage, before 88% -> after 96% for source-owned
team-goal source parity confidence, before 90% -> after 96% for focused
botlib/AAS/EA wiring into team-goal selection, and overall botlib plus adjacent
qagame AI execution wiring 92% -> 93%.
Completed work:
- Promoted the retail qagame
ai_dmq3.cteam-goal helper identities over0x10013BE0..0x10015960, covering team predicates, ordered-task restore, refusal/status helpers, CTF/1FCTF/Obelisk/Harvester seek and retreat dispatchers, andBotTeamGoals. - Added a parity gate that checks alias promotion against Ghidra rows, symbol-map names/signatures, Binary Ninja HLIL entry and cross-call anchors, and direct source-body anchors for every promoted helper.
- Pinned the related AAS travel-time and EA action botlib import wiring from
qagame syscall constants through native Quake Live import slots and generated
QL_G_trap_*wrappers.
Task A311: Pin ZMQ message pipe queue tail wiring [COMPLETED]
Priority: High
Primary areas: references/analysis/quakelive_symbol_aliases.json,
tests/test_platform_services.py,
docs/reverse-engineering/quakelive_steam_mapping_round_408.md
Parity estimate: before 70% -> after 94% for focused ZMQ message pipe
queue tail wiring, before 92.1% -> after 92.2% for ZMQ-related source
reconstruction confidence, and overall Quake Live source parity
55.71% -> 55.72%.
Completed work:
- Rechecked the deferred
ypipe_conflate_t<msg_t,256>final vtable callback that Binary Ninja renders asoperator new[]. - Added aliases for the conflating message-pipe probe callback and the
non-deleting
ypipe_base_t<msg_t,256>destructor. - Added a static parity guard tying the aliases to Ghidra rows, HLIL lock/probe body, vtable slot order, and analysis-symbol RTTI/vtable anchors.
Task A310: Pin ZMQ endpoint container lifecycle wiring [COMPLETED]
Priority: High
Primary areas: references/analysis/quakelive_symbol_aliases.json,
tests/test_platform_services.py,
docs/reverse-engineering/quakelive_steam_mapping_round_407.md
Parity estimate: before 48% -> after 93% for focused ZMQ endpoint
container lifecycle wiring, before 91.9% -> after 92.1% for ZMQ-related
source reconstruction confidence, and overall Quake Live source parity
55.70% -> 55.71%.
Completed work:
- Rechecked the deferred endpoint lifecycle helpers against socket-base endpoint allocation, TCP protocol detection, concrete TCP address ownership, endpoint URI rendering, and session-base destructor cleanup.
- Added aliases for the endpoint container constructor/destructor at
sub_41AAE0andsub_41AB60. - Added a static parity guard tying the aliases to Ghidra rows, retained HLIL
constructor/destructor bodies, the
tcpliteral, renderer dispatch, and session cleanup evidence.
Task A309: Pin qagame AI DMNet tutorial-tail mapping [COMPLETED]
Priority: High
Primary areas: references/analysis/quakelive_symbol_aliases.json,
references/symbol-maps/qagame.json,
tests/test_botlib_qagame_ai_dmnet_tutorial_tail_parity.py,
tests/test_ctf_oneflag_retail_parity.py,
docs/reverse-engineering/botlib-qagame-ai-dmnet-tutorial-tail-mapping-2026-06-06.md,
src/code/game/ai_dmq3.c, src/code/game/ai_main.c,
src/code/game/g_cmds.c, src/code/game/g_public.h,
src/code/game/g_syscalls.c, src/code/server/sv_game.c,
src/code/server/ql_game_imports.inc
Parity estimate: before 0% -> after 94% for focused qagame tutorial-tail
alias coverage, before 85% -> after 98% for source-owned
BotCTFCarryingFlag retail predicate parity, before 87% -> after 94% for
focused training/botlib movement and EA wiring confidence, and overall botlib
plus adjacent qagame AI execution wiring 91% -> 92%.
Completed work:
- Promoted the retail-only qagame
ai_dmnet.ctutorial-tail identities over0x1000ECC0..0x10013B00, including teammate seeking, teammate leading, torment-human, fragbait lead, instagib,BotCTFCarryingFlag, andBotTeam. - Reconstructed the safe source-owned
BotCTFCarryingFlagpredicate so it accepts the retail second CTF-like gametype slot, represented in current source asGT_ATTACK_DEFEND, alongsideGT_CTF. - Added a parity gate that checks alias promotion against Ghidra rows, symbol-map names/signatures, Binary Ninja HLIL entry/call anchors, Ghidra decompile strings, source-owned helper bodies, training cvars, and botlib movement/EA import wiring.
- Documented the remaining source gap: the retail tutorial node bodies require
a future
bot_state_ttail-layout reconstruction before they can be compiled accurately intoai_dmnet.c.
Task A308: Pin ZMQ TCP address endpoint parser wiring [COMPLETED]
Priority: High
Primary areas: references/analysis/quakelive_symbol_aliases.json,
tests/test_platform_services.py,
docs/reverse-engineering/quakelive_steam_mapping_round_406.md
Parity estimate: before 57% -> after 91% for focused ZMQ TCP address
endpoint parser wiring, before 91.7% -> after 91.9% for ZMQ-related
source reconstruction confidence, and overall Quake Live source parity
55.69% -> 55.70%.
Completed work:
- Rechecked
tcp_address.cppendpoint parsing against HLIL source-file strings, promotedtcp_address_t/tcp_address_mask_tvtable symbols, Ghidra function rows, and existing listener/connecter call-site evidence. - Added 5 aliases for NIC-name resolution, default and sockaddr-backed address construction, the address destructor body, and listener-side address mask matching.
- Re-pinned existing TCP address resolve/stringify and address-mask
resolve/stringify aliases so listener
getsocknamereporting, accept filtering, and options mask parsing remain tied to retail evidence.
Task A307: Pin qagame AI DMNet seek/battle node mapping [COMPLETED]
Priority: High
Primary areas: references/analysis/quakelive_symbol_aliases.json,
tests/test_botlib_qagame_ai_dmnet_battle_parity.py,
docs/reverse-engineering/botlib-qagame-ai-dmnet-battle-node-mapping-2026-06-06.md,
src/code/game/ai_dmnet.c, src/code/game/g_public.h,
src/code/game/g_syscalls.c, src/code/server/sv_game.c,
src/code/server/ql_game_imports.inc
Parity estimate: before 50% -> after 96% for focused qagame ai_dmnet.c
seek/battle node alias coverage, before 88% -> after 96% for focused
botlib goal-stack/movement import wiring into qagame battle flow, and overall
botlib plus adjacent qagame AI execution wiring 90% -> 91%.
Completed work:
- Completed the qagame
ai_dmnet.cseek/battle decision-network alias set over0x1000C6E0..0x1000E700, filling the missingAIEnter_*aliases around the already-promoted seek and battle node functions. - Added a parity gate that checks alias promotion against Ghidra rows, symbol-map names/signatures, Binary Ninja HLIL entry/call anchors, reconstructed source anchors, and botlib goal-stack/movement import wiring.
- Documented the evidence trail and the observed qagame-to-botlib movement wiring in the dedicated reverse-engineering note for this slice.
Task A306: Pin ZMQ subscription trie/mtrie wiring [COMPLETED]
Priority: High
Primary areas: references/analysis/quakelive_symbol_aliases.json,
tests/test_platform_services.py,
docs/reverse-engineering/quakelive_steam_mapping_round_405.md
Parity estimate: before 40% -> after 88% for focused ZMQ subscription
trie/mtrie wiring, before 91.5% -> after 91.7% for ZMQ-related source
reconstruction confidence, and overall Quake Live source parity
55.68% -> 55.69%.
Completed work:
- Rechecked XPUB/XSUB subscription-prefix ownership against HLIL call sites, source-file strings, Ghidra rows, and the round-404 DIST routing aliases.
- Added 8 aliases covering
mtrie_tteardown, pipe-set destruction, node deletion, redundancy testing, XPUB mtrie-to-DIST matching,trie_tteardown, trie node deletion, and trie apply/walk behavior. - Re-pinned existing
mtrie_tadd/remove andtrie_tadd/remove aliases so prefix insertion, recursive pruning, compressed child-range maintenance, and XSUB subscription replay remain tied to retail evidence.
Task A305: Pin qagame AI DMNet goal-prelude mapping [COMPLETED]
Priority: High
Primary areas: references/analysis/quakelive_symbol_aliases.json,
tests/test_botlib_qagame_ai_dmnet_goal_parity.py,
docs/reverse-engineering/botlib-qagame-ai-dmnet-goal-prelude-mapping-2026-06-06.md,
src/code/game/ai_dmnet.c, src/code/game/g_public.h,
src/code/game/g_syscalls.c, src/code/server/sv_game.c,
src/code/server/ql_game_imports.inc
Parity estimate: before 5% -> after 96% for focused qagame ai_dmnet.c
LTG/node prelude alias coverage, before 86% -> after 95% for focused
botlib goal/movement import wiring into qagame node flow, and overall botlib
plus adjacent qagame AI execution wiring 89% -> 90%.
Completed work:
- Promoted the qagame
ai_dmnet.clong-term-goal and node-entry prelude over0x100083C0..0x1000C640, including air-goal selection, nearby-goal selection, LTG fallback, intermission/stand/respawn entry, path clearing, activate-entity seeking, and seek-NBG entry. - Added a parity gate that checks alias promotion against Ghidra rows, symbol-map names/signatures, Binary Ninja HLIL entry/call anchors, reconstructed source anchors, and botlib goal/movement import wiring.
- Documented the evidence trail and the observed qagame-to-botlib wiring in the dedicated reverse-engineering note for this slice.
Task A304: Pin ZMQ FQ/LB/DIST pipe routing helper wiring [COMPLETED]
Priority: High
Primary areas: references/analysis/quakelive_symbol_aliases.json,
tests/test_platform_services.py,
docs/reverse-engineering/quakelive_steam_mapping_round_404.md
Parity estimate: before 42% -> after 90% for focused ZMQ FQ/LB/DIST
pipe routing helper wiring, before 91.2% -> after 91.5% for ZMQ-related
source reconstruction confidence, and overall Quake Live source parity
55.67% -> 55.68%.
Completed work:
- Rechecked
fq.cpp,lb.cpp, anddist.cpphelper bodies against HLIL entry points, source-file strings, Ghidra function rows, and existingpipe_t/queue aliases. - Added 17 aliases covering fair-queue attach/activate/terminate/probe, load-balancer terminate/activate/probe, distribution attach/activate/ terminate/send/write, and the FQ/LB vector push helpers.
- Re-pinned existing
zmq_fq_t_recvpipeandzmq_lb_t_sendpipenames so the recovered routing layer remains tied to read/write vtable dispatch, multipart state handling, flush/termination behavior, andEAGAINfallbacks.
Task A303: Pin qagame AI command team-order mapping [COMPLETED]
Priority: High
Primary areas: references/analysis/quakelive_symbol_aliases.json,
tests/test_botlib_qagame_ai_cmd_parity.py,
docs/reverse-engineering/botlib-qagame-ai-cmd-team-order-mapping-2026-06-06.md,
src/code/game/ai_cmd.c, src/code/server/sv_game.c,
src/code/server/ql_game_imports.inc
Parity estimate: before 0% -> after 95% for focused qagame ai_cmd.c
team-order alias coverage, before 82% -> after 94% for focused botlib
match-parser wiring into qagame command handling, and overall botlib plus
adjacent qagame AI/chat command wiring 88% -> 89%.
Completed work:
- Promoted 39 qagame team-message and team-order identities, with both
FUN_...andsub_...aliases, across0x10004930..0x100080A0. - Cross-checked the slice against symbol-map names/signatures, Ghidra function
rows, HLIL entry/call anchors, and reconstructed
ai_cmd.csource bodies. - Added a focused parity gate for team-goal lookup, time parsing, addressed
message filtering, patrol waypoint parsing, team-order LTG transitions,
subteam/checkpoint/formation/leadership handlers, CTF status handling, and
the central
BotMatchMessagedispatcher. - Pinned the botlib match parser import wiring used by the command layer:
BOTLIB_AI_FIND_MATCHandBOTLIB_AI_MATCH_VARIABLEthrough game syscall mapping, server import initialization, and generated qagame wrappers.
Task A302: Pin ZMQ message pipe backing queue wiring [COMPLETED]
Priority: High
Primary areas: references/analysis/quakelive_symbol_aliases.json,
tests/test_platform_services.py,
docs/reverse-engineering/quakelive_steam_mapping_round_403.md
Parity estimate: before 37% -> after 89% for focused ZMQ message pipe
backing queue wiring, before 90.9% -> after 91.2% for ZMQ-related source
reconstruction confidence, and overall Quake Live source parity
55.66% -> 55.67%.
Completed work:
- Rechecked
pipe.cppqueue allocation and vtable evidence forpipepair,pipe_t, normalypipe_t<msg_t,256>, conflatingypipe_conflate_t<msg_t,256>, andyqueue<msg_t,256>. - Added 28 aliases covering conflating write/read helpers, pipe scalar and array-item destructor thunks, normal and conflating message ypipe constructors/destructors/callbacks, shared ypipe flush publishing, and message yqueue chunk allocation/destruction/push/unpush.
- Re-pinned 7 existing
pipe_towners so the recovered queue callbacks remain tied to pipepair allocation, pipe construction/destruction, read/write, rollback, and hiccup queue replacement.
Task A301: Pin qagame bot chat prologue mapping [COMPLETED]
Priority: High
Primary areas: references/analysis/quakelive_symbol_aliases.json,
tests/test_botlib_chat_parity.py,
docs/reverse-engineering/botlib-qagame-chat-prologue-mapping-2026-06-06.md,
src/code/game/ai_chat.c
Parity estimate: before 0% -> after 96% for focused qagame bot
chat/ranking prologue alias coverage, before 90% -> after 93% for focused
botlib plus qagame chat wiring confidence, and overall botlib plus adjacent
qagame AI/chat wiring 87% -> 88%.
Completed work:
- Promoted 24 qagame bot chat/ranking prologue identities, with both
FUN_...andsub_...aliases, across0x10001000..0x100033F0. - Cross-checked the slice against qagame owner metadata, imports, exports,
symbol-map names/signatures, Ghidra function rows, HLIL entry/call anchors,
and the reconstructed
ai_chat.csource bodies. - Added a focused parity gate for the active-player, ranking, opponent-name, map-title, weapon-name, visible-enemy, valid-chat-position, chat-handler, chat-time, and chat-test source/HLIL shapes.
Task A300: Pin ZMQ socket-base default virtual/interface wiring [COMPLETED]
Priority: High
Primary areas: references/analysis/quakelive_symbol_aliases.json,
tests/test_platform_services.py,
docs/reverse-engineering/quakelive_steam_mapping_round_402.md
Parity estimate: before 54% -> after 91% for focused socket_base_t
default virtual/interface wiring, before 90.7% -> after 90.9% for
ZMQ-related source reconstruction confidence, and overall Quake Live source
parity 55.65% -> 55.66%.
Completed work:
- Rechecked the shared
socket_base_tprimary vtable and thearray_item_t<0>,i_poll_events, andi_pipe_eventssubobject vtables against the retail HLIL and Ghidra function rows. - Added 17 aliases covering the socket-base scalar deleting destructor, process-destroy state transition, default unsupported xsetsockopt/xsend/xrecv callbacks, assert-false activation/timer callbacks, poll in-event command pumping, pipe-event forwarding, pipe-terminated cleanup, and subobject destructor thunks.
- Re-pinned 4 existing socket-base and pending-connection helpers so command-pump, destroyed-flag teardown, complete destruction, and pending connection erase behavior remain tied to the shared callback evidence.
Task A299: Pin ZMQ PAIR/STREAM socket-family wiring [COMPLETED]
Priority: High
Primary areas: references/analysis/quakelive_symbol_aliases.json,
tests/test_platform_services.py,
docs/reverse-engineering/quakelive_steam_mapping_round_401.md,
src/code/server/sv_zmq.c
Parity estimate: before 35% -> after 88% for focused PAIR/STREAM
socket-family wiring, before 90.4% -> after 90.7% for ZMQ-related source
reconstruction confidence, and overall Quake Live source parity
55.64% -> 55.65%.
Completed work:
- Rechecked the Quake Live Steam libzmq factory edges for PAIR (
0) and STREAM (11) against HLIL, Ghidra function rows, promoted vtable symbols, existing stream aliases, and the reconstructed server ZMQ service context. - Added 22 aliases covering PAIR constructor/destructor, singleton-pipe attach/termination, send/receive/probe callbacks, PAIR interface thunks, STREAM constructor/destructor, pipe attachment, termination, write activation, and STREAM interface thunks.
- Re-pinned 5 existing shared/STREAM aliases so identity-framed STREAM send/receive/prefetch behavior remains tied to factory-call evidence, source-file strings, vtable slots, and function rows.
Task A298: Pin ROQ cinematic continuation beyond botlib boundary [COMPLETED]
Priority: High
Primary areas: tests/test_botlib_structure_tail_cgame_boundary_parity.py,
src/code/client/cl_cin.c,
references/analysis/quakelive_symbol_aliases.json,
docs/reverse-engineering/botlib-roq-cinematic-continuation-boundary-mapping-2026-06-06.md
Parity estimate: before 68% -> after 99% for focused ROQ cinematic
continuation boundary classification, before 0% -> after 98% for direct
decodeCodeBook/RoQInterrupt source and HLIL coverage inside botlib
boundary gates, and overall botlib plus adjacent client/cinematic wiring
86% -> 87%.
Completed work:
- Extended the botlib structure-tail/cgame-boundary gate from
ROQ_GenYUVTablesthrough the adjacent retail0x004B1010..0x004B3510cinematic decode/control slab. - Pinned the promoted adjacent owners from
yuv_to_rgbanddecodeCodeBookthroughRoQInterrupt,CIN_RunCinematic,CIN_PlayCinematic, andSCR_RunCinematic. - Added direct source anchors for the large ROQ codebook and interrupt dispatch bodies, including sample-depth branches, VQ expansion calls, streamed-read loop handling, audio decode branches, quad-info dispatch, and oversized-frame guard behavior.
- Rechecked the continuation against committed Ghidra function rows, HLIL
call/constant anchors, and
cl_cin.csource ownership. - Verified that promoted aliases from the botlib support tail through this
full cinematic continuation now all have direct
test_botlib_*.pymentions.
Task A297: Pin ZMQ publication socket-family wiring [COMPLETED]
Priority: High
Primary areas: references/analysis/quakelive_symbol_aliases.json,
tests/test_platform_services.py,
docs/reverse-engineering/quakelive_steam_mapping_round_400.md,
src/code/server/sv_zmq.c
Parity estimate: before 46% -> after 89% for focused
PUB/SUB/PULL/PUSH and XPUB/XSUB socket-family wiring, before 90.0% -> after
90.4% for ZMQ-related source reconstruction confidence, and overall Quake
Live source parity 55.63% -> 55.64%.
Completed work:
- Rechecked the Quake Live Steam libzmq factory cases for PUB (
1), SUB (2), PULL (7), PUSH (8), XPUB (9), and XSUB (10) against HLIL, Ghidra function rows, vtable symbols, existing aliases, and the retained server statsQL_ZMQ_PUBsource usage. - Added 39 aliases covering PUB/SUB wrappers, PULL fair-queue receive, PUSH load-balancer send, and the XPUB/XSUB scalar/interface destructor thunks that complete their vtable coverage.
- Re-pinned 23 existing XPUB/XSUB and shared activation/output aliases so the publication pipeline remains tied to factory-call evidence, source-file strings, vtable slots, function rows, and retained stats publication code.
Task A296: Pin post-structure botlib boundary into client timing and ROQ [COMPLETED]
Priority: High
Primary areas: tests/test_botlib_structure_tail_cgame_boundary_parity.py,
src/code/client/cl_cgame.c, src/code/client/cl_cin.c,
references/analysis/quakelive_symbol_aliases.json,
docs/reverse-engineering/botlib-post-structure-client-cinematic-boundary-mapping-2026-06-06.md
Parity estimate: before 86% -> after 99% for focused post-structure
botlib/client ownership-boundary classification, before 72% -> after 99%
for focused cgame timing and ROQ cinematic helper coverage inside botlib
boundary gates, and overall botlib plus adjacent parser/client wiring
85% -> 86%.
Completed work:
- Extended the botlib structure-tail/cgame-boundary gate past
CL_GetServerCommandinto the retail0x004B0610..0x004B0F60slab. - Pinned the promoted adjacent owners:
CL_GameCommand,CL_CGameRendering,CL_AdjustServerTimeDelta,CL_FirstSnapshot,CL_SetCGameTime,RllDecodeStereoToStereo,move8_32,blit8_32,blitVQQuad32fs, andROQ_GenYUVTables. - Explicitly bounded retail
0x004B0A50as the source-modeled cgame native import integrity guard row, not as a botlib owner or promoted alias. - Rechecked source anchors in
cl_cgame.candcl_cin.cagainst the committed Quake Live HLIL and Ghidra function rows. - Verified that promoted aliases from the botlib support tail through this
adjacent boundary range now all have direct
test_botlib_*.pymentions.
Task A295: Pin ZMQ REP/router socket-family wiring [COMPLETED]
Priority: High
Primary areas: references/analysis/quakelive_symbol_aliases.json,
tests/test_platform_services.py,
docs/reverse-engineering/quakelive_steam_mapping_round_399.md,
src/code/server/sv_zmq.c
Parity estimate: before 39% -> after 88% for focused REP/router
socket-family wiring, before 89.7% -> after 90.0% for ZMQ-related source
reconstruction confidence, and overall Quake Live source parity
55.62% -> 55.63%.
Completed work:
- Rechecked the Quake Live Steam libzmq factory cases for REP (
4) and ROUTER (6) against HLIL, Ghidra function rows, vtable symbols, existing aliases, and the retained server RCONQL_ZMQ_ROUTERsource usage. - Added 20 REP/router aliases and re-pinned 4 existing ROUTER aliases covering constructor/destructor ownership, REP send/receive state gating, ROUTER pipe attachment, option handling, termination, activation, identity lookup, and multipart send/receive callbacks.
- Added a focused regression guard tying the aliases to factory-call evidence, source-file strings, vtable slots, function rows, and the retained RCON ROUTER socket construction.
Task A294: Reconstruct botlib import callback surface delete identity [COMPLETED]
Priority: High
Primary areas: src/code/server/sv_bot.c,
src/code/game/botlib.h,
tests/test_botlib_import_callback_surface_parity.py,
tests/test_botlib_server_game_bridge_parity.py,
tests/test_botlib_internal_parity.py,
tests/test_engine_cvar_retail_parity.py,
docs/reverse-engineering/botlib-import-callback-surface-mapping-2026-06-06.md
Parity estimate: before 94% -> after 99% for focused botlib import
callback surface mapping, before 85% -> after 99% for focused debug
line/polygon callback identity, and overall botlib plus related server/game
wiring 97% -> 97%.
Completed work:
- Rechecked the
SV_BotInitBotLibcallback table at retail0x004DD940against the Quake Live HLIL locals, promoted aliases, Ghidra rows,botlib_import_tfield order, and source assignment order. - Reconstructed the retail delete callback identity by assigning
botlib_import.DebugLineDeletedirectly toBotImport_DebugPolygonDelete, matching retail's sharedsub_4dd430table entry for both line and polygon delete. - Preserved the compatibility
BotImport_DebugLineDeletewrapper while keeping the runtime callback table faithful to retail pointer identity. - Added focused parity coverage for trace copying, BSP metadata callbacks, memory/hunk callbacks, filesystem callback placement, and debug line/polygon callback behavior.
- Normalized the botlib parity gates' Ghidra
functions.csvreferences to the committedreferences/reverse-engineering/ghidra/quakelive_steam/corpus while keeping alias-map lookups on the existingquakelive_steam_srpkey.
Task A293: Pin botlib debug draw native micro-slab [COMPLETED]
Priority: High
Primary areas: src/code/game/g_public.h,
src/code/game/g_syscalls.c, src/code/game/ai_main.c,
src/code/game/botlib.h, src/code/server/sv_game.c,
src/code/botlib/be_interface.c, src/code/botlib/be_ai_move.c,
tests/test_botlib_debug_draw_native_micro_slab_parity.py,
docs/reverse-engineering/botlib-debug-draw-native-micro-slab-mapping-2026-06-06.md
Parity estimate: before 72% -> after 99% for focused botlib debug
draw native micro-slab mapping, before 90% -> after 97% for focused
direct-only botlib native import classification, and overall botlib plus
qagame native import wiring 96% -> 97%.
Completed work:
- Rechecked native slots 83 and 84 against the Quake Live HLIL native import table, Ghidra row sizes, source native enum, qagame direct import wrappers, and the server native import initializer.
- Pinned the odd retail relationship where these native table slots sit
between the AAS tail and EA slab, while their botlib export offsets follow
the AI movement/weapon/genetic tail at
0x1e8and0x1ec. - Verified that the helpers are direct-native only and do not belong in
G_MapNativeImportas legacy syscall-compatible IDs. - Tied the qagame
BotTestAAScaller to the botlib AI export bodies forBotDrawDebugAreasandBotDrawAvoidSpots.
Task A292: Pin botlib AI movement/weapon native tail [COMPLETED]
Priority: High
Primary areas: src/code/game/g_public.h,
src/code/game/g_syscalls.c, src/code/server/sv_game.c,
src/code/server/ql_game_imports.inc,
tests/test_botlib_ai_movement_weapon_native_tail_parity.py,
docs/reverse-engineering/botlib-ai-movement-weapon-native-tail-mapping-2026-06-06.md
Parity estimate: before 78% -> after 99% for focused AI
movement/weapon/genetic native tail mapping, before 95% -> after 97% for
focused botlib native import table coverage, and overall botlib plus qagame
native import wiring 95% -> 96%.
Completed work:
- Rechecked native slots 166 through 184 against the Quake Live HLIL import table, Ghidra row sizes where present, source native enum, legacy syscall map, server import initializer, and generated qagame wrappers.
- Pinned the non-linear
AddAvoidSpotordering: wrapper order beforeBotMoveToGoal, retail native slot 177 afterInitMoveState, and retail trampoline address0x004e23d0. - Preserved the raw-thunk classifications for
AllocMoveStateat0x4e2500andAllocWeaponStateat0x4e25b0. - Verified the movement float ABI paths for
AddAvoidSpot,MoveInDirection, andMovementViewTarget. - Added focused parity coverage to keep botlib AI slot 184 from drifting into the adjacent Quake Live service import slab.
Task A291: Reconstruct botlib AI goal native slab float marshaling [COMPLETED]
Priority: High
Primary areas: src/code/game/g_syscalls.c,
src/code/server/ql_game_imports.inc,
tests/test_botlib_ai_goal_native_slab_parity.py,
docs/reverse-engineering/botlib-ai-goal-native-slab-mapping-2026-06-06.md
Parity estimate: before 76% -> after 99% for focused AI goal/item native
slab mapping, before 90% -> after 96% for focused botlib float
syscall/native marshaling coverage, and overall botlib plus qagame native
import wiring 94% -> 95%.
Completed work:
- Rechecked native slots 137 through 165 against the Quake Live HLIL import table, Ghidra row sizes where present, source native enum, legacy syscall map, server import initializer, and generated qagame wrappers.
- Pinned the retail native table-order differences for avoid-goal reset/remove wrappers and camp/map/level goal lookup wrappers.
- Preserved the non-row classifications for
BotInitLevelItemsat0x4e22a0and rawBotUpdateEntityItemstable address0x4e22b0. - Reconstructed
BotMutateGoalFuzzyLogicfloat argument marshaling throughPASSFLOAT(range)andQL_G_PASSFLOAT(range). - Added focused parity coverage to prevent the goal/item native slab from being reordered by legacy export offset or losing float ABI conversions.
Task A290: Reconstruct botlib AI character/chat native slots [COMPLETED]
Priority: High
Primary areas: src/code/game/g_public.h,
src/code/game/g_syscalls.c, src/code/server/sv_game.c,
src/code/server/ql_game_imports.inc,
tests/test_botlib_ai_character_chat_native_slab_parity.py,
tests/test_botlib_chat_parity.py,
tests/test_game_native_export_helper_parity.py,
docs/reverse-engineering/botlib-ai-character-chat-native-slab-mapping-2026-06-06.md
Parity estimate: before 74% -> after 99% for focused AI character/chat
native slab mapping, before 88% -> after 95% for focused botlib native
import direct-vs-compat classification, and overall botlib plus qagame native
import wiring 93% -> 94%.
Completed work:
- Rechecked native slots 110 through 136 against the Quake Live HLIL import table, Ghidra row sizes, source native enum, legacy syscall map, server import initializer, and generated qagame wrappers.
- Reconstructed
G_QL_IMPORT_BOTLIB_AI_CHAT_LENGTH = 126and mappedBOTLIB_AI_CHAT_LENGTHdirectly toQL_G_trap_BotChatLength. - Reconstructed
G_QL_IMPORT_BOTLIB_AI_STRING_CONTAINS = 129and mappedBOTLIB_AI_STRING_CONTAINSdirectly toQL_G_trap_StringContains. - Preserved the raw-thunk classification for
BotAllocChatStateat0x4e1d80instead of promoting a fake Ghidra function row. - Updated stale compatibility-only coverage and added focused parity coverage to prevent the character/chat native import slab from regressing.
Task A289: Reconstruct client SteamUserStats float descriptor lane [COMPLETED]
Priority: High
Primary areas: src/code/client/cl_main.c,
src/common/platform/platform_steamworks.c,
src/common/platform/platform_steamworks.h,
tests/steamworks_harness.c, tests/test_steamworks_harness.py,
tests/test_platform_services.py,
docs/reverse-engineering/quakelive_steam_mapping_round_383.md
Parity estimate: before 86% -> after 99% for focused client
STATS descriptor-control-flow parity, before 99% -> after 99.5%
for client SteamUserStats readback wrapper coverage, and broader
Steamworks parity remains approximately 99% because live backend values,
localized achievement metadata, and production service availability are
outside this deterministic source/harness pass.
Completed work:
- Rechecked the retained
users.statscallback descriptor walk at HLIL anchors0x0046006b,0x00460074,0x004600ef,0x00460103,0x0046010e,0x0046008d, and0x00460149. - Parsed the committed HLIL data table rooted at
data_55da98and confirmeddata_55da8c = 0x58, seven-dword rows, and all 88 shipped descriptor discriminators set to zero. - Added
QL_Steamworks_GetUserStatFloatfor the clientSteamUserStatsvtable slot0x44 / 4, plus the disabled output-clearing fallback. - Converted the retained client stat catalog into explicit
{ name, isFloat }descriptors and preserved the current catalog as integer rows. - Updated the
STATSJSON builder to retain the retail float/int branch while keeping the shipped row behavior unchanged. - Extended the executable Steamworks harness and ctypes coverage for the float readback slot, including invalid-input guards, output clearing, forwarding, failure propagation, and disabled fallback behavior.
Task A288: Pin botlib AAS native wrapper slab [COMPLETED]
Priority: High
Primary areas: src/code/game/g_public.h,
src/code/game/g_syscalls.c, src/code/server/sv_game.c,
src/code/server/ql_game_imports.inc,
tests/test_botlib_aas_native_wrapper_slab_parity.py,
docs/reverse-engineering/botlib-aas-native-wrapper-slab-mapping-2026-06-06.md
Parity estimate: before 70% -> after 98% for focused AAS native wrapper
slab mapping, before 92% -> after 94% for focused qagame botlib native
import table coverage, and overall botlib plus qagame native import wiring
92% -> 93%.
Completed work:
- Rechecked native slots 61 through 82 against the Quake Live HLIL import table, Ghidra row sizes, source native enum, legacy syscall map, server import initializer, and generated qagame wrappers.
- Pinned the retail table-order detail where
AAS_BBoxAreasandAAS_AreaInfooccupy slots 61 and 62 before the earlier-addressedAAS_EntityInfotrampoline at slot 63. - Preserved the raw-thunk classification for
AAS_Initializedat0x4e1840andAAS_Timeat0x4e1860instead of promoting fake Ghidra function rows. - Verified the wrapper marshaling details for
AAS_TimeandAAS_PredictClientMovement, including the float bit-cast andQL_G_PASSFLOAT(frametime)handoff. - Added focused parity coverage to prevent AAS native imports from being reordered by name/address or disconnected from the legacy syscall bridge.
Task A287: Extend SteamUserStats readback harness coverage [COMPLETED]
Priority: High
Primary areas: src/common/platform/platform_steamworks.c,
tests/steamworks_harness.c, tests/test_steamworks_harness.py,
tests/test_platform_services.py,
docs/reverse-engineering/quakelive_steam_mapping_round_382.md
Parity estimate: before 58% -> after 98% for focused client
SteamUserStats readback harness parity, before 96% -> after 99% for
retained users.stats readback wrapper evidence confidence, and broader
Steamworks parity remains approximately 99% because live backend values,
localized achievement metadata, and the observed-but-unwrapped float-stat lane
are outside this deterministic harness pass.
Completed work:
- Rechecked the retained
users.statscallback JSON builder at HLIL anchors0x0046008d,0x0046018e,0x004601a6, and0x004601c6. - Added deterministic mock state for user stat value, achievement state, unlock time, display attribute text, last SteamID, last stat/achievement name, last display-attribute key, call counts, and result toggles.
- Added client
SteamUserStatsharness slots for display attributes, integer stat reads, and achievement reads at0x30 / 4,0x48 / 4, and0x50 / 4. - Exported enabled/disabled harness wrappers for
QL_Steamworks_GetUserStatInt,QL_Steamworks_GetUserAchievement, andQL_Steamworks_GetAchievementDisplayAttribute. - Added ctypes and static parity coverage tying the HLIL evidence, Round 188 source reconstruction note, production wrappers, mock vtable slots, executable test, plan entry, and Round 382 note together.
Task A286: Pin native-only botlib EA action slab [COMPLETED]
Priority: High
Primary areas: src/code/game/g_public.h,
src/code/game/g_syscalls.c, src/code/game/g_local.h,
src/code/game/botlib.h, src/code/botlib/be_ea.c,
src/code/botlib/be_interface.c, src/code/server/sv_game.c,
src/code/server/ql_game_imports.inc,
tests/test_botlib_ea_native_action_slab_parity.py,
docs/reverse-engineering/botlib-ea-native-action-slab-mapping-2026-06-06.md
Parity estimate: before 78% -> after 99% for focused EA native action
slab mapping, before 84% -> after 96% for focused native-only botlib import
classification, and overall botlib plus qagame native import wiring
91% -> 92%.
Completed work:
- Rechecked native slots 85 through 109 against the Quake Live HLIL import table, Ghidra row sizes, source native enum, server import initializer, and generated qagame wrappers.
- Pinned
G_QL_IMPORT_BOTLIB_EA_WALK = 89as a direct-native-only import. - Verified that no legacy
BOTLIB_EA_WALKenum member ortrap_EA_Walkwrapper should be reconstructed ing_syscalls.c/g_local.h. - Cross-checked the
ea_export_tsource chain fromACTION_WALKthroughEA_Walk,Init_EA_Export, andQL_G_trap_EA_Walk. - Added focused parity coverage to prevent the native EA slab from being reordered by name or backfilled with a fake legacy syscall.
Task A285: Extend SteamUserStats clear/reset harness coverage [COMPLETED]
Priority: High
Primary areas: src/common/platform/platform_steamworks.c,
tests/steamworks_harness.c, tests/test_steamworks_harness.py,
tests/test_platform_services.py,
docs/reverse-engineering/quakelive_steam_mapping_round_375.md
Parity estimate: before 45% -> after 98% for focused SteamUserStats
clear/reset harness parity, before 96% -> after 99% for retained
stats_clear wrapper evidence confidence, and broader Steamworks parity
remains approximately 99% because live backend behavior is outside this
opt-in reconstruction pass.
Completed work:
- Rechecked the retained
stats_clearcommand owner at0x00460520and itsSteamUserStats()slot0x54call at0x00460531. - Added deterministic mock state for reset-call count, last
achievementsToovalue, and configurable reset result. - Added
QLR_SteamUserStats_ResetAllStatsto the mock SteamUserStats vtable at0x54 / 4and exported enabled/disabled harness wrappers forQL_Steamworks_ClearStats. - Added ctypes coverage for the pre-initialisation guard, boolean forwarding, failure propagation, and disabled-build fallback behavior.
- Added static parity coverage and
docs/reverse-engineering/quakelive_steam_mapping_round_375.mdto pin the HLIL evidence, production offset, mock vtable, executable test, and plan note together.
Task A284: Correct botlib-adjacent qagame world import slots [COMPLETED]
Priority: High
Primary areas: src/code/game/g_public.h,
src/code/game/g_syscalls.c, src/code/server/sv_game.c,
src/code/server/ql_game_imports.inc,
tests/test_botlib_qagame_world_import_slab_parity.py,
docs/reverse-engineering/botlib-qagame-world-import-slab-mapping-2026-06-06.md
Parity estimate: before 76% -> after 98% for focused qagame world/import
slab native slot parity, before 90% -> after 91% for focused
botlib-adjacent qagame import environment coverage, and overall botlib plus
related server/game wiring 90% -> 91%.
Completed work:
- Rechecked the qagame world/import native table at
0x0056CFFC..0x0056D02Cagainst Quake Live HLIL and promoted aliases. - Reconstructed direct native import slots for
G_IN_PVS_IGNORE_PORTALS,G_AREAS_CONNECTED, andG_ENTITY_CONTACT. - Corrected the native enum/server import order so slot 39 is
G_QL_IMPORT_LINKENTITYand slot 40 isG_QL_IMPORT_UNLINK_ENTITY. - Bound the recovered slots in
G_MapNativeImportandSV_InitGameImportswhile leavingEntityContactCapsuleon the legacy compatibility path. - Added focused parity coverage for aliases, Ghidra row sizes, HLIL wrapper shapes, native table order, syscall remap, qagame wrappers, and source initializer assignments.
Task A283: Extend client Steam identity and SteamUtils harness coverage [COMPLETED]
Priority: High
Primary areas: src/common/platform/platform_steamworks.c,
tests/steamworks_harness.c, tests/test_steamworks_harness.py,
tests/test_platform_services.py,
docs/reverse-engineering/quakelive_steam_mapping_round_373.md
Parity estimate: before 68% -> after 98% for focused client Steam
identity/SteamUtils harness parity, before 96% -> after 99% for bootstrap
identity/app-id wrapper evidence confidence, and broader Steamworks parity
remains approximately 99% because live backend behavior is outside this
opt-in reconstruction pass.
Completed work:
- Rechecked the retained local SteamID helper at
0x00460550, persona cvar sync helper at0x00460610, IP-country helper at0x00460690, andSteamUtils()->GetAppIDcallsites at0x00431c48and0x00460dd6. - Added deterministic mock call counters for SteamFriends persona name, SteamUser identity, SteamUtils IP country, and SteamUtils app ID.
- Exported enabled/disabled harness wrappers for persona-name, IP-country, app-id, and user-SteamID lookup.
- Added ctypes coverage for persona/country copying, app-id forwarding, SteamID low/high projection, unavailable-user failure behavior, and disabled-build output clearing.
- Added static parity coverage and
docs/reverse-engineering/quakelive_steam_mapping_round_373.mdto pin the HLIL evidence, production offsets, mock vtable, executable test, and plan note together.
Task A282: Bind and pin server/qagame botlib bridge slots [COMPLETED]
Priority: High
Primary areas: src/code/game/g_public.h,
src/code/game/g_syscalls.c, src/code/server/sv_game.c,
src/code/server/sv_bot.c,
tests/test_botlib_server_game_bridge_parity.py,
docs/reverse-engineering/botlib-server-game-bridge-mapping-2026-06-06.md
Parity estimate: before 72% -> after 100% for focused server/qagame
botlib bridge alias coverage, before 82% -> after 98% for focused native
qagame botlib import-slot source parity, and focused botlib plus server/game
wiring 89% -> 90%.
Completed work:
- Cross-checked the promoted
SV_Bot*,BotImport_*, andQL_G_trap_Bot*aliases against the committed Ghidra row sizes and Quake Live HLIL. - Reconstructed native qagame import slots 44, 47, and 48 as
G_QL_IMPORT_BOT_FREE_CLIENT,G_QL_IMPORT_DEBUG_POLYGON_CREATE, andG_QL_IMPORT_DEBUG_POLYGON_DELETE. - Routed
G_BOT_FREE_CLIENT,G_DEBUG_POLYGON_CREATE, andG_DEBUG_POLYGON_DELETEthroughG_MapNativeImportandSV_InitGameProgs. - Added focused source/HLIL/table coverage for the server bot lifecycle, botlib setup/shutdown, reliable command consumption, snapshot entity lookup, and qagame native import table.
- Added a dedicated mapping note and a range scan requiring direct
test_botlib_*.pymentions for the promoted bridge aliases.
Task A281: Extend SteamFriends enumeration harness coverage [COMPLETED]
Priority: High
Primary areas: src/common/platform/platform_steamworks.c,
tests/steamworks_harness.c, tests/test_steamworks_harness.py,
tests/test_platform_services.py,
docs/reverse-engineering/quakelive_steam_mapping_round_372.md
Parity estimate: before 72% -> after 98% for focused SteamFriends
friend-list harness parity, before 98% -> after 99% for retained browser
friend-summary wrapper evidence confidence, and broader Steamworks parity
remains approximately 99% because live backend behavior is outside this
opt-in reconstruction pass.
Completed work:
- Rechecked the retained
GetFriendListHLIL block at0x0043355dthrough0x00433a00, confirming SteamFriends slots0x0c,0x10,0x1c,0x18,0x14,0x2c,0xb4, and0x20. - Added deterministic SteamFriends mock enumeration state plus
GetFriendCountandGetFriendByIndexvtable slots at0x0c / 4and0x10 / 4. - Exported enabled/disabled harness wrappers for friend count, by-index identity lookup, friend summary, and persona-name lookup.
- Added ctypes coverage for flag forwarding, SteamID projection, invalid-index clearing, persona-name copying, full friend-summary projection, and offline fallback behavior.
- Added static parity coverage and
docs/reverse-engineering/quakelive_steam_mapping_round_372.mdto pin the HLIL evidence, production offsets, mock vtable, executable test, and plan note together.
Task A280: Split Freeze winning-team thaw respawn path [COMPLETED]
Priority: High
Primary areas: src/code/game/g_active.c,
tests/test_game_active_pmove_wiring_parity.py,
tests/test_game_round_controller_helper_parity.py,
docs/reverse-engineering/freeze-tag-winning-thaw-respawn-mapping-2026-06-06.md,
docs/reverse-engineering/freeze-tag-mapping-2026-06-06.md,
docs/reverse-engineering/qagame-mapping.md
Parity estimate: before 55% -> after 96% for the focused configured
winning-team thaw respawn lane. The broader Freeze thaw-respawn tail moves
approximately 88% -> 94%, while broader Freeze Tag gametype wiring moves
approximately 95% -> 96%.
Completed work:
- Rechecked
FUN_1004C1B0/Freeze_RoundStateTransitionin the committed qagame Ghidra corpus and pinned thepm_type == PM_FREEZEbranch that emitsEV_THAW_PLAYER, writesPM_NORMAL, and tailcallsClientSpawn. - Added
G_FreezeRespawnThawedWinnering_active.cto mirror that direct round-controller thaw visual and respawn handoff. - Routed
G_FreezeThawWinningPlayersthrough the new helper instead ofG_FreezeThawClient, keeping winning-team thaw distinct from assisted, admin, and auto-thaw paths. - Added focused source/evidence tests for the direct helper and updated Freeze round-controller parity coverage.
- Added a dedicated mapping note and updated the umbrella Freeze/qagame maps.
Task A279: Pin botlib-adjacent native cgame import slab [COMPLETED]
Priority: High
Primary areas: src/code/client/cl_cgame.c,
src/code/cgame/cg_public.h,
references/analysis/quakelive_symbol_aliases.json,
tests/test_botlib_cgame_native_import_slab_parity.py,
docs/reverse-engineering/botlib-cgame-native-import-slab-mapping-2026-06-06.md
Parity estimate: before 45% -> after 100% for focused native cgame
import-slab alias coverage, before 78% -> after 97% for focused
import-table source initializer coverage, and focused botlib plus cgame-boundary
related wiring 88% -> 89%.
Completed work:
- Widened the botlib-related alias/test scan to the native cgame slab at
0x004AF820..0x004B0500. - Pinned all promoted aliases in that range against
quakelive_symbol_aliases.jsonand Ghidra row sizes where rows exist. - Added HLIL wrapper-shape anchors for command, collision-model, sound, renderer, advertisement bridge, snapshot/input, parser, cinematic, social, avatar, and adjacent lifecycle owners.
- Cross-checked
CG_QL_IMPORT_COUNT = 128and the reconstructedCL_InitCGameImportssource initializer assignments. - Added a final scan gate confirming no promoted names in this slab remain
without direct
test_botlib_*.pycoverage; reserved retail-only rows remain fail-closed rather than overpromoted.
Task A278: Close botlib parser-tail promoted alias coverage [COMPLETED]
Priority: High
Primary areas: src/code/botlib/l_precomp.c,
src/code/botlib/l_script.c, src/code/botlib/l_script.h,
references/analysis/quakelive_symbol_aliases.json,
tests/test_botlib_parser_tail_coverage_parity.py,
docs/reverse-engineering/botlib-parser-tail-coverage-mapping-2026-06-06.md
Parity estimate: before 82% -> after 100% for focused parser-tail
promoted-alias test coverage, before 78% -> after 97% for focused
PC_EvaluateTokens source-shape coverage, before 74% -> after 96% for
focused l_script.c escape/number/expect-type source-shape coverage, and
overall botlib parser/support static mapping 88% -> 89%.
Completed work:
- Widened the botlib alias/test scan to
0x004A83C0..0x004AF820and isolated the four remaining promoted parser-tail aliases without direct botlib test mentions:PC_EvaluateTokens,PS_ReadEscapeCharacter,PS_ReadNumber, andPS_ExpectTokenType. - Pinned those helpers against
quakelive_symbol_aliases.json,functions.csv, HLIL function headers, and retail callsites in thequakelive_steam.exepart03/part04 HLIL split. - Cross-checked reconstructed source shape for the precompiler expression evaluator, script escape decoder, numeric token scanner, and token-type validator.
- Added a final support-tail scan gate confirming no aliases in this botlib
parser/support band remain without a direct
test_botlib_*.pymention. - Added a focused mapping note; no C source body changes or alias changes were justified.
Task A277: Extend SteamFriends voice-speaking wrapper coverage [COMPLETED]
Priority: High
Primary areas: tests/steamworks_harness.c,
tests/test_steamworks_harness.py, tests/test_platform_services.py,
docs/reverse-engineering/quakelive_steam_mapping_round_368.md,
docs/plans/steamworks-parity-plan.md
Parity estimate: before 60% -> after 97% for focused SteamFriends
voice-speaking wrapper harness parity, before 98% -> after 99% for
retained client voice command wrapper evidence confidence, and broader
Steamworks parity remains approximately 99% because live Steam backend
behavior and modern networking replacement work remain outside this opt-in
reconstruction pass.
Completed work:
- Rechecked the retained SteamFriends voice-speaking evidence at
0x00460441and0x004604dc. - Added mock state and a
SteamFriendsvtable slot at0x6c / 4forSetInGameVoiceSpeaking. - Exported stable enabled and disabled harness wrappers for
QL_Steamworks_SetInGameVoiceSpeaking. - Added ctypes coverage for SteamID word-combination, speaking-on/off forwarding, call counts, and the offline fallback contract.
- Added static parity coverage tying the source wrapper slot, mock vtable, executable coverage, HLIL evidence, and round 368 mapping note together.
Task A276: Close residual promoted botlib alias test coverage [COMPLETED]
Priority: High
Primary areas: src/code/botlib/be_aas_cluster.c,
src/code/botlib/be_aas_debug.c, src/code/botlib/be_ai_chat.c,
references/analysis/quakelive_symbol_aliases.json,
tests/test_botlib_residual_promoted_alias_coverage.py,
docs/reverse-engineering/botlib-residual-promoted-alias-coverage-2026-06-06.md
Parity estimate: before 70% -> after 100% for focused residual
promoted-alias test coverage, before 82% -> after 96% for focused AAS
cluster/debug residual source-shape coverage, before 84% -> after 97% for
focused chat match-piece and integrity-tail source-shape coverage, and overall
botlib static mapping/test coverage 87% -> 88%.
Completed work:
- Rescanned the promoted core botlib alias band from
0x004829C0through0x004A83C0and isolated the five remaining direct test-mention gaps:AAS_CheckAreaForPossiblePortals,AAS_ShowFacePolygon,BotFreeMatchPieces,BotCheckInitialChatIntegrety, andBotCheckReplyChatIntegrety. - Pinned those helpers against
quakelive_symbol_aliases.json,functions.csv, HLIL function headers, and their retail callsites inquakelive_steam.exe_hlil_part03.txt. - Cross-checked the reconstructed source shape for cluster portal candidate detection, debug face polygon drawing, chat match-piece cleanup, and the initial/reply chat integrity walkers.
- Added a final promoted-core botlib scan gate confirming no aliases in this
band remain without a direct
test_botlib_*.pymention. - Added a focused mapping note; no C source body changes or alias changes were justified.
Task A275: Extend SteamUser voice wrapper harness coverage [COMPLETED]
Priority: High
Primary areas: tests/steamworks_harness.c,
tests/test_steamworks_harness.py, tests/test_platform_services.py,
docs/reverse-engineering/quakelive_steam_mapping_round_367.md,
docs/plans/steamworks-parity-plan.md
Parity estimate: before 72% -> after 97% for focused SteamUser voice
wrapper harness parity, before 96% -> after 98% for client Steam voice
transport evidence confidence, and broader Steamworks parity remains
approximately 99% because live Steam microphone/backend behavior and modern
networking replacement work remain outside this opt-in reconstruction pass.
Completed work:
- Rechecked the retained SteamUser voice slot evidence at
0x0046044c,0x00460459,0x004604b1,0x00460d4b, and0x00461b07. - Added deterministic harness mock state and
SteamUservtable slots for start, stop, compressed voice, decompression, and optimal sample rate. - Exported stable enabled and disabled harness wrappers for the production Steam voice API family.
- Added ctypes coverage for payload projection, output-size failure zeroing, compressed/uncompressed flags, sample-rate forwarding, call counts, and the offline fallback contract.
- Added static parity coverage tying the source wrapper slots, mock vtable, harness coverage, HLIL evidence, and round 367 mapping note together.
Task A274: Pin late botlib movement support mapping [COMPLETED]
Priority: High
Primary areas: src/code/botlib/be_aas_move.c,
src/code/botlib/be_aas_reach.c, src/code/botlib/be_ai_move.c,
references/analysis/quakelive_symbol_aliases.json,
tests/test_botlib_movement_late_support_parity.py,
docs/reverse-engineering/botlib-movement-late-support-mapping-2026-06-06.md
Parity estimate: before 68% -> after 96% for focused late AAS
movement/support mapping, before 72% -> after 96% for focused late travel
dispatch coverage, and overall botlib plus movement/reachability wiring
86% -> 87%.
Completed work:
- Recomputed the botlib row coverage and confirmed the direct core remains
closed except for the documented libjpeg false leads and folded
0x00486F40weapon-jump thunk. - Identified promoted movement/reachability aliases that lacked focused parity-test coverage.
- Pinned
AAS_DropToFloor,AAS_AgainstLadder,AAS_OnGround,AAS_ApplyFriction,AAS_ClipToBBox,AAS_GetJumpPadInfo,AAS_Reachability_EqualFloorHeight, andAAS_FindFaceReachabilitiesagainst aliases, Ghidra rows, HLIL anchors, and source shape. - Pinned the late travel handlers
BotTravel_Elevator,BotTravel_FuncBobbing,BotFinishTravel_WeaponJump,BotTravel_JumpPad,BotFinishTravel_JumpPad,BotReachabilityTime, andBotMoveInGoalArea, plus theirBotMoveToGoaldispatch wiring. - Added a focused parity gate and mapping note; no C source body changes or alias changes were justified.
Task A273: Extend legacy Steam P2P read-boundary coverage [COMPLETED]
Priority: High
Primary areas: tests/test_steamworks_harness.py,
tests/test_platform_services.py,
docs/reverse-engineering/quakelive_steam_mapping_round_366.md,
docs/plans/steamworks-parity-plan.md
Parity estimate: before 96% -> after 98% for focused legacy P2P
read-boundary harness parity, before 98% -> after 98.5% for legacy Steam
P2P wrapper evidence confidence, and broader Steamworks parity remains
approximately 99% with live backend behavior and modern networking
replacement design still outside this opt-in reconstruction pass.
Completed work:
- Rechecked the retained
SteamNetworkingandSteamGameServerNetworkingavailability/read slot evidence in the retail HLIL and existing Steamworks mapping rounds. - Extended the client P2P harness path so a staged packet rejected by a too-small read buffer clears stale output size and remote SteamID values.
- Extended the server P2P harness path with the matching too-small buffer rejection coverage.
- Added static parity coverage for import names, client/server vtable slots, mock read-output clearing, and the round 366 evidence note.
- Left production Steamworks wrappers unchanged because this pass proved local harness boundary behavior rather than a new retail slot or live SDK edge.
Task A272: Close botlib-adjacent cgame shutdown import boundary [COMPLETED]
Priority: High
Primary areas: src/code/client/cl_cgame.c, src/code/client/cl_main.c,
src/code/client/client.h, src/code/qcommon/common.c,
src/code/cgame/cg_public.h, references/analysis/quakelive_symbol_aliases.json,
tests/test_botlib_cgame_shutdown_import_boundary_parity.py,
docs/reverse-engineering/botlib-cgame-shutdown-import-boundary-mapping-2026-06-06.md
Parity estimate: before 70% -> after 98% for focused cgame shutdown owner
mapping, before 80% -> after 92% for adjacent cgame native residual import
classification, and overall botlib plus related parser/import/lifecycle wiring
85% -> 86%.
Completed work:
- Rechecked
0x004AF820..0x004B0500across HLIL, Ghidrafunctions.csv, source lifecycle owners, and native cgame import wiring. - Promoted
0x004AFBF0 -> CL_ShutdownCGame, matching the sourceKEYCATCH_CGAME,CG_SHUTDOWN,VM_Free, andcgvm = NULLlifecycle sequence. - Bounded the remaining unaliased cgame-native import rows at
0x004AFFC0,0x004B00C0, and0x004B0370as residual table trampolines whose exact public meanings remain weaker than their slot neighborhoods. - Confirmed the current source keeps the unresolved retail-only slots behind
QL_CG_trap_RetailReservedImport, preserving fail-closed behavior instead of inventing live service or renderer behavior. - Added a focused parity gate and mapping note for the botlib-adjacent cgame shutdown/import boundary; no C source body changes were justified.
Task A271: Extend Steam UGC call-result failure projection coverage [COMPLETED]
Priority: High
Primary areas: tests/steamworks_harness.c,
tests/test_steamworks_harness.py, tests/test_platform_services.py,
docs/reverse-engineering/quakelive_steam_mapping_round_364.md,
docs/plans/steamworks-parity-plan.md
Parity estimate: before 58% -> after 96% for focused UGC call-result
failure projection coverage, before 94% -> after 98% for combined UGC
query callback pump projection, and broader Steamworks parity remains
approximately 99% because live backend timing, workshop availability, and
the raw filter semantic remain intentionally bounded.
Completed work:
- Rechecked the retained
SteamUGCcreate/send query slots and theSteamUGCQueryCompleted_tcall-result owner. - Added a harness queue helper for UGC call-result payloads with explicit
ioFailureand payload-presence controls. - Added executable coverage for raw failed results,
ioFailure, no-payload failure, and no-payload non-IO failure projections. - Pinned call-handle preservation and zeroed no-payload event projection.
- Added static dispatcher assertions for the mapped call-result fields and failure branches.
Task A270: Close botlib structure-tail and cgame boundary mapping [COMPLETED]
Priority: High
Primary areas: src/code/botlib/l_struct.c, src/code/client/cl_cgame.c,
src/code/client/ql_cgame_imports.inc, src/code/cgame/cg_syscalls.c,
references/analysis/quakelive_symbol_aliases.json,
tests/test_botlib_structure_tail_cgame_boundary_parity.py,
docs/reverse-engineering/botlib-structure-tail-cgame-boundary-mapping-2026-06-06.md
Parity estimate: before 78% -> after 98% for focused botlib
structure-tail boundary classification, before 72% -> after 97% for
adjacent cgame snapshot/configstring owner naming, and overall botlib plus
related parser/import wiring 84% -> 85%.
Completed work:
- Rechecked
0x004AE830..0x004AF820across HLIL, Ghidrafunctions.csv, botlib source, and client/cgame import wiring. - Promoted
0x004AF570 -> CL_GetSnapshotand0x004AF690 -> CL_ConfigstringModified, separating true client owners from the existing native cgame import wrappers. - Confirmed
ReadStructureremains the final promoted botlib structure-reader owner in this seam. - Classified
ReadChar,ReadString,WriteIndent,WriteFloat,WriteStructWithIndent, andWriteStructureas source-visible but unpromoted in this retail address band. - Added a focused parity gate and mapping note for the structure-tail to cgame-import boundary; no C source body changes were justified.
Task A269: Extend Steam UGC query result readback coverage [COMPLETED]
Priority: High
Primary areas: tests/steamworks_harness.c,
tests/test_steamworks_harness.py,
docs/reverse-engineering/quakelive_steam_mapping_round_363.md,
docs/plans/steamworks-parity-plan.md
Parity estimate: before 55% -> after 94% for focused UGC query
result/preview/release harness coverage, before 96% -> after 98% for
combined UGC query wrapper and call-result projection, and broader Steamworks
parity remains approximately 99% because live backend timing, workshop
availability, and the raw filter semantic remain intentionally bounded.
Completed work:
- Rechecked the retained
SteamUGCquery/readback HLIL slots at0x00460DF3,0x00460E04,0x0045FD88, and0x0045FDAA. - Extended the Steamworks harness with mocked
GetQueryUGCResult,GetQueryUGCPreviewURL, andReleaseQueryUGCRequestvtable slots. - Added mock state for published-file ID, title, description, preview URL, result/preview success flags, query handles, and row indexes.
- Exported enabled and disabled harness wrappers for the retained UGC query readback/release surface.
- Added ctypes coverage for success, release, failure zeroing, and disabled offline fallback behavior.
Task A268: Promote botlib CRC and libvar runtime owners [COMPLETED]
Priority: High
Primary areas: src/code/botlib/l_crc.c, src/code/botlib/l_libvar.c,
src/code/botlib/be_aas_route.c,
references/analysis/quakelive_symbol_aliases.json,
tests/test_botlib_crc_libvar_alias_closure_parity.py,
docs/reverse-engineering/botlib-crc-libvar-alias-closure-2026-06-06.md
Parity estimate: before 76% -> after 99% for focused CRC/libvar alias
ownership, before 88% -> after 98% for route-cache CRC owner mapping, and
overall botlib support/runtime mapping 83% -> 84%.
Completed work:
- Rechecked the unpromoted
0x004A84B0..0x004A8790support-runtime block immediately afterGetBotLibAPI. - Promoted
CRC_ProcessStringand nine libvar runtime helpers in the retail symbol-alias map. - Captured
LibVarGetandLibVarDeAllocas source-visible readability helpers that retail folded into emitted callers, so they remain intentionally unpromoted. - Tied the CRC helper to AAS route-cache area and cluster CRC write/read wiring.
- Added a focused regression gate and mapping note; no C source body changes were justified for this slice.
Task A267: Close WebUI server-browser retained refresh parity [COMPLETED]
Priority: High
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py, tests/test_netcode_parity_manifest.py,
docs/reverse-engineering/steam-retail-server-browser-appid-interop-2026-06-06.md
Parity estimate: before 96% -> after 100% for the focused WebUI
server-browser list/refresh support lane. Broader Steam server-browser parity
remains approximately 99% because live Steam backend timing and
server-side Steam GameServer public-app publication still require opt-in
runtime validation.
Completed work:
- Rechecked the retained WebUI
RequestServers,RefreshList, list-response, list-failure, and refresh-complete HLIL againstquakelive_steam.exe. - Confirmed retail
RefreshListonly refreshes the retainedISteamMatchmakingServersquery handle and does not publish a newservers.refresh.startevent or rearm browser active/timeout state. - Removed the SRP-only active-refresh gate from native list response/failure callbacks so retained-handle refresh rows publish like retail rows.
- Kept native timeout protection for SRP's frame-driven initial request path
while allowing callback-driven
RefreshCompleteto publish the retailservers.refresh.endevent after retained-handle refreshes. - Re-audited the SRP-to-retail publication side and confirmed the existing
Steam GameServer bootstrap/state path mirrors retail product, game-dir,
identity, metadata, and heartbeat publication; public-retail app identity
remains a runtime Steam context requirement because retail has no source-side
app-id argument in
SteamGameServer_Init. - Added static parity gates and mapping notes for the retained refresh callback semantics.
Task A266: Extend Steam GameServer callback pump coverage [COMPLETED]
Priority: High
Primary areas: tests/steamworks_harness.c,
tests/test_steamworks_harness.py, tests/test_platform_services.py,
docs/reverse-engineering/quakelive_steam_mapping_round_360.md,
docs/plans/steamworks-parity-plan.md
Parity estimate: before 63% -> after 97% for the focused Steam
GameServer callback pump coverage lane. Steam GameServer callback registration
plus payload projection moves approximately 92% -> 98%, while broader
Steamworks parity remains approximately 99% because live backend connection
timing, auth policy, VAC behavior, and transport behavior remain intentionally
bounded behind opt-in online services.
Completed work:
- Rechecked
SteamServerCallbacks_Init(0x00466DB0) against the mapping report, promoted server callback aliases, and importedSteamServerCallbacksvtables in the Ghidra symbols corpus. - Confirmed the platform layer already prepares retained callback objects for
SteamServersConnected_t,SteamServerConnectFailure_t,SteamServersDisconnected_t,ValidateAuthTicketResponse_t, server-sideP2PSessionRequest_t,GSStatsReceived_t, andGSStatsStored_t. - Extended the Steamworks harness with retained targets for the four server callbacks that were not previously executable-test-backed.
- Added queue helpers and ctypes coverage proving those payloads cross
QL_Steamworks_RunServerCallbacks, including result, retry, and SteamID projection. - Tightened static parity coverage for all seven server callback IDs, object preparations, object registrations, and unregister calls.
Task A265: Reconstruct Freeze Tag thaw respawn tail [COMPLETED]
Priority: High
Primary areas: src/code/game/g_freeze.c, src/code/game/g_combat.c,
src/code/game/g_local.h, tests/test_game_active_pmove_wiring_parity.py,
tests/test_cgame_event_transport_parity.py,
docs/reverse-engineering/freeze-tag-thaw-respawn-tail-mapping-2026-06-06.md
Parity estimate: before 38% -> after 88% for the focused Freeze
EV_THAW_PLAYER / PM_NORMAL / ClientSpawn respawn tail. The broader
Freeze thaw-completion event lane moves approximately 86% -> 93%, while
broader Freeze Tag gametype wiring moves approximately 94% -> 95%.
Completed work:
- Rechecked
FUN_1004CD40/G_FreezeClientEndFrameand confirmed assisted thaw falls intoFUN_10046d80after helper reward, obituary, and team-sound publication. - Rechecked
FUN_1004C1B0/Freeze_RoundStateTransitionand pinned the independent winning-team thaw sequence:EV_THAW_PLAYER,PM_NORMAL, thenClientSpawn. - Reconstructed the Freeze marker branch in
GibEntity: the normalEV_GIB_PLAYERevent remains first, then marked frozen clients emitEV_THAW_PLAYER, restorePM_NORMAL, and rerunClientSpawn. - Split helper assist credit into
G_FreezeAwardThawAssistso score, assist medal, and centerprint side effects survive before the thawed client state is rebuilt throughClientSpawn. - Added focused parity tests and mapping notes for the retail thaw respawn tail, while retaining the old direct thaw visual only as a stale-marker fallback.
Task A264: Close botlib residual address and native import wiring audit [COMPLETED]
Priority: High
Primary areas: references/analysis/quakelive_symbol_aliases.json,
references/reverse-engineering/ghidra/quakelive_steam/functions.csv,
src/code/botlib/be_interface.c, src/code/game/g_syscalls.c,
src/code/server/sv_game.c, src/code/server/ql_game_imports.inc,
tests/test_botlib_residual_gap_and_wiring_parity.py,
docs/reverse-engineering/botlib-residual-gap-and-wiring-audit-2026-06-06.md
Parity estimate: before 70% -> after 98% for focused residual botlib
address classification and before 90% -> after 98% for native botlib
import bridge closure. Overall botlib plus related wiring moves approximately
82% -> 83% because this round locks down classification and bridge
consistency without changing source behavior.
Completed work:
- Recomputed the
0x00482000..0x004A8400botlib-neighborhood function scan against the nestedquakelive_steamsymbol alias map. - Captured the exact residual set as fifteen pre-
AAS_Tracelibjpeg memory-manager false-lead rows plus the compiler-foldedsub_486F40weapon-jump thunk. - Added a regression gate proving the neighborhood has
417Ghidra rows,401row-backed promoted aliases,407promoted aliases in the band overall, and only the documented residual addresses left. - Added a bridge-wide native import check proving all
134G_QL_IMPORT_BOTLIB_*slots are registered and backed by generated/localQL_G_trap_*wrappers, with the three intentional direct-native slots called out explicitly. - Documented why no new source reconstruction or alias promotion is justified for this residual pass.
Task A263: Extend main Steam client callback pump coverage [COMPLETED]
Priority: High
Primary areas: tests/steamworks_harness.c,
tests/test_steamworks_harness.py, tests/test_platform_services.py,
docs/reverse-engineering/quakelive_steam_mapping_round_359.md,
docs/plans/steamworks-parity-plan.md
Parity estimate: before 62% -> after 97% for the focused main client
callback pump coverage lane. Steam client callback registration plus payload
projection moves approximately 91% -> 98%, while broader Steamworks parity
remains approximately 99% because live Steam backend timing, stats
validity, presence cadence, and P2P networking behavior remain intentionally
bounded behind opt-in online services.
Completed work:
- Rechecked
SteamCallbacks_Init(0x004613A0) against the mapping report, promoted callback handler aliases, and importedSteamCallbackscallback/call-result vtables in the Ghidra symbols corpus. - Confirmed the platform layer already prepares the retained client callback objects for rich presence, user stats, persona state, client P2P session, game-server change, friend rich presence, and UGC query completion.
- Extended the Steamworks harness with retained callback targets for the five normal client callbacks that were not previously executable-test-backed.
- Added queue helpers and ctypes coverage proving those payloads cross
QL_Steamworks_RunCallbacks, including friend-summary enrichment and server/password string projection. - Tightened static parity coverage for all client callback IDs, normal callback registrations, and the UGC call-result preparation.
Task A262: Restore public retail Steam server-browser AppID interop [COMPLETED]
Priority: High
Primary areas: src/common/platform/platform_steamworks.c,
src/common/platform/platform_steamworks.h, src/code/client/cl_main.c,
src/code/client/cl_cgame.c, tests/steamworks_harness.c,
tests/test_steamworks_harness.py,
docs/reverse-engineering/steam-retail-server-browser-appid-interop-2026-06-06.md
Parity estimate: before 72% -> after 96% for the focused public-retail
Steam server-browser AppID interop lane. Broader WebUI server-browser parity
remains approximately 99% because live Steam backend timing and server-side
Steam GameServer app-context publication still require opt-in runtime
validation.
Completed work:
- Traced the empty WebUI list to the native Steam browser path filtering list requests and returned rows by the running Steam app id while the legacy Quake III master fallback is policy-disabled.
- Added explicit
ForAppSteam browser and favorite helpers so the recovered current-app wrappers remain intact while the WebUI browser can target public retail Quake Live discovery. - Added
cl_steamServerBrowserAppId, defaulting to public retail app id282440, and stored the selected app id on native list/detail state for callback-time validation. - Routed WebUI favorite add/remove through the same discovery app id used by Favorites/History list requests.
- Added executable harness coverage and source-parity assertions for current-app behavior, public-retail request app id, public-retail row validation, ping/detail projection, and favorites.
Task A261: Map botlib edge math and grapple helper owners [COMPLETED]
Priority: High
Primary areas: src/code/botlib/be_aas_reach.c,
src/code/botlib/be_aas_move.c, src/code/botlib/be_ai_move.c,
references/analysis/quakelive_symbol_aliases.json,
tests/test_botlib_move_edge_grapple_helper_parity.py,
docs/reverse-engineering/botlib-move-edge-grapple-helper-mapping-2026-06-06.md
Parity estimate: before 70% -> after 97% for focused AAS edge helper
mapping and before 78% -> after 97% for focused move-AI angle/grapple
helper mapping. Overall botlib plus movement/reachability helper wiring moves
approximately 81% -> 82% because this pass closes static helper ownership
without changing live-map movement behavior.
Completed work:
- Rechecked the remaining real botlib-neighborhood gaps after the route prelude pass and separated them from the known libjpeg false lead.
- Promoted
VectorDistance,VectorBetweenVectors,AngleDiff,GrappleState, andBotResetGrapplefrom HLIL/Ghidra evidence. - Pinned their source consumers in
AAS_ClosestEdgePoints,BotTravel_Grapple, rocket/BFG jump travel, andBotMoveToGoal. - Preserved
sub_486F40as an explicit non-promotion because retail folds the identical rocket/BFGAAS_WeaponJumpZVelocity(origin, 120)wrappers into a single thunk.
Task A260: Reconstruct Freeze Tag assisted-thaw obituary and team sound [COMPLETED]
Priority: High
Primary areas: src/code/game/g_freeze.c, src/code/cgame/cg_event.c,
tests/test_game_active_pmove_wiring_parity.py,
tests/test_cgame_event_transport_parity.py,
docs/reverse-engineering/freeze-tag-thaw-obituary-sound-mapping-2026-06-06.md,
docs/reverse-engineering/freeze-tag-mapping-2026-06-06.md,
docs/reverse-engineering/qagame-mapping.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 45% -> after 91% for the focused assisted-thaw
obituary/global-team-sound corridor. The broader Freeze thaw-completion event
lane moves approximately 72% -> 86%, while broader Freeze Tag gametype
wiring moves approximately 93% -> 94% because the deeper retail
GibEntity/ClientSpawn thaw visual tail remains a separate source
reconstruction target.
Completed work:
- Rechecked
FUN_1004CD40in the committed qagame Ghidra/HLIL corpus and confirmed assisted thaw emitsEV_OBITUARYwithMOD_THAW, thawed client, helper client, andSVF_BROADCASTimmediately after assist credit. - Mapped the following
EV_GLOBAL_TEAM_SOUNDpayload to the existingG_BroadcastGlobalTeamSoundbridge, usingGTS_RED_RETURNfor blue-team clients andGTS_BLUE_RETURNotherwise. - Added
G_FreezeEmitThawCompletionEventsand routed non-auto thaw completion through it before the existing directEV_THAW_PLAYERvisual handoff. - Rechecked cgame
CG_Obituarystrings in the committed cgame HLIL and symbol map, then restoredMOD_THAWtext for world auto-thaw, local helper thaw, and remote helper thaw. - Added static parity coverage and a dedicated mapping note that records the
reconstructed assisted-thaw layer and leaves the retail
GibEntityrespawn tail as the next explicit gap.
Task A259: Map AAS route prelude helpers [COMPLETED]
Priority: High
Primary areas: src/code/botlib/be_aas_route.c,
src/code/botlib/be_aas_route.h, src/code/botlib/be_aas_main.c,
src/code/botlib/be_ai_move.c,
references/analysis/quakelive_symbol_aliases.json,
tests/test_botlib_route_prelude_parity.py,
docs/reverse-engineering/botlib-route-prelude-mapping-2026-06-06.md
Parity estimate: before 55% -> after 96% for focused AAS route-prelude
helper mapping. Route-cache invalidation and travel-flag wiring moves
approximately 72% -> 97%, while overall botlib plus related AAS route/import
wiring moves approximately 80% -> 81% because later route runtime and
alternative-route work was already mapped in the prior tranche.
Completed work:
- Rechecked the retail
quakelive_steam.exeHLIL range0x004925F0..0x00492F20and separated actual AAS route helpers from the adjacent libjpeg memory-manager false lead at0x00482150..0x004829A0. - Promoted eleven missing route-prelude aliases for routing debug info, cluster-local area numbering, travel-flag table initialization/access, routing-cache invalidation, area-content flag table access, reversed reachability creation, area travel time, and portal max travel-time initialization.
- Documented which source helpers remain unpromoted because retail inlines or fuses them into larger route-cache functions.
- Added focused parity coverage tying aliases to Ghidra rows, HLIL anchors, debug strings, source structures, AAS init order, and move-AI consumers.
Task A258: Extend Steam lobby callback pump coverage [COMPLETED]
Priority: High
Primary areas: tests/steamworks_harness.c,
tests/test_steamworks_harness.py, tests/test_platform_services.py,
docs/reverse-engineering/quakelive_steam_mapping_round_358.md,
docs/plans/steamworks-parity-plan.md
Parity estimate: before 58% -> after 96% for the focused lobby callback
pump coverage lane. Steam lobby callback registration plus payload projection
moves approximately 90% -> 98%, while broader Steamworks parity remains
approximately 99% because live Steam backend timing and browser event
ordering remain intentionally bounded behind opt-in online services.
Completed work:
- Rechecked the retail
SteamLobbyCallbacks_InitHLIL constructor at0x004656A0, the Ghidra importedSteamLobbyCallbackscallback vtables, and the mapping report row for the eight lobby callback payload types. - Confirmed the platform layer already prepares and registers callback
objects for
LobbyCreated_t,LobbyEnter_t,LobbyChatUpdate_t,LobbyChatMsg_t,LobbyDataUpdate_t,LobbyGameCreated_t,LobbyKicked_t, andGameLobbyJoinRequested_t. - Extended the Steamworks harness with retained callback targets and raw queue helpers for the seven lobby callback payloads that were not previously executable-test-backed.
- Expanded ctypes callback-pump coverage so all eight lobby payloads cross
QL_Steamworks_RunCallbacks, including the chat-message body retrieval through the mockedGetLobbyChatEntryslot. - Tightened static parity coverage for all eight callback IDs, object preparations, and object registrations.
Task A257: Reconstruct Freeze Tag frozen powerup marker producer [COMPLETED]
Priority: High
Primary areas: src/code/game/g_freeze.c,
src/code/cgame/cg_players.c, src/code/cgame/cg_draw.c,
tests/test_game_active_pmove_wiring_parity.py,
docs/reverse-engineering/freeze-tag-frozen-marker-mapping-2026-06-06.md,
docs/reverse-engineering/freeze-tag-mapping-2026-06-06.md,
docs/reverse-engineering/qagame-mapping.md
Parity estimate: before 35% -> after 94% for the focused qagame
frozen-marker producer lane. The combined Freeze Tag qagame/cgame
presentation bridge moves approximately 88% -> 94%, while broader Freeze
Tag gametype wiring moves approximately 92% -> 93% because the larger
FUN_1004BC80 thaw obituary/team-sound/GibEntity split remains open.
Completed work:
- Rechecked the retail qagame death/freeze path against committed Ghidra and
confirmed
client + 0x17c = 0x7fffffffplusgentity + 0xc4 = 0x8000when Freeze Tag records a frozen player. - Cross-checked
FUN_1004BC80HLIL and confirmed thearg2 == 1thaw/respawn branch clears the same client marker and entitystate bit. - Added
G_FreezeSetClientFrozenPowerupMarkerso qagame now publishesps.powerups[PW_NUM_POWERUPS] = INT_MAXandent->s.powerups = ( 1 << PW_NUM_POWERUPS )on freeze entry, and clears both surfaces during init/thaw. - Anchored the bridge against existing cgame consumers in
CG_IsFrozenPlayer,CG_PlayerSprites, and the team overlay frozen bit. - Added a dedicated mapping note and static parity coverage for the retail offsets, source helper, and remaining thaw-event reconstruction gap.
Task A256: Map botlib chat private helper owners [COMPLETED]
Priority: Medium
Primary areas: src/code/botlib/be_ai_chat.c,
src/code/botlib/be_interface.c, src/code/game/botlib.h,
references/analysis/quakelive_symbol_aliases.json,
tests/test_botlib_chat_private_helper_parity.py,
docs/reverse-engineering/botlib-chat-private-helper-mapping-2026-06-06.md
Parity estimate: before 82% -> after 96% for the focused chat
private-helper corridor and before 90% -> after 91% for overall botlib
chat mapping plus public chat export/import wiring. Remaining uncertainty is
live chat-data behavior across retail syn.c, rnd.c, match.c, rchat.c,
and per-bot initial chat files rather than private helper ownership.
Completed work:
- Rechecked the
be_ai_chat.cprivate-helper band against committedquakelive_steam.exeHLIL and Ghidra function rows. - Promoted
InitConsoleMessageHeap,BotRemoveTildes,BotReplaceWeightedSynonyms,BotReplaceReplySynonyms, andStringsMatch. - Preserved source bodies unchanged; the current reconstruction already matches the retail static shape for heap setup, tilde scrubbing, synonym replacement, and match-piece variable capture.
- Documented why
BotChatStateFromHandle,AllocConsoleMessage,FreeConsoleMessage, andStringReplaceWordsremain source-visible but unpromoted: the observed retail rows fold those operations into callers or do not expose standalone owners. - Added focused parity coverage for aliases, Ghidra sizes, HLIL helper call sites, source helper bodies, setup/shutdown/matching/expansion wiring, and the private/public AI export boundary.
Task A255: Normalize Steam GameServer and P2P vtable ABI wrappers [COMPLETED]
Priority: High
Primary areas: src/common/platform/platform_steamworks.c,
tests/steamworks_harness.c, tests/test_platform_services.py,
docs/reverse-engineering/quakelive_steam_mapping_round_356.md,
docs/plans/steamworks-parity-plan.md
Parity estimate: before 70% -> after 96% for the focused
GameServer/P2P vtable ABI wrapper family. The combined Steam GameServer
metadata, identity, packet bridge, and legacy P2P wrapper surfaces move
approximately 95% -> 98%, while broader Steamworks parity remains
approximately 99% because live backend validation remains intentionally
bounded behind opt-in online services.
Completed work:
- Rechecked the committed HLIL around
0x00465A40,0x00465A60,0x00465B00,0x00465B70, and0x00465D50and confirmed the affected lanes are Steam C++ interface vtable dispatches. - Added
QL_STEAMWORKS_FASTCALLand converted the retainedISteamNetworking,ISteamGameServer, andISteamGameServerNetworkingtypedefs to the sameself, unused, ...ABI shape used elsewhere in the Steam wrapper layer. - Updated GameServer metadata, identity, logged-on, public-IP, incoming/outgoing packet, and legacy P2P call sites to pass the explicit unused second argument before mapped retail parameters.
- Updated Steamworks harness vtable mocks to the corrected ABI shape so argument ordering remains executable-test-backed.
- Tightened static parity assertions for the ABI macro, representative typedefs, and mapped call sites.
Task A254: Map botlib goal item heap and avoid-goal wiring [COMPLETED]
Priority: Medium
Primary areas: src/code/botlib/be_ai_goal.c,
src/code/botlib/be_interface.c, src/code/game/botlib.h,
src/code/game/g_local.h, src/code/game/g_public.h,
src/code/game/g_syscalls.c, src/code/game/ai_dmq3.c,
src/code/server/sv_game.c, src/code/server/ql_game_imports.inc,
references/analysis/quakelive_symbol_aliases.json,
tests/test_botlib_goal_item_parity.py,
docs/reverse-engineering/botlib-goal-item-mapping-2026-06-06.md
Parity estimate: before 79% -> after 95% for the focused goal item
heap/info-entity/avoid-selection corridor. Overall botlib plus goal item
export/import wiring moves approximately 88% -> 89% because this pass
closes static ownership and routing gaps without claiming live map-specific
AAS item behavior, dynamic dropped-item behavior, or tactical item-selection
quality.
Completed work:
- Rechecked the retail
be_ai_goal.citem config, fuzzy-weight index, level-item heap, info-entity, avoid-goal, dynamic entity-item update, and LTG/NBG selection band against the committed HLIL and Ghidra function rows. - Promoted the missing private-owner aliases
ItemWeightIndex,InitLevelItemHeap,BotFreeInfoEntities, andBotAddToAvoidGoals. - Confirmed no C source rewrite is currently justified; small source-visible level-item helpers remain unaliased because the evidence supports them as inlined operations inside larger retail owners.
- Added focused parity coverage for the source shape, botlib export block, qagame legacy/native syscall bridge, server VM dispatch, direct native import wrappers, and qagame level-item/camp-spot consumers.
- Added a dedicated mapping note for the goal-item heap and avoid-goal wiring tranche.
Task A253: Reconstruct Steam GameServer P2P active-client gate [COMPLETED]
Priority: High
Primary areas: src/code/server/sv_client.c, tests/test_platform_services.py,
docs/reverse-engineering/quakelive_steam_mapping_round_355.md,
docs/plans/steamworks-parity-plan.md,
docs/reverse-engineering/quakelive_steam_mapping_round_01.md,
docs/mapping-ref/quakelive_steam_mapping_report.md
Parity estimate: before 72% -> after 96% for the focused server-side
P2PSessionRequest_t admission gate. The broader Steam GameServer callback
bundle moves approximately 98% -> 99%, while broader Steamworks parity
remains approximately 99% because live backend callback cadence and NAT
behavior stay intentionally bounded behind opt-in online services.
Completed work:
- Rechecked retail
SteamServerCallbacks_OnP2PSessionRequest(0x00465B70) in the committed HLIL and confirmed the callback scans client slots for*client == 4, matchingCS_ACTIVE, plus a two-word SteamID match before dispatchingSteamGameServerNetworkingslot0x0c. - Added
SV_FindActiveClientBySteamIdbeside the broader SteamID finder so auth-ticket responses can still locate pre-active clients while P2P session admission mirrors the retail active-slot gate. - Updated
SV_SteamServerP2PSessionRequestCallbackto remove the extraplatformAuthSucceededcondition, reject missing active SteamID matches, log accepted matches, and then call the retained server P2P accept wrapper. - Tightened static parity coverage for the active-client finder, callback dispatch, removed auth-success gate, accepted diagnostic, and missing-player rejection path.
- Corrected stale Steamworks mapping language that described the callback as authenticated-client gated rather than active-client gated.
Task A252: Reconstruct Freeze Tag thaw-progress eFlag buckets [COMPLETED]
Priority: High
Primary areas: src/code/game/g_client.c, src/code/game/g_freeze.c,
tests/test_game_active_pmove_wiring_parity.py,
docs/reverse-engineering/freeze-tag-thaw-progress-eflags-mapping-2026-06-06.md,
docs/reverse-engineering/freeze-tag-mapping-2026-06-06.md,
docs/reverse-engineering/qagame-mapping.md, docs/gameplay/cvars.md
Parity estimate: before 40% -> after 92% for the focused Freeze
thaw-progress low-bit producer lane. The broader Freeze thaw/end-frame lane
moves approximately 94% -> 96%, while broader Freeze Tag gametype wiring
moves approximately 91% -> 92% because this pass closes a static
producer-side bucket mismatch without claiming live client visual validation.
Completed work:
- Rechecked
FUN_1004CD40/G_FreezeClientEndFramein the committed Ghidra corpus and pinned the top-of-function comparisons againstDAT_105a472c / 3and(DAT_105a472c / 3) * 2. - Mapped the retail
gclient + 0x1c0bit writes to the sharedEF_DEAD(0x1) andEF_TICKING(0x2) constants, preserving the retail clear-high-bucket and OR-only middle/final bucket behavior. - Reconstructed
G_FreezeUpdateThawProgressFlagsand called it at the top ofG_FreezeClientEndFrame, before helper lookup and remaining-time mutation, matching the recovered retail ordering. - Cleared the reused low Freeze progress bits on freeze entry and thaw exit so stale progress state does not leak across reconstructed source transitions.
- Added static parity coverage and mapping notes for the Ghidra anchors,
source bucket helper, transition cleanup, and related
EV_THAW_TICKproducer wiring.
Task A251: Map botlib character cache and characteristic export wiring [COMPLETED]
Priority: Medium
Primary areas: src/code/botlib/be_ai_char.c,
src/code/botlib/be_interface.c, src/code/game/be_ai_char.h,
src/code/game/botlib.h, src/code/game/g_local.h,
src/code/game/g_public.h, src/code/game/g_syscalls.c,
src/code/server/sv_game.c, src/code/server/ql_game_imports.inc,
references/analysis/quakelive_symbol_aliases.json,
tests/test_botlib_character_cache_parity.py,
docs/reverse-engineering/botlib-character-cache-mapping-2026-06-06.md
Parity estimate: before 80% -> after 96% for the focused
character cache/default/interpolation/accessor helper corridor and
before 87% -> after 88% for overall botlib plus related character
export/import wiring. Remaining uncertainty is live bot-character data behavior
across maps and character files, not the static helper ownership or API routing
covered here.
Completed work:
- Rechecked
quakelive_steam.exeHLIL and Ghidra rows for thebe_ai_char.chelper band fromBotDumpCharacterthroughBotShutdownCharacters. - Promoted missing private helper aliases for character dumping, string cleanup, unconditional cleanup, default merge, cache lookup, interpolation, and characteristic index validation.
- Verified that no C source rewrite is currently justified; the existing source already preserves the retail cache fallback ladder, default-character merge, float-only interpolation, characteristic conversion/clamping, and parser/runtime index-check split.
- Added
tests/test_botlib_character_cache_parity.pyto pin aliases, Ghidra sizes, HLIL anchors, source shape, botlib export order, legacy syscall dispatch, native qagame import wrappers, and bot AI consumer wiring. - Added a focused mapping note documenting observed evidence, inferred helper names, confidence, and residual live-data risk.
Task A250: Recheck demo record/playback and browser demo-list wiring [COMPLETED]
Priority: Medium
Primary areas: src/code/client/cl_main.c, src/code/client/cl_cgame.c,
src/code/client/cl_keys.c, src/code/cgame/cg_draw.c,
src/code/cgame/cg_view.c,
tests/test_demo_record_playback_mapping_parity.py,
docs/reverse-engineering/demo-record-playback-mapping-2026-06-06.md
Parity estimate: before 96% -> after 99% for the focused protocol-91 demo
recording/playback, browser GetDemoList, console completion, and cgame demo
HUD/control wiring surface. Remaining uncertainty is live .dm_91 replay
freshness across third-party captures, not a known static source mismatch.
Completed work:
- Rechecked the
quakelive_steam.exeHLIL and Ghidra rows forCL_WriteDemoMessage,CL_StopRecord_f,CL_DemoFilename,CL_Record_f,CL_WalkDemoExt,CL_NextDemo,CL_DemoCompleted,CL_ReadDemoMessage, andCL_PlayDemo_f. - Verified that the core packet envelope and playback reader already match
retail: little-endian server sequence and payload length, post-header
payload writes,
MAX_MSGLENrejection, truncation handling, protocol-list fallback, and the-1/-1terminator. - Reconstructed the browser-facing demo-list return shape by preserving raw
.dm_91file-list entries fromCL_WebHost_BuildDemoListJsoninstead of stripping the protocol suffix before returning the JSON array. - Added static parity coverage that pins the retail aliases, HLIL anchors,
protocol-91 extension path, browser
dm_91listing, retained console.dm_73completion quirk, cgamedemoPlaybackdraw handoff, demo HUD controls, and the new mapping note.
Task A249: Reconstruct Freeze Tag helper entity-query topology [COMPLETED]
Priority: High
Primary areas: src/code/game/g_freeze.c,
tests/test_game_active_pmove_wiring_parity.py,
tests/test_game_round_controller_helper_parity.py,
tests/test_game_helper_seam_parity.py,
docs/reverse-engineering/freeze-tag-helper-query-mapping-2026-06-06.md,
docs/reverse-engineering/freeze-tag-mapping-2026-06-06.md,
docs/reverse-engineering/qagame-mapping.md, docs/gameplay/cvars.md
Parity estimate: before 72% -> after 94% for the focused Freeze
thaw-helper search topology. The broader Freeze thaw/end-frame lane moves
approximately 91% -> 94%, while broader Freeze Tag gametype wiring moves
approximately 90% -> 91% because this pass closes helper enumeration
topology without claiming live match validation.
Completed work:
- Rechecked
FUN_1004CD40/G_FreezeClientEndFramein Ghidra and HLIL, including the thaw-radius mins/maxs build and qagame import call atDAT_104b13ac + 0xa4. - Identified the import as the recovered
trap_EntitiesInBox/QL_G_trap_EntitiesInBoxbridge with a0x400entity-list limit. - Reconstructed
G_FreezeCountThawHelpersto enumerate the thaw-radius AABB throughtrap_EntitiesInBoxbefore applying the shared thaw-helper predicate, replacing the previous source-only flatlevel.maxclientsscan. - Kept the public count-returning helper API stable while selecting the first valid entity-list helper, matching retail's per-frame helper choice more closely than the previous nearest-client selection.
- Updated Freeze mapping notes, gameplay cvar notes, and static parity tests to pin the retail entity-query topology.
Task A248: Map botlib genetic-selection wiring [COMPLETED]
Priority: Medium
Primary areas: src/code/botlib/be_ai_gen.c,
src/code/botlib/be_interface.c, src/code/game/be_ai_gen.h,
src/code/game/botlib.h, src/code/game/ai_main.c,
src/code/game/g_local.h, src/code/game/g_public.h,
src/code/game/g_syscalls.c, src/code/server/sv_game.c,
src/code/server/ql_game_imports.inc,
references/analysis/quakelive_symbol_aliases.json,
tests/test_botlib_genetic_selection_parity.py,
docs/reverse-engineering/botlib-genetic-selection-mapping-2026-06-06.md
Parity estimate: before 72% -> after 96% for the focused
genetic-selection helper/export corridor and before 86% -> after 87% for
overall botlib plus fuzzy/genetic interbreed wiring. Remaining uncertainty is
live interbreed behavior quality and map/bot-data effects rather than the
static selector ownership or import/export routing covered here.
Completed work:
- Rechecked
quakelive_steam.exeHLIL and Ghidra function rows for thebe_ai_gen.chelper pair aroundGeneticSelectionandGeneticParentsAndChildSelection. - Promoted the missing
sub_49C6C0 -> GeneticSelectionalias and rechecked the existingsub_49C810 -> GeneticParentsAndChildSelectionexport owner. - Verified no C body change is currently justified; the checked-in genetic selector source already matches the retail static shape for weighted selection, fallback selection, parent exclusion, rank reversal, child selection, and failure-output zeroing.
- Added
tests/test_botlib_genetic_selection_parity.pyto pin aliases, Ghidra sizes, HLIL anchors, source shape, AI export order, qagame consumer behavior, legacy syscall dispatch, server VM dispatch, and Quake Live native import wrapper wiring.
Task A247: Reconstruct Steam GameServerStats logged-on request gate [COMPLETED]
Priority: Medium
Primary areas: src/common/platform/platform_steamworks.c,
src/common/platform/platform_steamworks.h, tests/steamworks_harness.c,
tests/test_steamworks_harness.py, tests/test_platform_services.py,
docs/plans/steamworks-parity-plan.md,
docs/reverse-engineering/quakelive_steam_mapping_round_354.md
Parity estimate: before 40% -> after 94% for the focused
GameServerStats logged-on request gate, before 97% -> after 98% for the
combined idSteamStats callback/value/descriptor/request-bootstrap lane, and
approximately 99% for broader Steamworks parity. Remaining uncertainty is
live backend timing and callback cadence, which stay intentionally bounded
behind QL_BUILD_ONLINE_SERVICES / QL_BUILD_STEAMWORKS opt-in behavior.
Completed work:
- Rechecked the retail
quakelive_steam.exeHLIL forSteamStats_OnServersConnected(0x00467190) and the repeated constructor/bootstrap gate at0x004679d9. - Reconstructed
QL_Steamworks_ServerIsLoggedOnthrough the observedSteamGameServervtable slot0x20, with the disabled-build stub returningqfalse. - Gated
QL_Steamworks_ServerRequestUserStatsbehind the logged-on check before issuingSteamGameServerStats::RequestUserStatsthrough slot0x00. - Extended the Steamworks harness with a mocked
SteamGameServer::BLoggedOnslot, result control, call counting, and enabled/disabled exports. - Added regression coverage proving the logged-off path suppresses the
SteamGameServerStatsrequest while the logged-on path reaches the retail request slot.
Task A246: Map botlib AAS lifecycle wiring [COMPLETED]
Priority: Medium
Primary areas: src/code/botlib/be_aas_bspq3.c,
src/code/botlib/be_aas_cluster.c, src/code/botlib/be_aas_entity.c,
src/code/botlib/be_aas_file.c, src/code/botlib/be_aas_main.c,
src/code/botlib/be_interface.c, src/code/game/botlib.h,
src/code/game/g_syscalls.c, src/code/server/sv_game.c,
src/code/server/ql_game_imports.inc,
references/analysis/quakelive_symbol_aliases.json,
tests/test_botlib_aas_lifecycle_parity.py,
docs/reverse-engineering/botlib-aas-lifecycle-mapping-2026-06-06.md
Parity estimate: before 78% -> after 94% for the focused AAS
BSP/file/entity lifecycle corridor and before 85% -> after 86% for overall
botlib plus AAS lifecycle/import wiring. Remaining uncertainty is live-map
.aas content, map-dependent clustering/reachability quality, and runtime bot
behavior rather than the static lifecycle ownership or public wiring covered
here.
Completed work:
- Rechecked
quakelive_steam.exeHLIL and Ghidra function rows for the AAS BSP wrapper, BSP entity parser, cluster initialization, entity query, AAS file/lump, and main setup/start-frame/load-map/shutdown bands. - Promoted missing aliases for
AAS_Trace,AAS_EntityCollision,AAS_inPVS,AAS_BSPModelMinsMaxsOrigin,AAS_FreeBSPEntities,AAS_EntityModelindex,AAS_EntityType,AAS_EntityModelNum,AAS_OriginOfMoverWithModelNum,AAS_NextEntity,AAS_SwapAASData,AAS_LoadAASLump, andAAS_WriteAASLump. - Verified no C body change is currently justified; the checked-in AAS lifecycle source already matches the retail static shape for the mapped owners.
- Added
tests/test_botlib_aas_lifecycle_parity.pyto pin aliases, Ghidra sizes, HLIL anchors, lifecycle source shape, BSP/AAS export order, server VM syscall dispatch, Quake Live native import slab entries, and qagame syscall wrappers.
Task A245: Reconstruct Grappling Hook impact media and consolidate hook wiring [COMPLETED]
Priority: Medium
Primary areas: src/code/cgame/cg_local.h,
src/code/cgame/cg_main.c, src/code/cgame/cg_weapons.c,
references/analysis/quakelive_symbol_aliases.json,
references/symbol-maps/cgame.json,
tests/test_grappling_hook_mapping_parity.py,
docs/reverse-engineering/grappling-hook-wiring-mapping-2026-06-06.md
Parity estimate: before 93% -> after 98% for the focused Grappling Hook
wiring and cgame-impact lane. Broader repo-wide parity remains approximately
99%; the remaining grapple uncertainty is the qagame hook temp-event
weapon-field question and any untested live-map bot grapple path quality.
Completed work:
- Rechecked
quakelive_steam.exe,qagamex86.dll, andcgamex86.dllGhidra/HLIL evidence for bot grapple reachability/travel, qagame hook projectile lifecycle, shared grapple pmove pull, cgame hook rendering, and cgame impact media. - Reconstructed the missing cgame grapple-impact media branch: registered the
retail
gfx/damage/cracked_mrkshader andsound/weapons/grapple/grhit.oggsound, then routedCG_MissileHitWallWP_GRAPPLING_HOOKimpacts through that sound, cracked mark, and the retail 16-unit mark radius. - Promoted qagame hook lifecycle aliases for
fire_grapple,G_MissileImpact,Weapon_GrapplingHook_Fire,Weapon_HookFree,Weapon_HookThink,FireWeapon, andTeleportPlayer, while retaining the existing cgame and botlib hook aliases. - Added a focused mapping document and regression test covering source, symbol-map comments, alias promotion, and Ghidra/HLIL anchors across the Grappling Hook corridor.
Task A244: Reconstruct Freeze Tag thaw-helper timer and wiring [COMPLETED]
Priority: High
Primary areas: src/code/game/g_freeze.c, src/code/game/g_client.c,
src/code/game/g_local.h, src/code/game/g_main.c,
tools/tests/match_sim/harness.py,
tests/test_game_active_pmove_wiring_parity.py,
tests/test_game_round_controller_helper_parity.py,
tests/test_game_runframe_parity.py,
docs/reverse-engineering/freeze-tag-mapping-2026-06-06.md,
docs/reverse-engineering/qagame-mapping.md, docs/gameplay/cvars.md
Parity estimate: before 71% -> after 91% for the focused Freeze
thaw-helper/end-frame lane. Broader Freeze Tag gametype wiring moves
approximately 88% -> 90% because round-state, scoreboard, last-alive, and
death wiring were already mostly reconstructed. The follow-up A249 pass closes
the exact helper entity-query topology; live retail DLL validation remains open.
Completed work:
- Rechecked
qagamex86.dllGhidra and HLIL evidence for the retail Freeze helper band, especiallyFUN_1004CD40/G_FreezeClientEndFrameand the small retained-helper lookup atFUN_1004CD00. - Replaced the source-only accumulated thaw/tick-deadline model with the retail-shaped remaining-time counter and helper-active latch.
- Reworked per-frame thaw handling to decrement by
level.msecwhile a valid helper remains in range, refill towardg_freezeThawTimewhen abandoned, retain helper credit through the recovered lookup boundary, and treatg_freezeThawTickas the non-zeroEV_THAW_TICKevent gate. - Centralized helper validity checks for same-team connected live clients,
PM_NORMALstate, radius, and line of sight, then shared that predicate between counting and retained-helper lookup. - Refreshed the lightweight match-simulation harness, cvar notes, qagame mapping notes, and static parity tests to pin the corrected retail interpretation.
Task A243: Reconstruct CG_Missile renderer wiring [COMPLETED]
Priority: Medium
Primary areas: src/code/cgame/cg_ents.c,
src/code/cgame/cg_weapons.c, src/code/cgame/cg_local.h,
tests/test_cgame_displaycontext_parity.py,
tests/test_game_weapon_parity.py,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 86% -> after 96% for the focused
CG_Missile renderer and related color/axis wiring. Overall cgame mapping
coverage remains 854 / 854 committed anchors (100%); repo-wide parity
remains approximately 98% because this pass tightens an already mapped
renderer rather than opening new corpus coverage.
Completed work:
- Rechecked
0x100175F0 -> CG_Missilein cgame HLIL, the GhidraFUN_100175f0function row, and the adjacent weapon-color helper evidence. - Reconstructed the retail invalid-weapon guard as
CG_Errorwithout mutatings1->weapon, matching the>= 16retail table boundary. - Removed the source-only
cent->lerpAnglesrewrite fromCG_Missileand aligned stationary proximity-mine axis setup tocurrentState.angles. - Exposed the shared weapon-color override helper and routed grenade missile
entity colors through forced team/enemy weapon color before falling back to
cg_weaponColor_grenade.
Task A242: Reconstruct Steam GameServer incoming UDP packet bridge [COMPLETED]
Priority: High
Primary areas: src/common/platform/platform_steamworks.c,
src/common/platform/platform_steamworks.h, src/code/server/sv_main.c,
tests/steamworks_harness.c, tests/test_steamworks_harness.py,
tests/test_platform_services.py,
docs/reverse-engineering/quakelive_steam_mapping_round_353.md,
docs/plans/steamworks-parity-plan.md
Parity estimate: before 35% -> after 92% for the focused incoming
Steam GameServer UDP handoff lane. The combined incoming/outgoing GameServer
UDP bridge moves approximately 82% -> 96%, while broader Steamworks parity
remains approximately 99% because live backend validation and online
service replacement remain intentionally bounded.
Completed work:
- Rechecked
SteamServer_HandleIncomingPacket(0x00465d50) in HLIL, the GhidraFUN_00465d50row, the Round 04 alias promotion, and the adjacent outgoing packet drain atSteamGameServerslot0x98. - Added
QL_Steamworks_ServerHandleIncomingPacketfor slot0x94, plus the matching disabled inline stub. - Wired
SV_PacketEventthroughSV_SteamServerHandleIncomingPacket, packing IPv4 bytes in the retail order and forwarding the original packet payload and source port into the Steam GameServer wrapper. - Extended the Steamworks harness and source-bound tests to cover incoming packet payload capture, endpoint capture, result propagation, and disabled fallback behavior.
Task A241: Map botlib AAS sample/query wiring [COMPLETED]
Priority: Medium
Primary areas: src/code/botlib/be_aas_sample.c,
src/code/botlib/be_interface.c, src/code/game/botlib.h,
src/code/game/g_public.h, src/code/game/g_syscalls.c,
src/code/server/sv_game.c, src/code/server/ql_game_imports.inc,
references/analysis/quakelive_symbol_aliases.json,
tests/test_botlib_aas_sample_parity.py,
docs/reverse-engineering/botlib-aas-sample-mapping-2026-06-06.md
Parity estimate: before 79% -> after 95% for the focused AAS
sample/query helper corridor and before 84% -> after 85% for overall
botlib plus AAS sample/import wiring. Remaining uncertainty is live-map .aas
content and map-dependent bot behavior, not the static sample/query ownership
or qagame-facing import surface covered here.
Completed work:
- Rechecked
quakelive_steam.exeHLIL and Ghidra function rows for the AAS sample/query band fromAAS_PresenceTypeBoundingBoxthroughAAS_PlaneFromNum, including link heap lifecycle, point/area presence queries, client bbox tracing, trace-area collection, face/plane helpers, entity linking, bbox area enumeration, and area info copy-out. - Promoted missing aliases for
AAS_AreaPresenceType,AAS_PointPresenceType,AAS_AreaEntityCollision,AAS_InsideFace,AAS_BoxOnPlaneSide2,AAS_UnlinkFromAreas,AAS_AASLinkEntity,AAS_LinkEntityClientBBox, andAAS_PlaneFromNum. - Verified no
be_aas_sample.cC body change is currently justified; the checked-in source already matches the retail static shape for the mapped sample/query corridor. - Added
tests/test_botlib_aas_sample_parity.pyto pin aliases, Ghidra sizes, HLIL anchors, source helper shape, public AAS export order, server VM syscall dispatch, legacy qagame imports, Quake Live native import slab, qagame direct wrappers, and qagame syscall wrappers.
Task A240: Reconstruct Steam GameServerStats descriptor replay owner [COMPLETED]
Priority: High
Primary areas: src/code/server/sv_client.c,
tests/test_platform_services.py,
docs/reverse-engineering/quakelive_steam_mapping_round_352.md,
docs/plans/steamworks-parity-plan.md
Parity estimate: before 54% -> after 86% for the focused descriptor-table
replay lane. The combined idSteamStats callback/value/descriptor lane moves
approximately 98% -> 99%, while broader Steamworks parity remains
approximately 99% because online services stay opt-in and exact non-int
descriptor promotion plus live backend validation remain bounded.
Completed work:
- Rechecked
SteamStats_FlushPendingValues(0x004670c0),SteamStats_OnStatsReceived(0x004671d0),data_561060,data_561c00, the promoted symbol aliases, and the Ghidra rows for the retainedidSteamStatsdescriptor owner. - Reconstructed the server stats descriptor shape: count at owner
+0x10, pointer at+0x18, stride0x1c, type at descriptor+0x04, name at+0x08, int value at+0x0c, float/current value at+0x10, and average-rate count/session fields at+0x14/+0x18. - Converted the server stats owner from a bare name table to typed descriptor records and added type-aware load/flush dispatch for int, float, and average-rate Steam GameServerStats slots.
- Kept all 88 currently recovered qagame-facing stat names as int descriptors
and made the qagame
AddSteamStatimport decline non-int descriptors until stronger retail evidence identifies the public float/average-rate update owner.
Task A239: Reconstruct botlib AAS reachability-generation support [COMPLETED]
Priority: Medium
Primary areas: src/code/botlib/be_aas_move.c,
src/code/botlib/be_aas_optimize.c, src/code/botlib/be_aas_reach.c,
references/analysis/quakelive_symbol_aliases.json,
tests/test_botlib_reachability_generation_parity.py,
docs/reverse-engineering/botlib-reachability-generation-mapping-2026-06-06.md
Parity estimate: before 82% -> after 96% for the focused
reachability-generation support corridor and before 82% -> after 84% for
overall botlib plus related movement/route wiring. Remaining uncertainty is
live-map .aas content and generated reachability quality, not the static
runtime helper ownership covered here.
Completed work:
- Rechecked
quakelive_steam.exeHLIL and Ghidra function rows for the reachability-generation utility band around jump velocity solving, jump reach run-start probing, geometry helpers, area predicates, reachability heap allocation, store/flattening, best-link selection, weapon-jump area flags, and reachability initialization. - Promoted missing aliases from
AAS_ClientMovementHitBBoxthroughAAS_BestReachableLinkArea, includingAAS_HorizontalVelocityForJump,AAS_JumpReachRunStart,AAS_FaceArea,AAS_AreaVolume,AAS_SetupReachabilityHeap,AAS_AllocReachability,AAS_FaceCenter, fall/jump-distance math, liquid/damage area predicates,AAS_ReachabilityExists, andAAS_StoreReachability. - Reconstructed the retail non-
BSPCAAS_Optimizebody as the observed no-op diagnostic stub while retaining the previous GPL optimizer under theBSPCmap-compiler/tooling path. - Added
tests/test_botlib_reachability_generation_parity.pyto pin aliases, Ghidra sizes, HLIL anchors, source shape, the runtime optimizer stub, and retainedBSPCoptimizer branch.
Task A238: Reconstruct Steam GameServerStats value wrappers [COMPLETED]
Priority: High
Primary areas: src/common/platform/platform_steamworks.[ch],
tests/steamworks_harness.c, tests/test_steamworks_harness.py,
tests/test_platform_services.py,
docs/reverse-engineering/quakelive_steam_mapping_round_351.md,
docs/plans/steamworks-parity-plan.md
Parity estimate: before 72% -> after 94% for the focused
SteamGameServerStats int/float/average-rate value-wrapper lane. The combined
idSteamStats callback plus value-wrapper reconstruction moves approximately
97% -> 98% for the focused lane, while broader Steamworks parity remains
approximately 99% because live backend behavior and full descriptor-table
replay remain explicit validation boundaries.
Completed work:
- Rechecked
SteamStats_FlushPendingValues(0x004670c0),SteamStats_OnStatsReceived(0x004671d0), theSteamGameServerStatsimport row, and promoted symbol aliases for the server stats owner. - Reconstructed the observed
SteamGameServerStatsfloat get slot0x04, float set slot0x10, and average-rate update slot0x18, alongside the already reconstructed request, int, achievement, and store slots. - Extended disabled stubs so the online-services-off build keeps a stable API while returning clean fallbacks and zeroed outputs.
- Built a full
SteamGameServerStatsharness mock vtable and executable coverage for request, int/float read, int/float write, average-rate update, achievement, store, and failure zeroing.
Task A237: Map botlib movement travel runtime parity [COMPLETED]
Priority: Medium
Primary areas: src/code/botlib/be_ai_move.c,
src/code/botlib/be_interface.c, src/code/game/botlib.h,
src/code/game/g_syscalls.c, src/code/server/sv_game.c,
src/code/server/ql_game_imports.inc,
references/analysis/quakelive_symbol_aliases.json,
tests/test_botlib_move_travel_parity.py,
docs/reverse-engineering/botlib-move-travel-mapping-2026-06-06.md
Parity estimate: before 73% -> after 94% for the focused
be_ai_move.c movement/travel helper corridor and before 80% -> after 82%
for overall botlib plus movement/import wiring. Remaining uncertainty is
live-map .aas behavior and bot tactical movement quality, not the static
runtime owner mapping covered here.
Completed work:
- Rechecked
quakelive_steam.exeHLIL and Ghidra function rows for mover helpers, reachability selection, direct movement, travel methods, finish handlers, andBotMoveToGoaldispatch. - Promoted missing movement/travel aliases from
BotOnMoverthroughBotFuncBobStartEnd, including low-level gap/barrier/blocking helpers and jump, ladder, teleport, elevator, func_bobbing, waterjump, and walk-off-ledge owners. - Corrected the stale
sub_4A2620alias fromBotFinishTravel_WalkOffLedgetoBotTravel_Jump; the walk-off-ledge pair is now mapped assub_4A21A0 -> BotTravel_WalkOffLedgeandsub_4A24E0 -> BotFinishTravel_WalkOffLedge. - Verified no
be_ai_move.cC body change is currently justified; the current source already matches the retail travel dispatch and helper shape for this static slice. - Added
tests/test_botlib_move_travel_parity.pyto pin aliases, Ghidra sizes, HLIL anchors, source shape, public botlib export order, server VM syscall dispatch, Quake Live native import slab, qagame direct wrappers, and qagame syscall wrappers.
Task A236: Reconstruct Steam GameServer stats callback wiring [COMPLETED]
Priority: High
Primary areas: src/common/platform/platform_steamworks.[ch],
src/code/server/sv_client.c, tests/steamworks_harness.c,
tests/test_steamworks_harness.py, tests/test_platform_services.py,
docs/reverse-engineering/quakelive_steam_mapping_round_350.md,
docs/plans/steamworks-parity-plan.md
Parity estimate: before 84% -> after 97% for the focused
idSteamStats GameServer stats callback/bootstrap lane. Broader Steamworks
parity remains approximately 99% because online services remain opt-in and
live Steam backend behavior plus full descriptor-table callback replay remain
explicit validation boundaries.
Completed work:
- Rechecked
SteamGameServerUtilsimport evidence,idSteamStatsGSStatsReceived_t/GSStatsStored_tcallback vtables, and HLIL registrations at callback IDs0x708and0x709. - Added public GS stats callback event structs, binding slots, raw payload
dispatchers, retained registration/unregistration, and the optional
QL_Steamworks_ServerGetAppIDwrapper through server-utils slot0x24. - Wired the server stats owner to retain the server app id, observe
received/stored callback results, and re-request values for the retail
partial-validation result
8. - Extended the Steamworks harness with mock
SteamGameServerUtils, queueable GS stats payloads, and full enabled/disabled regression coverage for the callback pump and server app-id wrapper.
Task A235: Map botlib AAS route runtime parity [COMPLETED]
Priority: Medium
Primary areas: src/code/botlib/be_aas_route.c,
src/code/botlib/be_aas_routealt.c, src/code/botlib/be_interface.c,
src/code/game/botlib.h, src/code/game/g_syscalls.c,
src/code/server/sv_game.c, src/code/server/ql_game_imports.inc,
references/analysis/quakelive_symbol_aliases.json,
tests/test_botlib_route_runtime_parity.py,
docs/reverse-engineering/botlib-route-runtime-mapping-2026-06-06.md
Parity estimate: before 70% -> after 96% for the focused AAS
route-cache/readback helper mapping and before 82% -> after 97% for the
focused route query, prediction, and alternative-route-goal source mapping.
Overall botlib plus related AAS route/import wiring moves approximately
78% -> 80% because this pass promotes a cohesive route-runtime tranche
without claiming exhaustive live-map .aas graph behavior.
Completed work:
- Rechecked
quakelive_steam.exeHLIL, Ghidra function rows, and existing mapping rounds for the AAS route-cache, route-query, prediction, and alternative-route helper corridor. - Promoted missing route-cache helper aliases for
AAS_FreeOldestCache,AAS_FreeAllClusterAreaCache,AAS_InitClusterAreaCache,AAS_FreeAllPortalCache,AAS_InitRoutingUpdate,AAS_ReadCache,AAS_ReadRouteCache, andAAS_InitReachabilityAreas. - Verified the current source shape already matches retail for
.rcdroute-cache persistence, readback validation, initialization/shutdown ordering, area/portal route lookup,AAS_PredictRoute, reachability copy/iteration, model reachability, andAAS_AlternativeRouteGoals. - Added
tests/test_botlib_route_runtime_parity.pyto pin the new aliases, Ghidra sizes, Binary Ninja HLIL anchors, source body shape, public AAS export order, server import wrappers, qagame syscall wrappers, and qagame alternative-route consumers. - Documented the negative check that no route algorithm C body change is currently justified; the remaining uncertainty is live-map route data and broader bot behavior, not the mapped route-runtime source owner.
Task A234: Pin legacy Steam P2P networking vtables [COMPLETED]
Priority: High
Primary areas: tests/steamworks_harness.c,
tests/test_steamworks_harness.py,
docs/reverse-engineering/quakelive_steam_mapping_round_349.md,
docs/plans/steamworks-parity-plan.md
Parity estimate: before 82% -> after 96% for the focused legacy
ISteamNetworking client/server wrapper and harness lane. Broader Steamworks
parity remains approximately 99% because the retained retail-era P2P path
is now executable evidence while live Steam runtime behavior and a documented
modern ISteamNetworkingSockets / ISteamNetworkingMessages adapter remain
explicitly open.
Completed work:
- Rechecked the
SteamNetworkingandSteamGameServerNetworkingimport evidence plus HLIL availability/read/send call sites for the legacy P2P wrapper slots. - Added a mock
SteamAPI_SteamNetworkingprovider with send, availability, read, and accept slots matching the reconstructed wrapper offsets. - Replaced the null game-server networking mock with equivalent server-side
P2P slots and added a one-shot
SteamGameServer::GetNextOutgoingPacketharness path. - Added enabled/disabled ctypes wrappers and focused tests proving payload, SteamID, channel, send-type, failure, read, accept, and outgoing UDP packet behavior.
Task A233: Pin Steam favorite-server matchmaking wiring [COMPLETED]
Priority: High
Primary areas: src/code/client/cl_cgame.c,
tests/steamworks_harness.c, tests/test_steamworks_harness.py,
tests/test_platform_services.py,
docs/reverse-engineering/quakelive_steam_mapping_round_348.md,
docs/plans/steamworks-parity-plan.md
Parity estimate: before 88% -> after 98% for the focused
SetFavoriteServer SteamMatchmaking add/remove wrapper and client fallback
lane. Broader Steam server-browser and WebUI bridge parity remains
approximately 99% because live friends/history/recent-mode behavior and
live Steam favorite persistence remain validation uncertainties.
Completed work:
- Rechecked the retail
qz_instancemethod row at0x0055C188, the0x00432681dispatcher case, and the Ghidra import evidence forSteamMatchmakingplusSteamUtils. - Extended the Steamworks harness with mock
SteamMatchmakingfavorite-game add/remove slots at vtable offsets0x08and0x0c, capture getters, result controls, and disabled-build stubs. - Added executable coverage proving app ID, IP, shared connection/query port, favorite flag, add timestamp, remove timestamp absence, and provider failure propagation.
- Made the client local favorites cache mirror an explicit compatibility fallback when an opted-in Steam provider cannot update favorites.
Task A232: Close Attack and Defend retail parity wiring [COMPLETED]
Priority: High
Primary areas: src/code/game/g_team.c, src/code/game/g_items.c,
src/code/cgame/cg_main.c, tests/test_attack_defend_retail_parity.py
Parity estimate: before 97% -> after 100% for the focused Attack and
Defend gametype rules, flag-status transport, map item validation, score
history, round controller, spawn/reset, media registration, POI, scoreboard,
and HUD wiring surface. Broader gameplay/gametype parity remains approximately
99% repo-wide because this pass closes AD-specific drift while leaving
unrelated gametype and validation-freshness boundaries unchanged.
Completed work:
- Rechecked
qagamex86.dllandcgamex86.dllsymbol maps plus Binary Ninja HLIL and Ghidra evidence forTeam_SetFlagStatus,G_CheckTeamItems,Team_TouchOurFlag,Team_TouchEnemyFlag,G_ADHandleDamageScore,AD_RoundStateTransition,G_ADUpdateScoreHistory,CG_ParseADScores,CG_DrawADRoundScoreboard,CG_DrawObjectiveStatus,CG_PlayerObjectiveSprite, andCG_RegisterGraphics. - Restored the retail CTF-family AD flag-status path so
Team_InitGameinitializes red/blue status forGT_ATTACK_DEFENDandTeam_SetFlagStatuspublishes the two-characterCS_FLAGSTATUSpayload for both CTF and Attack and Defend. - Restored AD map-item validation in
G_CheckTeamItems, matching the retail red/blue flag warning branch for gametype0xb. - Restored AD client media registration for the red/blue flag model bank and
neutral/dropped flag model bank in
CG_RegisterGraphics, matching the retail cgame evidence that includes gametype0xbin those assets. - Added
tests/test_attack_defend_retail_parity.pyto pin the AD symbol-map owners, retail evidence snippets, server flag/status and item-validation gates, round controller, damage/bonus flow, spawn/frame hooks,scores_ad/adscorestransport, cgame flag media, POI, and HUD wiring.
Task A231: Label invalid Steam browser request modes as internet default [COMPLETED]
Priority: High
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py,
docs/reverse-engineering/quakelive_steam_mapping_round_347.md,
docs/plans/steamworks-parity-plan.md
Parity estimate: before 85% -> after 99% for the focused
invalid/default WebUI server-browser request-mode labeling path. Broader
Steam server-browser parity remains approximately 99% because native
list/detail owners are already reconstructed and the remaining uncertainty is
live friends/history result parity plus any distinct recent-mode UI evidence,
not the observed invalid/default RequestServers dispatch.
Completed work:
- Rechecked the retail
JSBrowser_RequestServersHLIL brancharg2 - 1 u> 3, which routes mode0and out-of-range retained values to the internetISteamMatchmakingServersrequest slot with thegamedir=baseq3filter. - Confirmed the source dispatch helpers already agreed with retail:
invalid/default modes enter
QL_STEAM_SERVER_BROWSER_INTERNETnatively andAS_GLOBALin the source-browser fallback path. - Updated
CL_SteamBrowser_RequestModeLabelso the retained default case now reportsinternetinstead ofunknown, aligning diagnostics and fallback telemetry with the actual dispatch path. - Added a platform-service parity assertion that the request-mode label block
has the explicit mode-0 and default
internetreturns and no longer contains anunknownrequest-mode label.
Task A230: Lock CTF and One Flag retail parity wiring [COMPLETED]
Priority: High
Primary areas: src/code/game/g_team.c, src/code/game/g_combat.c,
src/code/game/g_cmds.c, src/code/game/ai_dmq3.c,
src/code/game/ai_team.c, src/code/cgame/cg_servercmds.c,
src/code/cgame/cg_main.c, src/code/cgame/cg_newdraw.c,
tests/test_ctf_oneflag_retail_parity.py
Parity estimate: before 99% -> after 100% for the focused CTF and One
Flag gametype rules, scoring, status, bot, scoreboard, and HUD wiring surface.
Broader gameplay/gametype parity remains approximately 99% repo-wide
because this pass found the source behavior already aligned with the committed
retail references and converted the audit into focused regression coverage
without changing unrelated gametype lanes.
Completed work:
- Rechecked
qagamex86.dllandcgamex86.dllsymbol maps plus Binary Ninja HLIL evidence forTeam_SetFlagStatus,Team_TouchOurFlag,Team_TouchEnemyFlag,Pickup_Team,Team_FragBonuses,Team_CheckHurtCarrier,CheckAlmostCapture,CG_ParseCtfScores,CG_ParseCTFStats,CG_OneFlagStatus,CG_OtherTeamHasFlag,CG_YourTeamHasFlag, andCG_DrawPlayerHasFlag. - Verified qagame CTF and One Flag initialization/status configstrings,
dropped-flag return/reset handling, neutral-flag pickup/capture flow,
capture assist accounting, near-capture event selection, and the retail
carrier-bonus split where
Team_CheckHurtCarrieronly stamps red/blue flag or Harvester skull carrier damage whileTeam_FragBonuseshandles One Flag neutral-carrier frags. - Verified score transports and client parsing stay on the retail
scores_ctf/ctfstatsfamily path, including the two-character CTF flag status payload versus the single-character One Flag payload. - Verified client HUD/objective wiring for One Flag neutral status icons, CTF/One Flag ownerdraw visibility predicates, local carried-flag rendering, and CTF-family feeder rows.
- Verified bot inventory, flag-state event handling, and team-order dispatch keep CTF red/blue flag state separate from One Flag neutral-flag state.
- Added
tests/test_ctf_oneflag_retail_parity.pyto pin the audited retail surface across qagame, cgame, and bot wiring.
Task A229: Tighten native Steam detail query-handle fallback [COMPLETED]
Priority: High
Primary areas: src/common/platform/platform_steamworks.c,
tests/steamworks_harness.c, tests/test_steamworks_harness.py,
tests/test_netcode_parity_manifest.py,
docs/reverse-engineering/quakelive_steam_mapping_round_346.md
Parity estimate: before 86% -> after 98% for the focused native
server-browser detail query-handle failure path. Broader WebUI server-browser
ownership remains approximately 99% because the list and detail native
owners were already wired; this pass closes the partial ping/rules/players
query allocation hole and preserves the documented source status-query
fallback. Repo-wide parity remains 99% because the
QL_BUILD_ONLINE_SERVICES default-disabled policy boundary is unchanged.
Completed work:
- Rechecked the
JSBrowserDetails_RequestServerDetailsevidence for the retainedPingServer -> ServerRules -> PlayerDetailsdispatch order and the adjacentCancelServerQueryvtable slot. - Updated
QL_Steamworks_RequestServerDetailsso the three-detail-probe bundle is all-or-nothing: any non-positive query handle cancels the valid partial handles, leaves output handles zeroed, and returns false. - Verified
QL_Steamworks_BeginServerBrowserDetailRequeststays inactive on partial native detail allocation failure, allowing the client's existing UDP status-query fallback to run. - Added a Steamworks harness detail-query result setter plus enabled-build regression coverage for the low-level wrapper and retained detail owner.
- Pinned the new lifecycle invariant in the netcode parity manifest and documented the source-side inference boundary in round 346.
Task A228: Close Race gametype retail parity [COMPLETED]
Priority: High
Primary areas: src/code/game/g_race.c,
tests/test_racepoint_commands.py,
tests/test_game_nonteam_scoreboard_helper_parity.py,
tests/test_game_helper_seam_parity.py
Parity estimate: before 98% -> after 100% for the focused Race gametype
server command, checkpoint, timing, score transport, admin-point, and
scoreboard wiring surface. Broader gameplay/gametype parity remains
approximately 99% repo-wide because this pass closes the remaining
Race-specific qagame scoreboard/start-predicate drift without changing the
known compatibility-only lanes.
Completed work:
- Rechecked qagame and cgame retail evidence for
race_info,race_init,admin_race_point_N, Race touch events, finish ranking, andscores_racerow transport. - Aligned
G_RaceBuildScoreStringwith retail qagame ownership by consuminglevel.numPlayingClientsandlevel.sortedClientsinstead of rebuilding a local Race order with a privateqsortcomparator. - Tightened the Race start predicate to the retail targetname-free authored
map behavior while preserving the command-spawned
arp*admin chain for immediate testing/editing. - Extended the compiled Race command probe and static parity guards to pin the retail score row shape: client number, personal best/PERS_SCORE, clamped ping, and session seconds in the sorted-client order.
Task A227: Close Red Rover retail gametype parity [COMPLETED]
Priority: High
Primary areas: src/code/game/g_client.c, src/code/game/g_cmds.c,
src/code/game/g_combat.c, src/code/game/g_local.h, src/code/game/g_rr.c,
tests/test_game_round_controller_helper_parity.py,
tests/test_game_active_pmove_wiring_parity.py,
tests/test_game_helper_seam_parity.py,
docs/reverse-engineering/qagame-setteam-reconstruction-2026-05-25.md
Parity estimate: before 90% -> after 100% for the focused Red Rover
gametype server surface: damage-score/active-round gating, infected
spawn/loadout ownership, and SetTeam warmup/pre-release wiring. Broader Red
Rover gametype wiring moves approximately 95% -> 100% because the round
controller, infection seeding/spread, survivor bonus, autojoin, scoreboard,
cgame HUD, and last-alive paths were already source-owned while the retail
boolean damage helper dispatch and direct Red Rover SetTeam spawn branch still
needed to be closed. Repo-wide parity remains 99%.
Completed work:
- Rechecked
qagamex86.dllsymbols, Ghidra function inventory, Binary Ninja HLIL0x100643E0, and theG_Damagegametype-12 call site. - Converted
G_RRHandleDamageScoreto the retail helper shape: same-team suppression, active-round gating, health/armor damage caps, and 100-damage score buckets for the non-infected lane. - Preserved the already recovered infected-survivor score policy inside the active-round helper after retail damage capping.
- Wired
G_Damageso Red Rover calls the helper at the retail post-armor split point and aborts inactive-round damage when the helper returns false. - Split the Red Rover spawn/loadout finalizer so infected clients consume the zombie gauntlet/health path before the generic loadout finalizer, matching the retail survivor-vs-infected branch.
- Restored the Red Rover seed/spread forced-conversion shortcut so RR team
mutations rerun
G_RRResetClientForRounddirectly, matching the retail internal team-change latch without broadening externalSetTeam. - Retired the stale non-owning
g_rr.cstub so the source tree no longer carries a second, divergent Red Rover implementation. - Extended the Red Rover parity tests to pin the source helper, public prototypes, combat/SetTeam dispatch, loadout split, build-owner boundary, and HLIL offsets used for reconstruction.
Task A226: Close Domination gametype retail parity [COMPLETED]
Priority: High
Primary areas: src/code/game/g_team.c, src/code/game/g_local.h,
src/code/game/g_main.c, tests/test_game_domination_parity.py
Parity estimate: before 93% -> after 100% for the focused Domination
gametype server and client-wiring surface. Broader gameplay/gametype parity
remains approximately 99% repo-wide because this pass closes the known
Domination-specific qagame reward, point activation, and defense routing gaps
without changing unrelated gametype lanes.
Completed work:
- Rechecked
qagamex86.dllBinary Ninja HLIL and symbol-map evidence forTeam_SelectDominationSpawnPoint,G_DominationRewardCaptureParticipants,G_DominationSelectPrimaryCapturer,G_DominationPointActivate,G_UpdateDominationPointCountConfigstrings,G_DominationCheckDefenseBonus,SP_team_dom_point, and theTeam_FragBonusesDomination branch. - Restored the retail qagame five-point registration cap and delayed
team_dom_pointfloor-settling activation trace while preserving delayed spawn-target retry wiring. - Added current-frame Domination participant lists, primary-capturer retention, and retail capture/assist reward fan-out with the 25/15 score bonuses, award sprites, persistent counters, and rank medal events.
- Routed Domination frags through the retail owned-point defense check before
CTF flag logic and accepted the retail
DEFENSEmedal token in the rank resolver. - Added focused Domination parity tests and validated them with the existing Domination count and gametype lifecycle fixtures plus a Debug Win32 native solution build.
Task A225: Tighten native Steam browser request-handle fallback [COMPLETED]
Priority: High
Primary areas: src/common/platform/platform_steamworks.c,
src/code/client/cl_main.c, tests/steamworks_harness.c,
tests/test_steamworks_harness.py, tests/test_platform_services.py,
tests/test_netcode_parity_manifest.py,
docs/reverse-engineering/quakelive_steam_mapping_round_345.md
Parity estimate: before 88% -> after 98% for the focused native
server-browser request-owner failure path. Broader WebUI server-browser
ownership remains approximately 99% because the list and detail native
owners were already wired; this pass closes the null-handle fallback hole and
relabels friends/history compatibility telemetry as fallback-only. Repo-wide
parity remains 99% because the QL_BUILD_ONLINE_SERVICES default-disabled
policy boundary is unchanged.
Completed work:
- Rechecked
quakelive_steam.exeHLIL and alias evidence forJSBrowser_RequestServers,SteamBrowser_RefreshList,JSBrowser_OnRefreshComplete, and the retainedISteamMatchmakingServersrequest-mode slots. - Confirmed the current client list path is native-first for internet, LAN, friends, favorites, and history modes when an opted-in Steamworks provider exposes the native server-browser interface.
- Updated
QL_Steamworks_BeginServerBrowserOwnerRequestso a zero native request handle returns false, leaves the owner idle, and lets the existing source-browser fallback run instead of timing out an active-but-handleless native refresh. - Added a Steamworks harness request-result setter and lifecycle coverage for the zero-handle path.
- Relabeled the browser compatibility diagnostics so friends/history now read as source fallback mappings after native request-handle failure, not as permanently source-owned modes.
Task A224: Wire Clan Arena retail damage-score helper [COMPLETED]
Priority: High
Primary areas: src/code/game/g_team.c, src/code/game/g_combat.c,
src/code/game/g_local.h, tests/test_game_round_controller_helper_parity.py
Parity estimate: before 92% -> after 98% for the focused Clan Arena
damage-score and active-round damage gate lane. Broader Clan Arena gametype
wiring moves approximately 96% -> 98% because the round controller,
spectator reset/release, compact scoreboard, castats, and last-alive event
surfaces were already reconstructed while the dedicated retail CA damage helper
was still absent. Repo-wide parity remains 99%.
Completed work:
- Rechecked
qagamex86.dllGhidra metadata/function inventory and Binary Ninja HLIL for0x10037F80,0x10037FD0,0x10038230, and the sibling Attack & Defend damage helper. - Added
G_CAHandleDamageScoreto mirror the retail CA post-armor damage helper: same-team suppression, active-round gating, health/armor damage caps, and 100-damage score bucket conversion through directPERS_SCOREincrements plusCalculateRanks. - Wired
G_Damageso Clan Arena calls the CA helper at the retail post-armor split point and aborts inactive-round damage when the helper returns false. - Extended the round-controller parity test to pin the source helper,
G_Damagedispatch, and the HLIL evidence offsets used for reconstruction.
Task A223: Name the SteamDataSource non-avatar fallback owner [COMPLETED]
Priority: High
Primary areas: src/code/client/cl_steam_resources.c,
src/code/client/cl_main.c, tests/test_platform_services.py,
tests/test_awesomium_browser_parity.py,
tools/ci/verify-awesomium-browser-host-parity.ps1,
docs/reverse-engineering/quakelive_steam_mapping_round_344.md
Parity estimate: before 82% -> after 96% for the focused
SteamDataSource fallback-owner diagnostic surface. Broader SteamDataSource
resource-bridge source visibility moves approximately 93% -> 95% because
the fallback owner is now named and cvar-published, while exact live Awesomium
delayed-response ownership remains bounded. Repo-wide parity remains 99%
because the QL_BUILD_ONLINE_SERVICES default-disabled policy boundary is
unchanged.
Completed work:
- Rechecked
quakelive_steam.exesymbols and HLIL forSteamDataSource,QLResourceInterceptor, theAwesomium::DataSource::SendResponseboundary, and prior mapping rounds 91 and 289. - Added a source-visible
QLResourceInterceptor launcher/web fallbackowner label for non-avatarsteam://requests outside the avatar-native SteamDataSource subset. - Published SteamDataSource subset, native-gap, and fallback-owner labels through the retained resource-bridge ROM cvar surface.
- Updated non-avatar Steam resource diagnostics to say they are routed to the launcher/web fallback owner rather than leaving the route as a generic missing-owner message.
- Extended platform-service, Awesomium parity, and verifier-script anchors to pin the label and cvars.
Task A222: Wire WebUI server browser native Steam detail owner [COMPLETED]
Priority: High
Primary areas: src/code/client/cl_main.c,
src/common/platform/platform_steamworks.[ch],
tests/test_steamworks_harness.py, tests/steamworks_harness.c,
tests/test_platform_services.py, tests/test_netcode_parity_manifest.py,
docs/reverse-engineering/quakelive_steam_mapping_round_343.md
Parity estimate: before 74% -> after 98% for the focused WebUI
server-detail request dispatch lane. Broader server-browser/details parity
moves approximately 98% -> 99% because native detail callbacks are now
wired while provider-disabled and failed native requests still retain explicit
source-owned fallbacks. Repo-wide parity remains 99% because the
QL_BUILD_ONLINE_SERVICES default-disabled policy boundary is unchanged.
Completed work:
- Rechecked
quakelive_steam.exeHLIL, alias, and prior mapping evidence forSteamBrowser_RequestServerDetails,JSBrowserDetails_RequestServerDetails, the0x58-byte callback object, the base/base+4/base+8 callback views, and thePingServer -> ServerRules -> PlayerDetailsquery order. - Added
QL_Steamworks_ReadServerBrowserPingResponseso raw Steamgameserveritem_tping payloads project into the retainedservers.details.<ip>_<port>.responseWebUI shape. - Added a client-owned native detail object with ping, rules, and players callbacks that publish the retained detail response/failed/end event families.
- Made
CL_Steam_RequestServerDetailsnative-first for opted-in Steamworks builds, keeping the existing UDP status query as an explicit fallback. - Extended harness, platform-service, and netcode parity tests to pin the new native detail owner, projection helper, and source fallback boundary.
Task A221: Allow retail LAN clients through server auth fallback [COMPLETED]
Priority: High
Primary areas: src/code/server/sv_game.c, src/code/server/sv_client.c,
tests/test_platform_services.py
Parity estimate: before 92% -> after 100% for the focused retail-client
LAN dedicated-server auth slice. Repo-wide parity remains 99% because this
closes a narrow policy mismatch without changing the broader default-disabled
online-service boundary.
Completed work:
- Aligned the qagame-facing
trap_VerifySteamAuthfallback with the existingSys_IsLANAddresschallenge fast path so retail clients on a private LAN no longer fail withFailed to verify Steam auth token. - Kept LAN joins out of the live Steam GameServer auth-session bootstrap even if userinfo happens to carry an auth token.
- Updated platform-service coverage so the LAN fallback and auth-session skip remain pinned.
Task A220: Wire WebUI server browser native Steam list owner [COMPLETED]
Priority: High
Primary areas: src/code/client/cl_main.c, tests/test_platform_services.py,
tests/test_netcode_parity_manifest.py,
docs/reverse-engineering/webui-server-browser-native-steamworks-2026-06-05.md
Parity estimate: before 82% -> after 100% for the focused WebUI
server-list dispatch slice. Broader server-browser/details parity moves
approximately 96% -> 98% because native list callbacks are now wired while
detail requests still retain the existing UDP status fallback. Repo-wide parity
remains 99% because the QL_BUILD_ONLINE_SERVICES default-disabled policy
boundary is unchanged.
Completed work:
- Rechecked the
quakelive_steam.exeHLIL and alias evidence forJSBrowser_RequestServers,SteamBrowser_RequestServers,JSBrowser_OnServerResponded,JSBrowser_OnServerFailedToRespond,JSBrowser_OnRefreshComplete, and theSteamMatchmakingServersimport. - Confirmed the empty WebUI Internet list was caused by routing through the policy-disabled legacy UDP master query rather than by missing Steam auth.
- Added a native
ISteamMatchmakingServerListResponseowner incl_main.cso opted-in Steamworks builds publishservers.details.*.response,servers.details.*.failed, andservers.refresh.endevents into the WebUI. - Kept default builds and runtime-disabled profiles on the explicit fallback
path; Steam and other Quake Live online services remain opt-in behind
QL_BUILD_ONLINE_SERVICES. - Updated focused platform and netcode parity guards so the browser request surface is pinned as native-first with source-owned fallback.
Task A219: Map botlib precompiler source-handle API parity [COMPLETED]
Priority: Medium
Primary areas: src/code/botlib/l_precomp.c,
src/code/botlib/be_interface.c, src/code/game/botlib.h,
src/code/game/g_public.h, src/code/game/g_syscalls.c,
src/code/server/sv_game.c, src/code/server/ql_game_imports.inc,
tests/test_botlib_internal_parity.py,
docs/reverse-engineering/botlib-precompiler-source-handle-mapping-2026-06-05.md
Parity estimate: before 76% -> after 96% for the focused precompiler
source-handle API slice. Overall botlib plus related parser/API wiring moves
approximately 68% -> 69% because this pass closes a compact ABI boundary
without changing broader macro expansion, script lexing, AAS, or gameplay
heuristics.
Completed work:
- Selected
l_precomp.cpublic source-handle wrappers as the next botlib slice after the structure/character/weight parser corridor. - Rechecked retail
quakelive_steam.exeHLIL and Ghidrafunctions.csvevidence forPC_LoadSourceHandle,PC_FreeSourceHandle,PC_ReadTokenHandle,PC_SourceFileAndLine,PC_SetBaseFolder, andPC_CheckOpenSourceHandles. - Pinned source and retail behavior for
MAX_SOURCEFILES == 64, valid handle range1..63, token field copying,TT_STRINGquote stripping, source file/line reporting, base-folder forwarding, and open-source leak warnings. - Confirmed related wiring through
botlib_export_t,GetBotLibAPI, legacySV_GameSystemCallsImpldispatch, qagame compatibility import table wrappers, and classictrap_PC_*syscall stubs. - Documented that
BOTLIB_PC_ADD_GLOBAL_DEFINEhas a named direct native qagame import slot while the four PC source-handle calls intentionally remain behind the retained compatibility import surface.
Task A218: Extend botlib parser-resource sibling mapping [COMPLETED]
Priority: Medium
Primary areas: src/code/botlib/be_ai_char.c,
src/code/botlib/be_ai_weight.c,
tests/test_botlib_internal_parity.py,
docs/reverse-engineering/botlib-structure-resource-reader-mapping-2026-06-05.md
Parity estimate: before 97% -> after 98% for the focused botlib
parser-resource corridor selected around l_struct.c and its adjacent
resource loaders. Overall botlib plus related parser wiring moves
approximately 67% -> 68% because this pass adds characteristic and
fuzzy-weight parser evidence without changing broader AAS, movement, or combat
heuristics.
Completed work:
- Extended the selected botlib parser section from structure-table resources
into the closest source siblings:
be_ai_char.ccharacter resources andbe_ai_weight.cfuzzy-weight resources. - Rechecked retail
quakelive_steam.exeHLIL and Ghidra evidence forBotLoadCharacterFromFile,BotLoadCachedCharacter,BotLoadCharacterSkill,ReadValue,ReadFuzzyWeight,ReadFuzzySeperators_r,ReadWeightConfig, andFindFuzzyWeight. - Pinned retail allocation/layout evidence: character load allocation
0x2cc, weight config allocation0x444,MAX_CHARACTERISTICS == 80,MAX_WEIGHT_FILES == 128, and the weight filename copy at offset0x404. - Preserved parser quirks as retail parity facts, including the characteristic upper-bound check shape and fuzzy-switch missing-default fallback.
- Documented that
be_ai_weight.cwriter helpers remain inside#if 0, reinforcing that active retail evidence belongs to the read-side parser surface for this round.
Task A217: Map botlib structure resource reader parity [COMPLETED]
Priority: Medium
Primary areas: src/code/botlib/l_struct.c,
src/code/botlib/be_ai_goal.c, src/code/botlib/be_ai_weap.c,
references/analysis/quakelive_symbol_aliases.json,
tests/test_botlib_internal_parity.py,
docs/reverse-engineering/botlib-structure-resource-reader-mapping-2026-06-05.md
Parity estimate: before 72% -> after 97% for the focused
l_struct.c resource-reader plus item/weapon/projectile consumer-table mapping
slice. Overall botlib plus related parser wiring moves approximately
65% -> 67% because this pass tightens a narrow resource-parser proof
surface without changing broader bot movement, AAS, or gameplay heuristics.
Completed work:
- Selected botlib structure resource parsing as the next productive forward section because it gates bot item, weapon, and projectile resource data.
- Rechecked retail
quakelive_steam.exeHLIL and Ghidra evidence forFindField,ReadNumber, andReadStructure, including diagnostic strings, numeric bounds behavior, nested-structure handling, and consumer call sites. - Confirmed the checked-in C source already matches the observed retail shape,
including the source-local
ReadChar/ReadStringhelpers that retail folds intoReadStructure. - Added focused regression coverage that pins the structure-reader source contract, bot item/weapon consumers, alias map entries, HLIL anchors, and Ghidra call-site evidence.
- Extended the pass to the concrete
iteminfo,weaponinfo, andprojectileinfofield tables, retail allocation sizes, table data addresses, top-level resource tokens, and weapon/projectile fix-up wiring. Documented the adjacent writer helpers as source-real but not yet safely retail-aliased because the visibleWriteStructurecaller is debug-gated.
Task A216: Verify server snapshot related wiring parity [COMPLETED]
Priority: High
Primary areas: src/code/server/sv_snapshot.c, src/code/server/sv_bot.c,
src/code/server/sv_game.c, src/code/game/g_syscalls.c,
src/code/game/ai_main.c, src/code/client/cl_parse.c,
src/code/client/cl_cgame.c, src/code/cgame/cg_snapshot.c,
tests/test_netcode_parity_manifest.py
Parity estimate: before 100% -> after 100% for the focused server
snapshot related-wiring slice. Repo-wide parity remains 99% because this
pass confirmed adjacent retail wiring and added a missing guard without
changing the broader compatibility-only or validation-freshness boundaries.
Completed work:
- Rechecked the server snapshot construction/send path, client parse/readback path, cgame snapshot pump, qagame visibility exports, and bot snapshot entity bridge against the committed HLIL aliases and existing parity tests.
- Confirmed no additional source behavior drift after the
SV_SendClientSnapshotwrapper closure: snapshot body writing still flows directly to overflow handling/send, client/cgame readback remains ordered, and bot clients query the built snapshot ring without packet emission. - Added a focused parity guard that pins
SV_BotGetSnapshotEntityandQL_G_trap_BotGetSnapshotEntityto retailsub_4DDAC0/sub_4E17E0, including the legacy syscall, native import slot, qagame syscall mapping, andBotAI_GetSnapshotEntityhandoff.
Task A215: Verify client connection adjacent wiring parity [COMPLETED]
Priority: High
Primary areas: src/code/client/cl_main.c, src/code/client/cl_net_chan.c,
src/code/server/sv_client.c, src/code/server/sv_main.c,
src/code/cgame/cg_newdraw.c, tests/test_engine_netcode_parity.py
Parity estimate: before 96% -> after 100% for the adjacent client
connection wiring slice. Repo-wide parity remains 99% because this pass
confirmed the focused wiring and corrected a stale guard rather than changing
the broader online-service or validation-freshness boundaries.
Completed work:
- Rechecked the related connection corridor around client connect/retry, challenge and connect responses, packet dispatch, client netchan setup, and server challenge/direct-connect acceptance.
- Confirmed the cgame serverinfo handoff still pulls the retail map-name
ownerdraw label from
CS_SERVERINFOthroughSERVERINFO_KEY_MAPNAME. - Corrected the broad engine-netcode parity guard so it matches the stricter
retail-backed cgame ownerdraw tests for the
CG_MapNameTexthelper. - Reran the focused and adjacent parity tests covering netcode manifest, engine netcode, client full-parity gate, client command/netchan wrappers, command registration/run-loop mapping, platform challenge/direct-connect wiring, and cgame map-name display wiring.
Task A214: Close client connection-response protocol parity [COMPLETED]
Priority: High
Primary areas: src/code/client/client.h, src/code/client/cl_main.c,
tests/test_netcode_parity_manifest.py,
docs/reverse-engineering/netcode-parity-manifest.json
Parity estimate: before 94% -> after 100% for the focused client
connection-response protocol slice. Repo-wide parity remains 99% because
the online-service policy and broader external validation freshness boundaries
are unchanged.
Completed work:
- Rechecked
CL_Connect_f,CL_CheckForResend, andCL_ConnectionlessPacketagainst the committedquakelive_steam.exeHLIL and Ghidra corpus. - Restored the retail bad-address path by publishing
CL_WebView_PublishGameError( "Bad server address" )after the failed address parse, matching retailsub_4F3570. - Added the missing 0x400-byte
challengeResponsesideband text slot beforeclc.netchanand copiedCmd_Argv(2)into it before enteringCA_CHALLENGING, matching the retail0x016177fc->0x01617bfclayout/order. - Tightened the netcode parity guard so the retail sideband copy, client connection layout, and connectionless state transition order remain pinned.
Task A213: Close server snapshot retail send parity [COMPLETED]
Priority: High
Primary areas: src/code/server/sv_snapshot.c,
src/code/server/sv_client.c, tests/test_netcode_parity_manifest.py,
docs/reverse-engineering/netcode-parity-manifest.json
Parity estimate: before 95% -> after 100% for the focused
SV_SendClientSnapshot retail send-wrapper slice. Repo-wide parity remains
99% because broader compatibility-only and online-service boundaries are
unchanged.
Completed work:
- Rechecked the
quakelive_steam.exeHLIL for0x004E5AC0and the Ghidrafunctions.csvrow forSV_SendClientSnapshot. - Removed the classic
SV_WriteDownloadToClientinjection fromSV_SendClientSnapshot, matching the retail order fromSV_WriteSnapshotToClientdirectly to overflow handling andSV_SendMessageToClient. - Kept legacy UDP download requests from arming stale
downloadNamestate now that QL snapshots no longer carrysvc_downloadblocks. - Updated the netcode manifest and parity guard so reintroducing snapshot-side classic download payloads is treated as a regression.
Task A212: Recheck client-side prediction retail parity [COMPLETED]
Priority: High
Primary areas: src/code/cgame/cg_predict.c,
src/code/cgame/cg_view.c, src/code/cgame/cg_ents.c,
src/code/cgame/cg_snapshot.c, tests/test_cgame_snapshot_parity.py,
references/symbol-maps/cgame.json, docs/reverse-engineering/cgame-mapping.md,
docs/reverse-engineering/cgame-client-prediction-parity-recheck-2026-06-05.md
Parity estimate: before 100% -> after 100% for the focused cgame
client-side prediction and related wiring slice. Repo-wide parity remains
99% because this pass strengthened validation for an already-closed
strict-retail corridor rather than closing a new whole-repo gap.
Completed work:
- Rechecked the
cgamex86.dllGhidra metadata, symbol map, and cgame mapping notes for the retail prediction corridor. - Confirmed no gameplay source patch was needed:
cg_predict.calready keeps the retail replay shape for interpolation fallbacks, localpmove_tsetup, command replay, item/trigger prediction, mover adjustment, step smoothing, projectile nudge, predicted rail replay, and transition handoff. - Tightened
tests/test_cgame_snapshot_parity.pyto pin the mapped solid-list, box/capsule trace, point-contents, interpolation, red/blue-flag predicate, high-value item skip, and complete prediction symbol-map evidence set. - Rechecked and pinned related wiring around prediction:
CG_DrawActiveFramecaller order,CG_AddPacketEntitiespredicted-player proxy, non-predicted local-player refresh, mover compensation, initial/next/ transition snapshot handoffs, snapshot pump, native draw wrapper, snapshot import, usercmd import, pmove settings, and the mapped retail symbols for those edges.
Task A211: Close server browser protocol and master heartbeat parity [COMPLETED]
Priority: High
Primary areas: src/code/client/cl_main.c, src/code/client/cl_cgame.c,
src/code/server/sv_main.c, src/code/server/sv_init.c,
src/code/server/sv_client.c, src/code/qcommon/common.c,
src/common/platform/platform_steamworks.c, tests/test_netcode_parity_manifest.py,
docs/reverse-engineering/network-server-browser-master-heartbeat-parity-2026-06-05.md
Parity estimate: before 96% -> after 100% for the focused server browser
protocol and master heartbeat slice. Repo-wide parity remains 99% because
the online-service boundary and broader native Steam product-integration policy
are unchanged.
Completed work:
- Rechecked the
quakelive_steam.exeHLIL and Ghidra corpus forgetserversResponse,getinfo xxx,getstatus,sv_master, protocol91, and the Steam GameServer / SteamMatchmakingServers imports. - Confirmed the active profile owns the Quake Live browser/status tokens and info keys, while legacy UDP master traffic remains policy-gated.
- Fixed
SV_MasterHeartbeatso explicit configuredhost:portmaster entries keep their port instead of being overwritten withPORT_MASTER. - Added a focused regression guard for the QL browser parser, request grammar, heartbeat token, Steam heartbeat owner, and committed retail evidence.
- Rechecked the related
qz_instancebrowser dispatch, browser event publication, nativeISteamMatchmakingServerswrapper, server info/status key publication, Steam GameServer published state, spawn/frame/reconnect/ shutdown heartbeat lifecycle, and default-disabled legacy UDP service gate. - Added a wiring-level parity guard so the related browser/heartbeat source graph remains pinned at 100% for this focused source-owned and policy-gated slice.
Task A210: Close selected 335-339 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_BLUE_TEAM_TIMEHELD_HASTE, CG_BLUE_TEAM_TIMEHELD_INVIS,
CG_FLAG_STATUS, CG_HEALTH_COLORIZED, and CG_MATCH_STATE ownerdraw set.
Repo-wide parity remains 98% because unrelated compatibility,
source-legacy, online-service, and packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher for raw ownerdraw cases0x14Fthrough0x153. - Confirmed blue Haste and Invisibility time-held ownerdraws normalize
through
0x10039AE0selector cases4and5, select the bluescorestats_teamrow, accumulate qagame hold-stat seconds through the Haste/Invisibility powerup mappings, and format through the recovered%i:%i%iminute-second helper. - Confirmed
CG_FLAG_STATUSroutes to the recovered retail objective-status graphic strip, with source parity covering the CTF-family, one-flag, Harvester, and Domination strip paths plus the preserved fallback label route for unsupported states. - Confirmed
CG_HEALTH_COLORIZEDresolves local or followed-client health/armor color, preserves the competitive HUDscorebox_followshader fallback, and keeps both shader-tint and filled-rect draw paths. - Confirmed
CG_MATCH_STATEpaints only the compact uppercase phase banner (MATCH SUMMARY,MATCH WARMUP, orMATCH IN PROGRESS) and leaves timeout/overtime text to their dedicated ownerdraws. - Added focused structural coverage and refreshed the cgame ownerdraw and mapping ledgers for the selected five.
Task A209: Close selected 330-334 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_BLUE_TEAM_PICKUPS_REGEN, CG_BLUE_TEAM_PICKUPS_HASTE,
CG_BLUE_TEAM_PICKUPS_INVIS, CG_BLUE_TEAM_TIMEHELD_FLAG, and
CG_BLUE_TEAM_TIMEHELD_REGEN ownerdraw set. Repo-wide parity remains 98%
because unrelated compatibility, source-legacy, online-service, and
packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher,0x10037F80sparse pickup-count helper, and0x10039AE0time-held helper for raw ownerdraw cases0x14Athrough0x14E. - Confirmed blue Regeneration, Haste, and Invisibility pickup ownerdraws
select the blue team-stat row, normalize through retail pickup selector
cases
9,10, and11, and paint direct integer counts from the parsedscorestats_teampayload. - Confirmed blue flag and Regeneration time-held ownerdraws select the blue
row, accumulate qagame hold-stat seconds through the flag/Regen powerup
mappings, and format through the recovered
%i:%i%iminute-second helper. - Confirmed the selected rows keep retail TDM/CTF payload membership, route
through the correct pickup versus time-held draw helpers, refresh
competitive scorestats through
CG_IsTeamPickupOwnerDraw, and have no value, width, or key callback routes. - Added focused structural coverage and refreshed the cgame ownerdraw and mapping ledgers for the selected five.
Task A208: Close selected 325-329 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_BLUE_TEAM_PICKUPS_BS, CG_BLUE_TEAM_TIMEHELD_QUAD,
CG_BLUE_TEAM_TIMEHELD_BS, CG_BLUE_TEAM_PICKUPS_FLAG, and
CG_BLUE_TEAM_PICKUPS_MEDKIT ownerdraw set. Repo-wide parity remains 98%
because unrelated compatibility, source-legacy, online-service, and
packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher,0x10037F80pickup-count helper, and0x10039AE0time-held helper for raw ownerdraw cases0x145through0x149. - Confirmed blue Battle Suit, flag, and Medkit pickup ownerdraws select the
blue team-stat row, normalize through the retail pickup selector, and paint
direct integer counts from the parsed
scorestats_teampayload. - Confirmed blue Quad and Battle Suit time-held ownerdraws select the blue
row, accumulate qagame hold-stat seconds, and format through the recovered
%i:%i%iminute-second helper. - Confirmed the selected rows keep retail TDM/CTF payload membership, route
through the correct pickup versus time-held draw helpers, refresh
competitive scorestats through
CG_IsTeamPickupOwnerDraw, and have no value, width, or key callback routes. - Added focused structural coverage and refreshed the cgame ownerdraw and mapping ledgers for the selected five.
Task A207: Close selected 308-312 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_RED_TEAM_TIMEHELD_HASTE, CG_RED_TEAM_TIMEHELD_INVIS,
CG_BLUE_FLAGSTATUS, CG_BLUE_NAME, and CG_BLUE_SCORE ownerdraw set.
Repo-wide parity remains 98% because unrelated compatibility,
source-legacy, online-service, and packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher for raw ownerdraw cases0x134through0x138. - Confirmed red Haste and Invisibility time-held ownerdraws normalize
through
0x10039AE0selector cases4and5, read the retailscorestats_teamcaches, and format with the minute-second helper. - Confirmed the blue flag-status, team-name, and score ownerdraws route to
retail leaves
0x10030A80,0x10030090, and0x1002FF50with matching team selection, fallback, alignment, and score value callback behavior. - Confirmed only the time-held pair refreshes competitive scorestats through the team-pickup ownerdraw predicate and that all selected width/key callback boundaries match retail.
- Added focused structural coverage and refreshed the cgame ownerdraw and mapping ledgers for the selected five.
Task A206: Close selected 315-319 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_BLUE_BASESTATUS, CG_BLUE_PLAYER_COUNT, CG_BLUE_CLAN_PLYRS,
CG_BLUE_TIMEOUT_COUNT, and CG_BLUE_TEAM_MAP_PICKUPS ownerdraw set.
Repo-wide parity remains 98% because unrelated compatibility,
source-legacy, online-service, and packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher for raw ownerdraw cases0x13Bthrough0x13F. - Confirmed
CG_BLUE_BASESTATUSstays on the shared0x10030A80flag/base-status helper with blue/base semantics and the expected competitive refresh boundary. - Confirmed
CG_BLUE_PLAYER_COUNT,CG_BLUE_CLAN_PLYRS, andCG_BLUE_TIMEOUT_COUNTpreserve the retail player-count formatter, round-family players-remaining gate, positive-team-size timeout gate, blue cached team-count source, blue timeout source, and alignment paths. - Confirmed
CG_BLUE_TEAM_MAP_PICKUPSenters the zero-offset blue aggregate pickup strip, consumes the parsed bluescorestats_teamrow, and refreshes competitive scorestats throughCG_IsTeamPickupOwnerDraw. - Added focused structural coverage and refreshed the cgame ownerdraw and mapping ledgers for the selected five.
Task A205: Close selected 320-324 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_BLUE_TEAM_PICKUPS_RA, CG_BLUE_TEAM_PICKUPS_YA,
CG_BLUE_TEAM_PICKUPS_GA, CG_BLUE_TEAM_PICKUPS_MH, and
CG_BLUE_TEAM_PICKUPS_QUAD ownerdraw set. Repo-wide parity remains 98%
because unrelated compatibility, source-legacy, online-service, and
packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher and0x10037F80team-pickup helper for raw ownerdraw cases0x140through0x144. - Confirmed the selected blue pickup ownerdraws normalize from
CG_BLUE_TEAM_MAP_PICKUPSto offsets1through5, consume the blue row of parsedscorestats_teamfields, and paint RA/YA/GA/MH/Quad counts through the retail direct integer text path. - Confirmed qagame publishes red then blue team-stat rows, cgame parses both
rows into
cg.teamScoreStats.values, and the retail TDM/CTF field order backs the selected RA/YA/GA/MH/Quad cache slots. - Confirmed the selected rows route through
CG_DrawTeamPickupOwnerDraw, refresh competitive scorestats throughCG_IsTeamPickupOwnerDraw, and have no value, width, or key callback routes. - Added focused structural coverage and refreshed the cgame ownerdraw and mapping ledgers for the selected five.
Task A204: Close selected 303-307 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/cgame/cg_servercmds.c,
tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 96% -> after 100% for the selected
CG_RED_TEAM_PICKUPS_REGEN, CG_RED_TEAM_PICKUPS_HASTE,
CG_RED_TEAM_PICKUPS_INVIS, CG_RED_TEAM_TIMEHELD_FLAG, and
CG_RED_TEAM_TIMEHELD_REGEN ownerdraw set. Repo-wide parity remains
98% because unrelated compatibility, source-legacy, online-service, and
packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher, pickup helper0x10037F80, time-held helper0x10039AE0, retail selector tables, and team scoreboard parsers for raw ownerdraw cases0x12fthrough0x133. - Confirmed red Regen/Haste/Invis pickup ownerdraws normalize through the
sparse retail selector to caches
data_10aa687c,data_10aa6880, anddata_10aa6884, then paint through the direct integer text path. - Confirmed red flag and Regeneration time-held ownerdraws normalize through
the retail time-held selector to
data_10aa68a4anddata_10aa6898, then use the shared%i:%i%iminute-second formatter. - Corrected the source TDM/CTF scoreboard aggregate header order so retail
scoreboard payloads populate the same sparse cache slots; the synthetic
CG_TEAMSTAT_MAP_PICKUPSslot remains limited to the compactscorestats_teampath. - Added focused structural coverage and refreshed the cgame ownerdraw and mapping ledgers for the selected five.
Task A203: Close selected 282 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for
CG_2ND_PLYR_TIER. Repo-wide parity remains 98% because unrelated
compatibility, source-legacy, online-service, and packaging surfaces are
unchanged.
Completed work:
- Rechecked the retail
cgamex86.dllownerdraw target set for raw ownerdraw0x11Aand confirmedCG_2ND_PLYR_TIERhas no retail draw helper route. - Confirmed source keeps
CG_2ND_PLYR_TIERas an explicit direct no-op with the neighboringCG_2ND_PLYR_PRboundary while leaving the broad second-player resolver range intact for adjacent ids. - Confirmed compact scorestats may still parse progression tier for data parity, but the tier ownerdraw has no placement guard, metric dispatcher, competitive refresh, value, width, key, or direct draw route.
- Added focused structural coverage and refreshed the cgame ownerdraw and mapping ledgers for the selected id.
Task A202: Close selected 277-281 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_2ND_PLYR_AVG_PICKUP_TIME_MH, CG_2ND_PLYR_EXCELLENT,
CG_2ND_PLYR_IMPRESSIVE, CG_2ND_PLYR_HUMILIATION, and
CG_2ND_PLYR_PR ownerdraw set. Repo-wide parity remains 98% because
unrelated compatibility, source-legacy, online-service, and packaging surfaces
are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher, pickup-average helper0x10037730, award-count helper0x10037990, and raw no-route boundary for ownerdraw cases0x115through0x119. - Confirmed
CG_2ND_PLYR_AVG_PICKUP_TIME_MHselects slot 1, consumes the compact MH pickup-average scorestats payload, paints through retail%3.2f, and preserves the"-"fallback when the MH pickup count is zero. - Confirmed
CG_2ND_PLYR_EXCELLENT,CG_2ND_PLYR_IMPRESSIVE, andCG_2ND_PLYR_HUMILIATIONselect slot 1, consume parsed duel-score award counts, and paint through the retail%dformatter. - Confirmed
CG_2ND_PLYR_PRremains an explicit no-op ownerdraw boundary: progression PR is still parsed from compact scorestats, but retail has no raw0x119draw helper, placement guard, competitive refresh, value, width, or key callback route. - Added focused structural coverage and refreshed the cgame ownerdraw and mapping ledgers for the selected five.
Task A201: Close selected 237-241 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_2ND_PLYR_SHOTS_RG, CG_2ND_PLYR_SHOTS_PG,
CG_2ND_PLYR_SHOTS_BFG, CG_2ND_PLYR_SHOTS_CG, and
CG_2ND_PLYR_SHOTS_NG ownerdraw set. Repo-wide parity remains 98%
because unrelated compatibility, source-legacy, online-service, and
packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher,0x10036B00weapon-shot leaf, and0x1002E2B0weapon resolver for raw ownerdraw cases0xedthrough0xf1. - Confirmed the selected second-player shot ownerdraws select slot 1,
resolve RG/PG/BFG/CG/NG to weapon indexes
7,8,9,0xd, and0xb, readdata_10A6038C, and paint through the retail%dformatter. - Confirmed source normalization, metric dispatch, qagame scorestats emission, cgame scorestats parsing, competitive placement refresh, and ownerdraw/value/width/key callback absence match the retail wiring.
- Added focused structural coverage and refreshed the cgame ownerdraw and mapping ledgers for the selected five.
Task A200: Close selected 272-276 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_2ND_PLYR_PICKUPS_GA, CG_2ND_PLYR_PICKUPS_MH,
CG_2ND_PLYR_AVG_PICKUP_TIME_RA, CG_2ND_PLYR_AVG_PICKUP_TIME_YA,
and CG_2ND_PLYR_AVG_PICKUP_TIME_GA ownerdraw set. Repo-wide parity
remains 98% because unrelated compatibility, source-legacy,
online-service, and packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher, pickup-count helper0x10036EB0, and pickup-average helper0x10037730for raw ownerdraw cases0x110through0x114. - Confirmed
CG_2ND_PLYR_PICKUPS_GAandCG_2ND_PLYR_PICKUPS_MHselect slot 1, consume compact GA/MH pickup-countscorestatspayloads, and paint through the retail%dformatter. - Confirmed
CG_2ND_PLYR_AVG_PICKUP_TIME_RA,CG_2ND_PLYR_AVG_PICKUP_TIME_YA, andCG_2ND_PLYR_AVG_PICKUP_TIME_GAselect slot 1, consume compact pickup average payloads, paint through retail%3.2f, and preserve the retail"-"fallback when the associated pickup count is zero. - Confirmed source normalization, placement metric dispatch, qagame scorestats emission, cgame scorestats parsing, competitive placement refresh, and ownerdraw/value/width/key callback absence match the retail wiring.
- Added focused structural coverage and refreshed the cgame ownerdraw and mapping ledgers for the selected five.
Task A198: Close selected 232-236 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_2ND_PLYR_SHOTS_MG, CG_2ND_PLYR_SHOTS_SG,
CG_2ND_PLYR_SHOTS_GL, CG_2ND_PLYR_SHOTS_RL, and
CG_2ND_PLYR_SHOTS_LG ownerdraw set. Repo-wide parity remains 98%
because unrelated compatibility, source-legacy, online-service, and
packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher,0x10036B00weapon-shot leaf, and0x1002E2B0weapon resolver for raw ownerdraw cases0xe8through0xec. - Confirmed the selected second-player shot ownerdraws select slot 1,
resolve MG/SG/GL/RL/LG to weapon indexes
2,3,4,5, and6, readdata_10A6038C, and paint through the retail%dformatter. - Confirmed source normalization, metric dispatch, qagame scorestats emission, cgame scorestats parsing, competitive placement refresh, and ownerdraw/value/width/key callback absence match the retail wiring.
- Added focused structural coverage and refreshed the cgame ownerdraw and mapping ledgers for the selected five.
Task A199: Close selected 267-271 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_2ND_PLYR_ACC_PL, CG_2ND_PLYR_ACC_HMG, CG_2ND_PLYR_PICKUPS,
CG_2ND_PLYR_PICKUPS_RA, and CG_2ND_PLYR_PICKUPS_YA ownerdraw set.
Repo-wide parity remains 98% because unrelated compatibility,
source-legacy, online-service, and packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher, HLIL weapon-accuracy leaf, pickup-count/summary leaf, and shared placement weapon resolver for raw ownerdraw cases0x10Bthrough0x10F. - Confirmed
CG_2ND_PLYR_ACC_PLandCG_2ND_PLYR_ACC_HMGstay on the pre-switch0x10036D60accuracy helper, normalize through the retail0x1002E2B0weapon resolver, preserve the Quake Live enum gaps for PL/HMG, and consume hit/shot-derivedscorestatsaccuracy payloads. - Confirmed
CG_2ND_PLYR_PICKUPS,CG_2ND_PLYR_PICKUPS_RA, andCG_2ND_PLYR_PICKUPS_YAstay on the pre-switch0x10036EB0pickup helper, select slot 1, and consume compact RA/YA/GA/MH pickup count and average scorestats payloads. - Confirmed the selected pickup summary/count ownerdraws preserve retail
placement summary icon/text layout, direct
%dcount formatting for RA/YA, competitive refresh, and absence from directCG_OwnerDraw, value, width, and key callback routes. - Added focused structural coverage for constants, retail target-group
membership, HLIL resolver/cache/format/layout signals, server/client
scorestatstransport, weapon and pickup mapping, dispatcher routing, callback absence, and competitive refresh wiring. - Refreshed the cgame ownerdraw and mapping ledgers for the selected five.
Task A197: Close selected 298-302 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_RED_TEAM_PICKUPS_BS, CG_RED_TEAM_TIMEHELD_QUAD,
CG_RED_TEAM_TIMEHELD_BS, CG_RED_TEAM_PICKUPS_FLAG, and
CG_RED_TEAM_PICKUPS_MEDKIT ownerdraw set. Repo-wide parity remains
98% because unrelated compatibility, source-legacy, online-service, and
packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher,0x10037F80pickup-count leaf, and0x10039AE0time-held leaf for raw ownerdraw cases0x12athrough0x12e. - Confirmed
CG_RED_TEAM_PICKUPS_BS,CG_RED_TEAM_PICKUPS_FLAG, andCG_RED_TEAM_PICKUPS_MEDKITstay in thearg5 - 0x124retail pickup range and paint the direct red team integer fields for offsets6,9, and0xa. - Confirmed
CG_RED_TEAM_TIMEHELD_QUADandCG_RED_TEAM_TIMEHELD_BSroute through0x10039AE0, resolve offsets0and1, and format seconds through the recovered%i:%i%iminute-second helper. - Confirmed source metadata, team-scorestats transports, pickup/time-held dispatcher split, competitive refresh, and value/width/key callback absence match retail wiring.
- Added focused structural coverage and refreshed the cgame ownerdraw and mapping ledgers for the selected five.
Task A196: Close selected 227-231 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_2ND_PLYR_HITS_BFG, CG_2ND_PLYR_HITS_CG,
CG_2ND_PLYR_HITS_NG, CG_2ND_PLYR_HITS_PL, and
CG_2ND_PLYR_HITS_HMG ownerdraw set. Repo-wide parity remains 98%
because unrelated compatibility, source-legacy, online-service, and
packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher,0x100369D0weapon-hit leaf, and0x1002E2B0weapon resolver for raw ownerdraw cases0xe3through0xe7. - Confirmed the selected second-player hit ownerdraws select slot 1,
resolve BFG/CG/NG/PL/HMG to weapon indexes
9,0xd,0xb,0xc, and0xe, readdata_10A603CC, and paint through the retail%dformatter. - Confirmed source normalization, metric dispatch, qagame scorestats emission, cgame scorestats parsing, competitive placement refresh, and ownerdraw/value/width/key callback absence match the retail wiring.
- Added focused structural coverage and refreshed the cgame ownerdraw and mapping ledgers for the selected five.
Task A195: Close selected 293-297 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_RED_TEAM_PICKUPS_RA, CG_RED_TEAM_PICKUPS_YA,
CG_RED_TEAM_PICKUPS_GA, CG_RED_TEAM_PICKUPS_MH, and
CG_RED_TEAM_PICKUPS_QUAD ownerdraw set. Repo-wide parity remains 98%
because unrelated compatibility, source-legacy, online-service, and
packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher and0x10037F80team-pickup leaf for raw ownerdraw cases0x125through0x129. - Confirmed all five selected ownerdraws stay in the
arg5 - 0x124retail range, resolve to offsets1through5, and paint the direct red team pickup-count fields through the common integer text path. - Confirmed source metadata maps the selected rows to
CG_TEAMSTAT_PICKUPS_RA,CG_TEAMSTAT_PICKUPS_YA,CG_TEAMSTAT_PICKUPS_GA,CG_TEAMSTAT_PICKUPS_MH, andCG_TEAMSTAT_PICKUPS_QUAD, backed by the retail team-scorestats header andscorestats_teamtransports. - Confirmed the selected rows route through
CG_DrawTeamPickupOwnerDraw, refresh competitive scorestats throughCG_IsTeamPickupOwnerDraw, and have no value, width, key, or time-held callback routes. - Added focused structural coverage and refreshed the cgame ownerdraw and mapping ledgers for the selected five.
Task A194: Close selected 262-266 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_2ND_PLYR_ACC_RG, CG_2ND_PLYR_ACC_PG, CG_2ND_PLYR_ACC_BFG,
CG_2ND_PLYR_ACC_CG, and CG_2ND_PLYR_ACC_NG ownerdraw set. Repo-wide
parity remains 98% because unrelated compatibility, source-legacy,
online-service, and packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher and HLIL weapon-accuracy leaf for raw ownerdraw cases0x106through0x10A. - Confirmed all five selected ownerdraws stay on the pre-switch
0x10036D60accuracy helper, normalize through the retail0x1002E2B0weapon resolver, and consume hit/shot-derivedscorestatsaccuracy payloads. - Confirmed the selected accuracy ownerdraws resolve to Railgun, Plasmagun, BFG, Chaingun, and Nailgun, preserving the Quake Live enum gaps for CG and NG.
- Confirmed all five selected ownerdraws preserve the retail best-row white
0.8alpha override, refresh the competitive score cache, draw through the placement metric dispatcher instead of directCG_OwnerDrawcases, and have no value, width, or key callback routes. - Added focused structural coverage for constants, retail target-group
membership, HLIL resolver/cache/format/color/paint signals, server/client
scorestatstransport, weapon mapping, dispatcher routing, callback absence, and competitive refresh wiring. - Refreshed the cgame ownerdraw and mapping ledgers for the selected five.
Task A193: Close selected 222-226 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_2ND_PLYR_HITS_GL, CG_2ND_PLYR_HITS_RL,
CG_2ND_PLYR_HITS_LG, CG_2ND_PLYR_HITS_RG, and
CG_2ND_PLYR_HITS_PG ownerdraw set. Repo-wide parity remains 98%
because unrelated compatibility, source-legacy, online-service, and
packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher,0x100369D0weapon-hit leaf, and0x1002E2B0weapon resolver for raw ownerdraw cases0xdethrough0xe2. - Confirmed the selected second-player hit ownerdraws select slot 1,
resolve GL/RL/LG/RG/PG to weapon indexes
4,5,6,7, and8, readdata_10A603CC, and paint through the retail%dformatter. - Confirmed source normalization, metric dispatch, qagame scorestats emission, cgame scorestats parsing, competitive placement refresh, and ownerdraw/value/width/key callback absence match the retail wiring.
- Added focused structural coverage and refreshed the cgame ownerdraw and mapping ledgers for the selected five.
Task A192: Close selected 257-261 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_2ND_PLYR_ACC_MG, CG_2ND_PLYR_ACC_SG, CG_2ND_PLYR_ACC_GL,
CG_2ND_PLYR_ACC_RL, and CG_2ND_PLYR_ACC_LG ownerdraw set. Repo-wide
parity remains 98% because unrelated compatibility, source-legacy,
online-service, and packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher and HLIL weapon-accuracy leaf for raw ownerdraw cases0x101through0x105. - Confirmed all five selected ownerdraws stay on the pre-switch
0x10036D60accuracy helper, normalize through the retail0x1002E2B0weapon resolver, and consume hit/shot-derivedscorestatsaccuracy payloads. - Confirmed the selected accuracy ownerdraws resolve to Machinegun, Shotgun, Grenade Launcher, Rocket Launcher, and Lightning Gun.
- Confirmed all five selected ownerdraws preserve the retail best-row white
0.8alpha override, refresh the competitive score cache, draw through the placement metric dispatcher instead of directCG_OwnerDrawcases, and have no value, width, or key callback routes. - Added focused structural coverage for constants, retail target-group
membership, HLIL resolver/cache/format/color/paint signals, server/client
scorestatstransport, weapon mapping, dispatcher routing, callback absence, and competitive refresh wiring. - Refreshed the cgame ownerdraw and mapping ledgers for the selected five.
Task A191: Close selected 288-292 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_RED_BASESTATUS, CG_RED_PLAYER_COUNT, CG_RED_CLAN_PLYRS,
CG_RED_TIMEOUT_COUNT, and CG_RED_TEAM_MAP_PICKUPS ownerdraw set.
Repo-wide parity remains 98% because unrelated compatibility,
source-legacy, online-service, and packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher paths for raw ownerdraw cases0x120through0x124. - Confirmed red base status shares
0x10030A80with flag status, red player count routes to0x100333C0, red clan-player count routes to0x100335F0behind the players-remaining gate, and red timeout count routes to0x10033530behind the positive team-size gate. - Confirmed red map pickups enter the
0x10037F80aggregate pickup strip as the zero-offset red range case, preserving parsedscorestats_teamfields, icon selection, visible positive-count filtering, and the retail25/28slot strides. - Added focused structural coverage and refreshed the cgame ownerdraw and mapping ledgers for the selected five.
Task A190: Close selected 217-221 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_2ND_PLYR_FRAGS_NG, CG_2ND_PLYR_FRAGS_PL,
CG_2ND_PLYR_FRAGS_HMG, CG_2ND_PLYR_HITS_MG, and
CG_2ND_PLYR_HITS_SG ownerdraw set. Repo-wide parity remains 98%
because unrelated compatibility, source-legacy, online-service, and
packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher,0x100368A0weapon-frag leaf,0x100369D0weapon-hit leaf, and0x1002E2B0weapon resolver for raw ownerdraw cases0xd9through0xdd. - Confirmed
CG_2ND_PLYR_FRAGS_NG,CG_2ND_PLYR_FRAGS_PL, andCG_2ND_PLYR_FRAGS_HMGselect slot 1, resolve to weapon indexes0xb,0xc, and0xe, readdata_10A6030C, and paint through the retail%dformatter. - Confirmed
CG_2ND_PLYR_HITS_MGandCG_2ND_PLYR_HITS_SGselect slot 1, resolve to weapon indexes2and3, readdata_10A603CC, and paint through the retail%dformatter. - Confirmed source normalization, metric dispatch, qagame scorestats emission, cgame scorestats parsing, competitive placement refresh, and ownerdraw/value/width/key callback absence match the retail wiring across the frag-order and accuracy-order payload split.
- Added focused structural coverage and refreshed the cgame ownerdraw and mapping ledgers for the selected five.
Task A189: Close selected 252-256 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_2ND_PLYR_DMG_BFG, CG_2ND_PLYR_DMG_CG, CG_2ND_PLYR_DMG_NG,
CG_2ND_PLYR_DMG_PL, and CG_2ND_PLYR_DMG_HMG ownerdraw set. Repo-wide
parity remains 98% because unrelated compatibility, source-legacy,
online-service, and packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher and HLIL damage leaf for raw ownerdraw cases0xfcthrough0x100. - Confirmed all five selected ownerdraws stay on the pre-switch
0x10036C30damage helper, normalize through the retail0x1002E2B0weapon resolver, and consume the parsedscorestatsdamage payload. - Confirmed the selected damage ownerdraws resolve to BFG, Chaingun, Nailgun, Proximity Launcher, and Heavy Machinegun, preserving the Quake Live enum gaps for CG/NG/PL/HMG.
- Confirmed all five selected ownerdraws refresh the competitive score cache,
draw through the placement metric dispatcher instead of direct
CG_OwnerDrawcases, and have no value, width, or key callback routes. - Added focused structural coverage for constants, retail target-group
membership, HLIL resolver/cache/format/paint signals, server/client
scorestatstransport, weapon mapping, dispatcher routing, callback absence, and competitive refresh wiring. - Refreshed the cgame ownerdraw and mapping ledgers for the selected five.
Task A188: Close selected 212-216 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_2ND_PLYR_FRAGS_LG, CG_2ND_PLYR_FRAGS_RG,
CG_2ND_PLYR_FRAGS_PG, CG_2ND_PLYR_FRAGS_BFG, and
CG_2ND_PLYR_FRAGS_CG ownerdraw set. Repo-wide parity remains 98%
because unrelated compatibility, source-legacy, online-service, and
packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher,0x100368A0weapon-frag leaf, and0x1002E2B0weapon resolver for raw ownerdraw cases0xd4through0xd8. - Confirmed the selected second-player frag ownerdraws select slot 1,
resolve LG/RG/PG/BFG/CG to weapon indexes
6,7,8,9, and0xd, readdata_10A6030C, and paint through the retail%dformatter. - Confirmed source normalization, metric dispatch, qagame scorestats emission, cgame scorestats parsing, competitive placement refresh, and ownerdraw/value/width/key callback absence match the retail wiring.
- Added focused structural coverage and refreshed the cgame ownerdraw and mapping ledgers for the selected five.
Task A187: Close selected 247-251 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_2ND_PLYR_DMG_GL, CG_2ND_PLYR_DMG_RL, CG_2ND_PLYR_DMG_LG,
CG_2ND_PLYR_DMG_RG, and CG_2ND_PLYR_DMG_PG ownerdraw set. Repo-wide
parity remains 98% because unrelated compatibility, source-legacy,
online-service, and packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher and HLIL damage leaf for raw ownerdraw cases0xf7through0xfb. - Confirmed all five selected ownerdraws stay on the pre-switch
0x10036C30damage helper, normalize through the retail0x1002E2B0weapon resolver, and consume the parsedscorestatsdamage payload. - Confirmed the selected damage ownerdraws resolve to Grenade Launcher, Rocket Launcher, Lightning Gun, Railgun, and Plasmagun in the same order as the qagame producer and cgame parser.
- Confirmed all five selected ownerdraws refresh the competitive score cache,
draw through the placement metric dispatcher instead of direct
CG_OwnerDrawcases, and have no value, width, or key callback routes. - Added focused structural coverage for constants, retail target-group
membership, HLIL resolver/cache/format/paint signals, server/client
scorestatstransport, weapon mapping, dispatcher routing, callback absence, and competitive refresh wiring. - Refreshed the cgame ownerdraw and mapping ledgers for the selected five.
Task A186: Close selected 283-287 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/cgame/cg_newdraw.c,
tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_RED_FLAGSTATUS, CG_RED_SCORE, CG_RED_NAME,
CG_RED_OWNED_FLAGS, and CG_RED_AVG_PING ownerdraw set. Repo-wide
parity remains 98% because unrelated compatibility, source-legacy,
online-service, and packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher and HLIL leaves for raw ownerdraw cases0x11bthrough0x11f. - Confirmed
CG_RED_FLAGSTATUSstays on the shared team flag/base-status icon leaf, including red status selection and shader fallback behavior. - Confirmed
CG_RED_SCOREstays on the aligned team-score leaf and remains the only selected ownerdraw with aCG_GetValuecallback route. - Confirmed
CG_RED_NAMEstays on the aligned team-name leaf with the configured-name and default-name fallback path. - Confirmed
CG_RED_OWNED_FLAGSstays behind the retail Domination / Attack-Defend gate before drawing the red owned-point count. - Restored the shared
CG_DrawTeamAveragePingleaf to retail behavior: matching score rows are averaged without a negative-ping skip, no matching rows still paint(0), thresholds are>40and>80, alpha is0.8, and text formats as(%d). - Added focused structural coverage for constants, retail target-group membership, HLIL branch/format/color signals, local dispatcher routes, value/width/key callback membership, competitive-refresh absence, and the selected ownerdraw ledger rows.
- Refreshed the cgame ownerdraw and mapping ledgers for the selected five.
Task A185: Close selected 242-246 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_2ND_PLYR_SHOTS_PL, CG_2ND_PLYR_SHOTS_HMG, CG_2ND_PLYR_DMG_G,
CG_2ND_PLYR_DMG_MG, and CG_2ND_PLYR_DMG_SG ownerdraw set. Repo-wide
parity remains 98% because unrelated compatibility, source-legacy,
online-service, and packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher and HLIL leaves for raw ownerdraw cases0xf2through0xf6. - Confirmed
CG_2ND_PLYR_SHOTS_PLandCG_2ND_PLYR_SHOTS_HMGstay on the pre-switch0x10036B00shot-count helper, normalize through the retail weapon resolver, and consume the parsedscorestatsshot-count payload. - Confirmed
CG_2ND_PLYR_DMG_G,CG_2ND_PLYR_DMG_MG, andCG_2ND_PLYR_DMG_SGstay on the pre-switch0x10036C30damage helper, normalize to Gauntlet/Machinegun/Shotgun, and consume the parsedscorestatsdamage payload. - Confirmed all five selected ownerdraws refresh the competitive score cache,
draw through the placement metric dispatcher instead of direct
CG_OwnerDrawcases, and have no value, width, or key callback routes. - Added focused structural coverage for constants, retail target-group
membership, HLIL helper-field signals, server/client
scorestatstransport, weapon mapping, dispatcher routing, callback absence, and competitive refresh wiring. - Refreshed the cgame ownerdraw and mapping ledgers for the selected five.
Task A184: Close selected 207-211 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_2ND_PLYR_FRAGS_G, CG_2ND_PLYR_FRAGS_MG,
CG_2ND_PLYR_FRAGS_SG, CG_2ND_PLYR_FRAGS_GL, and
CG_2ND_PLYR_FRAGS_RL ownerdraw set. Repo-wide parity remains 98%
because unrelated compatibility, source-legacy, online-service, and
packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher,0x100368A0weapon-frag leaf, and0x1002E2B0placement weapon resolver for raw ownerdraw cases0xcfthrough0xd3. - Confirmed the selected second-player frag head resolves to G/MG/SG/GL/RL
weapon indexes
1through5, reads the slot-1 weapon-frag cells, and formats through the retail%dliteral. - Confirmed the source placement resolver normalizes the selected second-slot ownerdraws back to the first-player family before weapon lookup and text construction.
- Confirmed the qagame-to-cgame compact
scorestatstransport uses the same G/MG/SG/GL/RL-leading weapon-frag order before the ownerdraws readcg.scoreStats[clientNum].weaponFrags. - Added focused structural coverage for constants, retail target-group membership, HLIL resolver/cache/format/paint signals, source weapon mapping, server send path, cgame parse path, placement dispatch, competitive refresh wiring, and callback/direct-switch absence.
- Refreshed the cgame ownerdraw and mapping ledgers for the selected five.
Task A183: Close selected 202-206 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_2ND_PLYR_ACC, CG_2ND_PLYR_FLAG, CG_2ND_PLYR_AVATAR,
CG_2ND_PLYR_TIMEOUT_COUNT, and CG_2ND_PLYR_HEALTH_ARMOR ownerdraw
set. Repo-wide parity remains 98% because unrelated compatibility,
source-legacy, online-service, and packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher and HLIL leaves for raw ownerdraw cases0xcathrough0xce. - Confirmed
CG_2ND_PLYR_ACCstays on the pre-switch placement accuracy helper and uses the retail%d%%total-accuracy path. - Confirmed
CG_2ND_PLYR_FLAGstays on the pre-switch placement flag helper and draws the cached country-flag shader orCG_RegisterCountryFlagfallback without team-flag powerup logic. - Confirmed
CG_2ND_PLYR_AVATARdirectly calls the slot-1 avatar/model-icon path and preserves the avatar-handle-before-model-icon fallback. - Confirmed
CG_2ND_PLYR_TIMEOUT_COUNTremains an explicit retail no-op, with no placement guard, competitive refresh, value, width, or key callback route. - Confirmed
CG_2ND_PLYR_HEALTH_ARMORdirectly calls the secondary health/armor comparison bars, including local-client stat fallback, damage-loss segment, left-anchored secondary bars, and no text paint. - Added focused structural coverage for constants, retail target-group membership, HLIL offset/format/fallback signals, local helper routes, competitive refresh wiring, callback absence, and direct no-op behavior.
- Refreshed the cgame ownerdraw and mapping ledgers for the selected five.
Task A182: Feed retail arena catalog into live Awesomium start-server map list [COMPLETED]
Priority: High
Primary areas: src/code/client/cl_cgame.c,
src/code/client/cl_awesomium_win32.cpp,
tests/test_awesomium_browser_parity.py
Parity estimate: before 99.1% -> after 99.2% for the focused Awesomium
WebUI arena-listing lane. Repo-wide parity remains 98% because unrelated
compatibility, source-legacy, online-service, and packaging surfaces are
unchanged.
Completed work:
- Rechecked the retail
GetMapListHLIL, the map-pool loader notes, and the shipped WebUI bundle: Start Match synchronously importsGetMapList()andGetFactoryList(), then filters maps by the selected factory's numericbasegt. - Switched the native WebUI map builder to prefer Quake Live's retail
mappool.txtrotation source, merging duplicatemap|factoryrows into one descriptor per unique map and deriving the 13-slotgametypestable from parsed factorybasegtdefinitions; arena files now provide display metadata and fallback descriptors. - Added startup-time map/factory JSON payloads plus post-document-ready map and factory catalog sync. The map catalog still streams in bounded batches, and the factory catalog sync keeps the WebUI factory filter from staying on the one-entry fallback.
- Hardened the injected bridge so factory
basegttokens map to retailgametype_tids, the full bridge reinstalls after Awesomium document context resets, and Browserify/CommonJSmapdb/factoriesmodule exports are refreshed in place when the native catalog changes. - Added runtime diagnostics for qz/module map and factory counts, updated focused Awesomium parity coverage, and revalidated the windowed live client: the retail map pool loaded 173 rotation entries and the WebUI exposed 93 unique maps plus 22 factories.
Task A181: Close selected 197-201 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/cgame/cg_newdraw.c,
tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_2ND_PLYR_DEATHS, CG_2ND_PLYR_DMG, CG_2ND_PLYR_TIME,
CG_2ND_PLYR_PING, and CG_2ND_PLYR_WINS ownerdraw set. Repo-wide
parity remains 98% because unrelated compatibility, source-legacy,
online-service, and packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher and HLIL leaves for raw ownerdraw cases0xc5through0xc9. - Confirmed
CG_2ND_PLYR_DEATHSandCG_2ND_PLYR_DMGstay on the second-slot placement deaths/damage leaves and now use the retail%dformatter literal. - Confirmed
CG_2ND_PLYR_TIMEremains an inert ownerdraw boundary: retail exposes no raw0xc7switch case, placement guard, value, width, or key callback route. - Confirmed
CG_2ND_PLYR_PINGstays on the retail ping leaf, including%dtext formatting,>40/>80color thresholds, zero blue component, and0.8alpha. - Confirmed
CG_2ND_PLYR_WINSstays on the slot-1 wins/losses string path fed by the retail%d/%dscorestats payload. - Added focused structural coverage for constants, retail target-group membership, HLIL cache/format/color signals, local dispatcher routes, competitive score refresh wiring, callback absence, and the inert time boundary.
- Refreshed the cgame ownerdraw and mapping ledgers for the selected five.
Task A180: Close selected 192-196 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/cgame/cg_newdraw.c,
tests/test_cgame_displaycontext_parity.py,
tests/test_cgame_ownerdraw_text_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_1ST_PLYR_TIER, CG_2ND_PLYR, CG_2ND_PLYR_READY,
CG_2ND_PLYR_SCORE, and CG_2ND_PLYR_FRAGS ownerdraw set. Repo-wide
parity remains 98% because unrelated compatibility, source-legacy,
online-service, and packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher and HLIL leaves for raw ownerdraw cases0xc0through0xc4. - Confirmed
CG_1ST_PLYR_TIERremains an inert boundary: compact scorestats can still carry progression tier, but retail exposes no raw0xc0ownerdraw, placement guard, value, width, or key callback route. - Confirmed
CG_2ND_PLYRandCG_2ND_PLYR_SCOREuse the direct slot-1 name and score helpers, including cached second-player text,"-"fallback, retail%dscore formatting, and alignment. - Confirmed
CG_2ND_PLYR_READYstays on the secondary status/ready helper, preservingLEADS/TIED/TRAILSandREADY/NOT READYbehavior. - Restored the retail
%dliteral for placement frag ownerdraw text soCG_2ND_PLYR_FRAGSmatches the0x100361F0slot-1 frag path. - Added focused structural coverage for constants, retail target-group membership, HLIL cache/status/format signals, local dispatcher routes, competitive score refresh wiring, callback absence, and the inert tier boundary.
- Refreshed the cgame ownerdraw and mapping ledgers for the selected five.
Task A179: Close selected 187-191 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/cgame/cg_newdraw.c,
src/code/cgame/cg_servercmds.c, src/code/game/g_cmds.c,
tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_1ST_PLYR_AVG_PICKUP_TIME_MH, CG_1ST_PLYR_EXCELLENT,
CG_1ST_PLYR_IMPRESSIVE, CG_1ST_PLYR_HUMILIATION, and
CG_1ST_PLYR_PR ownerdraw set. Repo-wide parity remains 98% because
unrelated compatibility, source-legacy, online-service, and packaging
surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher,0x10037730pickup-average leaf, and0x10037990award-count leaf for raw ownerdraw cases0xbbthrough0xbf. - Confirmed
CG_1ST_PLYR_AVG_PICKUP_TIME_MHcloses the first-player pickup average band, reads the MH average cache, and shares the retail"-"zero-count fallback. - Confirmed
CG_1ST_PLYR_EXCELLENT,CG_1ST_PLYR_IMPRESSIVE, andCG_1ST_PLYR_HUMILIATIONstay on the retail award-count path and are fed by the qagame duel score row plus cgame score parsing. - Restored the retail
%dliteral for placement award-count ownerdraw text. - Confirmed
CG_1ST_PLYR_PRremains an inert ownerdraw boundary: compact scorestats still transport progression PR/tier, but retail does not route raw0xbfthrough ownerdraw, guard, value, width, or key callbacks. - Added focused structural coverage for constants, retail target-group membership, HLIL average/award cache signals, qagame send path, cgame parse path, formatter, dispatcher guard, callback absence, and direct-switch absence.
- Refreshed the cgame ownerdraw and mapping ledgers for the selected five.
Task A178: Close selected 182-186 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/cgame/cg_newdraw.c,
src/code/cgame/cg_servercmds.c, src/code/game/g_cmds.c,
tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 98% -> after 100% for the selected
CG_1ST_PLYR_PICKUPS_GA, CG_1ST_PLYR_PICKUPS_MH,
CG_1ST_PLYR_AVG_PICKUP_TIME_RA,
CG_1ST_PLYR_AVG_PICKUP_TIME_YA, and
CG_1ST_PLYR_AVG_PICKUP_TIME_GA ownerdraw set. Repo-wide parity remains
98% because unrelated compatibility, source-legacy, online-service, and
packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher,0x10036EB0pickup-count leaf, and0x10037730pickup-average leaf for raw ownerdraw cases0xb6through0xba. - Confirmed
CG_1ST_PLYR_PICKUPS_GAandCG_1ST_PLYR_PICKUPS_MHstay on the direct retail pickup-count path and consume the same compact GA/MH pickup order used by qagame send and cgame parse. - Restored the retail pickup-average zero-count fallback: RA/YA/GA average
ownerdraws now paint
"-"when the corresponding count is zero and%3.2fwhen a pickup interval is available. - Pinned both compact
scorestatsand legacy duel-score parsing for the selected pickup counts and average intervals. - Added focused structural coverage for constants, retail target-group membership, HLIL count/average cache signals, qagame send path, cgame parse path, visible average fallback, dispatcher guard, callback absence, and direct-switch absence.
- Refreshed the cgame ownerdraw and mapping ledgers for the selected five.
Task A177: Close selected 177-181 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/cgame/cg_newdraw.c,
src/code/cgame/cg_servercmds.c, src/code/game/g_cmds.c,
tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 97% -> after 100% for the selected
CG_1ST_PLYR_ACC_PL, CG_1ST_PLYR_ACC_HMG,
CG_1ST_PLYR_PICKUPS, CG_1ST_PLYR_PICKUPS_RA, and
CG_1ST_PLYR_PICKUPS_YA ownerdraw set. Repo-wide parity remains
98% because unrelated compatibility, source-legacy, online-service, and
packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher,0x10036D60weapon-accuracy leaf,0x10036EB0pickup leaf, and0x1002E2B0placement weapon resolver for raw ownerdraw cases0xb1through0xb5. - Confirmed the selected accuracy tail resolves to PL/HMG weapon indexes
0xcand0xe, reads thedata_10A6034Caccuracy cache, formats through the retail%d%%literal, and inherits the best-row color override. - Restored the retail
CG_1ST_PLYR_PICKUPSsummary strip: nonzero RA/YA/GA/MH pickups draw the retail pickup shader, count text, and%3.2faverage interval from the compact scorestats payload. - Confirmed
CG_1ST_PLYR_PICKUPS_RAandCG_1ST_PLYR_PICKUPS_YAstay on the direct retail pickup-count path and now use the retail%dformatter. - Pinned qagame-to-cgame compact pickup wiring: qagame sends RA/YA/GA/MH
counts and average intervals, cgame parses them into
pickupCountsandpickupAvgSeconds, and the ownerdraws consume the same order. - Added focused structural coverage for constants, retail target-group membership, resolver returns, pickup shader handles, server send path, cgame parse path, summary drawing, direct count drawing, dispatcher guard, callback absence, and direct-switch absence.
- Refreshed the cgame ownerdraw and mapping ledgers for the selected five.
Task A176: Close selected 6-10 cgame front-panel status ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/cgame/cg_newdraw.c,
src/code/cgame/cg_main.c, tests/test_cgame_ownerdraw_text_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_GAME_TYPE_MAP, CG_GAME_STATUS, CG_MATCH_DETAILS,
CG_MATCH_END_CONDITION, and CG_MATCH_STATUS ownerdraw set. Repo-wide
parity remains 98% because unrelated compatibility, source-legacy,
online-service, and packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher for raw ownerdraw cases0x06through0x0A. - Confirmed
CG_GAME_TYPE_MAP,CG_GAME_STATUS,CG_MATCH_DETAILS,CG_MATCH_END_CONDITION, andCG_MATCH_STATUSroute to the recovered intro-panel detail, standalone game-status, match-details, match-end-condition, and match-status helpers respectively. - Confirmed the selected batch preserves the intended callback boundary:
CG_GAME_STATUSandCG_MATCH_STATUSparticipate in the width callback, while all five stay out of value and key callbacks. - Added focused structural coverage for constants, retail target membership, source switch routes, helper behavior, shipped menu reachability, display-context wiring, and width callback splits for the selected five.
- Refreshed the cgame ownerdraw and mapping ledgers for this selected batch.
Task A175: Close selected 172-176 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/cgame/cg_newdraw.c,
src/code/cgame/cg_servercmds.c, src/code/game/g_cmds.c,
tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_1ST_PLYR_ACC_RG, CG_1ST_PLYR_ACC_PG,
CG_1ST_PLYR_ACC_BFG, CG_1ST_PLYR_ACC_CG, and
CG_1ST_PLYR_ACC_NG ownerdraw set. Repo-wide parity remains 98%
because unrelated compatibility, source-legacy, online-service, and packaging
surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher,0x10036D60weapon-accuracy leaf, and0x1002E2B0placement weapon resolver for raw ownerdraw cases0xacthrough0xb0. - Confirmed the selected accuracy band resolves to RG/PG/BFG/CG/NG weapon
indexes
7,8,9,0xd, and0xb, reads thedata_10A6034Caccuracy cache, and formats through the retail%d%%literal. - Confirmed the selected ownerdraws inherit the restored retail comparison
color path: the row whose weapon accuracy beats the opposing placement
slot paints white with
0.8alpha. - Pinned the qagame-to-cgame compact accuracy wiring: qagame sends
accuracy_hitsandaccuracy_shots, cgame parses both in the same weapon order, then derivesweaponAccuracybefore the ownerdraw reads it. - Added focused structural coverage for constants, retail target-group membership, resolver returns, cache reads, weapon mapping, server send path, cgame parse path, formatter, comparison color, dispatcher guard, callback absence, and direct-switch absence.
- Refreshed the cgame ownerdraw and mapping ledgers for the selected five.
Task A174: Close selected 1-5 cgame front-panel ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/cgame/cg_newdraw.c,
src/code/cgame/cg_servercmds.c, src/code/cgame/cg_main.c,
tests/test_cgame_ownerdraw_text_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_SERVER_SETTINGS, CG_STARTING_WEAPONS, CG_GAME_LIMIT,
CG_GAME_TYPE, and CG_GAME_TYPE_ICON ownerdraw set. Repo-wide parity
remains 98% because unrelated compatibility, source-legacy,
online-service, and packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher for raw ownerdraw cases0x01through0x05. - Confirmed
CG_SERVER_SETTINGS,CG_STARTING_WEAPONS,CG_GAME_LIMIT,CG_GAME_TYPE, andCG_GAME_TYPE_ICONroute to the recovered settings, starting-weapon icon strip, game-limit label, gametype text, and gametype icon helpers respectively. - Confirmed the selected batch preserves the intended callback boundary:
CG_GAME_TYPEalone participates in the width callback, while all five stay out of value and key callbacks. - Added focused structural coverage for constants, retail target membership, source switch routes, helper behavior, shipped menu reachability, display-context wiring, and configstring inputs for the selected five.
- Refreshed the cgame ownerdraw and mapping ledgers for this selected batch.
Task A173: Close selected 167-171 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/cgame/cg_newdraw.c,
src/code/cgame/cg_servercmds.c, src/code/game/g_cmds.c,
tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 98% -> after 100% for the selected
CG_1ST_PLYR_ACC_MG, CG_1ST_PLYR_ACC_SG,
CG_1ST_PLYR_ACC_GL, CG_1ST_PLYR_ACC_RL, and
CG_1ST_PLYR_ACC_LG ownerdraw set. Repo-wide parity remains 98%
because unrelated compatibility, source-legacy, online-service, and packaging
surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher,0x10036D60weapon-accuracy leaf, and0x1002E2B0placement weapon resolver for raw ownerdraw cases0xa7through0xab. - Confirmed the selected accuracy head resolves to MG/SG/GL/RL/LG weapon
indexes
2through6, reads thedata_10A6034Caccuracy cache, and formats through the retail%d%%literal. - Restored the retail per-weapon accuracy comparison color: the row whose
accuracy beats the opposing placement slot for the same weapon paints
white with
0.8alpha. - Pinned the qagame-to-cgame compact accuracy wiring: qagame sends
accuracy_hitsandaccuracy_shots, cgame parses both in the same weapon order, then derivesweaponAccuracybefore the ownerdraw reads it. - Added focused structural coverage for constants, retail target-group membership, resolver returns, cache reads, weapon mapping, server send path, cgame parse path, formatter, comparison color, dispatcher guard, callback absence, and direct-switch absence.
- Refreshed the cgame ownerdraw and mapping ledgers for the selected five.
Task A172: Close selected 90-94 cgame endgame/selected-player ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/cgame/cg_newdraw.c,
tests/test_cgame_ownerdraw_text_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_PLYR_END_GAME_SCORE, CG_PLYR_BEST_WEAPON_NAME,
CG_SELECTED_PLYR_TEAM_COLOR, CG_SELECTED_PLYR_ACCURACY, and
CG_FOLLOW_PLAYER_NAME ownerdraw set. Repo-wide parity remains 98%
because unrelated compatibility, source-legacy, online-service, and packaging
surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher for raw ownerdraw cases0x5Athrough0x5E. - Confirmed
CG_PLYR_END_GAME_SCORE,CG_PLYR_BEST_WEAPON_NAME,CG_SELECTED_PLYR_TEAM_COLOR,CG_SELECTED_PLYR_ACCURACY, andCG_FOLLOW_PLAYER_NAMEroute to the endgame score, selected best weapon, selected team color, selected accuracy, and follow-name helpers respectively. - Confirmed the selected batch preserves the intended competitive-score refresh boundary: only the endgame score row refreshes, while the selected-player and follow-name ownerdraws do not.
- Added focused structural coverage for constants, retail target membership, source switch routes, helper behavior, shipped menu reachability, competitive refresh, and callback absence for the selected five.
- Refreshed the cgame ownerdraw and mapping ledgers for this selected batch.
Task A171: Close selected 162-166 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/cgame/cg_newdraw.c,
src/code/cgame/cg_servercmds.c, src/code/game/g_cmds.c,
tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_1ST_PLYR_DMG_BFG, CG_1ST_PLYR_DMG_CG,
CG_1ST_PLYR_DMG_NG, CG_1ST_PLYR_DMG_PL, and
CG_1ST_PLYR_DMG_HMG ownerdraw set. Repo-wide parity remains 98%
because unrelated compatibility, source-legacy, online-service, and packaging
surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher,0x10036C30weapon-damage leaf, and0x1002E2B0placement weapon resolver for raw ownerdraw cases0xa2through0xa6. - Confirmed the selected damage tail resolves to BFG/CG/NG/PL/HMG weapon
indexes
9,0xd,0xb,0xc, and0xe, reads thedata_10A6040Cdamage cache, and formats through the retail%dliteral. - Pinned the qagame-to-cgame compact weapon-damage wiring for the selected tail weapon band.
- Added focused structural coverage for constants, retail target-group membership, resolver returns, cache reads, weapon mapping, server send path, cgame parse path, dispatcher guard, callback absence, and direct-switch absence.
- Refreshed the cgame ownerdraw and mapping ledgers for the selected five.
Task A170: Close selected 85-89 cgame model/second-place/chat ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/cgame/cg_newdraw.c,
tests/test_cgame_ownerdraw_text_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_1STPLACE_PLYR_MODEL, CG_2NDPLACE, CG_2ND_PLACE_SCORE,
CG_PLAYER_OBIT, and CG_AREA_NEW_CHAT ownerdraw set. Repo-wide
parity remains 98% because unrelated compatibility, source-legacy,
online-service, and packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher for raw ownerdraw cases0x55through0x59. - Confirmed
CG_1STPLACE_PLYR_MODEL,CG_2NDPLACE,CG_2ND_PLACE_SCORE,CG_PLAYER_OBIT, andCG_AREA_NEW_CHATroute to the first-place model, compact score, wide second-place score, obituary feed, and new-chat helpers respectively. - Confirmed the selected batch preserves the intended competitive-score refresh boundary: first-place model and second-place score rows refresh, while obituary and chat ownerdraws do not.
- Added focused structural coverage for constants, retail target membership, source switch routes, helper behavior, shipped menu reachability, competitive refresh, and callback absence for the selected five.
- Refreshed the cgame ownerdraw and mapping ledgers for this selected batch.
Task A169: Close selected 80-84 cgame award/scoreboard ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/cgame/cg_newdraw.c,
src/code/game/g_main.c,
tests/test_cgame_ownerdraw_text_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_MOST_DAMAGEDEALT_PLYR, CG_SPECTATORS, CG_MATCH_WINNER,
CG_1STPLACE, and CG_1ST_PLACE_SCORE ownerdraw set. Repo-wide
parity remains 98% because unrelated compatibility, source-legacy,
online-service, and packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher,0x1003A0D0award-player HLIL leaf, and adjacent scoreboard call targets for raw ownerdraw cases0x50through0x54. - Confirmed
CG_MOST_DAMAGEDEALT_PLYRremains the final pre-switch award-player image route fed byCS_AWARD_MOST_DAMAGEDEALT. - Confirmed
CG_SPECTATORS,CG_MATCH_WINNER,CG_1STPLACE, andCG_1ST_PLACE_SCOREroute to the spectator list, match winner, compact score, and wide first-place score helpers respectively. - Added focused structural coverage for constants, retail target membership, pre-switch/switch separation, configstring producer/consumer wiring, shipped menu reachability, competitive refresh, and callback absence for the selected five.
- Refreshed the cgame ownerdraw and mapping ledgers for this selected batch.
Task A168: Close selected 157-161 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/cgame/cg_newdraw.c,
src/code/cgame/cg_servercmds.c, src/code/game/g_cmds.c,
tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_1ST_PLYR_DMG_GL, CG_1ST_PLYR_DMG_RL,
CG_1ST_PLYR_DMG_LG, CG_1ST_PLYR_DMG_RG, and
CG_1ST_PLYR_DMG_PG ownerdraw set. Repo-wide parity remains 98%
because unrelated compatibility, source-legacy, online-service, and packaging
surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher,0x10036C30weapon-damage leaf, and0x1002E2B0placement weapon resolver for raw ownerdraw cases0x9dthrough0xa1. - Confirmed the selected damage band resolves to GL/RL/LG/RG/PG weapon
indexes
4through8, reads thedata_10A6040Cdamage cache, and formats through the retail%dliteral. - Pinned the qagame-to-cgame compact weapon-damage wiring for the selected middle weapon band.
- Added focused structural coverage for constants, retail target-group membership, resolver returns, cache reads, weapon mapping, server send path, cgame parse path, dispatcher guard, callback absence, and direct-switch absence.
- Refreshed the cgame ownerdraw and mapping ledgers for the selected five.
Task A167: Close selected 75-79 cgame award-player ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/cgame/cg_newdraw.c,
src/code/game/g_main.c,
tests/test_cgame_ownerdraw_text_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_MOST_VALUABLE_OFFENSIVE_PLYR,
CG_MOST_VALUABLE_DEFENSIVE_PLYR, CG_MOST_VALUABLE_PLYR,
CG_BEST_ITEMCONTROL_PLYR, and CG_MOST_ACCURATE_PLYR ownerdraw
set. Repo-wide parity remains 98% because unrelated compatibility,
source-legacy, online-service, and packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher and0x1003A0D0award-player HLIL leaf for raw ownerdraw cases0x4Bthrough0x4F. - Confirmed the selected ownerdraws route through the pre-switch award-player
helper rather than the ordinary
CG_OwnerDrawswitch body. - Confirmed the selected award-player helpers are fed by qagame-published
CS_AWARD_*configstrings and cgame resolves them before drawing the profile image for the winning client. - Added focused structural coverage for constants, retail target membership, pre-switch ordering, configstring producer/consumer wiring, shipped menu reachability, competitive refresh, and callback absence for the selected five.
- Refreshed the cgame ownerdraw and mapping ledgers for this selected batch.
Task A166: Close selected 152-156 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/cgame/cg_newdraw.c,
src/code/cgame/cg_servercmds.c, src/code/game/g_cmds.c,
tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_1ST_PLYR_SHOTS_PL, CG_1ST_PLYR_SHOTS_HMG,
CG_1ST_PLYR_DMG_G, CG_1ST_PLYR_DMG_MG, and
CG_1ST_PLYR_DMG_SG ownerdraw set. Repo-wide parity remains 98%
because unrelated compatibility, source-legacy, online-service, and packaging
surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher,0x10036B00weapon-shot leaf,0x10036C30weapon-damage leaf, and0x1002E2B0placement weapon resolver for raw ownerdraw cases0x98through0x9c. - Tightened placement weapon-damage formatting to the retail
%dliteral, matching the shareddata_10068E44format used by the damage helper. - Confirmed the selected shot tail resolves to PL/HMG weapon indexes
0xcand0xe, while the selected damage head resolves to G/MG/SG weapon indexes1,2, and3. - Pinned the qagame-to-cgame compact
accuracy_shotsand weapon-damage wiring used by the selected ownerdraws. - Added focused structural coverage for constants, retail target-group membership, resolver returns, cache reads, weapon mapping, server send path, cgame parse path, dispatcher guard, callback absence, and direct-switch absence.
- Refreshed the cgame ownerdraw and mapping ledgers for the selected five.
Task A165: Close gauntlet/impressive/rampage/midair/perfect cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/cgame/cg_newdraw.c,
tests/test_cgame_ownerdraw_text_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_GAUNTLET, CG_IMPRESSIVE, CG_RAMPAGES, CG_MIDAIRS, and
CG_PERFECT ownerdraw set. Repo-wide parity remains 98% because
unrelated compatibility, source-legacy, online-service, and packaging surfaces
are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher and0x10035340medal HLIL leaf for raw ownerdraw cases0x46through0x4A. - Confirmed
CG_GAUNTLET,CG_IMPRESSIVE, andCG_PERFECTroute through the real medal target group and read the selected-score gauntlet, impressive, and perfect fields. - Confirmed
CG_RAMPAGESandCG_MIDAIRSremain retail no-ops between medal IDs with no authored menu usage and no helper route. - Added focused structural coverage for constants, retail switch membership, source medal/no-op separation, selected-score field reads, menu reachability, and callback absence for the selected five.
- Refreshed the cgame ownerdraw and mapping ledgers for this selected batch.
Task A164: Close assist/capture/combo/defend/excellent cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/cgame/cg_newdraw.c,
tests/test_cgame_ownerdraw_text_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_ASSISTS, CG_CAPTURES, CG_COMBOKILLS, CG_DEFEND, and
CG_EXCELLENT ownerdraw set. Repo-wide parity remains 98%
because unrelated compatibility, source-legacy, online-service, and packaging
surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher and0x10035340medal HLIL leaf for raw ownerdraw cases0x41through0x45. - Confirmed
CG_ASSISTS,CG_CAPTURES,CG_DEFEND, andCG_EXCELLENTroute through the real medal target group and read the selected-score assist, capture, defend, and excellent fields. - Confirmed
CG_COMBOKILLSremains a retail no-op between medal IDs with no authored menu usage and no helper route. - Added focused structural coverage for constants, retail switch membership, source medal/no-op separation, selected-score field reads, menu reachability, and callback absence for the selected five.
- Refreshed the cgame ownerdraw and mapping ledgers for this selected batch.
Task A163: Close selected 147-151 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/cgame/cg_newdraw.c,
src/code/cgame/cg_servercmds.c, src/code/game/g_cmds.c,
tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_1ST_PLYR_SHOTS_RG, CG_1ST_PLYR_SHOTS_PG,
CG_1ST_PLYR_SHOTS_BFG, CG_1ST_PLYR_SHOTS_CG, and
CG_1ST_PLYR_SHOTS_NG ownerdraw set. Repo-wide parity remains 98%
because unrelated compatibility, source-legacy, online-service, and packaging
surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher,0x10036B00weapon-shot leaf, and0x1002E2B0placement weapon resolver for raw ownerdraw cases0x93through0x97. - Confirmed the selected shot band resolves to RG/PG/BFG/CG/NG weapon indexes
7,8,9,0xd, and0xb, reads thedata_10A6038Cshot cache, and formats through the retail%dliteral. - Pinned the qagame-to-cgame compact
accuracy_shotswiring for the selected middle/tail weapon band. - Added focused structural coverage for constants, retail target-group membership, resolver returns, cache reads, weapon mapping, server send path, cgame parse path, dispatcher guard, callback absence, and direct-switch absence.
- Refreshed the cgame ownerdraw and mapping ledgers for the selected five.
Task A162: Close selected 142-146 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/cgame/cg_newdraw.c,
src/code/cgame/cg_servercmds.c, src/code/game/g_cmds.c,
tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_1ST_PLYR_SHOTS_MG, CG_1ST_PLYR_SHOTS_SG,
CG_1ST_PLYR_SHOTS_GL, CG_1ST_PLYR_SHOTS_RL, and
CG_1ST_PLYR_SHOTS_LG ownerdraw set. Repo-wide parity remains 98%
because unrelated compatibility, source-legacy, online-service, and packaging
surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher,0x10036B00weapon-shot leaf, and0x1002E2B0placement weapon resolver for raw ownerdraw cases0x8ethrough0x92. - Tightened placement weapon-shot formatting to the retail
%dliteral, matching the shareddata_10068E44format used by the shot helper. - Confirmed the selected shot head resolves to MG/SG/GL/RL/LG weapon indexes
2through6, reads thedata_10A6038Cshot cache, and is backed by compactaccuracy_shotsqagame-to-cgame wiring. - Added focused structural coverage for constants, retail target-group membership, resolver returns, cache reads, weapon mapping, server send path, cgame parse path, dispatcher guard, callback absence, and direct-switch absence.
- Refreshed the cgame ownerdraw and mapping ledgers for the selected five.
Task A161: Close powerup/teamcolor/killer/accuracy cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/cgame/cg_newdraw.c,
tests/test_cgame_ownerdraw_text_parity.py,
tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_CTF_POWERUP, CG_AREA_POWERUP, CG_TEAM_COLOR, CG_KILLER,
and CG_ACCURACY ownerdraw set. Repo-wide parity remains 98%
because unrelated compatibility, source-legacy, online-service, and packaging
surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher and HLIL leaves for raw ownerdraw cases0x3Cthrough0x40. - Confirmed
CG_CTF_POWERUPuses the persisted powerup item icon path,CG_AREA_POWERUPuses the retail powerup sprite stack, andCG_TEAM_COLORlands on the lower team-background helper with the local team value. - Corrected the powerup frag badge format to the retail
x %iliteral for the quad and battlesuit badge path. - Confirmed
CG_KILLERis draw-gated by the cached killer name and shares the sameFragged by %stext with the width callback. - Confirmed
CG_ACCURACYremains in the real medal switch group with%i%%text and alpha promotion for nonzero accuracy. - Added focused structural coverage for constants, retail targets, source dispatcher wiring, callback participation, menu reachability, and helper literals for the selected five.
Task A160: Close selected 137-141 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/cgame/cg_newdraw.c,
src/code/cgame/cg_servercmds.c, src/code/game/g_cmds.c,
tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_1ST_PLYR_HITS_BFG, CG_1ST_PLYR_HITS_CG,
CG_1ST_PLYR_HITS_NG, CG_1ST_PLYR_HITS_PL, and
CG_1ST_PLYR_HITS_HMG ownerdraw set. Repo-wide parity remains 98%
because unrelated compatibility, source-legacy, online-service, and packaging
surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher,0x100369D0weapon-hit leaf, and0x1002E2B0placement weapon resolver for raw ownerdraw cases0x89through0x8d. - Confirmed the selected hit tail resolves to BFG/CG/NG/PL/HMG weapon indexes
9,0xd,0xb,0xc, and0xe, reads thedata_10A603CChit cache, and formats through the retail%dliteral. - Pinned the qagame-to-cgame compact
accuracy_hitswiring for the selected tail weapon band. - Added focused structural coverage for constants, retail target-group membership, resolver returns, cache reads, weapon mapping, server send path, cgame parse path, dispatcher guard, callback absence, and direct-switch absence.
- Refreshed the cgame ownerdraw and mapping ledgers for the selected five.
Task A159: Close selected 132-136 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/cgame/cg_newdraw.c,
src/code/cgame/cg_servercmds.c, src/code/game/g_cmds.c,
tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_1ST_PLYR_HITS_GL, CG_1ST_PLYR_HITS_RL,
CG_1ST_PLYR_HITS_LG, CG_1ST_PLYR_HITS_RG, and
CG_1ST_PLYR_HITS_PG ownerdraw set. Repo-wide parity remains 98%
because unrelated compatibility, source-legacy, online-service, and packaging
surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher,0x100369D0weapon-hit leaf, and0x1002E2B0placement weapon resolver for raw ownerdraw cases0x84through0x88. - Confirmed the selected hit band resolves to GL/RL/LG/RG/PG weapon indexes
4through8, reads thedata_10A603CChit cache, and formats through the retail%dliteral. - Pinned the qagame-to-cgame compact
accuracy_hitswiring for the selected middle weapon band. - Added focused structural coverage for constants, retail target-group membership, resolver returns, cache reads, weapon mapping, server send path, cgame parse path, dispatcher guard, callback absence, and direct-switch absence.
- Refreshed the cgame ownerdraw and mapping ledgers for the selected five.
Task A158: Close flag/harvester/key cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/cgame/cg_newdraw.c,
tests/test_cgame_displaycontext_parity.py,
tests/test_cgame_ownerdraw_text_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_PLAYER_HASFLAG, CG_PLAYER_HASFLAG2D, CG_HARVESTER_SKULLS,
CG_HARVESTER_SKULLS2D, and CG_PLAYER_HASKEY ownerdraw set.
Repo-wide parity remains 98% because unrelated compatibility,
source-legacy, online-service, and packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher and HLIL leaves for raw ownerdraw cases0x37,0x38,0x39,0x3A, and0x3B. - Corrected the Harvester 3D cube ownerdraw geometry to match the retail
rect->y + 5offset while preserving the forced-2Dx + 3, y + 16cube-icon path. - Confirmed the carried-flag ownerdraw keeps the retail 4-pixel 3D inset,
forced-2D zero inset, and 1FCTF neutral-flag
dropflagprompt. - Confirmed the carried-key ownerdraw uses the replicated key-mask stat,
IT_KEYtag lookup, item visual registration, and half-width icon overlap. - Added focused structural coverage for constants, dispatcher routes,
CG_GetValueparticipation, width/key callback absence, display-context wiring, retail HLIL anchors, and menu reachability. - Refreshed the cgame ownerdraw and mapping ledgers for the selected five.
Task A157: Close selected 127-131 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/cgame/cg_newdraw.c,
src/code/cgame/cg_servercmds.c, src/code/game/g_cmds.c,
tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_1ST_PLYR_FRAGS_NG, CG_1ST_PLYR_FRAGS_PL,
CG_1ST_PLYR_FRAGS_HMG, CG_1ST_PLYR_HITS_MG, and
CG_1ST_PLYR_HITS_SG ownerdraw set. Repo-wide parity remains 98%
because unrelated compatibility, source-legacy, online-service, and packaging
surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher,0x100368A0weapon-frag leaf,0x100369D0weapon-hit leaf, and0x1002E2B0placement weapon resolver for raw ownerdraw cases0x7fthrough0x83. - Tightened placement weapon-hit formatting to the retail
%dliteral, matching the shareddata_10068E44format used by the hit helper. - Confirmed the selected frag tail is backed by the compact frag order and
the selected hit head is backed by the compact
accuracy_hitsorder across qagame send and cgame parse paths. - Added focused structural coverage for constants, retail target-group membership, resolver returns, cache reads, weapon mapping, server send path, cgame parse path, dispatcher guard, callback absence, and direct-switch absence.
- Refreshed the cgame ownerdraw and mapping ledgers for the selected five.
Task A156: Harden selected 86-90 cgame endgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/cgame/cg_newdraw.c,
src/code/cgame/cg_main.c,
tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_2NDPLACE, CG_2ND_PLACE_SCORE, CG_PLAYER_OBIT,
CG_AREA_NEW_CHAT, and CG_PLYR_END_GAME_SCORE ownerdraw set.
Repo-wide parity remains 98% because unrelated compatibility,
source-legacy, online-service, and packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher and HLIL call sites for raw ownerdraw cases0x56,0x57,0x58,0x59, and0x5A. - Confirmed current source preserves the compact second-place score helper, wide second-place score branch, obituary feed renderer, timed chat stack, and local endgame summary text family.
- Added focused structural coverage for source switch wiring, display-context callback absence, shipped menu reachability, competitive cache refresh, and helper behavior for the selected endgame slice.
- Refreshed the ownerdraw parity index and cgame mapping notes for this selected batch.
Task A155: Harden selected 91-95 cgame selected/follow ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/cgame/cg_newdraw.c,
src/code/cgame/cg_main.c,
tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_PLYR_BEST_WEAPON_NAME, CG_SELECTED_PLYR_TEAM_COLOR,
CG_SELECTED_PLYR_ACCURACY, CG_FOLLOW_PLAYER_NAME, and
CG_FOLLOW_PLAYER_NAME_EX ownerdraw set. Repo-wide parity remains
98% because unrelated compatibility, source-legacy, online-service, and
packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher and HLIL call sites for raw ownerdraw cases0x5B,0x5C,0x5D,0x5E, and0x5F. - Confirmed current source preserves the selected-score bounds checks, selected-client team-color fill, selected accuracy text path, best-weapon label table, and shared follow-name prefix/tint/alignment helper.
- Added focused structural coverage for source switch wiring, display-context callback absence, shipped menu reachability, and the helper behavior that backs each selected ownerdraw.
- Refreshed the ownerdraw parity index and cgame mapping notes for this selected/follow-player slice.
Task A154: Harden selected 81-85 cgame scoreboard ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/cgame/cg_newdraw.c,
src/code/cgame/cg_main.c,
src/code/cgame/cg_servercmds.c,
src/code/game/g_main.c,
tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_SPECTATORS, CG_MATCH_WINNER, CG_1STPLACE,
CG_1ST_PLACE_SCORE, and CG_1STPLACE_PLYR_MODEL ownerdraw set.
Repo-wide parity remains 98% because unrelated compatibility,
source-legacy, online-service, and packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher and HLIL call sites for raw ownerdraw cases0x51,0x52,0x53,0x54, and0x55. - Confirmed current source preserves the retail spectator-cache gate, match-winner text branch, compact score helper, wide first-place configstring line, and first-place model/profile preview path.
- Added focused structural coverage for source switch wiring, display-context callback absence, qagame/cgame configstring producer-consumer paths, and shipped menu reachability.
- Refreshed the ownerdraw parity index and cgame mapping notes for this selected scoreboard/endgame slice.
Task A153: Close renderer post-process command payload wiring [COMPLETED]
Priority: High
Primary areas: src/code/renderer/tr_backend.c,
tests/test_renderer_post_process_parity.py,
tests/test_renderer_internal_helper_mapping_parity.py
Parity estimate: before 99.99% -> after 100% for the scoped renderer
post-process command payload wiring lane. The strict renderer estimate remains
100% and repo-wide parity remains 98% because unrelated portability,
online-service, packaging, and source-legacy surfaces are unchanged.
Completed work:
- Rechecked the retail
quakelive_steam.exeHLIL forRB_ColorCorrectPostProcessCommand @ 0x00436DC0,RB_BloomPostProcessCommand @ 0x00436EC0,R_AddBloomPostProcessCommand @ 0x004384D0, andR_AddColorCorrectPostProcessCommand @ 0x0043CD10. - Rewired the color-correct pass to consume the queued command texture and
program handles instead of re-reading the live
s_postProcesshandles. - Rewired the bloom downsample, bright-pass, blur, quarter-pass, combine, and fallback blit path to consume the queued bloom command payload while keeping framebuffer binding under the recovered retail render-target owner.
- Added focused structural coverage that pins command payload consumption for color-correct and bloom execution.
Task A152: Close referenced-pak publication parity [COMPLETED]
Priority: High
Primary areas: src/code/qcommon/files.c,
tests/fs_searchpath_harness.c, tests/test_fs_search_paths.py,
tests/test_engine_cvar_retail_parity.py
Parity estimate: before 99% -> after 100% for the scoped
sv_referencedPaks / sv_referencedPakNames filesystem publication and
client autodownload decision lane. Repo-wide parity remains 98% because
unrelated compatibility, portability, online-service, packaging, and
source-legacy surfaces are unchanged.
Completed work:
- Rechecked the retail
quakelive_steam.exeHLIL forFS_ReferencedPakChecksumsat0x004D1DC0andFS_ReferencedPakNamesat0x004D1E20. - Removed the legacy Quake III fs_game-wide publication rule from the referenced-pak checksum and name builders so Quake Live now publishes only pk3s whose retail reference flags are nonzero.
- Kept the existing server
sv_referencedPaks/sv_referencedPakNamespublication and clientFS_PureServerSetReferencedPaksparse wiring intact. - Added filesystem-harness coverage proving an unreferenced mod pk3 is not published until its reference flag is set, plus source-visible HLIL guards for the recovered retail flag-only condition.
Task A151: Tighten native game API handoff parity [COMPLETED]
Priority: High
Primary areas: src/code/server/sv_game.c,
src/code/client/cl_cgame.c,
tests/test_game_native_export_helper_parity.py
Parity estimate: before 99.9% -> after 100% for the scoped native
qagame/cgame API-version handoff and retained QVM fallback ownership slice.
Repo-wide parity remains 98% because unrelated portability,
online-service, packaging, and source-legacy surfaces are unchanged.
Completed work:
- Rechecked the retail
qagamex86.dllandcgamex86.dlldllEntryevidence: qagame reports native API10, and cgame reports native API8. - Split the native-load API constants from the legacy VM fallback constants at the qagame and cgame loader call sites.
- Added structural coverage that pins native API handoff, legacy fallback API handoff, and the retained retail QVM fallback ownership note.
- Revalidated the focused native-export and qcommon fallback-VM parity probes.
Task A150: Close item/score/race cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/cgame/cg_newdraw.c,
tests/test_cgame_ownerdraw_text_parity.py,
tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_PLAYER_ITEM, CG_PLAYER_SCORE, CG_RACE_STATUS, CG_RACE_TIMES,
and CG_ONEFLAG_STATUS ownerdraw set. Repo-wide parity remains 98%
because unrelated compatibility, source-legacy, and packaging surfaces are
unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher and HLIL leaves for raw ownerdraw cases0x32,0x33,0x34,0x35, and0x36. - Confirmed current source preserves the retail holdable item branch, compact score wrapper, Race status/timing shared leaf, callback participation, and shipped menu reachability for the selected five.
- Restored the
CG_ONEFLAG_STATUSvisible leaf to the retailgfx/2d/flag_status/*shader bank, white draw color, and stolen-flag score-dependent y offset. - Added focused structural coverage for constants, dispatcher routes,
CG_GetValueparticipation, width/key callback absence, display-context wiring, retail HLIL anchors, and menu reachability. - Refreshed the cgame ownerdraw and mapping ledgers for the selected five.
Task A149: Close selected 122-126 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/cgame/cg_newdraw.c,
src/code/cgame/cg_servercmds.c, src/code/game/g_cmds.c,
tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_1ST_PLYR_FRAGS_LG, CG_1ST_PLYR_FRAGS_RG,
CG_1ST_PLYR_FRAGS_PG, CG_1ST_PLYR_FRAGS_BFG, and
CG_1ST_PLYR_FRAGS_CG ownerdraw set. Repo-wide parity remains 98%
because unrelated compatibility, source-legacy, and packaging surfaces are
unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher,0x100368A0weapon-frag leaf, and0x1002E2B0placement weapon resolver for raw ownerdraw cases0x7athrough0x7e. - Confirmed the retail resolver maps LG/RG/PG/BFG to weapon indexes
6through9and maps CG to0xd, preserving the Quake Live enum gap before nailgun/prox/chaingun. - Pinned the qagame-to-cgame compact
scorestatsweapon-frag wiring around the retail LG, RG, PG, BFG, CG lane inside the full frag order. - Added focused structural coverage for constants, retail target-group membership, resolver returns, weapon mapping, server send path, cgame parse path, dispatcher guard, callback absence, and direct-switch absence.
- Refreshed the cgame ownerdraw and mapping ledgers for the selected five.
Task A148: Harden selected 75-79 cgame award ownerdraw parity [COMPLETED]
Priority: High
Primary areas: tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_MOST_VALUABLE_OFFENSIVE_PLYR,
CG_MOST_VALUABLE_DEFENSIVE_PLYR, CG_MOST_VALUABLE_PLYR,
CG_BEST_ITEMCONTROL_PLYR, and CG_MOST_ACCURATE_PLYR ownerdraw set.
Repo-wide parity remains 98% because unrelated compatibility,
source-legacy, and packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dllownerdraw dispatcher route for raw cases0x4bthrough0x4f, all landing on the shared award-player image leaf at0x1003A0D0. - Verified the selected ownerdraws are handled before the source
CG_OwnerDrawswitch byCG_DrawAwardPlayer, fed by qagame-producedCS_AWARD_*configstrings and rendered through the profile-image helper. - Added focused structural coverage for constants, retail target routing, qagame producer wiring, cgame configstring consumption, shipped end-scoreboard menu reachability, display-context callbacks, and absence from value/width/key callback routes.
- Refreshed the cgame ownerdraw and mapping ledgers so the award lane now documents the recovered configstring-backed profile-image path.
Task A147: Close selected 117-121 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/cgame/cg_newdraw.c,
src/code/cgame/cg_servercmds.c, src/code/game/g_cmds.c,
tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_1ST_PLYR_FRAGS_G, CG_1ST_PLYR_FRAGS_MG,
CG_1ST_PLYR_FRAGS_SG, CG_1ST_PLYR_FRAGS_GL, and
CG_1ST_PLYR_FRAGS_RL ownerdraw set. Repo-wide parity remains 98%
because unrelated compatibility, source-legacy, and packaging surfaces are
unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher and HLIL leaf at0x100368A0, including the placement weapon-index helper, weapon-frag cache read,%dformat literal, and baseline text paint. - Tightened the placement weapon-frag formatter to the retail
%dliteral. - Pinned the qagame-to-cgame compact
scorestatsweapon-frag wiring around the retail G, MG, SG, GL, RL prefix order. - Added focused structural coverage for constants, retail target-group membership, weapon mapping, server send path, cgame parse path, dispatcher guard, callback absence, and direct-switch absence.
- Refreshed the cgame ownerdraw and mapping ledgers for the selected five.
Task A146: Close health/ammo cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: tests/test_cgame_ownerdraw_text_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_PLAYER_HEALTH_BAR_100, CG_PLAYER_HEALTH_BAR_200,
CG_PLAYER_AMMO_ICON, CG_PLAYER_AMMO_ICON2D, and CG_PLAYER_AMMO_VALUE
ownerdraw set. Repo-wide parity remains 98% because unrelated
compatibility, source-legacy, and packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher and HLIL leaves for raw ownerdraw cases0x2d,0x2e,0x2f,0x30, and0x31. - Confirmed current source preserves the retail primary/excess health-bar split, ammo icon 2D/3D branches, finite ammo text/shader rendering, and infinite-ammo icon fallback.
- Added focused structural coverage for constants, dispatcher routes,
CG_GetValueparticipation, width/key callback absence, display-context wiring, and shipped menu reachability.
Task A145: Close local status cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: tests/test_cgame_ownerdraw_text_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_PLAYER_ARMOR_VALUE, CG_PLAYER_ARMOR_BAR_100,
CG_PLAYER_ARMOR_BAR_200, CG_ARMORTIERED_COLORIZED, and
CG_PLAYER_HEALTH ownerdraw set. Repo-wide parity remains 98% because
unrelated compatibility, source-legacy, and packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher and HLIL leaves for raw ownerdraw cases0x28,0x29,0x2a,0x2b, and0x2c. - Confirmed current source preserves the retail armor/health shader-or-aligned-number paths, armor primary/excess bar clipping, and replicated armor-tier color fill.
- Added focused structural coverage for constants, dispatcher routes,
CG_GetValueparticipation, width/key callback absence, display-context wiring, and shipped menu reachability.
Task A144: Close selected 112-116 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/cgame/cg_newdraw.c,
tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 96% -> after 100% for the selected
CG_1ST_PLYR_ACC, CG_1ST_PLYR_FLAG, CG_1ST_PLYR_AVATAR,
CG_1ST_PLYR_TIMEOUT_COUNT, and CG_1ST_PLYR_HEALTH_ARMOR ownerdraw
set. Repo-wide parity remains 98% because unrelated compatibility,
source-legacy, and packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher and HLIL leaves for0x10036570,0x10036720,0x100366A0,0x10033040, plus the raw0x73no-op gap. - Tightened total accuracy formatting to the retail
%d%%literal and kept the placement flag route on the cached country-flag shader path. - Restored the placement avatar selection order: native avatar handle when
cg_drawProfileImagesand a replicated identity are available, then the cached model icon fallback, with no source-only dimming or armor fallback. - Rebuilt the spectator comparison ownerdraw around retail-style health and armor bands, including local playerState stat reads, tracked-client fallback, fixed retail colors, the short-lived damage-loss segment, primary-slot right alignment, cvar color gating, and removal of the non-retail text/marker overlay.
- Added focused structural coverage for the five selected ownerdraw IDs and refreshed the cgame ownerdraw and mapping ledgers.
Task A143: Close spectator/player-preview cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: tests/test_cgame_ownerdraw_text_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_SPEC_MESSAGES, CG_PLAYER_HEAD, CG_PLAYERMODEL,
CG_PLAYER_ARMOR_ICON, and CG_PLAYER_ARMOR_ICON2D ownerdraw set.
Repo-wide parity remains 98% because unrelated compatibility,
source-legacy, and packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher and HLIL leaves for raw ownerdraw cases0x23,0x24,0x25,0x26, and0x27. - Confirmed current source preserves the spectator message copy family, local head damage/idle interpolation, tracked/local model preview, and shared armor 2D/3D icon behavior.
- Added focused structural coverage for constants, dispatcher routes, shipped menu reachability, and absence from the value/width/key callback paths.
Task A142: Close vote shot/timer cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: tests/test_cgame_ownerdraw_text_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 99% -> after 100% for the selected
CG_VOTESHOT1, CG_VOTESHOT2, CG_VOTESHOT3, CG_VOTECOUNT3, and
CG_VOTETIMER ownerdraw set. Repo-wide parity remains 98% because
unrelated compatibility, source-legacy, and packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher and HLIL leaves for raw ownerdraw cases0x19,0x1a,0x1b,0x21, and0x22. - Confirmed current source preserves the retail vote preview path, default preview fallback, third vote-count label, timer text family, cvar payload wiring, and absence of value/width/key callback participation.
- Added focused structural coverage for dispatcher slots, shipped menu usage,
ui_vote%s%ishot/count payload transport, and vote active/string bridge state used by the timer menu.
Task A141: Close vote name/count cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/cgame/cg_newdraw.c,
tests/test_cgame_ownerdraw_text_parity.py,
tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 95% -> after 100% for the selected
CG_VOTENAME1, CG_VOTENAME2, CG_VOTENAME3, CG_VOTECOUNT1, and
CG_VOTECOUNT2 ownerdraw set. Repo-wide parity remains 98% because
unrelated compatibility, source-legacy, and packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher and HLIL leaves for raw ownerdraw cases0x1cthrough0x20. - Restored the retail text-width alignment path for vote-name labels while
preserving the
NamethenMapfallback payload order and raw rect-y paint origin. - Added focused structural coverage for dispatcher slots, display-context
callbacks,
ui_vote%s%iname/count payload wiring, shipped menu usage, and absence of value/width/key callback participation.
Task A140: Close selected 107-111 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/cgame/cg_newdraw.c,
tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 98% -> after 100% for the selected
CG_1ST_PLYR_DEATHS, CG_1ST_PLYR_DMG, CG_1ST_PLYR_TIME,
CG_1ST_PLYR_PING, and CG_1ST_PLYR_WINS ownerdraw set. Repo-wide
parity remains 98% because unrelated compatibility, source-legacy, and
packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher and HLIL leaves for0x10036320,0x10036770,0x10036070, and0x10036450, plus the raw0x6dno-op gap. - Tightened the placement ping ownerdraw to use the retail
>40and>80warning-color thresholds, forced blue to0.0, and forced alpha to0.8before painting. - Restored the wins slot to the retail preformatted
%d/%dwins/losses text path rather than the source-only bare wins count. - Added focused structural coverage for the five selected ownerdraw IDs, including dispatcher routes, metric helpers, the no-op time case, retail color evidence, and the absence of value/width/key callback wiring.
- Updated the cgame ownerdraw and mapping ledgers with the exact placement metric and ping-color evidence.
Task A139: Close vote gametype/map cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/cgame/cg_newdraw.c,
tests/test_cgame_ownerdraw_text_parity.py,
tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 94% -> after 100% for the selected
CG_VOTEGAMETYPE1, CG_VOTEGAMETYPE2, CG_VOTEGAMETYPE3,
CG_VOTEMAP1, and CG_VOTEMAP2 ownerdraw set. Repo-wide parity remains
98% because unrelated compatibility, source-legacy, and packaging
surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher and HLIL leaves for raw ownerdraw cases0x13through0x17. - Restored the retail text-width alignment path for vote gametype and raw-map
labels while preserving the gametype row's
rect->y - 8.0fpaint bias. - Added focused structural coverage for dispatcher slots, display-context
callbacks,
ui_vote%s%icvar payload wiring, menu reachability, and the absence of value/width/key callback participation.
Task A138: Tighten 83-87 cgame placement ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/cgame/cg_newdraw.c,
tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 98% -> after 100% for the selected
CG_1STPLACE, CG_1ST_PLACE_SCORE, CG_1STPLACE_PLYR_MODEL,
CG_2NDPLACE, and CG_2ND_PLACE_SCORE ownerdraw set. Repo-wide parity
remains 98% because unrelated compatibility, source-legacy, and packaging
surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dllHLIL and committed Ghidra dispatcher for raw ownerdraw cases0x53through0x57. - Restored compact placement score formatting through the shared retail score
helper, including Race
[-]Nstext and theSCORE_NOT_PRESENTskip. - Wired the compact placement ownerdraws into the competitive score-cache touch path used by HUD-only placement layouts.
- Tightened the wide second-place row to use the retail spectator-team gate before choosing between the local player row and cached runner-up row.
- Refreshed focused structural tests and ownerdraw/mapping ledgers for the completed placement lane.
Task A137: Close selected 100-105 cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/cgame/cg_newdraw.c,
tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md
Parity estimate: before 98% -> after 100% for the selected
CG_TEAM_PLYR_COUNT, CG_ENEMY_PLYR_COUNT, CG_1ST_PLYR,
CG_1ST_PLYR_READY, and CG_1ST_PLYR_SCORE ownerdraw set. Repo-wide
parity remains 98% because unrelated compatibility, source-legacy, and
packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher and HLIL leaves for0x10033650,0x10035BD0,0x10037BA0, and0x10035F30. - Corrected the friendly/enemy round player-count ownerdraws to paint the
cached team count at the raw ownerdraw origin, matching the retail
sub_10033650text path instead of the older centered source behavior. - Added focused structural coverage for the five selected ownerdraw IDs,
including dispatcher routes, pre-switch
CG_1ST_PLYR_READYhandling, raw text origins, and the absence of value/width/key callback wiring. - Updated the cgame ownerdraw and mapping ledgers with the raw-origin player-count evidence.
Task A136: Close gametype cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: tests/test_cgame_ownerdraw_text_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 98% -> after 100% for the selected
CG_GAME_TYPE, CG_GAME_TYPE_ICON, and CG_GAME_TYPE_MAP ownerdraw trio.
Repo-wide parity remains 98% because unrelated compatibility,
source-legacy, and packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
cgamex86.dlldispatcher evidence for raw ownerdraw cases4,5, and6, mapped toCG_DrawGameType,CG_DrawGameTypeIcon, andCG_DrawGameTypeMap. - Confirmed the current source preserves the direct draw routes, keeps only
CG_GAME_TYPEon the ownerdraw-width callback, and leaves the trio out of the value and key-handler callbacks. - Added focused structural coverage for the dispatcher, display-context callbacks, shipped menu reachability, gametype icon registration path, and intro-panel gametype-map wiring.
Task A135: Restore retail post-process gamma capture path [COMPLETED]
Priority: High
Primary areas: src/code/renderer/tr_init.c,
docs/renderer_cvar_matrix.md, tests/test_engine_cvar_retail_parity.py
Parity estimate: before 99% -> after 100% for the selected
renderer post-process gamma ownership lane. Repo-wide parity remains 98%
because unrelated compatibility, source-legacy, and packaging surfaces are
unchanged.
Completed work:
- Rechecked the retail
quakelive_steam.exeHLIL/Ghidra evidence forr_enablePostProcess,r_enableColorCorrect, thep_gammaRecipcolor-correct uniform, and the legacy Win32 gamma ramp fallback. - Removed the reconstruction-only
r_enablePostProcessforce-off so the shader-backed color-correct pass owns finalr_gammaoutput by default, matching retail and improving Windows desktop/PrintScreen capture parity. - Updated cvar parity tests and renderer cvar documentation to reflect the restored retail default and fallback boundary.
Task A134: Close player/opponent UI ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/ui/ui_main.c, tests/test_ui_menu_files.py,
docs/reverse-engineering/ui-ownerdrawtype-parity-index.md
Parity estimate: before 76% -> after 100% for the selected
UI_PLAYERMODEL, UI_OPPONENTMODEL, and UI_OPPONENT_NAME ownerdraw trio.
Repo-wide parity remains 98% because unrelated compatibility,
source-legacy, and packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
uix86.dllHLIL/Ghidra evidence forUI_DrawPlayerModelat0x10005690,UI_DrawOpponentat0x10006730,UI_DrawOpponentNameat0x100068F0, andUI_OwnerDrawHandleKeyat0x1000A820. - Rebuilt
UI_PLAYERMODELaround the retailmodel/headmodelcvar reads, empty team name,cg_loadout/cg_weaponPrimaryprimary weapon selection, weapon item validation, heavy-machinegun fallback for invalid primary weapon values, retail5/210/0view angles, and the pre-draw cachedplayerInfo_treset observed in HLIL. - Tightened
UI_OPPONENTMODELcvar refresh to use bufferedui_opponentModelreads before rebuilding and drawing the cachedplayerInfo_t, including the retail0/170/0view angles and pre-draw cached preview reset. - Tightened
UI_OPPONENT_NAMEto the retail bufferedui_opponentNamepaint path, kept the empty width-helper case, and removed the source-only ownerdraw key route that retail does not dispatch. - Updated the UI ownerdraw parity index so all retail-routed
Needs checkrows are now checked.
Verification:
python -m pytest tests/test_ui_menu_files.py -k "player_opponent_ownerdraws or handicap_netsource_netfilter"- Result:
2 passed, 76 deselected.
- Result:
python -m pytest tests/test_ui_menu_files.py- Result:
78 passed.
- Result:
Task A133: Close front-panel cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: tests/test_cgame_ownerdraw_text_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 98% -> after 100% for the selected
CG_SERVER_SETTINGS, CG_STARTING_WEAPONS, and CG_GAME_LIMIT ownerdraw
trio. Repo-wide parity remains 98% because no unrelated compatibility or
runtime-evidence surfaces changed.
Completed work:
- Rechecked the retail
CG_OwnerDrawdispatcher cases1,2, and3against the committed Ghidra/HLIL evidence. - Confirmed
CG_SERVER_SETTINGSstays on the custom-settings text and modified-weapon icon-strip leaf. - Confirmed
CG_STARTING_WEAPONSstays on theCS_LOADOUT_MASKicon-strip and queued-primary loadout preview leaf. - Confirmed
CG_GAME_LIMITstays on the narrowed retailCap Limit/Frag Limit/Round Limit/Score Limitlabel family. - Added focused structural coverage that guards switch wiring, display-context callback non-participation, menudef constants, and shipped menu reachability for the two shipped front-panel menu users.
Task A132: Close objective/powerup cgame ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/cgame/cg_newdraw.c,
tests/test_cgame_displaycontext_parity.py,
tests/test_cgame_hud_parity.py,
tests/test_game_key_item_parity.py,
docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 98% -> after 100% for the selected
CG_PLAYER_HASKEY, CG_CTF_POWERUP, and CG_AREA_POWERUP ownerdraw trio.
Repo-wide parity remains 98% because unrelated dirty worktree and runtime
evidence surfaces are unchanged.
Completed work:
- Rechecked the retail cgame
CG_OwnerDrawswitch and leaves at0x10031F90,0x100310F0, and0x10031160. - Reconstructed
CG_PLAYER_HASKEYto use the retailBG_FindItemByTypeAndTag( IT_KEY, tag )path for silver, gold, and master keys instead of a classname detour. - Confirmed
CG_CTF_POWERUPremains the directSTAT_PERSISTANT_POWERUPitem-icon ownerdraw. - Confirmed
CG_AREA_POWERUPis directly wired to the retail powerup stack helper and has nocg_drawSpritesorcg_drawSpriteSelfownerdraw gate. - Updated the cgame ownerdraw index so all menudef cgame rows are now checked or checked retail no-ops.
Task A131: Add full cgame ownerdraw parity index [COMPLETED]
Priority: High
Primary areas: docs/reverse-engineering/cg-ownerdrawtype-parity-index.md,
tests/test_cgame_displaycontext_parity.py
Parity estimate: before 0% -> after 100% for durable index coverage of
the src/ui/menudef.h cgame ownerdraw block. The current ledger has 327
checked rows, 12 checked retail no-ops, and no open partial rows after the
objective/powerup ownerdraw follow-up.
Completed work:
- Added a full tabulated listing for menudef cgame ownerdraw IDs
1..339, excludingCG_SHOW_*flags,UI_*ownerdraws, andui_shared.h-only source aliases outside the menudef range. - Recorded the current cgame implementation route and parity state for every row so future parity-picking has a stable index.
- Added a structural test that compares the ledger rows back to the menudef cgame block and rejects accidental UI/visibility-flag leakage.
Task A130: Close medal-adjacent cgame ownerdraw no-op parity [COMPLETED]
Priority: High
Primary areas: src/code/cgame/cg_newdraw.c,
tests/test_cgame_displaycontext_parity.py,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 95% -> after 100% for the focused
CG_COMBOKILLS, CG_RAMPAGES, and CG_MIDAIRS cgame ownerdraw lane.
Repo-wide parity remains 98% because unrelated dirty worktree changes and
non-Windows/runtime-evidence lanes are unchanged.
Completed work:
- Rechecked the committed cgame ownerdraw switch evidence for
0x1003B0F0 -> CG_OwnerDrawand the medal helper route at0x10035340 -> CG_DrawMedal. - Confirmed retail routes only
CG_ACCURACY,CG_ASSISTS,CG_CAPTURES,CG_DEFEND,CG_EXCELLENT,CG_GAUNTLET,CG_IMPRESSIVE, andCG_PERFECTto the medal helper;CG_COMBOKILLS(0x43),CG_RAMPAGES(0x48), andCG_MIDAIRS(0x49) are absent from the retail ownerdraw switch. - Made the three absent ownerdraws explicit no-op cases in
CG_OwnerDraw, preserving no menu usage, noCG_GetValueroute, noCG_OwnerDrawWidthroute, and the retail null key-handler behavior. - Added focused structural coverage for the retail switch absence, medal helper exclusion, display-context callback non-participation, and shipped menu reachability.
Verification:
python -m pytest tests/test_cgame_displaycontext_parity.py -k "combo_rampage_midair or team_pickup_timeheld_and_medal_dispatch_groups" -q- Result:
2 passed, 145 deselected.
- Result:
python -m pytest tests/test_cgame_displaycontext_parity.py -k "combo_rampage_midair or ownerdraw_dispatch_covers_committed_retail_switch_cases or ownerdraw_width_callback" -q- Result:
3 passed, 144 deselected.
- Result:
Task A129: Close team overlay transport and drawing parity [COMPLETED]
Priority: High
Primary areas: src/code/game/g_team.c,
src/code/cgame/cg_servercmds.c, src/code/game/bg_public.h,
src/code/cgame/cg_draw.c, tests/test_cgame_hud_parity.py
Parity estimate: before 98% -> after 100% for the focused team-overlay
transport/cache and classic HUD drawing lane. Repo-wide parity remains 98%
because unrelated dirty worktree changes and non-Windows/runtime-evidence lanes
are unchanged.
Completed work:
- Rechecked the retail evidence for cgame
CG_DrawTeamOverlayat0x10009DA0, cgameCG_ParseTeamInfoat0x100487B0, and qagameTeamplayInfoMessageat0x10068490. - Restored the retail eight-player overlay cap and made qagame format the
sorted top-eight teammate set it already selected from
level.sortedClients. - Kept the emitted
tinforow count tied to successfully serialized rows and guarded the cgame receiver against oversized, truncated, or invalid client rows before updatingsortedTeamPlayers. - Matched the retail drawing gates and row body: invulnerability-expand early
return, integer row placement,
ITEM_TEXTSTYLE_SHADOWEDhost text, sans name/location columns, mono health/armor columns,EF_DEADdead-row gating, and a powerup icon ladder that suppresses the neutral flag and frozen sentinel while preserving the invulnerability item path. - Added a focused parity test covering the eight-row cap, sorted top-eight
payload order,
tinforow count, and receiver-side bounds.
Verification:
python -m pytest tests/test_cgame_hud_parity.py -k "team_overlay" -q- Result:
3 passed, 29 deselected.
- Result:
python -m pytest tests/test_cgame_hud_parity.py tests/test_game_runframe_parity.py -q- Result:
35 passed, 2 failed; the two failures are unrelated existing HUD assertions forCG_DrawTeamInfoRowwidth andCG_DrawAreaPowerUpsprite gating on the dirty worktree.
- Result:
Task A128: Close map selection UI ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/ui/ui_main.c, tests/test_ui_menu_files.py,
docs/reverse-engineering/ui-ownerdrawtype-parity-index.md
Parity estimate: before 98% -> after 100% for the focused
UI_ALLMAPS_SELECTION, UI_MAPS_SELECTION, and UI_STARTMAPCINEMATIC
ownerdraw lane. Repo-wide parity remains 98% because unrelated
compatibility and packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
uix86.dllHLIL/Ghidra evidence forUI_DrawAllMapsSelectionat0x10006890andUI_DrawMapCinematicat0x10005560. - Confirmed
UI_ALLMAPS_SELECTIONuses the retail shared map-name draw path with the net/current selector flag, guards the map index against the retail active map count, and has an empty width-helper case with no key handler. - Confirmed
UI_MAPS_SELECTIONmatches the retail current-map name paint path and is reconstructed through the shared source helper with the current map selector flag. - Confirmed
UI_STARTMAPCINEMATICuses the retail map cinematic helper with the start/net selector flag, including map index reset,%s.roqlazy start, run/extents/draw behavior, and preview fallback. - Updated the ownerdraw parity index so the three selected IDs are now marked
checked and the unchecked retail-routed set is down to
UI_PLAYERMODEL,UI_OPPONENTMODEL, andUI_OPPONENT_NAME.
Verification:
python -m pytest tests/test_ui_menu_files.py -k "map_selection_ownerdraws"- Result:
1 passed, 76 deselected.
- Result:
python -m pytest tests/test_ui_menu_files.py- Result:
77 passed.
- Result:
Task A127: Close server info UI ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/ui/ui_main.c, tests/test_ui_menu_files.py,
docs/reverse-engineering/ui-ownerdrawtype-parity-index.md
Parity estimate: before 98% -> after 100% for the focused
UI_SERVERREFRESHDATE, UI_SERVERMOTD, and UI_GLINFO ownerdraw lane.
Repo-wide parity remains 98% because unrelated compatibility and packaging
surfaces are unchanged.
Completed work:
- Rechecked the retail
uix86.dllHLIL/Ghidra evidence forUI_DrawServerRefreshDateat0x10008F20,UI_DrawServerMOTDat0x10009080, andUI_DrawGLInfoat0x100093B0. - Confirmed
UI_SERVERREFRESHDATEmatches the retail active-refresh pulse path, server-count message, cachedui_lastServerRefresh_%itimestamp path, draw dispatcher route, andUI_OwnerDrawWidthroute. - Confirmed
UI_SERVERMOTDmatches the retail MOTD scroll state, wraparound dual-paint behavior, and thecl_motdStringfallback seeding toWelcome to Team Arena!before drawing. - Confirmed
UI_GLINFOmatches the retail vendor/version/pixel-format paint lines and the extension-string split/wrap behavior. - Confirmed none of the three selected ownerdraws has retail key-handler
wiring, and only
UI_SERVERREFRESHDATEparticipates in the width helper. - Updated the ownerdraw parity index so the three selected IDs are now marked checked and the unchecked retail-routed set reflects the remaining work.
Verification:
python -m pytest tests/test_ui_menu_files.py -k "server_info_ownerdraws"- Result:
1 passed, 75 deselected.
- Result:
python -m pytest tests/test_ui_menu_files.py- Result:
76 passed.
- Result:
Task A126: Close map media UI ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/ui/ui_main.c, tests/test_ui_menu_files.py,
docs/reverse-engineering/ui-ownerdrawtype-parity-index.md
Parity estimate: before 98% -> after 100% for the focused
UI_NETMAPPREVIEW, UI_MAPCINEMATIC, and UI_NETMAPCINEMATIC ownerdraw
lane. Repo-wide parity remains 98% because unrelated compatibility and
packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
uix86.dllHLIL/Ghidra evidence forUI_DrawMapCinematicat0x10005560,UI_DrawNetMapPreviewat0x100065B0, andUI_DrawNetMapCinematicat0x10006600. - Confirmed
UI_NETMAPPREVIEWmatches the retail current-server preview shader draw path and themenu/art/unknownmapfallback when no preview shader is available. - Confirmed
UI_MAPCINEMATICmatches the retail map selector validation, lazy%s.roqcinematic start, run/extents/draw sequence, failure marker, preview fallback, and ownerdraw dispatcher route. - Confirmed
UI_NETMAPCINEMATICmatches the retail current-server cinematic run/extents/draw sequence, current-net-map reset guard, preview fallback, and ownerdraw dispatcher route. - Locked the shared cinematic cleanup wiring:
_UI_InitinstallsUI_StopCinematic, positive handles stop directly, and ownerdraw cleanup handlesUI_MAPCINEMATICandUI_NETMAPCINEMATICby resetting their backing cinematic handles to-1. - Updated the ownerdraw parity index so the three selected IDs are now marked checked and the unchecked retail-routed set reflects the remaining work.
Verification:
python -m pytest tests/test_ui_menu_files.py -k "map_media_ownerdraws"- Result:
1 passed, 74 deselected.
- Result:
python -m pytest tests/test_ui_menu_files.py- Result:
75 passed.
- Result:
Task A125: Close skill and map preview UI ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/ui/ui_main.c, tests/test_ui_menu_files.py
Parity estimate: before 98% -> after 100% for the focused UI_SKILL,
UI_MAPPREVIEW, and UI_MAP_TIMETOBEAT ownerdraw lane. Repo-wide parity
remains 98% because unrelated compatibility and packaging surfaces are
unchanged.
Completed work:
- Rechecked the retail
uix86.dllHLIL/Ghidra evidence forUI_DrawSkillat0x10005350,UI_DrawMapPreviewat0x100053C0,UI_DrawMapTimeToBeatat0x100054A0, andUI_Skill_HandleKeyat0x1000A390. - Confirmed
UI_SKILLclampsg_spSkillinto the retail one-to-five range, paints the matching skill table entry, and wires the ownerdraw key handler to the retail click/enter cycle behavior. - Confirmed
UI_MAPPREVIEWvalidates the selected map slot, resets the current map cvars on invalid indexes, lazily caches levelshot shaders, falls back tomenu/art/unknownmap, and uses the net-map preview path from the ownerdraw dispatcher. - Confirmed
UI_MAP_TIMETOBEATvalidatesui_currentMap, resolves the retail gametype enum before indexing the per-map time table, formats the value as%02i:%02i, and paints it through the ownerdraw dispatcher. - Added regression coverage binding all three ownerdraws to the promoted retail evidence addresses, draw dispatch wiring, key dispatch wiring, and fallback/reset behavior.
Verification:
python -m pytest tests/test_ui_menu_files.py -k "skill_mappreview_maptime"- Result:
1 passed, 73 deselected.
- Result:
python -m pytest tests/test_ui_menu_files.py- Result:
74 passed.
- Result:
Task A124: Close bot selector UI ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/ui/ui_main.c, tests/test_ui_menu_files.py
Parity estimate: before 97% -> after 100% for the focused UI_BOTNAME,
UI_BOTSKILL, and UI_REDBLUE ownerdraw lane. Repo-wide parity remains
98% because unrelated compatibility and packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
uix86.dllHLIL/Ghidra evidence forUI_DrawBotNameat0x10006b30,UI_DrawBotSkillat0x10006bc0,UI_DrawRedBlueat0x10006c10, and the bot-name/bot-skill key handlers at0x1000a570and0x1000a5d0. - Made the
UI_BOTNAMEdraw path explicitly mirror the retail invalid-index behavior: clamp high indexes back to zero, print the retail invalid bot warning for remaining invalid indexes, and paint theSargefallback while keeping the add-bot selector bound to the bot catalog rather than the character roster. - Confirmed
UI_BOTSKILLalready matches the retail five-entry skill table paint path and wraparound key cycling. - Confirmed
UI_REDBLUEalready matches the retailRed/Bluepaint path, toggle handler, and non-returning ownerdraw key dispatch. - Locked all three ownerdraw draw dispatches, key dispatches, key wrap paths, fallback behavior, and add-bot catalog wiring with focused regression coverage.
Verification:
python -m pytest tests/test_ui_menu_files.py -k "botname_botskill_redblue or addbot_uses_bot_catalog"- Result:
2 passed, 71 deselected.
- Result:
python -m pytest tests/test_ui_menu_files.py- Result:
73 passed.
- Result:
Task A123: Close handicap and server-browser selector UI ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/ui/ui_main.c, tests/test_ui_menu_files.py
Parity estimate: before 96% -> after 99% for the focused
UI_HANDICAP, UI_NETSOURCE, and UI_NETFILTER ownerdraw lane. Repo-wide
parity remains 98% because unrelated compatibility and packaging surfaces
are unchanged.
Completed work:
- Rechecked the retail
uix86.dllHLIL/Ghidra evidence for the handicap draw and key handler, plus the browser source/filter draw, width, and key handlers at0x1000a040,0x1000a420, and0x1000a4f0. - Confirmed
UI_HANDICAPalready matched the retail5..100clamp, label table indexing, five-point key steps, and wrap behavior, then locked that draw/width/key-dispatch path with focused tests. - Corrected
UI_NETSOURCEdraw and ownerdraw-width bounds to rejectindex == numNetSources, and replaced the stale width check againstuiInfo.numJoinGameTypeswith the retail browser-source count. - Corrected
UI_NETFILTERdraw and ownerdraw-width bounds to rejectindex == numServerFilters, matching the retail seven-filter table limit. - Locked the Mplayer-skip source cycling, global-refresh gate, server-list rebuilds, non-returning ownerdraw key dispatch, and filter wrap behavior with focused regression coverage.
Verification:
python -m pytest tests/test_ui_menu_files.py -q --tb=short- Result:
72 passed.
- Result:
Task A122: Close crosshair, next-map, and selected-player UI ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/ui/ui_main.c, tests/test_ui_menu_files.py
Parity estimate: before 93% -> after 99% for the focused
UI_CROSSHAIR, UI_NEXTMAP, and UI_SELECTEDPLAYER ownerdraw lane.
Repo-wide parity remains 98% because unrelated compatibility and packaging
surfaces are unchanged.
Completed work:
- Rechecked the retail
uix86.dllHLIL/Ghidra evidence for the crosshair preview, next-map label, selected-player draw, player-list refresh, and selected-player key-handler paths. - Reconstructed
UI_CROSSHAIRpreview placement to use the retail24..40size clamp and fixedrect->x - 2,rect->y - rect->h + 2anchor instead of scaling/centering within the ownerdraw rect. - Reconstructed
UI_NEXTMAPto paint only the retail configstring0x29Apayload and removed the compatibility fallback through rotation-title configstrings from that ownerdraw. - Reconstructed
UI_SELECTEDPLAYERdrawing to use the retail buffered cvar read for eithercg_selectedPlayerNameorname, while preserving the player-list refresh and selected-player key cycling semantics. - Locked draw dispatch, key dispatch, cvar reads/writes, configstring reads, selected-player cache refresh, wrap behavior, and removed fallback paths with focused regression coverage.
Verification:
python -m pytest tests/test_ui_menu_files.py -q --tb=short- Result:
71 passed.
- Result:
Task A121: Close retail gametype-selector UI ownerdraw parity [COMPLETED]
Priority: High
Primary areas: src/code/ui/ui_main.c, tests/test_ui_menu_files.py
Parity estimate: before 95% -> after 99% for the focused
UI_GAMETYPE, UI_NETGAMETYPE, and UI_JOINGAMETYPE ownerdraw lane.
Repo-wide parity remains 98% because unrelated compatibility and packaging
surfaces are unchanged.
Completed work:
- Rechecked the retail
uix86.dllHLIL/Ghidra evidence for the gametype ownerdraw dispatch cases and their key handlers at0x1000a110,0x1000a210, and0x1000a300. - Removed the old non-retail
ui_Q3Modelside effect from theUI_GAMETYPEkey path while preserving retail cycling, cap/frag refresh, best-score reload, and map-feeder reset wiring. - Reconstructed the retail
UI_NETGAMETYPEhidden-enum skip so the selector cycles past One Flag CTF, Overload, and Harvester before updatingui_netGameType,ui_actualnetGameType,ui_currentNetMap, and the map feeder. - Locked the
UI_GAMETYPE,UI_NETGAMETYPE, andUI_JOINGAMETYPEdraw-dispatch, key-dispatch, cvar, feeder, and server-list wiring with focused regression coverage.
Verification:
python -m pytest tests/test_ui_menu_files.py -q --tb=short- Result:
70 passed.
- Result:
Task A120: Close three retail UI ownerdraw parity seams [COMPLETED]
Priority: High
Primary areas: src/code/ui/ui_main.c, tests/test_ui_menu_files.py
Parity estimate: before 94% -> after 99% for the focused
UI_VOTESTRING, UI_STARTING_WEAPONS, and UI_ADVERT ownerdraw lane.
Repo-wide parity remains 98% because the remaining non-ownerdraw
compatibility and packaging surfaces are unchanged.
Completed work:
- Rechecked the retail
uix86.dllHLIL/Ghidra ownerdraw dispatch evidence forUI_VOTESTRING,UI_STARTING_WEAPONS, andUI_ADVERT. - Reconstructed
UI_VOTESTRINGto use the retail buffered cvar read and integer x-anchor centering behavior instead of centering inside the rect width. - Reconstructed
UI_STARTING_WEAPONSto parse the loadout mask through the retail decimalatoipath and to draw the loadout+marker at the retail x-offset before the queued-primary icon. - Locked the advert ownerdraw parse/setup/refresh/paint/activate bridge with focused regression coverage, including default content, cell id, hidden-menu refresh rectangles, shader assignment, draw/update ordering, and activation script forwarding.
Verification:
python -m pytest tests/test_ui_menu_files.py -q --tb=short- Result:
69 passed.
- Result:
Task A119: Reconstruct retail ownership for ui_* cvars [COMPLETED]
Priority: High
Primary areas: src/code/ui/ui_main.c, src/code/ui/ui_local.h,
src/code/client/cl_ui.c, tests/test_ui_menu_files.py,
tests/test_cgame_hud_parity.py, tests/test_platform_services.py,
docs/reverse-engineering/ui-cvar-mapping-round-2026-05-28.md
Parity estimate: before 93% -> after 98% for the focused ui_* cvar
callback and ownership lane. Repo-wide parity remains 98% because the
source still carries bounded GPL-era and compatibility cvar rows outside the
retail uix86.dll table.
Completed work:
- Rechecked
uix86.dllGhidra and HLIL evidence for the retail UI cvar table, including the0x82row count, row field order,UI_RegisterCvars,UI_UpdateCvars, and the callback owners atsub_10011240,sub_10011630,sub_10011660, andsub_10011690. - Reconstructed the source cvar table callback lane with a retail-shaped row
order of
vmCvar, cvar name, default string, update callback, and flags. - Replaced ad hoc color modification-count checks with the retail
UI_UpdateCvarscallback rule and added the missing bulkui_teamColorandui_enemyColorrows. - Routed retail slider-color, force-model, and
cg_announcerrows through source-visible callbacks that mirror the committed HLIL behavior. - Corrected the native UI
S_RegisterSoundhost shim so the retail announcer callback's non-zero7argument remains true after qboolean normalization. - Documented the full retail
0x82row table, host-ownedui_*bridge cvars, and compatibility-only source cvars, then refreshed focused parity tests.
Task A118: Reconstruct cached retail ownership for web_* cvars [COMPLETED]
Priority: High
Primary areas: src/code/qcommon/common.c,
src/code/client/cl_cgame.c, tests/test_engine_cvar_retail_parity.py,
tests/test_engine_client_command_parity.py,
tests/test_awesomium_browser_parity.py,
tests/test_platform_services.py,
tools/ci/verify-awesomium-browser-host-parity.ps1,
docs/reverse-engineering/awesomium-browser-wiring.md,
docs/reverse-engineering/quakelive_steam_mapping_round_333.md
Parity estimate: before 96% -> after 99% for the focused web_* cvar
ownership lane. Overall Awesomium WebUI wiring remains 99.1% -> 99.1%;
repo-wide parity remains 98%.
Completed work:
- Rechecked the committed Ghidra and HLIL corpus for all retail
web_*cvar names and confirmed the supported set isweb_zoom,web_console, andweb_browserActive; the otherweb_*names in this subsystem are command registrations. - Reconstructed the core cached
web_browserActivecvar pointer incommon.cand routed the frame idle-sleep browser-active test through that pointer instead of a repeated name lookup. - Reconstructed cached browser-host cvar pointers for
web_zoom,web_console, andweb_browserActive, added a source-visible mapping table with recovered retail globals/defaults/flags, and routed console-message and live zoom consumers through the cached cvars. - Matched the retail
web_zoommodified-latch consumption path by clearing the cvar latch after the live Awesomium view consumes a zoom update. - Refreshed focused tests, verifier anchors, and mapping notes for the new cvar-owner evidence.
Task A117: Stop no-op Awesomium bridge cvar churn and guard Awesomium launches [COMPLETED]
Priority: High
Primary areas: src/code/client/cl_cgame.c, .vscode/build.ps1,
.vscode/launch.ps1, tests/test_awesomium_browser_parity.py,
tests/test_platform_services.py,
tools/ci/verify-awesomium-browser-host-parity.ps1,
docs/reverse-engineering/awesomium-browser-wiring.md
Parity estimate: before 99.0% -> after 99.1% for the focused Awesomium
WebUI wiring lane. Repo-wide parity remains 98% because default
online-service exclusion is policy-bounded.
Completed work:
- Rechecked the Ghidra/HLIL evidence for
Cvar_Set2and confirmed that the retail debug string is emitted before the unchanged-value return path, so the core cvar setter must not be softened to hide compatibility publisher spam. - Added a client-side
CL_SetCvarIfChanged()guard and routed repeated browser/advert bridge telemetry plus frame-loopweb_browserActivemirrors through it, while keeping retail-style open/hide cvar writes direct. - Added a build-settings stamp to the VS Code build wrapper and made
launch.ps1 -EnableAwesomiumrefuse a launch when the last build usedQLBuildOnlineServices=0, making accidental default-off WebUI tests fail early with a clear message. - Refreshed focused tests, verifier anchors, and the Awesomium wiring notes so the no-op cvar publish behavior and explicit Awesomium build path stay pinned.
Task A116: Remove Awesomium SDK replication and require external SDK dependencies [COMPLETED]
Priority: High
Primary areas: src/code/client/cl_awesomium_win32.cpp,
src/code/awesomium_process.vcxproj,
src/code/quakelive_steam.vcxproj,
src/code/win32/awesomium_process.cpp,
src/code/win32/awesomium_process.rc,
tests/test_awesomium_browser_parity.py,
tests/test_platform_services.py,
tools/ci/verify-awesomium-browser-host-parity.ps1,
tools/ci/verify-awesomium-process-parity.ps1,
docs/reverse-engineering/awesomium-browser-wiring.md,
docs/reverse-engineering/awesomium_process-mapping.md,
docs/reverse-engineering/quakelive_steam_mapping_round_332.md
Parity estimate: before 64% -> after 94% for the focused
Awesomium SDK-clean integration lane. Overall Awesomium WebUI wiring remains
estimated at 99.0% -> 99.0%; repo-wide parity remains 98%.
Completed work:
- Audited the Awesomium client/backend/helper build surface and found local
SDK-like replication in the C++ ABI fallback layer, generated
.defimport library, localChildProcessMaindeclaration, and vendor-owned helper metadata. - Removed local Awesomium object storage,
__thiscallthunks, decorated C++ import fallbacks, vtable-dispatch fallbacks, and rawBitmapSurfacefield offset reads from the live backend. - Corrected live SDK export usage for transparent-state setup and keyboard event injection, using the SDK-owned WebKeyboardEvent object path.
- Deleted
src/code/win32/awesomium.def, required externalAwesomiumSdkDir/AWESOMIUM_SDK_DIRfor online Awesomium builds, linkedawesomium.libfrom that SDK for the helper, and declared the external runtime dependency for the launcher. - Updated documentation, mapping notes, pytest coverage, and verifier guards so SDK replication does not re-enter silently.
Verification:
python -m pytest tests/test_awesomium_browser_parity.py tests/test_platform_services.py -q --tb=short- Result:
103 passed.
- Result:
powershell -ExecutionPolicy Bypass -File tools\ci\verify-awesomium-browser-host-parity.ps1 -RepoRoot E:\Repositories\QuakeLive-reverse- Result: all Awesomium browser host parity and SDK-clean dependency anchors present.
git diff --check -- ...- Result: clean; only Git line-ending normalization warnings were reported.
powershell -ExecutionPolicy Bypass -File tools\ci\build-windows-dlls.ps1 -RepoRoot E:\Repositories\QuakeLive-reverse -Solution src/code/quakelive.sln -Configuration Debug -Platform Win32 -PlatformToolset v143 -DisableOptionalCodecs- Result: build succeeded with
29existing warnings and0errors.
- Result: build succeeded with
Task A115: Reconstruct Awesomium qz method table return flags [COMPLETED]
Priority: High
Primary areas: src/code/client/cl_cgame.c,
src/code/client/cl_awesomium_win32.cpp,
tests/test_awesomium_browser_parity.py,
tests/test_platform_services.py,
tools/ci/verify-awesomium-browser-host-parity.ps1,
docs/reverse-engineering/awesomium-browser-wiring.md,
docs/reverse-engineering/quakelive_steam_mapping_round_331.md
Parity estimate: before 97% -> after 99.4% for the focused
Awesomium qz method-table/return-flag lane. Overall Awesomium WebUI wiring is
estimated at 98.9% -> 99.0%; repo-wide parity remains 98%.
Completed work:
- Rechecked
QLJSHandler_LookupMethodId,QLJSHandler_BindQzInstance,QLJSHandler_OnMethodCall, andQLJSHandler_OnMethodCallWithReturnValueagainst HLIL with Ghidra function/vtable ownership support. - Added source-visible retail bounds and row addresses for the
data_55c008qz method table. - Corrected
SetCvarandResetCvarto follow the retail return-valued method lane and return boolean success/failure values. - Updated the injected startup
qz_instancebridge so local cvar set/reset helpers normalize cvar names and return truthy values. - Added parity coverage and CI verifier anchors for the qz method table, return flags, startup bridge behavior, and mapping-round evidence.
Verification:
python -m pytest tests/test_awesomium_browser_parity.py tests/test_platform_services.py -q --tb=short- Result:
102 passed.
- Result:
powershell -ExecutionPolicy Bypass -File tools\ci\verify-awesomium-browser-host-parity.ps1 -RepoRoot E:\Repositories\QuakeLive-reverse- Result: all Awesomium browser host parity anchors present.
git diff --check -- src/code/client/cl_awesomium_win32.cpp src/code/client/cl_cgame.c src/code/client/client.h tests/test_awesomium_browser_parity.py tests/test_platform_services.py tools/ci/verify-awesomium-browser-host-parity.ps1 docs/reverse-engineering/awesomium-browser-wiring.md docs/reverse-engineering/quakelive_steam_mapping_round_330.md docs/reverse-engineering/quakelive_steam_mapping_round_331.md IMPLEMENTATION_PLAN.md- Result: clean; only Git line-ending normalization warnings were reported.
powershell -ExecutionPolicy Bypass -File tools\ci\build-windows-dlls.ps1 -RepoRoot E:\Repositories\QuakeLive-reverse -Solution src/code/quakelive.sln -Configuration Debug -Platform Win32 -PlatformToolset v143 -DisableOptionalCodecs- Result: build succeeded with
0warnings and0errors.
- Result: build succeeded with
Task A114: Reconstruct Awesomium WebSession lifecycle/cache wiring [COMPLETED]
Priority: High
Primary areas: src/code/client/cl_awesomium_win32.cpp,
src/code/client/cl_cgame.c, src/code/client/client.h,
tests/test_awesomium_browser_parity.py,
tools/ci/verify-awesomium-browser-host-parity.ps1,
docs/reverse-engineering/awesomium-browser-wiring.md,
docs/reverse-engineering/quakelive_steam_mapping_round_330.md
Parity estimate: before 96% -> after 99% for the focused
Awesomium WebSession lifecycle/cache lane. Overall Awesomium WebUI wiring is
estimated at 98.4% -> 98.9%; repo-wide parity remains 98%.
Completed work:
- Rechecked
sub_4F2A10,sub_4F2A30,sub_4F2A60,sub_4F2D30,sub_4F3CB0, andsub_4F3CD0against HLIL with Ghidra metadata and symbol-alias support. - Reconstructed WebSession slot
0x18initialization immediately afterWebCore::CreateWebSession. - Reclassified WebSession slot
0x1cas cache clear forweb_clearCacheand reload, removed it from shutdown, and routed live clear-cache throughCL_Awesomium_ClearCache. - Matched retail command-tail behavior for
web_showErrorand made live navigation failures enter the mapped load-failure handler. - Updated Awesomium wiring notes, mapping-round evidence, pytest coverage, and the browser-host parity verifier.
Verification:
python -m pytest tests/test_awesomium_browser_parity.py tests/test_platform_services.py -q --tb=short- Result:
101 passed.
- Result:
powershell -ExecutionPolicy Bypass -File tools\ci\verify-awesomium-browser-host-parity.ps1 -RepoRoot E:\Repositories\QuakeLive-reverse- Result: all Awesomium browser host parity anchors present.
git diff --check -- src/code/client/cl_awesomium_win32.cpp src/code/client/cl_cgame.c src/code/client/client.h docs/reverse-engineering/awesomium-browser-wiring.md docs/reverse-engineering/quakelive_steam_mapping_round_330.md tests/test_awesomium_browser_parity.py tools/ci/verify-awesomium-browser-host-parity.ps1- Result: clean; only Git line-ending normalization warnings were reported.
powershell -ExecutionPolicy Bypass -File tools\ci\build-windows-dlls.ps1 -RepoRoot E:\Repositories\QuakeLive-reverse -Solution src/code/quakelive.sln -Configuration Debug -Platform Win32 -PlatformToolset v143 -DisableOptionalCodecs- Result: build succeeded; existing UI/game config warnings were reported.
Task A113: Reconstruct application initialization host wiring [COMPLETED]
Priority: High
Primary areas: src/code/win32/win_main.c,
references/analysis/quakelive_symbol_aliases.json,
tests/test_application_initialization_mapping.py,
docs/reverse-engineering/application-initialization-wiring-reconstruction-2026-05-27.md
Parity estimate: before 96.5% -> after 98.0% for the scoped
application-initialization wiring lane. The repo-wide parity estimate remains
98%.
Completed work:
- Rechecked
WinMain @ 0x004ED830,Com_Init @ 0x004CBFD0,Sys_Init @ 0x004ED400,NET_Init @ 0x004EF320,CL_Init @ 0x004BC690,SV_Init @ 0x004E3AD0, and the adjacent ZMQ/browser startup handoffs against Binary Ninja HLIL with Ghidra metadata support. - Promoted
sub_4EC580toSys_WinkeyHookProcand reconstructed the WinMain-owned low-level keyboard hook that gatesVK_LWIN/VK_RWINbehindwinkey_disable. - Added shutdown unhook wiring to both
Sys_ErrorandSys_Quit, matching the retail unhook sites in the error and normal-exit paths. - Documented policy-aware startup divergences for Steam, ZMQ, and Awesomium so Quake Live-only online services remain behind the repository's disabled defaults.
- Added static parity coverage for the retail owner map, host call order, hook predicate, shutdown unhook, and policy-adjusted common/client/server startup wiring.
Verification:
python -m pytest tests/test_application_initialization_mapping.py -q --tb=short- Result:
3 passed.
- Result:
python -m pytest tests/test_renderer_win32_host_glue_parity.py tests/test_win32_raw_input_parity.py tests/test_engine_client_command_parity.py -q --tb=short- Result:
46 passed.
- Result:
python -m pytest tests/test_platform_services.py::test_client_steam_callback_owner_reconstructs_retail_frame_pump_and_lifecycle tests/test_platform_services.py::test_client_browser_host_core_reconstructs_retained_runtime_owner tests/test_platform_services.py::test_server_zmq_runtime_reconstructs_retail_publication_and_rcon_owners -q --tb=short- Result:
3 passed.
- Result:
python -m pytest tests/test_awesomium_browser_parity.py::test_awesomium_runtime_bootstrap_and_surface_pump_reconstruct_retail_host_contract tests/test_awesomium_browser_parity.py::test_awesomium_view_callbacks_reconstruct_tooltip_and_console_contracts -q --tb=short- Result:
2 passed.
- Result:
MSBuild.exe src\code\quakelive_steam.vcxproj /p:Configuration=Debug /p:Platform=Win32 /m /v:minimal- Result: succeeded; existing
cl_cgame.cunused-local warnings were reported.
- Result: succeeded; existing
git diff --check- Result: clean; only Git line-ending normalization warnings were reported.
Task A112: Retire generated UI bridge menu assets [COMPLETED]
Priority: High
Primary areas: src/code/ui/ui_main.c, src/code/ui/ui_atoms.c,
src/code/ui/ui_cdkey.c, src/code/ui/ui_local.h,
src/code/ui/ui.vcxproj, src/code/ui/Conscript,
tests/test_ui_menu_files.py, tests/test_platform_services.py,
docs/ui/scripting-guide.md
Parity estimate: before 99.90% -> after 99.96% for the scoped
retail UI menu-root purity lane. The strict-retail Windows module target
remains 100% and the repo-wide parity estimate remains 98%.
Completed work:
- Rechecked retail
uix86.dllevidence: HLIL/Ghidra both show the default menu root openingui/menus.txt, and the checked-insrc/ui/menus.txtloads retailui/main.menu. - Removed the generated
ql_bridge_*menu-script owner and its build entries so offline browser-service handling no longer writes replacement menu assets into the homepath. - Kept disabled browser verbs policy-compliant by swallowing unavailable
web_showBrowser/web_changeHashpaths while the existing retail menu tree remains active. - Reframed the native CD-key command as an explicit unavailable-command stub in native UI builds instead of preferring generated credentials menus.
- Updated parity tests, platform-service tests, docs, and CI font/build references to assert that retail menu files are used directly.
Verification:
python -m pytest tests/test_ui_menu_files.py tests/test_platform_services.py tests/test_non_windows_portability.py tests/test_ui_full_parity_gate.py -q --tb=short- Result:
165 passed, 1 skipped.
- Result:
Task A111: Reconstruct spectator client-state resync wiring [COMPLETED]
Priority: High
Primary areas: src/code/game/bg_public.h, src/code/game/g_cmds.c,
src/code/game/g_client.c, src/code/game/g_active.c,
src/code/cgame/cg_playerstate.c, src/code/cgame/cg_local.h,
tests/test_spectator_client_state_wiring_parity.py,
docs/reverse-engineering/spectator-client-state-wiring-reconstruction-2026-05-27.md,
docs/reverse-engineering/qagame-mapping.md,
docs/reverse-engineering/cgame-mapping.md,
references/symbol-maps/qagame.json, references/symbol-maps/cgame.json
Parity estimate: before 99.90% -> after 99.97% for the scoped
spectator client-state and item-state resync lane. The repo-wide parity
estimate remains 98%.
Completed work:
- Rechecked qagame
G_ApplyTeamChange @ 0x10040440andClientSpawn @ 0x1003BC30against Binary Ninja HLIL/Ghidra for the retail0x4000spectator client-state eFlag writes. - Added
EF_SPECTATOR_RESPAWNas the Quake Live alias for that network bit, intentionally sharing the GPLEF_VOTEDvalue because retail uses the same bit as the cgamespecrespcue. - Reconstructed qagame set/clear wiring in
G_ApplyTeamChangeandClientSpawn, and preserved the observer bit whenSpectatorClientEndFramecopies followed-player snapshots. - Replaced the raw cgame
0x00004000CG_Respawncheck withEF_SPECTATOR_RESPAWN, keeping the retailspecrespcommand handoff. - Mapped the surrounding spectator item-state responder:
specrespand spectator team entry callG_SyncSpectatorItemStatesForClient, while item pickup broadcast still packsEV_ITEM_PICKUP_SPECfor the cgame cache. - Added cross-binary static coverage plus qagame/cgame mapping and symbol-map notes for the eFlag, command, event payload, cache decoder, and overlay update/draw path.
Verification:
python -m pytest tests/test_spectator_client_state_wiring_parity.py -q --tb=short- Result:
8 passed.
- Result:
python -m pytest tests/test_spectator_client_state_wiring_parity.py tests/test_game_spectator_connection_parity.py tests/test_game_active_pmove_wiring_parity.py tests/test_game_helper_seam_parity.py tests/test_cgame_spectator_parity.py tests/test_cgame_snapshot_parity.py tests/test_cgame_event_transport_parity.py tests/test_cgame_hud_parity.py::test_spectator_item_timer_text_uses_retail_default_font_lane tests/test_game_vote_clear_parity.py -q --tb=short- Result:
111 passed, 1 skipped.
- Result:
git diff --check- Result: clean; only Git line-ending normalization warnings were reported.
- Broader context: the full
tests/test_cgame_hud_parity.pyfile still has an unrelatedtest_team_info_overlay_restores_fixed_retail_row_rendererassertion failure outside this spectator client-state lane.
Task A110: Reconstruct StepSlideMove down-clip and wiring map [COMPLETED]
Priority: High
Primary areas: src/code/game/bg_slidemove.c, src/code/game/bg_pmove.c,
src/code/game/g_pmove.c, src/code/cgame/cg_servercmds.c,
src/code/cgame/cg_predict.c, tests/pmove_validation_harness.c,
tests/test_pmove_validation_fixtures.py,
tests/test_step_jump_gate_parity.py,
docs/reverse-engineering/pmove-stepslidemove-wiring-reconstruction-2026-05-27.md
Parity estimate: before 98.8% -> after 99.9% for the scoped
StepSlideMove lane. The repo-wide parity estimate remains 98%.
Completed work:
- Rechecked qagame
PM_StepSlideMove @ 0x1002EFE0and cgamePM_StepSlideMove @ 0x100034B0against Binary Ninja HLIL, with Ghidra companion confirmation for the matching helper call graph. - Tightened the down-trace clip guard to the retail dot-product epsilon:
DotProduct(velocity, plane.normal) < 0.0f || fabs(dot) < 0.001f. - Preserved the retail direct reachability trace before recording step side
effects, plus the
startsolidrejection on the projected step-jump support probe. - Documented the full movement call matrix, step-jump latch split, and cgame prediction smoothing handoff.
- Added executable and structural parity coverage for the down-clip guard,
call-site wiring, normal/crouch takeoff latches, and
pmove_t::stepUpprediction export. - Pinned the
pmove_AirStepFriction,pmove_AirSteps, andpmove_StepHeightserver-to-cgame tuning transport that feeds the private step-move globals.
Verification:
python -m pytest tests/test_step_jump_gate_parity.py tests/test_pmove_validation_fixtures.py -q --tb=short- Result:
22 passed.
- Result:
python -m pytest tests/test_step_jump_gate_parity.py tests/test_pmove_helper_parity.py tests/test_pmove_validation_fixtures.py tests/test_pmove_movement_fixtures.py tests/test_pmove_selected_cvar_parity.py tools/tests/test_pmove_settings_configstring.py -q --tb=short- Result:
134 passed, 107 subtests passed.
- Result:
git diff --check- Result: clean; only Git line-ending normalization warnings were reported.
Task A109: Reconstruct CA/A-D spectator respawn handoff [COMPLETED]
Priority: High
Primary areas: src/code/game/g_team.c, src/code/game/g_client.c,
tests/test_game_attack_defend_parity.py,
tests/test_game_spectator_connection_parity.py,
tests/test_game_active_pmove_wiring_parity.py,
docs/reverse-engineering/qagame-spectator-state-movement-reconstruction-2026-05-26.md,
docs/reverse-engineering/qagame-client-spawn-reconstruction-2026-05-26.md,
docs/reverse-engineering/qagame-mapping.md,
references/symbol-maps/qagame.json
Parity estimate: before 99.8% -> after 99.9% for the scoped qagame
spectator state/movement lane. The repo-wide parity estimate remains 98%.
Completed work:
- Rechecked
G_CAADRespawnAsSpectator @ 0x10035960and the dependentClientSpawn @ 0x1003BC30spectator branch against Binary Ninja HLIL. - Collapsed the CA/A-D eliminated-player spectator helper back to the retail
sequence:
CopyToBodyQue, pre-seedPM_SPECTATOR,ClientSpawn, active team counts, andFollowCycleonly when both teams still have players. - Removed the source-only direct follow-target picker, post-spawn relink, and free/scoreboard fallback assignment from that helper.
- Taught
ClientSpawnto preserve a pre-existingPM_SPECTATORstate as the spectator-spawn selector, so active-team CA/A-D eliminations can reuse the retail spectator placement path without pretending the session team changed. - Updated attack/defend, spectator, and active-pmove static parity coverage, plus the qagame mapping, client-spawn note, spectator note, and symbol map.
Verification:
python -m pytest tests/test_game_attack_defend_parity.py tests/test_game_spectator_connection_parity.py -q --tb=short- Result:
10 passed.
- Result:
python -m pytest tests/test_game_active_pmove_wiring_parity.py::test_first_18_g_cvars_match_retail_defaults_flags_and_wiring tests/test_game_active_pmove_wiring_parity.py::test_spectator_impacts_and_predictable_event_sidecars_match_retail_wiring -q --tb=short- Result:
2 passed.
- Result:
python -m pytest tests/test_game_attack_defend_parity.py tests/test_game_spectator_connection_parity.py tests/test_game_active_pmove_wiring_parity.py tests/test_game_helper_seam_parity.py tests/test_pmove_helper_parity.py tests/test_game_factory_regen_parity.py tests/test_bg_misc_validation_fixtures.py tests/test_spawn_spec_cvars.py tests/test_cgame_spectator_parity.py -q --tb=short- Result:
164 passed.
- Result:
git diff --check- Result: clean; only Git line-ending normalization warnings were reported.
Task A108: Reconstruct initial and team-begin spawn fallback modes [COMPLETED]
Priority: High
Primary areas: src/code/game/g_client.c, src/code/game/g_team.c,
tests/test_game_active_pmove_wiring_parity.py,
tests/test_game_helper_seam_parity.py,
docs/reverse-engineering/qagame-client-spawn-reconstruction-2026-05-26.md,
docs/reverse-engineering/qagame-mapping.md,
references/hlil/quakelive/qagamex86.dll/qagamex86.dll.bndb_hlil.txt,
references/reverse-engineering/ghidra/qagamex86/decompile_top_functions.c
Parity estimate: before 98.8% -> after 99.0% for the scoped qagame
client-spawn band. The repo-wide parity estimate remains 98%.
Completed work:
- Rechecked
G_SelectRankedSpawnPoint @ 0x10039080andG_SelectClientSpawnPoint @ 0x10039730against Binary Ninja HLIL and the committed Ghidra companion body. - Reconstructed the neutral initial-spawn admission mode: ranked neutral initial selection now requires spawnflags bit 1 while still excluding bit 2.
- Added a ranked initial-spawn wrapper so
SelectInitialSpawnPointranks all eligible initialinfo_player_deathmatchstarts instead of taking the first matching entity fromG_Find. - Restored the team
TEAM_BEGINfallback retry fromteam_CTF_*playerto the same team'steam_CTF_*spawnclass before neutral deathmatch fallback. - Updated helper/active parity coverage and the qagame client-spawn mapping notes, leaving the training-map-specific ranked-spawn path as the next explicit follow-up.
Verification:
python -m pytest tests/test_game_helper_seam_parity.py tests/test_game_active_pmove_wiring_parity.py -q --tb=short- Result:
63 passed.
- Result:
python -m pytest tests/test_game_spectator_connection_parity.py tests/test_game_active_pmove_wiring_parity.py tests/test_game_helper_seam_parity.py tests/test_pmove_helper_parity.py tests/test_game_factory_regen_parity.py tests/test_bg_misc_validation_fixtures.py tests/test_spawn_spec_cvars.py tests/test_cgame_spectator_parity.py -q --tb=short- Result:
161 passed.
- Result:
git diff --check -- src/code/game/g_client.c src/code/game/g_team.c tests/test_game_helper_seam_parity.py tests/test_game_active_pmove_wiring_parity.py docs/reverse-engineering/qagame-client-spawn-reconstruction-2026-05-26.md docs/reverse-engineering/qagame-mapping.md- Result: pass; only repository LF-to-CRLF conversion warnings.
Task A107: Correct spectator follow command surface [COMPLETED]
Priority: High
Primary areas: src/code/game/g_cmds.c,
tests/test_game_spectator_connection_parity.py,
docs/reverse-engineering/qagame-spectator-state-movement-reconstruction-2026-05-26.md,
docs/reverse-engineering/qagame-spectator-follow-reconstruction-2026-05-22.md,
docs/reverse-engineering/qagame-mapping.md,
references/symbol-maps/qagame.json
Parity estimate: before 99.5% -> after 99.8% for the scoped qagame
spectator command surface. The repo-wide parity estimate remains 98%.
Completed work:
- Rechecked
Cmd_Follow_f @ 0x10040F30andCmd_FollowCycle_f @ 0x100412E0against the committed Binary Ninja HLIL after the broader spectator-state pass. - Corrected
Cmd_Follow_fsofollow1andfollow2remain owned bySetTeam, while thefollowcommand resolves player strings throughClientNumberFromString. - Restored the retail cgame
"pw"suffix guard that preserves the current followed flag carrier viaBG_PlayerCarryingFlag, and changed explicit target rejection to the retailps.pm_type == PM_SPECTATORcheck. - Removed source-only training-map print gates from
Cmd_Follow_fandCmd_FollowCycle_f; no-arg follow cleanup remains handled by the retail follow/end-frame paths. - Rebuilt the public follow-cycle entry around the retail
sess.sessionTeamspectator handoff before tailcalling the innerFollowCycleworker. - Updated static parity coverage, the spectator reconstruction notes, the qagame mapping ledger, and the qagame symbol-map comments.
Verification:
python -m pytest tests/test_game_spectator_connection_parity.py tests/test_spawn_spec_cvars.py tests/test_cgame_spectator_parity.py -q --tb=short- Result:
18 passed.
- Result:
python -m pytest tests/test_game_active_pmove_wiring_parity.py::test_spectator_impacts_and_predictable_event_sidecars_match_retail_wiring tests/test_pmove_helper_parity.py -q --tb=short- Result:
41 passed.
- Result:
python -m pytest tests/test_game_helper_seam_parity.py::test_last_alive_alert_helpers_match_recovered_retail_boundaries -q --tb=short- Result:
1 passed.
- Result:
- Wider adjacent suite note:
python -m pytest tests/test_game_spectator_connection_parity.py tests/test_game_active_pmove_wiring_parity.py tests/test_game_helper_seam_parity.py tests/test_pmove_helper_parity.py tests/test_game_factory_regen_parity.py tests/test_bg_misc_validation_fixtures.py tests/test_spawn_spec_cvars.py tests/test_cgame_spectator_parity.py -q --tb=shortcurrently reports159 passed, 2 failed; both failures are in unrelated ranked-spawn assertions intests/test_game_active_pmove_wiring_parity.pyandtests/test_game_helper_seam_parity.py. git diff --check- Result: pass; only repository LF-to-CRLF conversion warnings.
Task A106: Reconstruct ranked-spawn spawnflag exclusion [COMPLETED]
Priority: High
Primary areas: src/code/game/g_client.c,
tests/test_game_active_pmove_wiring_parity.py,
tests/test_game_helper_seam_parity.py,
docs/reverse-engineering/qagame-client-spawn-reconstruction-2026-05-26.md,
docs/reverse-engineering/qagame-mapping.md,
references/hlil/quakelive/qagamex86.dll/qagamex86.dll.bndb_hlil.txt,
references/reverse-engineering/ghidra/qagamex86/decompile_top_functions.c
Parity estimate: before 98.7% -> after 98.8% for the scoped qagame
client-spawn band. The repo-wide parity estimate remains 98%.
Completed work:
- Rechecked
G_SelectRankedSpawnPoint @ 0x10039080against Binary Ninja HLIL and the committed Ghidra companion body. - Identified the retail candidate admission guard that reads spawnflags at
entity + 0x248and rejects candidates with bit 2 set before distance scoring. - Added
RANKED_SPAWN_EXCLUDE_FLAGandG_RankedSpawnPointAllowed, then routed both the ranked-scoring path and the no-ranked-candidate fallback through the recovered filter. - Pinned the helper, constant, and ranked-picker call sites in the qagame helper and active pmove/spawn parity tests.
- Updated the client-spawn reconstruction note and qagame mapping ledger with the HLIL/Ghidra evidence and the remaining bit-1 fallback question.
Verification:
python -m pytest tests/test_game_helper_seam_parity.py tests/test_game_active_pmove_wiring_parity.py -q --tb=short- Result:
63 passed.
- Result:
git diff --check -- src/code/game/g_client.c src/code/game/g_local.h tests/test_game_helper_seam_parity.py tests/test_game_active_pmove_wiring_parity.py docs/reverse-engineering/qagame-client-spawn-reconstruction-2026-05-26.md docs/reverse-engineering/qagame-mapping.md IMPLEMENTATION_PLAN.md- Result: pass; only repository LF-to-CRLF conversion warnings.
Task A105: Split renderer framebuffer and shader procedure gates [COMPLETED]
Priority: High
Primary areas: src/code/renderer/tr_backend.c,
tests/test_renderer_internal_helper_mapping_parity.py,
docs/reverse-engineering/quakelive_steam_mapping_round_328.md,
docs/reverse-engineering/renderer-full-parity-audit-and-implementation-plan-2026-04-09.md,
docs/reverse-engineering/source-file-parity-ledger-2026-04-22.md,
references/hlil/quakelive/quakelive_steam.exe/quakelive_steam.exe_hlil_split/
Parity estimate: before 99.985% -> after 99.99% for the scoped
post-process proc gate lane. The strict renderer estimate remains 100% and
the repo-wide parity estimate remains 98%.
Completed work:
- Rechecked retail
sub_4500B0andsub_450640against HLIL to separate framebuffer target prerequisites from post-effect shader/program prerequisites. - Added
RBPP_LoadFramebufferProcsfor the retail framebuffer-only target lane: FBO/renderbuffer/rectangle entry points plus max rectangle texture size. - Added independent framebuffer procedure loaded/supported state to
ppState_t. - Rewired
RBPP_CreateRenderTargetto call the framebuffer-only loader, whileRBPP_LoadProgramremains behind the full shader/uniformRBPP_LoadProcsgate. - Updated the renderer mapping, audit, and source-file ledger;
tr_backend.cnow tracks79functions.
Verification:
python -m pytest tests/test_renderer_post_process_parity.py tests/test_renderer_internal_helper_mapping_parity.py tests/test_renderer_export_tail_parity.py tests/test_renderer_full_parity_gate.py -q --tb=short- Result:
46 passed, 1 skipped.
- Result:
python -m pytest tests/test_engine_cvar_retail_parity.py::test_engine_cvar_fortysecond_renderer_postprocess_state_tranche_matches_retail_contracts tests/test_engine_cvar_retail_parity.py::test_engine_cvar_twentyninth_renderer_postprocess_extension_tranche_matches_retail_contracts tests/test_engine_cvar_retail_parity.py::test_engine_cvar_thirtysecond_renderer_bloom_picmip_tranche_matches_retail_contracts -q --tb=short- Result:
3 passed.
- Result:
python -m pytest tests/test_engine_client_command_parity.py::test_postprocess_restart_routes_through_renderer_export_not_renderer_cmd_registration -q --tb=short- Result:
1 passed.
- Result:
git diff --check- Result: pass; only repository LF-to-CRLF conversion warnings.
Task A104: Reconstruct renderer post-process GL error and link wiring [COMPLETED]
Priority: High
Primary areas: src/code/renderer/tr_backend.c,
src/code/renderer/tr_init.c, src/code/renderer/tr_local.h,
tests/test_renderer_internal_helper_mapping_parity.py,
tests/test_renderer_post_process_parity.py,
docs/reverse-engineering/quakelive_steam_mapping_round_327.md,
docs/reverse-engineering/renderer-full-parity-audit-and-implementation-plan-2026-04-09.md,
docs/reverse-engineering/source-file-parity-ledger-2026-04-22.md,
references/analysis/quakelive_symbol_aliases.json,
references/hlil/quakelive/quakelive_steam.exe/quakelive_steam.exe_hlil_split/,
references/reverse-engineering/ghidra/quakelive_steam/functions.csv
Parity estimate: before 99.97% -> after 99.985% for the scoped
post-process GL error and link lane. The strict renderer estimate remains
100% and the repo-wide parity estimate remains 98%.
Completed work:
- Rechecked retail
sub_447E40,sub_4500B0,sub_4505F0, andsub_450640against HLIL and the committed Ghidra function inventory. - Restored
GL_CheckErrorsas a return-valued helper so post-process callers can branch on unignored GL errors while existing callers may ignore the result. - Rewired
RBPP_CreateRenderTargetto useGL_CheckErrors()after rectangle texture allocation and after framebuffer completeness, and removed the source-only renderbuffer bind from the attachment path. - Promoted
sub_4505F0asRBPP_LinkProgram, moving post-effect program create/attach/link and GL-error-gated success into its own retail-shaped helper. - Dropped the source-only
GL_OBJECT_LINK_STATUS_ARBlink-status query fromRBPP_LoadProgramand routed color-correct texture allocation throughGL_CheckErrors().
Verification:
python -m pytest tests/test_renderer_post_process_parity.py tests/test_renderer_internal_helper_mapping_parity.py tests/test_renderer_export_tail_parity.py tests/test_renderer_full_parity_gate.py -q --tb=short- Result:
45 passed, 1 skipped.
- Result:
python -m pytest tests/test_engine_cvar_retail_parity.py::test_engine_cvar_fortysecond_renderer_postprocess_state_tranche_matches_retail_contracts tests/test_engine_cvar_retail_parity.py::test_engine_cvar_twentyninth_renderer_postprocess_extension_tranche_matches_retail_contracts tests/test_engine_cvar_retail_parity.py::test_engine_cvar_thirtysecond_renderer_bloom_picmip_tranche_matches_retail_contracts -q --tb=short- Result:
3 passed.
- Result:
python -m pytest tests/test_engine_client_command_parity.py::test_postprocess_restart_routes_through_renderer_export_not_renderer_cmd_registration -q --tb=short- Result:
1 passed.
- Result:
git diff --check- Result: pass; only repository LF-to-CRLF conversion warnings.
Task A103: Tighten spectator follow state and POI divergence [COMPLETED]
Priority: High
Primary areas: src/code/game/g_active.c, src/code/game/g_cmds.c,
src/code/game/g_local.h, references/symbol-maps/qagame.json,
docs/reverse-engineering/qagame-mapping.md,
docs/reverse-engineering/qagame-spectator-state-movement-reconstruction-2026-05-26.md,
tests/test_game_spectator_connection_parity.py,
tests/test_game_active_pmove_wiring_parity.py,
tests/test_game_helper_seam_parity.py
Parity estimate: before 96% -> after 99.5% for scoped qagame spectator
follow-state and end-frame parity; repo-wide remains 98% pending the
active portability/runtime-evidence gaps.
Completed work:
- Rechecked
SpectatorClientEndFrame @ 0x10035470,StopFollowing @ 0x10040D10,Cmd_Follow_f @ 0x10040F30, andFollowCycle @ 0x10041130against the committed Binary Ninja HLIL. - Removed the source-only POI spectator camera storage and direct admin commands; retail follow cycling is client-only.
- Rebuilt
StopFollowingaround the retailSPECTATOR_FREEreset withPM_SPECTATOR,PMF_FOLLOWclearing, selfspectatorClient/clientNum, and linked-entity unlinking. - Routed
SpectatorThinkand stale end-frame targets through the recovered innerFollowCycleworker, including active-team fallback cycling when both teams still have live players. - Tightened
FollowCyclefilters for disconnected,PM_SPECTATOR,PMF_FOLLOW, and cross-team targets.
Verification:
python -m pytest tests/test_game_spectator_connection_parity.py tests/test_game_active_pmove_wiring_parity.py tests/test_game_helper_seam_parity.py tests/test_pmove_helper_parity.py tests/test_game_factory_regen_parity.py tests/test_bg_misc_validation_fixtures.py -q --tb=short- Result:
149 passed.
- Result:
python -m pytest tests/test_spawn_spec_cvars.py tests/test_cgame_spectator_parity.py -q --tb=short- Result:
11 passed.
- Result:
git diff --check- Result: pass; only repository LF-to-CRLF conversion warnings.
Task A102: Reconstruct renderer post-process renderbuffer cache [COMPLETED]
Priority: High
Primary areas: src/code/renderer/tr_backend.c,
tests/test_renderer_internal_helper_mapping_parity.py,
docs/reverse-engineering/quakelive_steam_mapping_round_326.md,
docs/reverse-engineering/renderer-full-parity-audit-and-implementation-plan-2026-04-09.md,
docs/reverse-engineering/source-file-parity-ledger-2026-04-22.md,
references/analysis/quakelive_symbol_aliases.json,
references/hlil/quakelive/quakelive_steam.exe/quakelive_steam.exe_hlil_split/,
references/reverse-engineering/ghidra/quakelive_steam/functions.csv
Parity estimate: before 99.95% -> after 99.97% for the scoped
post-process depth-stencil renderbuffer cache lane. The strict renderer
estimate remains 100% and the repo-wide parity estimate remains 98%.
Completed work:
- Rechecked retail
sub_44FFD0,sub_4500B0,sub_450710, andsub_450780against HLIL and the committed Ghidra function inventory. - Promoted
sub_44FFD0asRBPP_CreateDepthStencilRenderbufferand added the retail eight-entry width/height renderbuffer cache toppState_t. - Routed
RBPP_CreateRenderTargetthrough the cachedGL_DEPTH24_STENCIL8_EXTrenderbuffer helper before rectangle-texture and framebuffer creation. - Reset the reconstructed renderbuffer cache metadata during bloom resource shutdown, matching the retail rebuild/shutdown cache reset lane.
- Updated the renderer mapping, audit, source-file ledger, and symbol alias
evidence;
tr_backend.cnow tracks77functions.
Verification:
python -m pytest tests/test_renderer_post_process_parity.py tests/test_renderer_internal_helper_mapping_parity.py tests/test_renderer_export_tail_parity.py tests/test_renderer_full_parity_gate.py -q --tb=short- Result:
44 passed, 1 skipped.
- Result:
python -m pytest tests/test_engine_cvar_retail_parity.py::test_engine_cvar_fortysecond_renderer_postprocess_state_tranche_matches_retail_contracts tests/test_engine_cvar_retail_parity.py::test_engine_cvar_twentyninth_renderer_postprocess_extension_tranche_matches_retail_contracts tests/test_engine_cvar_retail_parity.py::test_engine_cvar_thirtysecond_renderer_bloom_picmip_tranche_matches_retail_contracts -q --tb=short- Result:
3 passed.
- Result:
python -m pytest tests/test_engine_client_command_parity.py::test_postprocess_restart_routes_through_renderer_export_not_renderer_cmd_registration -q --tb=short- Result:
1 passed.
- Result:
git diff --check- Result: pass; only repository LF-to-CRLF conversion warnings.
Task A101: Correct ranked spawn candidate window [COMPLETED]
Priority: High
Primary areas: src/code/game/g_client.c,
tests/test_game_active_pmove_wiring_parity.py,
tests/test_game_helper_seam_parity.py,
docs/reverse-engineering/qagame-client-spawn-reconstruction-2026-05-26.md,
docs/reverse-engineering/qagame-mapping.md
Parity estimate: before 98.5% -> after 98.7% for the scoped qagame
client-spawn band. The repo-wide parity estimate remains 98%.
Completed work:
- Rechecked
G_SelectRankedSpawnPoint @ 0x10039080against HLIL and the Ghidra companion body. - Restored the retail
0x1aretained ranked-spawn candidate cap by changingMAX_RANKED_SPAWN_POINTSfrom 32 to 26. - Pinned the cap in the active pmove/spawn wiring and helper seam parity tests.
- Updated the qagame client-spawn reconstruction note and mapping ledger with the ranked-picker evidence.
Verification:
python -m pytest tests/test_game_helper_seam_parity.py tests/test_game_active_pmove_wiring_parity.py -q --tb=short- Result:
1 failed, 62 passed; failure is an unrelated pre-existingg_cmds.cspectator free-cam expectation intest_team_loadout_bot_and_drop_cvars_keep_retail_behavioral_wiring.
- Result:
python -m pytest tests/test_game_helper_seam_parity.py::test_client_spawn_uses_recovered_loadout_and_rr_helpers tests/test_game_active_pmove_wiring_parity.py::test_first_18_g_cvars_match_retail_defaults_flags_and_wiring -q --tb=short- Result:
2 passed.
- Result:
Task A100: Reconstruct renderer bloom teardown and program cleanup ordering [COMPLETED]
Priority: High
Primary areas: src/code/renderer/tr_backend.c,
tests/test_renderer_post_process_parity.py,
tests/test_renderer_internal_helper_mapping_parity.py,
docs/reverse-engineering/quakelive_steam_mapping_round_325.md,
docs/reverse-engineering/renderer-full-parity-audit-and-implementation-plan-2026-04-09.md,
docs/reverse-engineering/source-file-parity-ledger-2026-04-22.md,
references/hlil/quakelive/quakelive_steam.exe/quakelive_steam.exe_hlil_split/,
src2/ghidra/quakelive_steam/quakelive_steam_decomp.cpp
Parity estimate: before 99.93% -> after 99.95% for the scoped
post-process bloom teardown lane. The strict renderer estimate remains
100% and the repo-wide parity estimate remains 98%.
Completed work:
- Rechecked retail
sub_437DA0andsub_4506A0against HLIL and the Ghidra companion corpus. - Updated
RBPP_DestroyBloomProgramsto destroy bloom programs in retail memory order: brightpass, downsample, blurvertical, blurhoriz, combine. - Rebuilt
RBPP_ShutdownBloomResourcesaround the retail grouped delete order: all textures, then all framebuffers, then all depth-stencil renderbuffers, followed by target slot clearing. - Added the retail
glDetachObjectARBpath toRBPP_DestroyProgramso shader objects detach before program deletion. - Kept
tr_backend.cat76tracked functions while tightening lifecycle parity in place.
Verification:
python -m pytest tests/test_renderer_post_process_parity.py tests/test_renderer_internal_helper_mapping_parity.py tests/test_renderer_export_tail_parity.py tests/test_renderer_full_parity_gate.py -q --tb=short- Result:
43 passed, 1 skipped.
- Result:
python -m pytest tests/test_engine_cvar_retail_parity.py::test_engine_cvar_fortysecond_renderer_postprocess_state_tranche_matches_retail_contracts tests/test_engine_cvar_retail_parity.py::test_engine_cvar_twentyninth_renderer_postprocess_extension_tranche_matches_retail_contracts tests/test_engine_cvar_retail_parity.py::test_engine_cvar_thirtysecond_renderer_bloom_picmip_tranche_matches_retail_contracts -q --tb=short- Result:
3 passed.
- Result:
python -m pytest tests/test_engine_client_command_parity.py::test_postprocess_restart_routes_through_renderer_export_not_renderer_cmd_registration -q --tb=short- Result:
1 passed.
- Result:
git diff --check- Result: pass; only repository LF-to-CRLF conversion warnings.
Task A99: Restore client-spawn team gametype selection band [COMPLETED]
Priority: High
Primary areas: src/code/game/g_client.c,
tests/test_game_helper_seam_parity.py,
docs/reverse-engineering/qagame-client-spawn-reconstruction-2026-05-26.md,
docs/reverse-engineering/qagame-mapping.md
Parity estimate: before 98% -> after 98.5% for the scoped qagame
client-spawn band. The repo-wide parity estimate remains 98%.
Completed work:
- Rechecked
G_SelectClientSpawnPoint @ 0x10039730against the HLILgametype - 4 <= 7branch and the current source gametype enum. - Replaced the broad source
g_gametype >= GT_CTFspawn-class shortcut withG_GametypeUsesTeamSpawnSelection. - Restored the retail edge cases: Clan Arena now uses team spawn classes, and Red Rover no longer routes through the CTF-style team spawn family before its Red Rover role/loadout finalizer.
- Extended the client-spawn reconstruction note and qagame mapping ledger.
Verification:
python -m pytest tests/test_game_helper_seam_parity.py tests/test_game_spectator_connection_parity.py tests/test_game_active_pmove_wiring_parity.py -q --tb=short- Result:
69 passed.
- Result:
Task A98: Reconstruct spectator state and fly-move parity [COMPLETED]
Priority: High
Primary areas: src/code/game/g_active.c,
src/code/game/bg_pmove.c, src/code/game/g_items.c,
src/code/game/g_main.c, src/code/game/bg_public.h,
references/symbol-maps/qagame.json,
docs/reverse-engineering/qagame-mapping.md,
docs/reverse-engineering/qagame-spectator-state-movement-reconstruction-2026-05-26.md,
tests/test_game_active_pmove_wiring_parity.py,
tests/test_game_factory_regen_parity.py,
tests/test_pmove_helper_parity.py
Parity estimate: before 93% -> after 99% for scoped spectator
state/movement and shared fly-move parity; repo-wide remains 98% pending
the active portability/runtime-evidence gaps.
Completed work:
- Rechecked qagame
SpectatorThinkat0x10033E30, adjacent spectator helpers, qagame/cgamePM_FlyMove, andPickup_Powerupagainst the committed HLIL and symbol maps. - Restored the retail spectator pmove ordering: unlink linked spectators
before pmove, set
PM_SPECTATORwith speed480, runPmove, copy the moved origin, and touch triggers afterward. - Restored the retail spectator input edge split: attack-edge follow cycling
returns before the later
BUTTON_ANYedge can drop follow state. - Collapsed shared
PM_FlyMoveback to the retail four-call path and removed source-only Flight fuel/thrust stat seeding from powerup pickup while keeping the retail cvar registrations.
Verification:
python -m pytest tests/test_game_spectator_connection_parity.py tests/test_game_active_pmove_wiring_parity.py tests/test_pmove_helper_parity.py tests/test_game_factory_regen_parity.py tests/test_bg_misc_validation_fixtures.py -q --tb=short- Result:
118 passed.
- Result:
git diff --check- Result: pass; only repository LF-to-CRLF conversion warnings.
Task A97: Reconstruct client-spawn no-spawn retry path [COMPLETED]
Priority: High
Primary areas: src/code/game/g_client.c, src/code/game/g_local.h,
tests/test_game_helper_seam_parity.py,
docs/reverse-engineering/qagame-client-spawn-reconstruction-2026-05-26.md,
docs/reverse-engineering/qagame-mapping.md
Parity estimate: before 96% -> after 98% for the scoped qagame
client-spawn band. The repo-wide parity estimate remains 98%.
Completed work:
- Rechecked
ClientSpawn @ 0x1003BC30,G_SelectClientSpawnPoint @ 0x10039730,G_SelectRankedSpawnPoint @ 0x10039080,Team_SelectDominationSpawnPoint @ 0x10038B60,G_InitClientSpawnState @ 0x1003B6C0,G_FinalizeSpawnLoadout @ 0x1003B5A0, andG_GiveItemByName @ 0x1003BB90against HLIL, Ghidra, and the curated symbol map. - Restored the retail active-player no-spawn branch:
ClientSpawnnow defers for 600 ms, writesPM_SPECTATOR, increments the retry counter, and returns before the full client reset when the spawn wrapper cannot produce an eligible point. - Replaced the inherited unbounded spawnpoint eligibility loop with a bounded
FL_NO_BOTS/FL_NO_HUMANSguard and a scheduled retry callback. - Added a dedicated reconstruction note and expanded qagame mapping coverage for the client-spawn helper family.
Verification:
python -m pytest tests/test_game_helper_seam_parity.py tests/test_game_spectator_connection_parity.py tests/test_game_active_pmove_wiring_parity.py -q --tb=short- Result:
69 passed.
- Result:
Task A96: Reconstruct renderer framebuffer owner and retire legacy scratch path [COMPLETED]
Priority: High
Primary areas: src/code/renderer/tr_backend.c,
tests/test_renderer_post_process_parity.py,
tests/test_renderer_internal_helper_mapping_parity.py,
docs/reverse-engineering/quakelive_steam_mapping_round_324.md,
docs/reverse-engineering/renderer-full-parity-audit-and-implementation-plan-2026-04-09.md,
docs/reverse-engineering/source-file-parity-ledger-2026-04-22.md,
references/hlil/quakelive/quakelive_steam.exe/quakelive_steam.exe_hlil_split/,
src2/ghidra/quakelive_steam/quakelive_steam_decomp.cpp
Parity estimate: before 99.9% -> after 99.93% for the scoped
post-process framebuffer owner lane. The strict renderer estimate remains
100% and the repo-wide parity estimate remains 98%.
Completed work:
- Rechecked retail
sub_4500B0,sub_437E40,sub_438790, andsub_4387D0against HLIL, the Ghidra companion corpus, and the alias ledger. - Confirmed the live retail-shaped framebuffer owner is the
GL_TEXTURE_RECTANGLE_ARBRBPP_CreateRenderTargetpath with shared depth-stencil renderbuffer attachment. - Removed the disconnected legacy
GL_TEXTURE_2Dscene-target structs, FBO-loader helpers, and fixed-function scratch-bloom helper family fromtr_backend.c. - Rewired end-of-frame release and queued post-process reset handling to call
RBPP_ReleaseSceneRenderTargetandRBPP_ResetIfNeededdirectly. - Updated the renderer audit and source-file ledger;
tr_backend.cnow tracks76functions after retiring the duplicate helper family.
Verification:
python -m pytest tests/test_renderer_post_process_parity.py tests/test_renderer_internal_helper_mapping_parity.py tests/test_renderer_export_tail_parity.py tests/test_renderer_full_parity_gate.py -q --tb=short- Result:
42 passed, 1 skipped.
- Result:
python -m pytest tests/test_engine_cvar_retail_parity.py::test_engine_cvar_fortysecond_renderer_postprocess_state_tranche_matches_retail_contracts tests/test_engine_cvar_retail_parity.py::test_engine_cvar_twentyninth_renderer_postprocess_extension_tranche_matches_retail_contracts tests/test_engine_cvar_retail_parity.py::test_engine_cvar_thirtysecond_renderer_bloom_picmip_tranche_matches_retail_contracts -q --tb=short- Result:
3 passed.
- Result:
python -m pytest tests/test_engine_client_command_parity.py::test_postprocess_restart_routes_through_renderer_export_not_renderer_cmd_registration -q --tb=short- Result:
1 passed.
- Result:
git diff --check- Result: pass; only repository LF-to-CRLF conversion warnings.
Task A95: Reconstruct teleporting state and related wiring [COMPLETED]
Priority: High
Primary areas: src/code/game/g_misc.c,
tests/test_teleport_state_reconstruction.py,
docs/reverse-engineering/qagame-teleport-state-reconstruction-2026-05-26.md,
docs/reverse-engineering/qagame-mapping.md,
docs/reverse-engineering/cgame-mapping.md,
references/symbol-maps/qagame.json,
references/hlil/quakelive/qagamex86.dll/qagamex86.dll.bndb_hlil_split/,
references/hlil/quakelive/cgamex86.dll/cgamex86.dll_hlil_split/
Parity estimate: before 96% -> after 99% for the scoped teleporting
state and related wiring lane. The repo-wide parity estimate remains 98%.
Completed work:
- Rechecked retail
TeleportPlayerat0x1005A420,Weapon_HookFreeat0x1006E330, target/trigger teleporter callbacks, holdable teleporter event handling, spectator-door teleporting, respawn teleport-in effects, dropped-powerup teleporter handling, bot movement flags, and cgame teleport consumers against HLIL, Ghidra, and symbol-map evidence. - Restored the missing
TeleportPlayeractive-hook cleanup edge:Weapon_HookFree( player->client->hook )now runs afterEF_TELEPORT_BITtoggles and before destination view-angle / killbox handling. - Added focused parity tests pinning the server helper, server producers,
cgame prediction/snapshot/view/event consumers, bot
PMF_TIME_KNOCKBACK->MFL_TELEPORTEDbridge, and dropped-powerup teleporter movement side path. - Added a dedicated reconstruction note and updated qagame/cgame mapping ledgers with the observed facts, source delta, confidence, and open evidence boundary.
Verification:
python -m pytest tests/test_teleport_state_reconstruction.py -q --tb=short- Result:
4 passed.
- Result:
python -m pytest tests/test_teleport_state_reconstruction.py tests/test_pmove_helper_parity.py tests/test_game_item_runframe_parity.py tests/test_game_target_parity.py tests/test_game_runthink_parity.py tests/test_cgame_snapshot_parity.py tests/test_cgame_event_transport_parity.py -q --tb=short- Result:
88 passed.
- Result:
git diff --check- Result: pass; only repository LF-to-CRLF conversion warnings.
Task A94: Split renderer color-correct init and live browser override [COMPLETED]
Priority: High
Primary areas: src/code/renderer/tr_backend.c,
tests/test_renderer_post_process_parity.py,
tests/test_renderer_internal_helper_mapping_parity.py,
tests/test_engine_cvar_retail_parity.py,
docs/reverse-engineering/quakelive_steam_mapping_round_323.md,
references/hlil/quakelive/quakelive_steam.exe/quakelive_steam.exe_hlil_split/,
src2/ghidra/quakelive_steam/quakelive_steam_decomp.cpp
Parity estimate: before 99.85% -> after 99.9% for the scoped
post-process color-correct browser override lane. The strict renderer estimate
remains 100% and the repo-wide parity estimate remains 98%.
Completed work:
- Rechecked retail
sub_43CD60andsub_43CFE0against HLIL and the Ghidra companion corpus. - Confirmed that the browser-active override belongs to the live uniform refresh helper, while the init helper seeds gamma reciprocal and contrast directly from cvars.
- Added a
browserOverrideparameter to the shared source uniform writer soRBPP_InitColorCorrectResourcespassesqfalseandRBPP_SetColorCorrectUniformsFromCvarspassesqtrue.
Verification:
python -m pytest tests/test_renderer_post_process_parity.py tests/test_renderer_internal_helper_mapping_parity.py tests/test_renderer_export_tail_parity.py tests/test_renderer_full_parity_gate.py -q --tb=short- Result:
41 passed, 1 skipped.
- Result:
python -m pytest tests/test_engine_cvar_retail_parity.py::test_engine_cvar_fortysecond_renderer_postprocess_state_tranche_matches_retail_contracts tests/test_engine_cvar_retail_parity.py::test_engine_cvar_twentyninth_renderer_postprocess_extension_tranche_matches_retail_contracts tests/test_engine_cvar_retail_parity.py::test_engine_cvar_thirtysecond_renderer_bloom_picmip_tranche_matches_retail_contracts -q --tb=short- Result:
3 passed.
- Result:
python -m pytest tests/test_engine_cvar_retail_parity.py::test_engine_cvar_twentythird_renderer_runtime_tuning_tranche_matches_retail_contracts tests/test_engine_cvar_retail_parity.py::test_engine_cvar_thirtyeighth_renderer_image_quality_tranche_matches_retail_contracts -q --tb=short- Result:
2 passed.
- Result:
python -m pytest tests/test_engine_client_command_parity.py::test_postprocess_restart_routes_through_renderer_export_not_renderer_cmd_registration -q --tb=short- Result:
1 passed.
- Result:
git diff --check- Result: pass; only repository LF-to-CRLF conversion warnings.
Task A93: Reconstruct renderer live post-process cvar refresh [COMPLETED]
Priority: High
Primary areas: src/code/renderer/tr_cmds.c,
src/code/renderer/tr_backend.c,
src/code/renderer/tr_init.c,
src/code/renderer/tr_local.h,
tests/test_renderer_post_process_parity.py,
tests/test_renderer_internal_helper_mapping_parity.py,
tests/test_engine_cvar_retail_parity.py,
docs/reverse-engineering/quakelive_steam_mapping_round_322.md,
references/hlil/quakelive/quakelive_steam.exe/quakelive_steam.exe_hlil_split/,
src2/ghidra/quakelive_steam/quakelive_steam_decomp.cpp
Parity estimate: before 99.7% -> after 99.85% for the scoped
post-process live cvar refresh lane. The strict renderer estimate remains
100% and the repo-wide parity estimate remains 98%.
Completed work:
- Rechecked the retail
RE_BeginFramepost-texture-mode branch against HLIL and the Ghidra companion corpus. - Moved live post-process modified-latch consumption out of
R_UpdatePostProcessCvars, preserving that function as the enable/restart state owner. - Added
R_RefreshLivePostProcessCvarsintr_cmds.cso frame-begin now refreshes color-correct uniforms fromr_gamma/r_contrast, refreshes bloom uniforms from the five live bloom cvars, and leavesr_gamma->modifiedfor the laterR_SetColorMappingspath. - Exposed the two active-state guarded backend uniform helpers through
tr_local.hwhile keeping the low-level uniform writers private.
Verification:
python -m pytest tests/test_renderer_post_process_parity.py tests/test_renderer_internal_helper_mapping_parity.py tests/test_renderer_export_tail_parity.py tests/test_renderer_full_parity_gate.py -q --tb=short- Result:
40 passed, 1 skipped.
- Result:
python -m pytest tests/test_engine_cvar_retail_parity.py::test_engine_cvar_fortysecond_renderer_postprocess_state_tranche_matches_retail_contracts tests/test_engine_cvar_retail_parity.py::test_engine_cvar_twentyninth_renderer_postprocess_extension_tranche_matches_retail_contracts tests/test_engine_cvar_retail_parity.py::test_engine_cvar_thirtysecond_renderer_bloom_picmip_tranche_matches_retail_contracts -q --tb=short- Result:
3 passed.
- Result:
python -m pytest tests/test_engine_client_command_parity.py::test_postprocess_restart_routes_through_renderer_export_not_renderer_cmd_registration -q --tb=short- Result:
1 passed.
- Result:
- Direct source sentinel for the
test_engine_cvar_fortyfirst_renderer_platform_scene_tranche_matches_retail_contractspost-process assertions:- Result: passed.
python -m pytest tests/test_engine_cvar_retail_parity.py::test_engine_cvar_fortyfirst_renderer_platform_scene_tranche_matches_retail_contracts -q --tb=short- Result: failed before the new post-process assertions on an unrelated
read-only
src/ui/ui_main.cr_inGameVideoexpectation.
- Result: failed before the new post-process assertions on an unrelated
read-only
git diff --check- Result: pass; only repository LF-to-CRLF conversion warnings.
Task A92: Reconstruct renderer color-correct uniform helper [COMPLETED]
Priority: High
Primary areas: src/code/renderer/tr_backend.c,
tests/test_renderer_post_process_parity.py,
tests/test_renderer_internal_helper_mapping_parity.py,
docs/reverse-engineering/quakelive_steam_mapping_round_321.md,
references/hlil/quakelive/quakelive_steam.exe/quakelive_steam.exe_hlil_split/,
src2/ghidra/quakelive_steam/quakelive_steam_decomp.cpp
Parity estimate: before 99.5% -> after 99.7% for the scoped
post-process color-correct uniform helper lane. The strict renderer estimate
remains 100% and the repo-wide parity estimate remains 98%.
Completed work:
- Rechecked
sub_43CD60,sub_43CFE0, andsub_436DC0against HLIL and the Ghidra companion corpus. - Split color-correct cvar-to-uniform writes out of the draw pass into
RBPP_SetColorCorrectUniformsand the active-state guardedRBPP_SetColorCorrectUniformsFromCvarshelper. - Seeded the color-correct program uniforms during
RBPP_InitColorCorrectResources, matching the initialization write sequence recovered fromsub_43CFE0. - Left
RBPP_ApplyColorCorrectPassfocused on framebuffer copy, live uniform refresh through the recovered helper, and full-screen draw execution.
Verification:
python -m pytest tests/test_renderer_post_process_parity.py tests/test_renderer_internal_helper_mapping_parity.py tests/test_renderer_export_tail_parity.py tests/test_renderer_full_parity_gate.py -q --tb=short- Result:
39 passed, 1 skipped.
- Result:
python -m pytest tests/test_engine_client_command_parity.py::test_postprocess_restart_routes_through_renderer_export_not_renderer_cmd_registration -q --tb=short- Result:
1 passed.
- Result:
python -m pytest tests/test_engine_cvar_retail_parity.py::test_engine_cvar_fortysecond_renderer_postprocess_state_tranche_matches_retail_contracts tests/test_engine_cvar_retail_parity.py::test_engine_cvar_twentyninth_renderer_postprocess_extension_tranche_matches_retail_contracts -q --tb=short- Result:
2 passed.
- Result:
git diff --check- Result: pass; only repository LF-to-CRLF conversion warnings.
Task A91: Correct renderer post-process bloom uniform slot order [COMPLETED]
Priority: High
Primary areas: src/code/renderer/tr_backend.c,
src/code/renderer/tr_local.h,
tests/test_renderer_post_process_parity.py,
tests/test_renderer_internal_helper_mapping_parity.py,
docs/reverse-engineering/quakelive_steam_mapping_round_320.md,
references/hlil/quakelive/quakelive_steam.exe/quakelive_steam.exe_hlil_split/,
src2/ghidra/quakelive_steam/quakelive_steam_decomp.cpp
Parity estimate: before 99% -> after 99.5% for the scoped
post-process bloom uniform naming lane. The strict renderer estimate remains
100% and the repo-wide parity estimate remains 98%.
Completed work:
- Rechecked
sub_4380F0,sub_438590, andsub_4386D0against HLIL and the Ghidra companion corpus for the combine uniform slot order. - Corrected the private five-float source signature so the last two arguments
are
sceneSaturationand thensceneIntensity. - Reordered the source-side combine uniform fields, uniform lookup, and uniform
write path to mirror the retail slots:
p_bloomsaturation,p_scenesaturation,p_bloomintensity,p_sceneintensity. - Added a dedicated mapping note and parity sentinels so the argument/slot order cannot drift back to shader-declaration order.
Verification:
python -m pytest tests/test_renderer_post_process_parity.py tests/test_renderer_internal_helper_mapping_parity.py tests/test_renderer_export_tail_parity.py tests/test_renderer_full_parity_gate.py -q --tb=short- Result:
38 passed, 1 skipped.
- Result:
python -m pytest tests/test_engine_client_command_parity.py::test_postprocess_restart_routes_through_renderer_export_not_renderer_cmd_registration -q --tb=short- Result:
1 passed.
- Result:
python -m pytest tests/test_engine_cvar_retail_parity.py::test_engine_cvar_thirtysecond_renderer_bloom_picmip_tranche_matches_retail_contracts -q --tb=short- Result:
1 passed.
- Result:
git diff --check- Result: pass; only repository LF-to-CRLF conversion warnings.
Task A90: Reconstruct qagame knockback application and blocking [COMPLETED]
Priority: High
Primary areas: src/code/game/g_combat.c, src/game/g_config.c,
tests/test_game_weapon_parity.py, tests/test_pmove_helper_parity.py,
docs/reverse-engineering/qagame-knockback-reconstruction-2026-05-26.md,
docs/reverse-engineering/qagame-mapping.md, docs/gameplay/cvars.md,
docs/gameplay-cvars-and-steam.md, references/symbol-maps/qagame.json,
references/symbol-maps/cgame.json,
src/code/game/ai_dmq3.c, src/code/game/g_target.c,
src/code/game/g_missile.c, src/code/botlib/be_aas_move.c,
src/code/botlib/be_ai_move.c,
references/hlil/quakelive/qagamex86.dll/qagamex86.dll.bndb_hlil_split/
Parity estimate: before 82% -> after 98% for the scoped qagame
knockback application, no-knockback producer, and movement-blocking lane. The repo-wide parity
estimate remains 98%.
Completed work:
- Rechecked retail
G_KnockbackScaleForMODat0x10048A10andG_Damageat0x10048C30against HLIL, Ghidra, and the existing symbol map. - Reconstructed signed knockback application so negative scalars invert the
damage direction and still latch
PMF_TIME_KNOCKBACK. - Kept
FL_NO_KNOCKBACKandDAMAGE_NO_KNOCKBACKas zeroing gates before velocity or timer side effects. - Removed non-retail
G_Damagevertical boost and crouch/low-health cripple velocity reduction;g_knockback_cripplenow remains only as the retail knockback timer floor. - Added focused source/evidence sentinels and a dedicated reconstruction note for the signed knockback and blocking seam, including the shared pmove friction, walk acceleration, drop-timer, spawn-side timer wiring, and teleport-side timer wiring.
- Removed the inherited Quake III
damage_knockbackfeedback slot/write/reset after rechecking retailG_DamageandP_DamageFeedback: Quake Live stores only armor, blood,damage_from, anddamage_fromWorldin that record. - Pinned the bot-side move initializer wiring where active
PMF_TIME_KNOCKBACKplus positivepm_timeraisesMFL_TELEPORTEDbefore the waterjump movement flag. - Pinned the no-knockback producers (
target_laser_thinkand juiced prox discharge), the null-directionDAMAGE_NO_KNOCKBACKconversion, the fatalFL_NO_KNOCKBACKordering, and the companion botlib weapon-jump predictor. - Aligned the
g_max_knockbackhelp text in both registration tables with the reconstructed positive-only clamp behavior. - Rechecked reconstructed source style: added the required function headers
for
G_ReadKnockbackCvarandG_UpdateKnockbackConfig, clarified theG_Damageknockback comment, and tab-indentedknockbackConfig_t. - Added a graph-level wiring map to the reconstruction note and pinned the live knockback, no-knockback, pmove, feedback, bot bridge, and botlib predictor nodes in the focused parity suite.
- Removed the source-only
g_debugDamageknockback summary instrumentation after the committed HLIL/string corpus showed only the retail health/damage/armor debug print inG_Damage.
Verification:
python -m pytest tests/test_game_weapon_parity.py -q --tb=short- Result:
35 passed.
- Result:
python -m pytest tests/test_game_active_pmove_wiring_parity.py -q --tb=short- Result:
32 passed.
- Result:
python -m pytest tests/test_pmove_helper_parity.py -q --tb=short- Result:
40 passed.
- Result:
python -m pytest tests/test_game_target_parity.py -q --tb=short- Result:
11 passed.
- Result:
python -m pytest tests/test_game_weapon_parity.py tests/test_game_active_pmove_wiring_parity.py tests/test_pmove_helper_parity.py tests/test_game_target_parity.py -q --tb=short- Result:
118 passed.
- Result:
git diff --check- Result: pass; only repository LF-to-CRLF warnings were reported.
Task A89: Reconstruct renderer post-process private refexport tail [COMPLETED]
Priority: High
Primary areas: src/code/renderer/tr_backend.c,
src/code/renderer/tr_init.c, src/code/renderer/tr_local.h,
src/code/renderer/tr_public.h,
tests/test_renderer_export_tail_parity.py,
tests/test_renderer_post_process_parity.py,
tests/test_renderer_internal_helper_mapping_parity.py,
docs/reverse-engineering/quakelive_steam_mapping_round_319.md,
references/hlil/quakelive/quakelive_steam.exe/quakelive_steam.exe_hlil_split/
Parity estimate: before 96% -> after 99% for the scoped post-process
private-tail lane. The strict renderer estimate remains 100% and the
repo-wide parity estimate remains 98%.
Completed work:
- Rechecked the retail
GetRefAPItail assignments arounddata_5878c0throughdata_5878cc, includingj_sub_4384D0andsub_451420. - Added the missing
RetailBloomPostProcessCommandrefexport slot between scene-target capture and post-process restart. - Assigned the bloom command and five-float bloom uniform setter through
GetRefAPI. - Factored the bloom uniform writes into
RBPP_SetBloomUniformsand added the cvar-refresh helper matchingsub_438590. - Mirrored the retail dirty-flag behavior so temporary tail-set bloom uniforms are restored from cvars after the next bloom command.
Verification:
python -m pytest tests/test_renderer_post_process_parity.py tests/test_renderer_internal_helper_mapping_parity.py tests/test_renderer_export_tail_parity.py tests/test_renderer_full_parity_gate.py -q --tb=short- Result:
37 passed, 1 skipped.
- Result:
python -m pytest tests/test_engine_client_command_parity.py::test_postprocess_restart_routes_through_renderer_export_not_renderer_cmd_registration -q --tb=short- Result:
1 passed.
- Result:
git diff --check- Result: pass; only repository LF-to-CRLF conversion warnings.
Task A88: Reconstruct renderer post-process backend command ABI [COMPLETED]
Priority: High
Primary areas: src/code/renderer/tr_backend.c,
src/code/renderer/tr_cmds.c, src/code/renderer/tr_init.c,
src/code/renderer/tr_local.h, src/code/renderer/tr_shader.c,
tests/test_renderer_post_process_parity.py,
tests/test_renderer_internal_helper_mapping_parity.py,
docs/reverse-engineering/quakelive_steam_mapping_round_318.md,
references/analysis/quakelive_symbol_aliases.json,
references/hlil/quakelive/quakelive_steam.exe/quakelive_steam.exe_hlil_split/
Parity estimate: before 88% -> after 96% for the scoped post-process
command ABI lane. The strict renderer estimate remains 100% and the
repo-wide parity estimate remains 98%.
Completed work:
- Rechecked the retail command emitter and executor evidence around
sub_43CD10,sub_4384D0,sub_43CBA0,sub_436DC0,sub_436EC0, and thesub_437A50backend dispatch table. - Reconstructed command payloads for color correction (
0x10bytes), bloom (0x38bytes), and scene-target binding (0x04bytes), preserving retail command IDs9,10, and11. - Added frontend emitters and backend handlers for the post-process command lane, then routed draw-surface scene capture and end-frame post-processing through queued commands instead of the swap-buffer shortcut.
- Updated command-list repair walking and the private refexport capture slot so the newly reconstructed commands are visible in related wiring.
- Promoted command-handler aliases for
sub_436DC0andsub_436EC0to match their observed command-size returns.
Verification:
python -m pytest tests/test_renderer_post_process_parity.py tests/test_renderer_internal_helper_mapping_parity.py tests/test_renderer_export_tail_parity.py tests/test_renderer_full_parity_gate.py -q --tb=shortpassed:35 passed, 1 skipped.python -m pytest tests/test_engine_client_command_parity.py::test_postprocess_restart_routes_through_renderer_export_not_renderer_cmd_registration -q --tb=shortpassed:1 passed.git diff --checkcompleted without whitespace errors; Git reported only line-ending normalization warnings for modified text files.
Task A87: Reconstruct renderer post-process bloom scene-target wiring [COMPLETED]
Priority: High
Primary areas: src/code/renderer/tr_backend.c,
src/code/renderer/tr_image.c, src/code/renderer/tr_local.h,
tests/test_renderer_post_process_parity.py,
tests/test_renderer_internal_helper_mapping_parity.py,
docs/reverse-engineering/quakelive_steam_mapping_round_317.md,
docs/reverse-engineering/renderer-full-parity-audit-and-implementation-plan-2026-04-09.md,
references/hlil/quakelive/quakelive_steam.exe/quakelive_steam.exe_hlil_split/
Parity estimate: before 98% -> after 99.5% for the scoped renderer
post-process scene-target and bloom/color-correct owner boundary. The strict
renderer estimate remains 100% and the repo-wide parity estimate remains
98%.
Completed work:
- Rechecked the retail
quakelive_steam.exepost-process evidence aroundsub_4384A0,sub_4380F0,sub_438790, screenshot readback, and the backend command ID0x0bscene-target rebind path. - Promoted the source-side
RBPP_BloomEnabled()predicate so the scene render target is gated by the same broad post-process, shader-support, andr_bloomActivechecks recovered from retail. - Moved the full-resolution scene target into the bloom resource lifecycle, matching the retail split where color correction owns a default-framebuffer copy/pass and bloom owns offscreen scene capture.
- Rewired scene-target binding, screenshot release/rebind, and post-process submission so color-correct-only frames no longer route world rendering through the bloom scene framebuffer.
- Added focused parity sentinels and a dedicated mapping note for the bloom-owned scene-target boundary.
Verification:
python -m pytest tests/test_renderer_post_process_parity.py tests/test_renderer_internal_helper_mapping_parity.py tests/test_renderer_full_parity_gate.py -q --tb=shortpassed:27 passed, 1 skipped.python -m pytest tests/test_renderer_export_tail_parity.py tests/test_engine_client_command_parity.py::test_postprocess_restart_routes_through_renderer_export_not_renderer_cmd_registration -q --tb=shortpassed:7 passed.git diff --checkcompleted without whitespace errors; Git reported only line-ending normalization warnings for modified text files.
Task A86: Reconstruct retail qagame score, vote, and cheat command ladder [COMPLETED]
Priority: High
Primary areas: src/code/game/g_cmds.c,
tests/test_game_helper_seam_parity.py,
docs/reverse-engineering/qagame-score-vote-cheat-command-reconstruction-2026-05-25.md,
docs/reverse-engineering/qagame-mapping.md,
references/hlil/quakelive/qagamex86.dll/qagamex86.dll.bndb_hlil_split/
Parity estimate: before 72% -> after 93% for the scoped ten-command
score/stat/ready/vote/cheat ClientCommand surface (score, acc,
pstats, readyup, vote, give, god, notarget, noclip, and kill)
plus the adjacent ragequit boundary and next-map vote wiring. The repo-wide
parity estimate remains 98%.
Completed work:
- Rechecked the qagame HLIL
ClientCommandladder atsub_10045DEC, the command strings arounddata_10084EF8throughdata_10084F40, and helper strings for accuracy payloads, vote handling, cheat toggles, and kill rejection. - Revalidated symbol-map ownership for
Cmd_Score_f,Cmd_Acc_f,Cmd_Pstats_f,Cmd_ReadyUp_f,Cmd_Vote_f,Cmd_Give_f,Cmd_God_f,Cmd_Notarget_f,Cmd_Noclip_f,Cmd_Kill_f, andClientCommand. - Reordered
ClientCommandsoacc,pstats,readyup, andvotesit in the recovered retail pre-intermission cluster afterscore. - Moved source-local compatibility branches (
ready,notready,unready,players,teams, andcvar) after the retailvotebranch. - Removed the later post-intermission
votebranch, makingG_HandleNextMapVotereachable during intermission throughCmd_Vote_f. - Added a focused parity sentinel tying the ten command names to source dispatch order, helper bodies, HLIL command strings, and recovered vote/cheat/self-kill messages.
Open boundary:
- Retail
ragequitis visible betweenreadyupandvote, but its target is a one-argument native import atdata_104B13AC + 0x300. This pass leaves it documented rather than reconstructing behavior before the import owner is cross-validated.
Verification:
python -m pytest tests/test_game_helper_seam_parity.py -q --tb=short -k "score_vote_cheat_client_command_tranche"passed:1 passed, 29 deselected.python -m pytest tests/test_game_helper_seam_parity.py -q --tb=shortpassed:30 passed.python -m pytest tests/test_game_exit_rules_parity.py::test_nextmap_vote_pipeline_matches_retail_intermission_vote_flow tests/test_vote_ui_throttle.py::test_vote_ui_throttle_transitions -q --tb=shortpassed/skipped:1 passed, 1 skipped.
Task A85: Reconstruct retail qagame chat and voice command ladder [COMPLETED]
Priority: High
Primary areas: src/code/game/g_cmds.c,
tests/test_game_helper_seam_parity.py,
docs/reverse-engineering/qagame-chat-voice-command-reconstruction-2026-05-25.md,
docs/reverse-engineering/qagame-mapping.md,
references/hlil/quakelive/qagamex86.dll/qagamex86.dll.bndb_hlil_split/
Parity estimate: before 78% -> after 95% for the scoped ten-command
chat/voice ClientCommand surface (say, say_team, tell, botSay,
vsay, vsay_team, vtell, vosay, vosay_team, and votell) plus the
adjacent vtaunt boundary and voice/tell transport helpers. The repo-wide
parity estimate remains 98%.
Completed work:
- Rechecked the qagame HLIL
ClientCommandladder atsub_10045DEC, the command strings atdata_10084EACthroughdata_10084EF0, and the helper bodies aroundsub_10041B60,sub_10041B90,sub_10041CC0,sub_10041E40,sub_10041E60, andsub_10041F50. - Revalidated symbol-map ownership for
Cmd_Say_f,Cmd_Tell_f,Cmd_BotSay_f,Cmd_Voice_f,Cmd_VoiceTell_f,Cmd_VoiceTaunt_f, andClientCommand. - Reordered
ClientCommandso the retail chat/voice cluster flows directly frombotSayintovsay; the source-localcomplainthook remains supported, but now sits after the adjacentvtauntretail boundary. - Added a focused parity sentinel tying the ten command names to source dispatch order, handler calls, HLIL strings, voice transport commands, private tell echo behavior, bot chat payloads, and voice flood labels.
- Added a dedicated reconstruction note and refreshed the qagame mapping ledger with this source-reconstruction pass.
Verification:
python -m pytest tests/test_game_helper_seam_parity.py -q --tb=short -k "chat_voice_client_command_tranche or game_say_reconstructs"passed:2 passed, 27 deselected.python -m pytest tests/test_game_helper_seam_parity.py -q --tb=shortpassed:29 passed.
Task A84: Reconstruct retail qagame server-command wiring tranche [COMPLETED]
Priority: High
Primary areas: src/code/game/g_cmds.c, src/code/game/g_svcmds.c,
src/code/game/g_bot.c, src/code/game/g_mem.c,
tests/test_game_helper_seam_parity.py,
docs/reverse-engineering/qagame-server-command-wiring-reconstruction-2026-05-25.md,
docs/reverse-engineering/qagame-mapping.md,
references/hlil/quakelive/qagamex86.dll/qagamex86.dll.bndb_hlil_split/
Parity estimate: before 82% -> after 94% for the scoped ten-command
qagame server-command surface (addscore, addteamscore, setmatchtime,
entitylist, forceteam, game_memory, addbot, botlist, game_crash,
and reload_access) plus the related direct-table, console-dispatch, bot
media-refresh, and helper wiring. The repo-wide parity estimate remains
98%.
Completed work:
- Rechecked the owning
qagamex86.dllcorpus metadata/import/export/function evidence, the qagame symbol map, thedata_10080750direct command table,ConsoleCommandatsub_10066B90, andSvcmd_AddBot_fatsub_10037910. - Revalidated the retail direct command table tail rows for
addscore,addteamscore, andsetmatchtimeagainst the recovered command strings, handlers, privilege floors, and observable score/time messages. - Revalidated server-console dispatch for
entitylist,forceteam,game_memory,addbot,botlist,game_crash, andreload_accessagainst source helpers and HLIL command-token comparisons. - Corrected
Svcmd_AddBot_fso its local-client media refresh sendsloaddeferred\n, matching retail Quake Live and the existingG_AddTrainerBotpath. - Added a focused parity sentinel tying the ten command names to source dispatch, helper bodies, symbol-map identities, HLIL strings, and the corrected addbot server-command spelling.
- Added a dedicated reconstruction note and refreshed the qagame mapping ledger with this source-reconstruction pass.
Verification:
python -m pytest tests/test_game_helper_seam_parity.py -q --tb=short -k "server_command_wiring or console_tail or direct_score_time"passed:3 passed, 25 deselected.python -m pytest tests/test_game_helper_seam_parity.py -q --tb=shortpassed:28 passed.
Task A83: Reconstruct retail qagame direct command table tail [COMPLETED]
Priority: High
Primary areas: src/code/game/g_cmds.c,
tests/test_game_helper_seam_parity.py,
docs/reverse-engineering/qagame-direct-command-table-tail-reconstruction-2026-05-25.md,
docs/reverse-engineering/qagame-mapping.md,
references/hlil/quakelive/qagamex86.dll/qagamex86.dll.bndb_hlil_split/
Parity estimate: before 18% -> after 91% for the scoped remaining
direct-command table tail (addscore, addteamscore, setmatchtime, and the
help-visible null-handler rcon row). The repo-wide parity estimate remains
98%.
Completed work:
- Rechecked the
data_10080750tail rows at0x100808F4,0x10080908,0x1008091C, and0x10080930, plus thesub_10061670,sub_10061730,sub_10062CE0, andsub_10070B40HLIL bodies. - Added direct table rows for
addscore,addteamscore,setmatchtime, and help-visiblercon. - Updated direct dispatch so matched rows with null handlers fall through
instead of being invoked, matching the recovered
rconrow. - Added score adjustment handlers for player and team score deltas with the
recovered
Player score adjusted.,Team score adjusted., and increase/decrease print strings. - Added
setmatchtimehandling that rewritesCS_LEVEL_START_TIMEfromlevel.time, formats whole seconds as%i:%i%i, and broadcasts the recovered match-time confirmation. - Added a reconstruction note, qagame mapping rows, and parity sentinels for the remaining table offsets, strings, and source wiring.
Verification:
python -m pytest tests/test_game_helper_seam_parity.py -q --tb=short -k "direct_score_time or direct_admin_access or direct_command_table"passed:3 passed, 24 deselected.
Task A82: Reconstruct retail qagame direct admin command tranche [COMPLETED]
Priority: High
Primary areas: src/code/game/g_cmds.c, src/code/game/g_main.c,
src/code/game/g_local.h, tests/test_game_helper_seam_parity.py,
docs/reverse-engineering/qagame-direct-admin-command-reconstruction-2026-05-25.md,
docs/reverse-engineering/qagame-mapping.md,
references/hlil/quakelive/qagamex86.dll/qagamex86.dll.bndb_hlil_split/
Parity estimate: before 34% -> after 87% for the scoped ten-command
direct admin/access command surface (mute, unmute, tempban, ban,
listaccess, unban, addadmin, addmod, demote, and abort) plus the
related access-list page printer, access-entry mutation helpers, kick/drop
helper, and opsay privilege-floor correction. The repo-wide parity estimate
remains 98%; later direct table rows such as addscore, addteamscore,
and setmatchtime are closed by Task A83.
Completed work:
- Rechecked the qagame HLIL direct command table at
data_10080750, the symbol map rows for0x10061550,0x10062470through0x10062C60, and the access-list page helper at0x100327D0. - Extended the direct command table with the ten selected retail rows and
corrected
opsayfrom admin to moderator privilege based on the adjacent table-entry byte layout. - Reworked
muteandunmutearound the shared PlayerID resolver and recovered broadcast strings, including the same-or-higher target guard formute. - Added source-side access-list mutation helpers and
G_PrintAccessListPagewith the recovered 20-entry page size, separator, tier labels, andTEMP/PERMmode column. - Rebuilt
tempbanandbanthrough the retail-style shared helper: direct rows use PlayerID lookup, refuse privileged targets, write temporary or permanent ban entries, and drop clients withwas kicked. - Added
addadmin,addmod,demote,unban,listaccess, andaborthandlers, including the recovered promotion/demotion broadcasts,priv %irefreshes, unban confirmation, timeout-active abort rejection,PRE_GAMEreset, andmap_restart 3. - Added a dedicated reconstruction note, expanded qagame mapping rows, and added helper seam parity tests covering the selected table offsets, exact HLIL strings, access-list format, and source wiring.
Verification:
python -m pytest tests/test_game_helper_seam_parity.py -q --tb=short -k "direct_admin_access or direct_mute or direct_command_table or timeout_race"passed:4 passed, 22 deselected.python -m pytest tests/test_game_helper_seam_parity.py -q --tb=shortpassed:26 passed.
Task A81: Restore retail parity for access, A&D bonus, flood, drop-health, knockback, and vampiric g_* CVar tranche [COMPLETED]
Priority: High
Primary areas: src/code/game/g_main.c, src/game/g_config.c,
src/code/game/g_combat.c, src/code/game/g_items.c,
src/code/game/g_team.c, src/code/game/g_active.c,
src/code/game/g_cmds.c, src/code/game/g_svcmds.c,
tests/test_game_active_pmove_wiring_parity.py,
docs/gameplay/cvars.md,
docs/attack_defend_bonuses.md,
references/hlil/quakelive/qagamex86.dll/qagamex86.dll.bndb_hlil_split/
Parity estimate: before 69% -> after 100% for the scoped ten-CVar
registration/default/flag/wiring surface. This batch explicitly skipped the
vote/complaint rows and the A78-A80 rows already closed in this local run,
while also avoiding rows called out as inspected by session
019e6082-1189-74e3-8bdc-423ce9f7ef4d.
Completed work:
- Rechecked retail qagame HLIL rows, defaults, and registration flags for
g_accessFile,g_adTouchScoreBonus,g_adElimScoreBonus,g_adCaptureScoreBonus,g_floodprot_maxcount,g_floodprot_decay,g_dropDamagedHealth,g_max_knockback,g_returnFlagOnSuicide, andg_vampiricDamage. - Corrected the Attack & Defend bonus rows from source-local archive flags
to retail
CVAR_SERVERINFO | CVAR_GAMERULEwhile preserving the recovered1,2, and3defaults and score/announcement wiring. - Corrected flood protection to retail runtime-only rows, including the
g_floodprot_maxcount=10default shared by active-client decay, command flood gating, andfloodstatus. - Corrected
g_dropDamagedHealthto retail default0withCVAR_TEMP | 0x00040000 | CVAR_GAMERULE, and aligned the custom-settings digest so theDROP DAMAGED HEALTHbit only appears when the cvar is enabled. - Corrected
g_max_knockbackto retail default120andCVAR_GAMERULEacross both the legacy game cvar table and the config helper table, then moved the invalid-value fallback used by knockback config/damage code to the same value. - Corrected
g_returnFlagOnSuicideto retail default0andCVAR_GAMERULE, while preserving the cached flag config wiring. - Corrected
g_vampiricDamageto retail0x00040000 | CVAR_GAMERULEand revalidated the combat reward, custom-settings, and Steam tag hooks. - Documented the tranche in gameplay CVar notes and refreshed the A&D bonus tuning note so it no longer describes the retail gamerule rows as archived.
Verification:
python -m pytest tests/test_game_active_pmove_wiring_parity.py -q --tb=shortpassed after the tranche update.python -m pytest tests/test_game_weapon_parity.py tests/test_bot_resource_loading.py tests/test_spawn_spec_cvars.py -q --tb=shortpassed for adjacent knockback/access/spawn documentation sentinels.
Task A80: Restore retail parity for Freeze reset, last-man, and Red Rover zombie g_* CVar tranche [COMPLETED]
Priority: High
Primary areas: src/code/game/g_main.c, src/code/game/g_active.c,
src/code/game/g_freeze.c, src/code/game/g_team.c,
src/code/game/g_client.c, tests/test_game_active_pmove_wiring_parity.py,
tests/test_freeze_cvars.py, tests/test_game_helper_seam_parity.py,
docs/gameplay/cvars.md,
references/hlil/quakelive/qagamex86.dll/qagamex86.dll.bndb_hlil_split/
Parity estimate: before 57% -> after 100% for the scoped ten-CVar
Freeze reset, last-man-standing, and Red Rover zombie spawn-trait
registration/default/wiring surface. This batch explicitly excluded the
g_* cvars already closed by session 019e6082-1189-74e3-8bdc-423ce9f7ef4d
and the local A55-A79 ledger.
Completed work:
- Rechecked retail qagame HLIL rows, defaults, and registration flags for
g_freezeThawWinningTeam,g_freezeThawThroughSurface,g_freezeResetWeaponsOnRound,g_freezeResetHealthOnRound,g_freezeResetArmorOnRound,g_freezeRemovePowerupsOnRound,g_lastManStandingWarning,g_lastManStandingMessage,g_rrInfectedZombieHealthBonus, andg_rrInfectedZombieSpeed. - Corrected the six Freeze reset/thaw rows to retail
CVAR_GAMERULEsurfaces, including the retailg_freezeThawWinningTeam=1default. - Corrected the last-man rows to zero flags and corrected
g_lastManStandingMessageand its empty-cvar fallback to the retailYou are the last standingpayload. - Corrected the Red Rover infected zombie health and speed rows to retail
CVAR_GAMERULEsurfaces while preserving the recovered50and1.15defaults. - Revalidated functionality through Freeze config caching, thaw-through-wall line-of-sight gates, winner thaw release, reset weapon/health/armor/powerup handling, CA/FZ/A&D/RR last-alive notification, Red Rover infected spawn health finalization, and infected speed scaling.
- Added HLIL-backed parity sentinels and updated gameplay cvar notes for the audited controls.
Verification:
python -m pytest tests/test_game_active_pmove_wiring_parity.py -q --tb=shortpassed:24 passed.python -m pytest tests/test_freeze_cvars.py tests/test_game_helper_seam_parity.py::test_client_spawn_uses_recovered_loadout_and_rr_helpers tests/test_game_helper_seam_parity.py::test_red_rover_helpers_match_recovered_retail_boundaries tests/test_game_round_controller_helper_parity.py::test_red_rover_controller_readback_helpers_match_retail_mapping_surface -q --tb=shortpassed:7 passed.python -m pytest tests/test_cgame_event_transport_parity.py::test_last_alive_shared_helper_emits_retail_last_standing_sound -q --tb=shortpassed:1 passed.
Task A79: Reconstruct retail qagame direct client-command tranche [COMPLETED]
Priority: High
Primary areas: src/code/game/g_cmds.c, src/code/game/g_local.h,
tests/test_game_helper_seam_parity.py,
docs/reverse-engineering/qagame-client-command-reconstruction-2026-05-25.md,
references/hlil/quakelive/qagamex86.dll/qagamex86.dll.bndb_hlil_split/
Parity estimate: before 42% -> after 89% for the scoped ten-command
direct client-command surface (players, timeout, timein, allready,
pause, unpause, lock, unlock, putteam, and opsay) plus the related
? help-table wiring. The repo-wide parity estimate remains 98% while
other command-table rows and compatibility-only surfaces remain separate
focused tasks.
Completed work:
- Rechecked the
qagamex86.dllmetadata/import/export corpus, the symbol map, and the HLIL direct command table atdata_10080750. - Replaced the single-entry direct
opsaydispatcher with a shared retail-like direct command table, privilege floor checks, and help filtering. - Rebuilt
/playersaround the retail%2d %llu %c %srow format, cached SteamID64 values, and the recovered" MA*"privilege marker map. - Added the shared direct-command state gate, PlayerID parser, and team-token parser with the exact recovered rejection strings.
- Added the per-team lock latch used by
lock,unlock, andG_TeamJoinAllowedwhile preservingg_teamSpawnAsSpecas a compatibility guard. - Reworked
allready,putteam,lock,unlock, timeout, pause, timein, and opsay wiring so the selected tranche follows the recovered table and helper boundaries. - Added a dedicated reconstruction note and expanded the helper seam parity tests for the selected table rows, helper names, HLIL strings, and source wiring.
Verification:
python -m pytest tests/test_game_helper_seam_parity.py::test_game_direct_command_table_reconstructs_retail_client_command_tranche tests/test_game_helper_seam_parity.py::test_team_join_guard_and_connect_broadcast_match_retail_flow tests/test_game_helper_seam_parity.py::test_timeout_race_and_direct_command_helpers_match_recovered_boundaries -q --tb=shortpassed:3 passed.
Task A78: Restore retail parity for Red Rover infection g_* CVar tranche [COMPLETED]
Priority: High
Primary areas: src/code/game/g_main.c, src/code/game/g_client.c,
src/code/game/g_active.c, src/code/game/g_cmds.c,
src/code/game/g_team.c, tests/test_game_active_pmove_wiring_parity.py,
tests/test_game_round_controller_helper_parity.py,
tests/test_game_helper_seam_parity.py,
tests/test_cgame_event_transport_parity.py, docs/gameplay/cvars.md,
references/hlil/quakelive/qagamex86.dll/qagamex86.dll.bndb_hlil_split/
Parity estimate: before 46% -> after 100% for the scoped ten-CVar Red
Rover infection registration/default/wiring surface. Defaults were mostly
present but one literal default differed and all selected rows had legacy
archive/norestart flag surfaces instead of retail gamerule/latch surfaces. The
repo-wide parity estimate remains 98% while remaining g_* rows continue
to be audited in focused batches.
Completed work:
- Rechecked retail qagame HLIL rows, defaults, and registration flags for
g_rrAllowNegativeScores,g_rrDamageScoreBonus,g_rrInfected,g_rrInfectedSpreadTime,g_rrInfectedSpreadWarningTime,g_rrInfectedSurvivorMinSpeed,g_rrInfectedSurvivorPingRate,g_rrInfectedSurvivorScoreBonus,g_rrInfectedSurvivorScoreMethod, andg_rrInfectedSurvivorScoreRate. - Corrected the nine infection scoring/spread/survivor rows to
CVAR_GAMERULEand correctedg_rrInfectedto the retailCVAR_LATCH | GAME_CVAR_FLAG_RETAIL_40000 | CVAR_GAMERULEsurface. - Corrected
g_rrInfectedSurvivorMinSpeedto the retail literal default500.0f. - Revalidated functional wiring through negative-score clamping, damage-based survivor scoring, survival bonus cadence, infection spread and warning timers, survivor slow-movement pings, ping-rate configstrings, custom-settings export, infected autojoin routing, infection seeding, round completion, death conversion, and last-alive notification paths.
- Added HLIL-backed parity sentinels and updated gameplay cvar notes for the audited Red Rover infection controls.
Verification:
python -m pytest tests/test_game_active_pmove_wiring_parity.py -q --tb=shortpassed:22 passed.python -m pytest tests/test_game_round_controller_helper_parity.py::test_red_rover_controller_readback_helpers_match_retail_mapping_surface tests/test_game_round_controller_helper_parity.py::test_red_rover_autojoin_helper_routes_team_selection tests/test_game_helper_seam_parity.py::test_client_spawn_uses_recovered_loadout_and_rr_helpers tests/test_game_helper_seam_parity.py::test_client_begin_and_respawn_dispatch_freeze_and_rr_like_retail tests/test_game_helper_seam_parity.py::test_red_rover_helpers_match_recovered_retail_boundaries tests/test_cgame_event_transport_parity.py::test_qagame_infected_event_uses_retail_recipient_slot tests/test_cgame_event_transport_parity.py::test_red_rover_survival_bonus_emits_retail_global_team_sound -q --tb=shortpassed:7 passed.
Task A77: Restore retail parity for round and Freeze timing g_* CVar tranche [COMPLETED]
Priority: High
Primary areas: src/code/game/g_main.c, src/code/game/g_active.c,
src/code/game/g_client.c, src/code/game/g_freeze.c,
src/code/game/g_combat.c, tests/test_game_active_pmove_wiring_parity.py,
tests/test_freeze_cvars.py, tests/test_game_round_controller_helper_parity.py,
docs/gameplay/cvars.md,
references/hlil/quakelive/qagamex86.dll/qagamex86.dll.bndb_hlil_split/
Parity estimate: before 58% -> after 100% for the scoped ten-CVar
round draw, Freeze warmup, thaw, protection, environmental respawn, and
auto-thaw registration/default/wiring surface. The repo-wide parity estimate
remains 98% while remaining g_* rows continue to be audited in focused
batches.
Completed work:
- Rechecked retail qagame HLIL rows, defaults, and registration flags for
g_roundWarmupDelay,g_roundDrawLivingCount,g_roundDrawHealthCount,g_freezeThawTime,g_freezeThawTick,g_freezeThawRadius,g_freezeRoundDelay,g_freezeProtectedSpawnTime,g_freezeEnvironmentalRespawnDelay, andg_freezeAutoThawTime. - Corrected registration flags: draw gates and most Freeze timing rows now
carry
CVAR_GAMERULE, whileg_roundWarmupDelayandg_freezeRoundDelaynow match the retailCVAR_SERVERINFO | CVAR_GAMERULEsurface. - Corrected recovered retail defaults:
g_freezeThawTickis now1,g_freezeProtectedSpawnTimeis now0,g_freezeEnvironmentalRespawnDelayis now5000, andg_freezeAutoThawTimeis now120000. - Revalidated functionality through CA/FZ draw resolution, end-round living and health prints, warmup-delay rescheduling, Freeze config caching, thaw radius and tick accumulation, post-round delay, post-thaw protection, environmental respawn release, and auto-thaw deadlines.
- Added HLIL-backed parity sentinels and updated gameplay cvar notes for the audited round and Freeze timing controls.
Verification:
python -m pytest tests/test_game_active_pmove_wiring_parity.py -q --tb=shortpassed:20 passed.python -m pytest tests/test_game_active_pmove_wiring_parity.py tests/test_freeze_cvars.py tests/test_game_round_controller_helper_parity.py tests/test_game_runframe_parity.py -q --tb=shortpassed:34 passed.- A broader adjacent sweep that also included
tests/test_game_exit_rules_parity.pystill exposes the unrelated existingExitLevelmapname sentinel mismatch outside this tranche; the touched round/Freeze timing surface is covered by the passing focused and adjacent suites above.
Task A76: Restore retail parity for player-appearance, lag rewind, and instagib g_* CVar tranche [COMPLETED]
Priority: High
Primary areas: src/code/game/g_main.c, src/code/game/g_active.c,
src/code/game/g_client.c, src/code/game/g_pmove.c,
src/code/game/g_weapon.c, tests/test_game_active_pmove_wiring_parity.py,
tests/test_cgame_displaycontext_parity.py, docs/gameplay/cvars.md,
references/hlil/quakelive/qagamex86.dll/qagamex86.dll.bndb_hlil_split/
Parity estimate: before 72% -> after 100% for the scoped ten-CVar
player-appearance, lag rewind, and instagib registration/default/wiring
surface. The repo-wide parity estimate remains 98% while remaining g_*
rows continue to be audited in focused batches.
Completed work:
- Rechecked retail qagame HLIL rows, defaults, and registration flags for
g_allowCustomHeadmodels,g_playerCylinders,g_playerheadmodelOverride,g_playerheadScale,g_playerheadScaleOffset,g_playermodelOverride,g_playerModelScale,g_lagHaxHistory,g_lagHaxMs, andg_instaGib. - Added the recovered
0x00010000game cvar flag alias and corrected the seven player-appearance rows so they match retail: six0x00010000 | CVAR_GAMERULErows and the dedicatedg_playerCylindersCVAR_GAMERULErow. - Corrected
g_lagHaxHistoryandg_lagHaxMsto retailCVAR_LATCHrows while preserving the recovered4and80defaults. - Corrected
g_instaGibto the retailCVAR_SERVERINFO | 0x00040000 | CVAR_GAMERULEregistration surface. - Revalidated functional wiring through player-cylinder and player-appearance configstrings, forced model/head userinfo rewrites, admin config caching, lag rewind allocation/store/shift/restore, weapon hitscan rewind bracketing, pmove instagib no-player-clip caching, factory reset, custom-settings, and rank payload export.
- Added HLIL-backed parity sentinels and updated gameplay cvar notes for the audited player-appearance, lag rewind, and instagib controls.
Verification:
python -m pytest tests/test_game_active_pmove_wiring_parity.py -q --tb=shortpassed:18 passed.python -m pytest tests/test_cgame_displaycontext_parity.py::test_game_cvar_transport_redundancy_stays_off_serverinfo_slabs tests/test_cgame_displaycontext_parity.py::test_cgame_player_cylinders_configstring_retains_direct_retail_parser_boundary tests/test_cgame_displaycontext_parity.py::test_cgame_player_appearance_configstring_reconstruction_uses_retail_parser_and_head_gate -q --tb=shortpassed:3 passed.python -m pytest tests/test_game_active_pmove_wiring_parity.py tests/test_cgame_displaycontext_parity.py::test_game_cvar_transport_redundancy_stays_off_serverinfo_slabs tests/test_cgame_displaycontext_parity.py::test_cgame_player_cylinders_configstring_retains_direct_retail_parser_boundary tests/test_cgame_displaycontext_parity.py::test_cgame_player_appearance_configstring_reconstruction_uses_retail_parser_and_head_gate tests/test_engine_netcode_parity.py tests/test_pmove_selected_cvar_parity.py tests/test_game_factory_regen_parity.py -q --tb=shortpassed:74 passed.- A broader
python -m pytest tests/test_engine_cvar_retail_parity.py -q --tb=shortsweep still exposes an unrelated existing Steamworks sentinel mismatch insrc/code/qcommon/common.c; the touchedg_*tranche is covered by the passing focused and adjacent suites above.
Task A75: Restore retail parity for flag-physics and forced-override g_* CVar tranche [COMPLETED]
Priority: High
Primary areas: src/code/game/g_main.c, src/code/game/g_local.h,
src/code/game/g_combat.c, src/code/game/g_team.c,
tests/test_game_active_pmove_wiring_parity.py,
docs/gameplay/cvars.md,
references/hlil/quakelive/qagamex86.dll/qagamex86.dll.bndb_hlil_split/
Parity estimate: before 54% -> after 100% for the scoped ten-CVar
flag-physics, friendly-fire dampening, and forced-override registration/wiring
surface. The repo-wide parity estimate remains 98% while remaining g_*
rows continue to be audited in focused batches.
Completed work:
- Rechecked retail qagame HLIL rows, defaults, and registration flags for
g_flagBounce,g_flagPhysics,g_throwFlagVelocity,g_throwFlagForwardMult,g_tackleFlag,g_droppedFlagBonus,g_neutralFlagPingRate,g_friendlyFireDampen,g_forceDmgThroughSurface, andg_forceAtmosphericEffects. - Corrected the flag cvar rows to retail defaults and flags, including
g_flagBouncedefault0.25/CVAR_GAMERULE,g_throwFlagForwardMultdefault2.5with no flags,g_droppedFlagBonusdefault1/CVAR_TEMP, and the retailg_neutralFlagPingRateregistration name/default/flag surface. - Added the missing
g_friendlyFireDampenrow and wired it into same-team damage wheng_friendlyFireallows friendly hits. - Updated the flag config cache so the throw forward multiplier is stored as
a float and both item drops and carried-flag tosses preserve classic
behavior unless
g_flagPhysicsenables the retail physics path. - Revalidated forced override wiring for atmosphere and damage-through-surface configstring publication.
Verification:
python -m pytest tests/test_game_active_pmove_wiring_parity.py -q --tb=shortpassed:16 passed.python -m pytest tests/test_game_active_pmove_wiring_parity.py tests/test_game_callvote_option_parity.py tests/test_game_item_runframe_parity.py tests/test_game_target_parity.py tests/test_game_runframe_parity.py tests/test_game_native_export_helper_parity.py tests/test_game_visibility_queue_parity.py tests/test_engine_netcode_parity.py -q --tb=shortpassed:68 passed.git diff --check -- ...reported no whitespace errors; Git only warned that touched text files will be normalized from LF to CRLF the next time Git writes them.
Task A74: Restore retail parity for Domination and auto-shuffle g_* CVar tranche [COMPLETED]
Priority: High
Primary areas: src/code/game/g_main.c, src/code/game/g_team.c,
tests/test_game_active_pmove_wiring_parity.py,
docs/gameplay/cvars.md,
references/hlil/quakelive/qagamex86.dll/qagamex86.dll.bndb_hlil_split/
Parity estimate: before 38% -> after 100% for the scoped ten-CVar
Domination and auto-shuffle registration/wiring surface. The repo-wide parity
estimate remains 98% while remaining g_* rows continue to be audited in
focused batches.
Completed work:
- Rechecked retail qagame HLIL rows, defaults, and registration flags for
g_domCapTime,g_domTeammateCapScale,g_domDistressThreshold,g_domEnableContention,g_domNeutralFlag,g_domScoreRate,g_shuffle_timedelay,g_shuffle_minplayers,g_shuffle_automatic, andg_shuffle_automatic_minplayers. - Corrected the six Domination rows from legacy archived controls to retail
CVAR_GAMERULErows while preserving the recovered defaults. - Corrected the four auto-shuffle rows to retail zero-flag rows, including
g_shuffle_timedelaydefault5000,g_shuffle_minplayersdefault3,g_shuffle_automaticdefault0, andg_shuffle_automatic_minplayersdefault6. - Corrected
Team_UpdateAutoShuffleStatesog_shuffle_timedelayis treated as milliseconds and passed directly intoG_AutoShuffleCountdown_Arm, while log/UI announcements round the millisecond value up to seconds. - Revalidated functional wiring through Domination capture/scoring cadence, teammate capture scaling, distress threshold, contention/neutralization rules, capture-time configstring publication, auto-shuffle threshold resolution, automatic shuffle gating, and countdown arming.
- Added HLIL-backed parity sentinels and updated gameplay cvar notes for the audited Domination and auto-shuffle controls.
Verification:
python -m pytest tests/test_game_active_pmove_wiring_parity.py -q --tb=shortpassed:14 passed.python -m pytest tests/test_game_active_pmove_wiring_parity.py tests/test_auto_shuffle_countdown.py tests/test_clanarena_shuffle.py tests/test_match_state_configstring.py tests/test_game_runframe_parity.py tests/test_cgame_domination_count_parity.py tests/test_game_callvote_option_parity.py tests/test_game_module_retail_parity_gate.py -q --tb=shortpassed:37 passed, 6 skipped.python -m pytest tests/test_game_helper_seam_parity.py::test_team_balance_helper_is_split_out_for_setteam_and_readyup tests/test_game_helper_seam_parity.py::test_input_spawn_and_host_map_paths_keep_retail_factory_gates tests/test_game_helper_seam_parity.py::test_custom_settings_cvar_helper_matches_recovered_boundary -q --tb=shortpassed:3 passed.- A broader adjacent sweep that included all of
tests/test_game_helper_seam_parity.pystill exposes an unrelated existingG_Saytoken sentinel mismatch outside this tranche.
Task A73: Restore retail parity for match-flow/warmup/timeout g_* CVar tranche [COMPLETED]
Priority: High
Primary areas: src/code/game/g_main.c, src/code/game/g_client.c,
src/code/game/g_combat.c, src/code/game/g_gametype_lifecycle.inc,
src/code/game/g_mem.c, src/code/game/g_spawn.c,
src/code/game/g_team.c, src/game/g_match_config.c,
tests/test_game_active_pmove_wiring_parity.py,
docs/gameplay/cvars.md,
references/hlil/quakelive/qagamex86.dll/qagamex86.dll.bndb_hlil_split/
Parity estimate: before 55% -> after 100% for the scoped ten-CVar
match-state, friendly-fire, debug-allocation, spawn-grant, warmup, ready-delay,
and timeout registration/wiring surface. The repo-wide parity estimate remains
98% while remaining g_* rows continue to be audited in focused batches.
Completed work:
- Rechecked retail qagame HLIL rows, defaults, and registration flags for
g_gameState,g_friendlyFire,g_debugAlloc,g_grantItemOnSpawn,g_doWarmup,g_warmup,g_warmupReadyDelay,g_warmupReadyDelayAction,g_timeoutCount, andg_timeoutLen. - Corrected
g_friendlyFireandg_grantItemOnSpawnto retailCVAR_GAMERULErows. - Corrected warmup/ready-delay rows:
g_warmupnow defaults to retail10,g_doWarmupnow carriesCVAR_ARCHIVE, and both ready-delay controls are zero-flag rows. - Corrected timeout rows:
g_timeoutLennow carriesCVAR_GAMERULE, andg_timeoutCountnow defaults to0withCVAR_SERVERINFO | CVAR_GAMERULE. - Revalidated behavior/wiring through game-state publication, friendly-fire damage gates, debug allocation prints, spawn grant scripts, warmup countdowns, duel ready-delay actions, match-config timeout loading, timeout pool refills, and match-state configstring publication.
- Added HLIL-backed parity sentinels and documented the audited match-flow, warmup, timeout, and spawn-grant controls for server operators.
Verification:
python -m pytest tests/test_game_active_pmove_wiring_parity.py -q --tb=shortpassed:12 passed.python -m pytest tests/test_game_active_pmove_wiring_parity.py tests/test_game_duel_ready_delay_parity.py tests/test_gametype_lifecycle.py tests/test_match_state_configstring.py tests/test_match_sim_harness.py tests/test_game_helper_seam_parity.py tests/test_game_callvote_option_parity.py tests/test_spawn_spec_cvars.py tests/test_game_module_retail_parity_gate.py -q --tb=shortpassed:81 passed, 8 skipped.
Task A72: Restore retail parity for server access/factory match g_* CVar tranche [COMPLETED]
Priority: High
Primary areas: src/code/game/g_main.c, src/code/game/g_utils.c,
src/code/game/g_factory.c, src/code/game/g_svcmds.c,
src/code/game/g_client.c, src/game/g_match_config.c,
tests/test_game_active_pmove_wiring_parity.py,
docs/gameplay/cvars.md,
references/hlil/quakelive/qagamex86.dll/qagamex86.dll.bndb_hlil_split/
Parity estimate: before 64% -> after 100% for the scoped ten-CVar
server access, ban/filter, factory selection, overtime/mercy, automatic
action, and malformed-userinfo registration and wiring surface. The repo-wide
parity estimate remains 98% while remaining g_* rows continue to be
audited in focused batches.
Completed work:
- Rechecked retail qagame HLIL rows, defaults, and registration flags for
g_password,g_needpass,g_banIPs,g_filterBan,g_factory,g_factoryTitle,g_overtime,g_mercytime,g_autoAction, andg_kickBadUserinfo. - Corrected registration surfaces:
g_factoryis now the retailCVAR_SERVERINFO | CVAR_ROMrow,g_overtimeisCVAR_SERVERINFO | CVAR_GAMERULE,g_mercytimeisCVAR_NORESTART | CVAR_GAMERULE,g_autoActiondefaults to0with zero flags, andg_kickBadUserinfonow carries zero flags. - Preserved the already-matching retail rows for password/needpass, ban/filter, and factory title while tightening indentation around the audited rows.
- Revalidated runtime wiring through password-to-needpass mirroring, IP ban
and filter decisions, factory selection/title application, match overtime
config loading, mercy-rule timing, malformed-userinfo kick/fallback
handling, and
g_autoActionparsing. - Added HLIL-backed parity sentinels and documented the audited server access/factory/match-flow controls for server operators.
Verification:
python -m pytest tests/test_game_active_pmove_wiring_parity.py -q --tb=shortpassed:10 passed.python -m pytest tests/test_game_active_pmove_wiring_parity.py tests/test_game_factory_regen_parity.py tests/test_game_helper_seam_parity.py tests/test_game_attack_defend_parity.py tests/test_game_round_controller_helper_parity.py tests/test_engine_netcode_parity.py tests/test_game_module_retail_parity_gate.py -q --tb=shortpassed:81 passed, 1 skipped.python -m pytest tests/test_match_state_configstring.py tests/test_match_sim_harness.py -q --tb=shortpassed:19 passed, 7 skipped.- A broader adjacent sweep that also included
tests/test_game_exit_rules_parity.pystill exposes an unrelated existingExitLevelsentinel mismatch: the source readsSERVERINFO_KEY_MAPNAMEwhile the test expects the literal"mapname"string.
Task A71: Restore retail parity for Team Arena environment g_* CVar tranche [COMPLETED]
Priority: High
Primary areas: src/code/game/g_main.c, src/code/cgame/cg_main.c,
src/code/game/g_arenas.c, src/code/game/g_team.c,
src/code/game/g_combat.c, src/code/game/g_spawn.c,
tests/test_game_active_pmove_wiring_parity.py,
docs/gameplay/cvars.md,
references/hlil/quakelive/qagamex86.dll/qagamex86.dll.bndb_hlil_split/,
references/hlil/quakelive/cgamex86.dll/cgamex86.dll_hlil_split/
Parity estimate: before 46% -> after 100% for the scoped ten-CVar
Team Arena environment, podium, Obelisk/Cube, MOTD, and dust registration
surface. The repo-wide parity estimate remains 98% while remaining
g_* rows continue to be audited in focused batches.
Completed work:
- Rechecked retail qagame HLIL rows, defaults, and registration flags for
g_allTalk,g_motd,g_podiumDist,g_podiumDrop,g_obeliskHealth,g_obeliskRegenAmount,g_obeliskRegenPeriod,g_obeliskRespawnDelay,g_cubeTimeout, andg_enableDust. - Corrected qagame registration flags:
g_allTalk,g_motd, andg_enableDustare plain zero-flag rows; podium, Obelisk, and Cube timing rows now carryCVAR_GAMERULEinstead of legacy zero/serverinfo/archive surfaces. - Corrected the cgame mirror for
g_obeliskRespawnDelayto the retail zero-flag row while preserving cgame's retailCVAR_SERVERINFOmirror forg_enableDust. - Revalidated behavior/wiring through all-talk chat gating, MOTD publication, podium placement, Obelisk health/regen/respawn timing, Harvester cube timeout, worldspawn dust key handling, and cgame dust/effect consumers.
- Added focused HLIL-backed parity sentinels and documented the audited Team Arena environment controls for server operators.
Verification:
python -m pytest tests/test_game_active_pmove_wiring_parity.py -q --tb=shortpassed:8 passed.python -m pytest tests/test_game_active_pmove_wiring_parity.py tests/test_game_factory_regen_parity.py tests/test_game_weapon_parity.py tests/test_game_battlesuit_parity.py tests/test_engine_netcode_parity.py tests/test_game_module_retail_parity_gate.py -q --tb=shortpassed:85 passed, 1 skipped.python -m pytest tests/test_cgame_hud_parity.py tests/test_engine_netcode_parity.py -q --tb=shortpassed:47 passed.- Broader dirty-tree sweeps that included unrelated cgame display/impact and Steam platform cvar tests still expose pre-existing failures outside this tranche; the touched CVar surfaces above are covered by the passing focused and adjacent suites.
git diff --check -- ...reported no whitespace errors; Git only warned that touched text files will be normalized from LF to CRLF the next time Git writes them.
Task A70: Restore retail parity for classic gameplay/admin g_* CVar tranche [COMPLETED]
Priority: High
Primary areas: src/code/game/g_main.c, src/code/game/g_active.c,
src/code/game/g_local.h, tests/test_game_active_pmove_wiring_parity.py,
docs/gameplay/cvars.md,
references/hlil/quakelive/qagamex86.dll/qagamex86.dll.bndb_hlil_split/
Parity estimate: before 74% -> after 100% for the scoped ten-CVar
classic gameplay/admin registration and inactivity-wiring surface. The
repo-wide parity estimate remains 98% while remaining g_* rows continue
to be audited in focused batches.
Completed work:
- Rechecked retail qagame HLIL rows, defaults, and registration flags for
g_speed,g_gravity,g_weaponRespawn,g_inactivity,g_inactivityWarning,g_dropInactive,g_debugMove,g_debugDamage,g_teamAutoJoin, andg_teamForceBalance. - Corrected registration flags for
g_speed,g_gravity,g_weaponRespawn, andg_teamForceBalanceso the source rows match the retail serverinfo/archive/gamerule bits recovered from HLIL. - Restored the retail
g_inactivityWarningrow with default10, exported the cvar to game code, and replaced the hardcoded ten-second warning path with the retail cvar-driven threshold and pluralized centerprint text. - Wired
g_dropInactiveintoClientInactivityTimer: timed-out inactive clients are moved to spectator when the cvar is disabled, and are dropped only when it is enabled, matching the retail branch. - Added the retail-style inactivity warning reset latch for
g_inactivitychanges, and revalidated existing wiring for debug movement/damage, team autojoin/force-balance, speed, gravity, and weapon-respawn behavior. - Added focused HLIL-backed parity sentinels and documented the audited classic gameplay/admin controls for server operators.
Verification:
python -m pytest tests/test_game_active_pmove_wiring_parity.py -q --tb=shortpassed:6 passed.python -m pytest tests/test_game_active_pmove_wiring_parity.py tests/test_game_helper_seam_parity.py tests/test_game_factory_regen_parity.py tests/test_game_weapon_parity.py tests/test_cvar_alias_console.py tests/test_engine_netcode_parity.py tests/test_game_module_retail_parity_gate.py -q --tb=shortpassed:103 passed, 1 skipped.git diff --check -- ...reported no whitespace errors; Git only warned that touched text files will be normalized from LF to CRLF the next time Git writes them.
Task A69: Restore retail parity for second weapon-special g_* CVar tranche [COMPLETED]
Priority: High
Primary areas: src/code/game/g_main.c, src/code/game/g_missile.c,
src/code/game/g_pmove.c, src/code/game/bg_pmove.c,
src/code/game/bg_public.h, src/code/game/g_local.h,
src/code/cgame/cg_servercmds.c, src/game/g_config.c,
tests/test_game_weapon_parity.py, tests/test_game_factory_regen_parity.py,
docs/gameplay/cvars.md,
references/hlil/quakelive/qagamex86.dll/qagamex86.dll.bndb_hlil_split/
Parity estimate: before 59% -> after 100% for the scoped ten-CVar
weapon-special, Quad Hog, and prox-mine registration/wiring surface. The
repo-wide parity estimate remains 98% while remaining g_* rows continue
to be audited in focused batches.
Completed work:
- Rechecked retail qagame HLIL rows and string/default storage for
g_midAirMinHeight,g_nailspeed,g_nailspread,g_damagePlums,g_quadDamageFactor,g_quadHog,g_quadHogIdle,g_quadHogPingRate,g_quadHogTime, andg_proxMineTimeout. - Corrected registration defaults and flags: midair height, damage plums,
Quad Damage, Quad Hog timers, and prox mine timeout now match the retail
table; Nailgun speed/spread and prox mine timeout now carry the recovered
0x00040000 | CVAR_GAMERULEflag combination; Quad Hog now carriesCVAR_LATCH | 0x00040000 | CVAR_GAMERULE. - Revalidated functional wiring through
G_InitWeaponConfig,G_IsMidAirEligibleTarget, Nailgun projectile spread/speed sampling, Quad Damage scaling, server-settings publication, Quad Hog pickup/frame timers, pmove cache/compact payload mirroring, custom-settings masks, and proximity mine activation. - Corrected retail units: Quad Hog ping rate is milliseconds (
1500) and is no longer multiplied by1000, while Quad Hog time/idle and prox mine timeout remain seconds-based and are converted at the timer boundary. - Added focused HLIL-backed parity sentinels and documented the audited controls for server operators.
Verification:
python -m pytest tests/test_game_weapon_parity.py -q --tb=shortpassed:33 passed.python -m pytest tests/test_game_weapon_parity.py tests/test_game_factory_regen_parity.py tests/test_game_ammopack_parity.py tests/test_cvar_console_write_parity.py tests/test_game_module_retail_parity_gate.py tests/test_pmove_selected_cvar_parity.py -q --tb=shortpassed:82 passed, 1 skipped.python -m pytest tests/test_pmove_helper_parity.py -q --tb=shortpassed:38 passed.git diff --check -- ...reported no whitespace errors; Git only warned that touched text files will be normalized from LF to CRLF the next time Git writes them.
Task A68: Restore retail parity for first weapon-special g_* CVar tranche [COMPLETED]
Priority: High
Primary areas: src/code/game/g_main.c, src/code/game/g_missile.c,
src/code/game/g_weapon.c, src/code/game/g_pmove.c,
tests/test_game_weapon_parity.py, tests/test_game_factory_regen_parity.py,
docs/gameplay/cvars.md,
references/hlil/quakelive/qagamex86.dll/qagamex86.dll.bndb_hlil_split/
Parity estimate: before 64% -> after 100% for the scoped ten-CVar
weapon-special registration and wiring surface. The repo-wide parity estimate
remains 98% while remaining weapon-special and item/powerup cvar rows
continue to be audited in focused batches.
Completed work:
- Rechecked retail qagame HLIL rows and string/default storage for
g_velocity_gh,g_guidedRocket,g_lightningDischarge,g_railJump,g_gauntletSpeedFactor,g_headShotDamage_rg,g_ironsights_mg,g_nailbounce,g_nailbouncepercentage, andg_nailcount. - Corrected registration flags: grapple velocity, lightning discharge, rail
jump, rail headshot damage, and the three audited Nailgun rows now use
0x00040000 | CVAR_GAMERULE; guided rockets and gauntlet speed factor now useCVAR_GAMERULE; machinegun ironsights now use retailCVAR_TEMP | 0x00040000 | CVAR_GAMERULE. - Revalidated functional wiring through
G_InitWeaponConfig,G_SynchronizeGrappleConfig, guided rocket think arming,G_ApplyRailJump, lightning discharge activation,G_PmoveCacheSettings, Nailgun count/bounce spawn paths, custom-settings mask participation,G_UpdateCvars, and factory config refreshes. - Added focused HLIL-backed parity sentinels and documented the audited weapon-special controls for server operators.
Verification:
python -m pytest tests/test_game_weapon_parity.py -q --tb=shortpassed:31 passed.python -m pytest tests/test_game_weapon_parity.py tests/test_game_factory_regen_parity.py tests/test_game_ammopack_parity.py tests/test_cvar_console_write_parity.py tests/test_game_module_retail_parity_gate.py tests/test_pmove_selected_cvar_parity.py -q --tb=shortpassed:80 passed, 1 skipped.
Task A67: Restore retail parity for velocity/acceleration g_* CVar tranche [COMPLETED]
Priority: High
Primary areas: src/code/game/g_main.c, src/code/game/g_missile.c,
src/game/g_config.c, tests/test_game_weapon_parity.py,
docs/gameplay/cvars.md,
references/hlil/quakelive/qagamex86.dll/qagamex86.dll.bndb_hlil_split/
Parity estimate: before 66% -> after 100% for the scoped ten-CVar
projectile velocity/acceleration registration and wiring surface. The
repo-wide parity estimate remains 98% while remaining weapon-special
cvar rows continue to be audited in focused batches.
Completed work:
- Rechecked retail qagame HLIL rows and string/default storage for
g_accelFactor_bfg,g_accelFactor_pg,g_accelFactor_rl,g_accelRate_bfg,g_accelRate_pg,g_accelRate_rl,g_velocity_bfg,g_velocity_gl,g_velocity_pg, andg_velocity_rl. - Corrected retail defaults and flags: acceleration factors now use default
1plus0x00040000 | CVAR_GAMERULE; acceleration rates now use default16plusCVAR_GAMERULE; audited velocity rows now use the retail1800,700,2000, and1000defaults plus0x00040000 | CVAR_GAMERULE. - Revalidated functional wiring through
G_InitWeaponConfig,G_SynchronizeRocketConfig, the rocket/plasma/BFG acceleration think callbacks,G_GetMissileAccelerationThinkTime, grenade/plasma/rocket/BFG projectile constructors, custom-settings mask participation,G_UpdateCvars, and factory config refreshes. - Added focused HLIL-backed parity sentinels and documented the audited projectile velocity/acceleration controls for server operators.
Verification:
python -m pytest tests/test_game_weapon_parity.py -q --tb=shortpassed:29 passed.python -m pytest tests/test_game_weapon_parity.py tests/test_game_factory_regen_parity.py tests/test_game_ammopack_parity.py tests/test_cvar_console_write_parity.py tests/test_game_module_retail_parity_gate.py tests/test_pmove_selected_cvar_parity.py -q --tb=shortpassed:78 passed, 1 skipped.
Task A66: Restore retail parity for splash radius/falloff g_* CVar tranche [COMPLETED]
Priority: High
Primary areas: src/code/game/g_main.c, src/code/game/g_weapon.c,
src/code/game/g_missile.c, src/game/g_config.c,
tests/test_game_weapon_parity.py, docs/gameplay/cvars.md,
references/hlil/quakelive/qagamex86.dll/qagamex86.dll.bndb_hlil_split/
Parity estimate: before 68% -> after 100% for the scoped ten-CVar
splash/radius/falloff registration and wiring surface. The repo-wide parity
estimate remains 98% while adjacent velocity, acceleration, and remaining
weapon-special cvar rows continue to be audited in focused batches.
Completed work:
- Rechecked retail qagame HLIL rows and string/default storage for
g_splashdamage_bfg,g_splashdamage_pl,g_splashradius_bfg,g_splashradius_gl,g_splashradius_pg,g_splashradius_pl,g_splashradius_rl,g_range_lg_falloff,g_range_sg_falloff, andg_rocketsplashOffset. - Corrected registration names and flags: BFG/prox splash damage and all
audited splash radius rows now use retail lowercase names and
0x00040000 | CVAR_GAMERULE; falloff ranges and rocket splash offset now useCVAR_GAMERULE. - Corrected retail defaults: BFG splash radius is
80, both falloff ranges are768, andg_rocketsplashOffsetis-10.0. - Revalidated functional wiring through
G_InitWeaponConfig, shotgun and lightning falloff helpers, grenade/plasma/rocket/BFG/prox missile spawn paths, rocket splash-origin offset handling, custom-settings mask participation,G_UpdateCvars, and factory config refreshes.
Verification:
python -m pytest tests/test_game_weapon_parity.py -q --tb=shortpassed:27 passed.python -m pytest tests/test_game_weapon_parity.py tests/test_game_factory_regen_parity.py tests/test_game_ammopack_parity.py tests/test_cvar_console_write_parity.py tests/test_game_module_retail_parity_gate.py tests/test_pmove_selected_cvar_parity.py -q --tb=shortpassed:76 passed, 1 skipped.
Task A65: Restore retail parity for second weapon damage g_* CVar tranche [COMPLETED]
Priority: High
Primary areas: src/code/game/g_main.c, src/code/game/g_weapon.c,
src/code/game/g_missile.c, src/code/game/g_combat.c,
src/game/g_config.c, tests/test_game_weapon_parity.py,
docs/gameplay/cvars.md,
references/hlil/quakelive/qagamex86.dll/qagamex86.dll.bndb_hlil_split/
Parity estimate: before 70% -> after 100% for the scoped ten-CVar
weapon damage/splash registration and wiring surface. The repo-wide parity
estimate remains 98% while the remaining splash radius, BFG splash, and
weapon range/velocity cvar rows continue to be walked in focused batches.
Completed work:
- Rechecked retail qagame HLIL rows and string/default storage for
g_damage_pg,g_damage_pl,g_damage_rg,g_damage_rl,g_damage_sg,g_damage_sg_falloff,g_damage_sg_outer,g_splashdamage_gl,g_splashdamage_pg, andg_splashdamage_rl. - Corrected the seven remaining direct/shotgun damage rows to use the
recovered
0x00040000 | CVAR_GAMERULEpair viaGAME_CVAR_FLAG_RETAIL_40000. - Corrected the audited splash damage registrations to retail lowercase cvar
names (
g_splashdamage_*) and retail flags, and changed rocket splash damage from the legacy100default to Quake Live's84default across registration, cache fallback, and custom-settings comparisons. - Revalidated functional wiring through
G_InitWeaponConfig,G_ClampModDamage, shotgun/rail weapon paths, grenade/plasma/rocket/prox missile spawn paths, custom-settings mask participation,G_UpdateCvars, and factory config refreshes.
Verification:
python -m pytest tests/test_game_weapon_parity.py -q --tb=shortpassed:25 passed.python -m pytest tests/test_game_weapon_parity.py tests/test_game_factory_regen_parity.py tests/test_game_ammopack_parity.py tests/test_cvar_console_write_parity.py tests/test_game_module_retail_parity_gate.py tests/test_pmove_selected_cvar_parity.py -q --tb=shortpassed:74 passed, 1 skipped.
Task A64: Restore retail parity for first ten weapon damage g_* CVars [COMPLETED]
Priority: High
Primary areas: src/code/game/g_main.c, src/code/game/g_weapon.c,
src/code/game/g_missile.c, src/code/game/g_combat.c,
src/game/g_config.c, tests/test_game_weapon_parity.py,
docs/gameplay/cvars.md,
references/hlil/quakelive/qagamex86.dll/qagamex86.dll.bndb_hlil_split/
Parity estimate: before 72% -> after 100% for the scoped ten-CVar
weapon damage registration and wiring surface. The repo-wide parity estimate
remains 98% while the remaining weapon damage/splash/range cvar rows are
still being walked in focused batches.
Completed work:
- Rechecked retail qagame HLIL rows and string/default storage for
g_damage_bfg,g_damage_cg,g_damage_g,g_damage_gh,g_damage_hmg,g_damage_gl,g_damage_lg,g_damage_lg_falloff,g_damage_mg, andg_damage_ng. - Confirmed the retail default strings (
100,8,50,10,6,5,12, and0) and corrected the ten registration flags to the recovered0x00040000 | CVAR_GAMERULEpair viaGAME_CVAR_FLAG_RETAIL_40000. - Revalidated functional wiring through
G_InitWeaponConfig,G_ClampModDamage, weapon and missile fire paths, custom-settings mask participation where retail exposes it,G_UpdateCvars, and factory config refreshes. - Added focused parity sentinels against the HLIL registration rows/default strings and documented the audited damage tranche for server operators.
Verification:
python -m pytest tests/test_game_weapon_parity.py -q --tb=shortpassed:23 passed.python -m pytest tests/test_game_weapon_parity.py tests/test_game_factory_regen_parity.py tests/test_game_ammopack_parity.py tests/test_cvar_console_write_parity.py tests/test_game_module_retail_parity_gate.py tests/test_pmove_selected_cvar_parity.py -q --tb=shortpassed:72 passed, 1 skipped.
Task A63: Restore retail parity for second knockback g_* CVar tranche [COMPLETED]
Priority: High
Primary areas: src/code/game/g_main.c, src/game/g_config.c,
src/code/game/g_combat.c, tests/test_game_weapon_parity.py,
docs/gameplay/cvars.md,
references/hlil/quakelive/qagamex86.dll/qagamex86.dll.bndb_hlil_split/
Parity estimate: before 70% -> after 100% for the scoped ten-CVar
knockback base/scalar surface. The repo-wide parity estimate remains 98%
while adjacent weapon cvar families continue to be walked in focused batches.
Completed work:
- Rechecked retail qagame HLIL rows and string/default storage for
g_knockback,g_knockback_bfg,g_knockback_gh,g_knockback_ng,g_knockback_pl,g_knockback_cg,g_knockback_hmg,g_knockback_z,g_knockback_z_self, andg_knockback_cripple. - Corrected default spellings for the remaining weapon-specific scalars,
vertical boosters, and cripple scalar to match retail byte strings:
1,-5,24, and0instead of source-only float-suffixed forms. - Corrected flags: global
g_knockback,g_knockback_z,g_knockback_z_self, andg_knockback_cripplenow useCVAR_GAMERULE; BFG, grapple, nailgun, proximity launcher, chaingun, and heavy machinegun rows now useCONFIG_CVAR_FLAG_RETAIL_40000 | CVAR_GAMERULE. - Revalidated wiring through
G_InitKnockbackConfig,G_KnockbackScaleForMOD, and the finalg_knockback.valuescaling inG_Damage; the later A90 pass removed the source-only vertical boost and cripple-velocity helpers after the retailG_Damagebranch was remapped.
Verification:
python -m pytest tests/test_game_weapon_parity.py -q --tb=shortpassed:21 passed.python -m pytest tests/test_game_weapon_parity.py tests/test_game_factory_regen_parity.py tests/test_game_ammopack_parity.py tests/test_cvar_console_write_parity.py tests/test_game_module_retail_parity_gate.py tests/test_pmove_selected_cvar_parity.py -q --tb=shortpassed:70 passed, 1 skipped.git diff --check -- src/code/game/g_main.c src/game/g_config.c tests/test_game_weapon_parity.py docs/gameplay/cvars.md IMPLEMENTATION_PLAN.mdpassed with only the repository's existing CRLF normalization warnings.
Task A62: Restore retail parity for first ten weapon knockback g_* CVars [COMPLETED]
Priority: High
Primary areas: src/game/g_config.c, src/code/game/g_combat.c,
tests/test_game_weapon_parity.py, tests/test_game_factory_regen_parity.py,
docs/gameplay/cvars.md,
references/hlil/quakelive/qagamex86.dll/qagamex86.dll.bndb_hlil_split/
Parity estimate: before 68% -> after 100% for the scoped ten-CVar
weapon knockback registration and combat wiring surface. The repo-wide parity
estimate remains 98% while adjacent weapon cvar families continue to be
walked in focused batches.
Completed work:
- Rechecked retail qagame HLIL rows and string/default storage for
g_knockback_g,g_knockback_mg,g_knockback_sg,g_knockback_gl,g_knockback_rl,g_knockback_rl_self,g_knockback_lg,g_knockback_rg,g_knockback_pg, andg_knockback_pg_self. - Corrected the registration default spellings to match retail byte strings:
1,1.10,0.90,1.75,0.85, and1.30instead of source-only float-suffixed forms. - Corrected the ten registration flags from plain
0to the recovered retail0x00040000 | CVAR_GAMERULEpair, and generalized the local helper toCONFIG_CVAR_FLAG_RETAIL_40000because the same bit also appears on non-spawn-item retail cvars. - Revalidated functional wiring through
G_InitKnockbackConfig,G_UpdateKnockbackConfig, factory refreshes,G_UpdateCvars, andG_KnockbackScaleForMODintoG_Damage.
Verification:
python -m pytest tests/test_game_weapon_parity.py -q --tb=shortpassed:19 passed.python -m pytest tests/test_game_factory_regen_parity.py tests/test_game_ammopack_parity.py -q --tb=shortpassed:29 passed.
Task A61: Restore retail parity for factory item-spawn and respawn g_* CVars [COMPLETED]
Priority: High
Primary areas: src/game/g_config.c, src/code/game/g_main.c,
src/code/game/g_items.c, src/code/game/g_vote.c,
tests/test_game_factory_regen_parity.py,
tests/test_game_ammopack_parity.py, docs/gameplay/cvars.md,
references/hlil/quakelive/qagamex86.dll/qagamex86.dll.bndb_hlil_split/
Parity estimate: before 72% -> after 100% for the scoped ten-CVar
factory item-spawn/respawn surface. The repo-wide parity estimate remains
98% because this closes table-flag/default mismatches inside an already
mostly wired gameplay seam.
Completed work:
- Rechecked retail qagame HLIL registration rows and string/default storage
for
g_ammoPack,g_ammoPackHack,g_ammoRespawn,g_powerupRespawn,g_spawnItemPowerup,g_spawnItemHoldable,g_spawnItemWeapons,g_spawnItemHealth,g_spawnItemArmor, andg_spawnItemAmmo. - Corrected the local registration flags: ammo-pack toggles now use
CVAR_LATCH | CVAR_GAMERULE, ammo/powerup respawn timers useCVAR_GAMERULE, and the sixg_spawnItem*cvars use the recovered0x00040000 | CVAR_GAMERULEretail bit pair viaCONFIG_CVAR_FLAG_RETAIL_40000. - Revalidated functional wiring through the factory cvar cache, item spawn gating, global-versus-weapon ammo family switching, ammo/powerup respawn timing, and loadout ammo vote toggles.
- Added focused parity sentinels against the HLIL table rows/default strings and updated the stale ammo-pack parity expectation that still pinned the pre-fix archive flags.
Verification:
python -m pytest tests/test_game_factory_regen_parity.py -q --tb=shortpassed:25 passed.python -m pytest tests/test_game_factory_regen_parity.py tests/test_game_ammopack_parity.py tests/test_bg_misc_validation_fixtures.py tests/test_bg_misc_helper_parity.py tests/test_bg_itemlist_indexes.py tests/test_bg_itemlist_retail_metadata.py tests/test_game_weapon_parity.py tests/test_cvar_console_write_parity.py tests/test_game_module_retail_parity_gate.py -q --tb=shortpassed:101 passed, 1 skipped.git diff --check -- src/code/game/g_main.c src/game/g_config.c tests/test_game_factory_regen_parity.py tests/test_game_ammopack_parity.py docs/gameplay/cvars.md IMPLEMENTATION_PLAN.mdpassed with only the repository's existing CRLF normalization warnings.
Task A60: Resolve remaining source-visible cl_* cvar surfaces [COMPLETED]
Priority: Medium
Primary areas: src/code/client/cl_main.c, src/code/client/client.h,
src/code/client/cl_console.c, src/code/macosx/Q3Controller.m,
tests/test_engine_cvar_retail_parity.py, docs/client_cvars.md,
references/hlil/quakelive/quakelive_steam.exe/quakelive_steam.exe_hlil_split/quakelive_steam.exe_hlil_part04.txt,
references/hlil/quakelive/quakelive_steam.exe/quakelive_steam.exe_hlil_split/quakelive_steam.exe_hlil_part06.txt,
references/reverse-engineering/ghidra/quakelive_steam/decompile_top_functions.c
Parity estimate: before 99% -> after 100% for the remaining
source-visible cl_* cvar/name inventory. Repo-wide remains 98% pending
the active compatibility-only and runtime-evidence gaps.
Completed work:
- Rechecked the remaining source-visible names against the recovered retail
CL_Initcvar slab, string table, dynamic connect path, and companion Ghidra corpus. - Kept
cl_currentServerAddressas the retail dynamic-only connect cvar:CL_Connect_fsets it from the requested server string, and neither retail nor source registers it inCL_Init. - Folded
cl_matchmakingProvider,cl_matchmakingPolicy,cl_statsProvider,cl_statsPolicy,cl_socialOverlayProvider, andcl_socialOverlayPolicyinto the guarded service-disclosure contract:CVAR_ROMdefaults, refresh throughCL_RefreshPlatformServiceCvars, and explicit absence from the retail client cvar slab. - Removed the non-retail Quake III/PunkBuster/platform carryovers
cl_allowDownload,cl_contimestamps,cl_conXOffset,cl_guid,cl_noprint,cl_punkbuster, andcl_showBannerfrom the checked source surface; console notify drawing now uses the recovered base x-adjust, and the legacy pak-compare fallback no longer exposes a client disable cvar. - Added focused regression coverage and refreshed
docs/client_cvars.mdwith the final inventory classification. - Verification:
python -m pytest tests/test_engine_cvar_retail_parity.py::test_engine_cvar_thirtyninth_client_service_disclosure_tranche_matches_guarded_retail_divergence_contracts tests/test_engine_cvar_retail_parity.py::test_engine_cvar_fortieth_client_remaining_cl_surface_matches_resolved_retail_contracts -q --tb=short->2 passed; focused clientcl_*parity sweep through the thirty-fourth to fortieth tranches ->7 passed;python -m pytest tests/test_client_full_parity_gate.py -q --tb=short->2 passed, 1 skipped;python -m pytest tests/test_cgame_console_surface_parity.py::test_voice_menu_timer_uses_retail_separate_latch -q --tb=short->1 passed; source/tracking inventory reportsREMAINING=0;git diff --checkon touched files passed with CRLF warnings only.
Task A59: Re-audit retail con_* cvar parity [COMPLETED]
Priority: High
Primary areas: src/code/client/cl_console.c,
tests/test_engine_cvar_retail_parity.py,
tests/test_cl_console_cgame_parity.py,
tests/test_engine_command_parity.py,
references/hlil/quakelive/quakelive_steam.exe/quakelive_steam.exe_hlil_split/quakelive_steam.exe_hlil_part04.txt,
references/hlil/quakelive/quakelive_steam.exe/quakelive_steam.exe_hlil_split/quakelive_steam.exe_hlil_part06.txt
Parity estimate: before 100% -> after 100% for the scoped retail
con_* console cvar surface. No production source patch was required because
the checked-in registrations and consumers already matched the recovered
retail evidence.
Completed work:
- Rechecked the engine-owned retail evidence for console cvars against
metadata.txt,imports.txt,exports.txt,functions.csv,analysis_symbols.txt, and the Binary Ninja HLIL rows around004b4a30. - Confirmed the exhaustive Quake Live retail
con_*set contains eight cvars, not ten:con_background,con_height,con_matchlimit,con_noprint,con_opacity,con_scale,con_speed, andcon_timestamps. - Rejected the tempting Quake III carryovers as non-retail for Quake Live:
con_notifytimeis absent from the Quake Live HLIL, andscr_conspeedis replaced by the retailcon_speedbounded cvar. - Added a focused regression guard that now proves the exact retail names,
defaults, flags, bounded ranges, HLIL registration rows, and source wiring
for every retail
con_*cvar, including background selection, console height, find-match limit, print suppression, opacity, scale, scroll speed, and timestamp/cgame physics-time routing. - Verification:
python -m pytest tests/test_engine_cvar_retail_parity.py::test_console_cvar_surface_matches_retail_hlil tests/test_engine_cvar_retail_parity.py::test_console_cvar_functional_wiring_matches_retail_hlil_surface tests/test_engine_cvar_retail_parity.py::test_engine_cvar_second_tranche_matches_retail_contracts tests/test_engine_cvar_retail_parity.py::test_engine_cvar_sixth_client_tranche_matches_retail_contracts -q --tb=short->4 passed;python -m pytest tests/test_cl_console_cgame_parity.py tests/test_engine_command_parity.py::test_console_and_alias_command_families_match_retail_wiring -q --tb=short->10 passed. A broader full-file sweep oftests/test_engine_cvar_retail_parity.pycurrently reports49 passed, 3 failedin unrelated renderer/Steam cvar tranches.
Task A58: Re-audit client/server usercmd movement transport [COMPLETED]
Priority: High
Primary areas: src/code/client/cl_input.c,
src/code/client/cl_cgame.c, src/code/cgame/cg_predict.c,
src/code/cgame/cg_syscalls.c, src/code/qcommon/msg.c,
src/code/server/sv_client.c, src/code/server/sv_game.c,
tests/test_usercmd_movement_transport_parity.py,
docs/reverse-engineering/quakelive_steam_mapping_round_17.md,
docs/reverse-engineering/quakelive_steam_mapping_round_57.md,
docs/reverse-engineering/quakelive_steam_mapping_round_62.md,
docs/reverse-engineering/quakelive_steam_mapping_round_126.md,
docs/reverse-engineering/quakelive_steam_mapping_round_277.md,
references/analysis/quakelive_symbol_aliases.json
Parity estimate: before 100% -> after 100% for the scoped usercmd
movement transport seam: client command creation, packet packing, keyed
qcommon deltas, server replay into qagame, and cgame prediction access to the
host command ring. No production source patch was required.
Completed work:
- Rechecked the retained retail mappings for
CL_CreateCmd,CL_CreateNewCommands,CL_ReadyToSendPacket,CL_WritePacket,CL_SendCmd,MSG_WriteDeltaUsercmdKey,MSG_ReadDeltaUsercmdKey,SV_ClientThink,SV_UserMove,SV_ExecuteClientMessage,QLCGImport_GetCurrentCmdNumber, andQLCGImport_GetUserCmd. - Added a focused end-to-end sentinel for the client command path, including
final
weapon/weaponPrimary/fovstorage,serverTimeand view-angle capture, primed command generation, packet throttle checks,cl_packetdupresend window,clc_moveversusclc_moveNoDelta, checksum-feed keying, orderedMSG_WriteDeltaUsercmdKey, andoutPacketsbookkeeping. - Pinned the qcommon keyed usercmd delta pair against Quake Live extensions:
weaponPrimaryandfovnow stay covered alongside the signedforwardmove,rightmove, andupmovebytes in both changed-field and copied-baseline read paths. - Added server replay coverage for
SV_UserMoveandSV_ClientThink, including delta-message selection, command-count guards, keyed decode, message-ack ping timestamping, pure-client gates, first-commandSV_ClientEnterWorld, stale-command suppression,lastUsercmd, qagameG_GET_USERCMD, botBOTLIB_USER_COMMAND, andGAME_CLIENT_THINK. - Added cgame import coverage proving prediction pulls commands through
trap_GetCurrentCmdNumber/trap_GetUserCmd, while host-sideCL_GetUserCmdstill rejects future and overwritten command numbers before copying from the command ring. - Verification:
python -m pytest tests/test_usercmd_movement_transport_parity.py -q --tb=short->5 passed;python -m pytest tests/test_usercmd_movement_transport_parity.py tests/test_engine_client_command_parity.py::test_usercmd_cgame_bridge_matches_retail_weapon_primary_and_fov_bytes tests/test_engine_client_command_parity.py::test_client_input_mapping_round_277_promotes_console_input_and_usercmd_symbols -q --tb=short->7 passed;python -m pytest tests/test_usercmd_movement_transport_parity.py tests/test_playerstate_replication.py tests/test_game_active_pmove_wiring_parity.py tests/test_cgame_snapshot_parity.py tests/test_cgame_playerstate_transition_parity.py tests/test_cgame_item_respawn_timer_parity.py tests/test_game_native_export_helper_parity.py tests/test_pmove_validation_fixtures.py tests/test_pmove_air_control_runtime_parity.py tests/test_pmove_jump_timing_parity.py tests/test_pmove_movement_fixtures.py tests/test_pmove_helper_parity.py tests/test_pmove_acceleration_scope_parity.py tests/test_pmove_crouch_time_parity.py tests/test_pmove_crouch_slide_friction_parity.py tests/test_pmove_reload_fallback_parity.py tests/test_pmove_water_scale_parity.py tests/test_bg_playerstate_bridge_parity.py tools/tests/test_pmove_settings_configstring.py tests/test_pmove_selected_cvar_parity.py -q --tb=short->199 passed, 107 subtests passed;python -m pytest tests/test_game_module_retail_parity_gate.py tests/test_qcommon_full_parity_gate.py tests/test_client_full_parity_gate.py -q --tb=short->6 passed, 3 skipped.
Task A57: Restore retail parity for spawn and sudden-death g_* CVars [COMPLETED]
Priority: High
Primary areas: src/code/game/g_main.c, src/game/g_config.c,
src/code/game/g_client.c, src/code/game/g_combat.c,
src/code/game/g_items.c, src/game/g_match_config.c,
docs/gameplay/cvars.md, tests/test_game_factory_regen_parity.py,
references/hlil/quakelive/qagamex86.dll/qagamex86.dll.bndb_hlil_split/qagamex86.dll.bndb_hlil_part02.txt,
references/hlil/quakelive/qagamex86.dll/qagamex86.dll.bndb_hlil_split/qagamex86.dll.bndb_hlil_part03.txt
Parity estimate: before 74% -> after 100% for the selected ten-cvar
surface: g_startingWeapons, g_startingHealth,
g_startingHealthBonus, g_startingArmor, g_suddenDeathRespawn,
g_suddenDeathRespawnStart, g_suddenDeathRespawnTick,
g_suddenDeathRespawnMax, g_suddenDeathRespawnIncrement, and
g_suddenDeathRespawnPrint. Repo-wide remains 98% pending the active
compatibility-only and runtime-evidence gaps.
Completed work:
- Rechecked the qagame HLIL registration rows and string/default data for the
selected spawn and sudden-death cvars, including the retail
g_startingWeaponsdefault mask (3) and the sharedCVAR_GAMERULEflag across the sudden-death controller. - Corrected
g_startingHealthto the retailCVAR_SERVERINFO | CVAR_GAMERULErow, correctedg_startingArmorandg_startingWeaponstoCVAR_GAMERULE, and changedg_startingWeaponsfrom source-local0to retail3. - Corrected
g_startingHealthBonusandg_suddenDeathRespawnin the config cvar registration layer so duplicate registration preserves the recoveredCVAR_GAMERULEflags. - Corrected
g_suddenDeathRespawnStart,g_suddenDeathRespawnTick,g_suddenDeathRespawnMax,g_suddenDeathRespawnIncrement, andg_suddenDeathRespawnPrintto their retailCVAR_GAMERULErows. - Revalidated wiring for spawn loadout masks, starting health/armor fallback, factory config caching, sudden-death match config caching, respawn-delay calculation, centerprint announcements, item respawn suppression, and match state publication.
- Verification:
python -m pytest tests/test_game_factory_regen_parity.py -q --tb=short->23 passed;python -m pytest tests/test_game_factory_regen_parity.py tests/test_match_state_configstring.py tests/test_gametype_lifecycle.py tests/test_game_helper_seam_parity.py tests/test_cvar_console_write_parity.py tests/test_game_module_retail_parity_gate.py -q --tb=short->61 passed, 6 skipped.
Task A56: Re-audit server/client snapshot playerState transport [COMPLETED]
Priority: High
Primary areas: src/code/server/sv_snapshot.c,
src/code/client/cl_parse.c, src/code/client/cl_cgame.c,
src/code/cgame/cg_syscalls.c, tests/test_playerstate_replication.py,
docs/reverse-engineering/quakelive_steam_mapping_round_17.md,
docs/reverse-engineering/quakelive_steam_mapping_round_65.md,
docs/reverse-engineering/quakelive_steam_mapping_round_127.md,
references/analysis/quakelive_symbol_aliases.json
Parity estimate: before 100% -> after 100% for the scoped snapshot
playerState transport seam: server snapshot playerState build/write, client
snapshot parse/ring storage, CL_GetSnapshot exposure, and cgame syscall
retrieval. No production source patch was required.
Completed work:
- Rechecked the retained retail mappings for
SV_BuildClientSnapshot,SV_WriteSnapshotToClient,SV_SendClientSnapshot,CL_ParseSnapshot,QLCGImport_GetCurrentSnapshotNumber, andQLCGImport_GetSnapshotagainst mapping rounds 17, 65, 127, and the committed alias ledger. - Expanded
tests/test_playerstate_replication.pyso the server-side snapshot path now pinsSV_GameClientNumcopying intoframe->ps, own client suppression, view-origin selection, visible-entity gathering,svc_snapshotfield order, area-mask write, playerState delta write, and packet-entity emission order. - Added client-side snapshot parse coverage for
serverCommandSequence, server time, delta metadata, snap flags, areamask,MSG_ReadDeltaPlayerstate, packet-entity parsing, invalid-frame discard, ping calculation fromps.commandTime, backup-ring storage, andcl.newSnapshots. - Added cgame import coverage showing
trap_GetSnapshotreachesCL_GetSnapshot, which validates the ring entry and copies areamask, playerState, and bounded packet entities into the cgame-visible snapshot. - Verification:
python -m pytest tests/test_playerstate_replication.py -q --tb=short->14 passed;python -m pytest tests/test_playerstate_replication.py tests/test_game_active_pmove_wiring_parity.py tests/test_cgame_snapshot_parity.py tests/test_cgame_playerstate_transition_parity.py tests/test_cgame_item_respawn_timer_parity.py tests/test_game_native_export_helper_parity.py tests/test_pmove_validation_fixtures.py tests/test_pmove_air_control_runtime_parity.py tests/test_pmove_jump_timing_parity.py tests/test_pmove_movement_fixtures.py tests/test_pmove_helper_parity.py tests/test_pmove_acceleration_scope_parity.py tests/test_pmove_crouch_time_parity.py tests/test_pmove_crouch_slide_friction_parity.py tests/test_pmove_reload_fallback_parity.py tests/test_pmove_water_scale_parity.py tests/test_bg_playerstate_bridge_parity.py tools/tests/test_pmove_settings_configstring.py tests/test_pmove_selected_cvar_parity.py -q --tb=short->194 passed, 107 subtests passed;python -m pytest tests/test_game_module_retail_parity_gate.py tests/test_qcommon_full_parity_gate.py tests/test_client_full_parity_gate.py -q --tb=short->6 passed, 3 skipped. The full server parity gate still reports the unrelated retainedSV-G01Steam GameServer lifecycle/callback/auth artifact lane as failing.
Task A55: Restore retail parity for cosmetic, item-timer, and loadout g_* CVars [COMPLETED]
Priority: High
Primary areas: src/code/game/g_main.c, src/code/game/g_local.h,
src/game/g_config.c, docs/gameplay/cvars.md,
tests/test_game_callvote_option_parity.py,
references/hlil/quakelive/qagamex86.dll/qagamex86.dll.bndb_hlil_split/qagamex86.dll.bndb_hlil_part02.txt,
references/hlil/quakelive/qagamex86.dll/qagamex86.dll.bndb_hlil_split/qagamex86.dll.bndb_hlil_part03.txt
Parity estimate: before 82% -> after 100% for the selected ten-cvar
surface: g_customSettings, g_itemTimers, g_itemHeight,
g_forceSmallScoreboardMessage, g_forceSendConfigstring,
g_forceAtmosphericEffects, g_forceDmgThroughSurface,
g_specItemTimers, g_loadout, and g_infiniteAmmo. Repo-wide remains
98% pending the active compatibility-only and runtime-evidence gaps.
Completed work:
- Rechecked the qagame HLIL registration rows and string/default data for the
selected ten
g_*CVars, including the recoveredCVAR_GAMERULEbit and theg_itemHeightretail default string at10086c34(35). - Aligned source registration defaults and flags:
g_customSettingsnow registers as default0withCVAR_SERVERINFO;g_itemTimersandg_itemHeightuseCVAR_SERVERINFO | CVAR_GAMERULE; the forced cosmetics cvars use their retail no-flag orCVAR_GAMERULErows;g_loadoutandg_infiniteAmmouse their retail game-rule surfaces. - Added the missing retail
g_specItemTimersregistration as a plain qagame cvar, matching the recovered table's default1and no-flag row. - Revalidated wiring for the selected cvars: custom-settings digest rebuilds, item timer broadcasts and late-join sync, forced-cosmetics configstring updates, loadout vote/cgame mirroring, and infinite-ammo factory/spawn/weapon paths.
- Updated gameplay cvar notes so the documented defaults/flags distinguish the
retail
g_itemHeightdefault (35) from the local invalid-height fallback. - Verification:
python -m pytest tests/test_game_callvote_option_parity.py -q --tb=short->9 passed;python -m pytest tests/test_cvar_console_write_parity.py tests/test_game_callvote_option_parity.py tests/test_game_factory_regen_parity.py tests/test_game_forfeit_parity.py tests/test_game_module_retail_parity_gate.py tests/test_game_helper_seam_parity.py tests/test_game_native_export_helper_parity.py tests/test_game_compact_scoreboard_parity.py -q --tb=short->74 passed, 1 skipped.
Task A54: Re-audit qcommon playerState delta-codec wiring [COMPLETED]
Priority: High
Primary areas: src/code/qcommon/msg.c, src/code/game/q_shared.h,
tests/test_playerstate_replication.py,
docs/reverse-engineering/quakelive_steam_mapping_round_57.md,
docs/reverse-engineering/qcommon-full-parity-audit-and-implementation-plan-2026-04-10.md,
references/analysis/quakelive_symbol_aliases.json
Parity estimate: before 100% -> after 100% for the scoped qcommon
playerState snapshot replication bridge: the Quake Live-expanded scalar
netfield table, signed command-axis mirrors, stats/persistant/ammo/powerup
array-mask sections, and server-to-cgame delta round trips. No production
source patch was required.
Completed work:
- Rechecked the retained retail mapping for
sub_4D5D50 -> MSG_WriteDeltaPlayerstateandsub_4D66C0 -> MSG_ReadDeltaPlayerstateagainst the committed alias ledger and mapping round 57. - Expanded
tests/test_playerstate_replication.pywith executable coverage for all four playerState array-mask sections, proving changedstats[],persistant[],ammo[], andpowerups[]slots round-trip while unchanged baseline slots survive the delta copy. - Added structural coverage for the full Quake Live scalar
playerStateFieldsorder and bit widths, including the movement-critical command-time, origin/velocity/viewangle, jump/crouch, weapon-primary, location, fov, and signedforwardmove/rightmove/upmovetail fields. - Pinned the signed-byte codec helpers so command-axis mirrors are compared
as signed bytes, serialized as unsigned byte payloads, and restored through
MSG_SetPlayerStateFieldValueon both changed and copied-from-baseline scalar fields. - Verification:
python -m pytest tests/test_playerstate_replication.py -q --tb=short->10 passed;python -m pytest tests/test_playerstate_replication.py tests/test_game_active_pmove_wiring_parity.py tests/test_cgame_snapshot_parity.py tests/test_cgame_playerstate_transition_parity.py tests/test_cgame_item_respawn_timer_parity.py tests/test_pmove_validation_fixtures.py tests/test_pmove_air_control_runtime_parity.py tests/test_pmove_jump_timing_parity.py tests/test_pmove_movement_fixtures.py tests/test_pmove_helper_parity.py tests/test_pmove_acceleration_scope_parity.py tests/test_pmove_crouch_time_parity.py tests/test_pmove_crouch_slide_friction_parity.py tests/test_pmove_reload_fallback_parity.py tests/test_pmove_water_scale_parity.py tests/test_bg_playerstate_bridge_parity.py tools/tests/test_pmove_settings_configstring.py tests/test_pmove_selected_cvar_parity.py -q --tb=short->184 passed, 107 subtests passed;python -m pytest tests/test_game_module_retail_parity_gate.py tests/test_qcommon_full_parity_gate.py -q --tb=short->4 passed, 2 skipped.
Task A53: Restore retail ammo_pack item sentinel wiring [COMPLETED]
Priority: High
Primary areas: src/code/game/bg_misc.c, src/code/game/g_items.c,
src/game/g_config.c, tests/test_game_ammopack_parity.py,
references/hlil/quakelive/qagamex86.dll/qagamex86.dll.bndb_hlil.txt,
references/symbol-maps/qagame.json
Parity estimate: before 96% -> after 100% for scoped ammo_pack
metadata, grab eligibility, factory-family gating, Pickup_Ammo forwarding,
and Add_Ammo sentinel fan-out. Repo-wide remains 98% pending the active
compatibility-only and runtime-evidence gaps.
Completed work:
- Rechecked the qagame item table and symbol-map evidence for
ammo_pack,Pickup_Ammo,Add_Ammo,g_ammoPack,g_ammoPackHack, andg_ammoRespawn. - Kept the shared item metadata aligned with retail:
ammo_packremains anIT_AMMOitem tagged with theWP_NUM_WEAPONSsentinel and the recovered pickup sound, model, icon, pickup name, and quantity. - Reshaped game-side ammo pickup wiring so
Pickup_Ammoresolves the entity count/item quantity and forwards the item tag once, whileAdd_Ammoowns the retailWP_NUM_WEAPONSsentinel path that scans owned weapons and adds per-weapon ammo-pack quantities. - Confirmed the existing shared grab rule still scans owned weapons below
their maximum ammo, and the factory gate still switches between global
ammo-pack and weapon-specific ammo families via
g_ammoPack/g_ammoPackHack. - Added focused regression coverage for the retail evidence, source metadata,
grab rule,
Add_Ammosentinel fan-out,Pickup_Ammoforwarding, and factory-family gate. - Verification:
python -m pytest tests/test_game_ammopack_parity.py -q --tb=short->4 passed;python -m pytest tests/test_bg_misc_validation_fixtures.py tests/test_bg_misc_helper_parity.py tests/test_bg_itemlist_indexes.py tests/test_bg_itemlist_retail_metadata.py -q --tb=short->47 passed;python -m pytest tests/test_game_factory_regen_parity.py tests/test_game_weapon_parity.py -q --tb=short->38 passed;python -m pytest tests/test_game_ammopack_parity.py tests/test_bg_misc_validation_fixtures.py tests/test_bg_misc_helper_parity.py tests/test_bg_itemlist_indexes.py tests/test_bg_itemlist_retail_metadata.py -q --tb=short->51 passed.
Task A52: Re-audit cgame prediction pmove replay wiring [COMPLETED]
Priority: High
Primary areas: src/code/cgame/cg_predict.c,
src/code/cgame/cg_playerstate.c, src/code/cgame/cg_snapshot.c,
tests/test_cgame_snapshot_parity.py,
docs/reverse-engineering/cgame-mapping.md,
docs/reverse-engineering/cgame-bg-parity-implementation-plan.md,
references/symbol-maps/cgame.json
Parity estimate: before 100% -> after 100% for the scoped cgame
prediction/playerState replay seam: local pmove_t setup, usercmd replay,
trigger/item prediction, mover correction, step smoothing, predictable-event
handoff, and committed retail symbol evidence. No production source patch was
required.
Completed work:
- Rechecked the retail cgame prediction map for
CG_PredictPlayerState,CG_TouchItem,CG_TouchTriggerPrediction,CG_UpdateStepChange,CG_UpdatePredictedRailFire, andCG_TransitionPlayerStateagainst the committed symbol map and existing source reconstruction. - Expanded the cgame snapshot parity sentinel so the full prediction replay
pipeline is pinned: projectile-nudge reset, local
pmove_settings_tcopy, trace/pointcontents callbacks, tracemask/body handling, command overflow guard, latest-command rail replay, next-snapshot seed selection,pmove_msecclamp, fixed-move view-angle update,Pmove, step smoothing, local projectile nudge, trigger prediction, final mover adjustment, and transition handoff. - Added structural coverage for item and trigger prediction sidecars, including retail server-authored pickup skips, grab/event/NODRAW/ammo side effects, no-predict and double-touch guards, box-trace trigger collision, teleport hyperspace, jump-pad activation, and jump-pad cache clearing.
- Added a committed-evidence sentinel tying the source wiring back to
references/symbol-maps/cgame.jsonand the cgame mapping ledgers. - Verification:
python -m pytest tests/test_cgame_snapshot_parity.py -q --tb=short->11 passed;python -m pytest tests/test_cgame_snapshot_parity.py tests/test_cgame_playerstate_transition_parity.py tests/test_cgame_item_respawn_timer_parity.py -q --tb=short->23 passed;python -m pytest tests/test_game_active_pmove_wiring_parity.py tests/test_cgame_snapshot_parity.py tests/test_cgame_playerstate_transition_parity.py tests/test_cgame_item_respawn_timer_parity.py tests/test_pmove_validation_fixtures.py tests/test_pmove_air_control_runtime_parity.py tests/test_pmove_jump_timing_parity.py tests/test_pmove_movement_fixtures.py tests/test_pmove_helper_parity.py tests/test_pmove_acceleration_scope_parity.py tests/test_pmove_crouch_time_parity.py tests/test_pmove_crouch_slide_friction_parity.py tests/test_pmove_reload_fallback_parity.py tests/test_pmove_water_scale_parity.py tests/test_bg_playerstate_bridge_parity.py tests/test_playerstate_replication.py tools/tests/test_pmove_settings_configstring.py tests/test_pmove_selected_cvar_parity.py -q --tb=short->180 passed, 107 subtests passed;python -m pytest tests/test_game_module_retail_parity_gate.py tests/test_qcommon_full_parity_gate.py -q --tb=short->4 passed, 2 skipped.
Task A51: Reconstruct VM bounded cvar registration and integer cache wiring [COMPLETED]
Priority: High
Primary areas: src/code/qcommon/cvar.c, src/code/qcommon/qcommon.h,
src/code/game/q_shared.h, src/code/client/cl_cgame.c,
tests/test_cvar_console_write_parity.py, tests/test_cgame_hud_parity.py,
docs/reverse-engineering/quakelive_steam_mapping_round_294.md,
references/hlil/quakelive/quakelive_steam.exe/quakelive_steam.exe_hlil_split/quakelive_steam.exe_hlil_part04.txt,
references/hlil/quakelive/quakelive_steam.exe/quakelive_steam.exe_hlil_split/quakelive_steam.exe_hlil_part06.txt
Parity estimate: before 97% -> after 98% for scoped core cvar
handling/management, VM cvar shadows, and bounded range registration. Repo-wide
remains 98% pending the active compatibility-only and runtime-evidence
gaps.
Completed work:
- Rechecked the retail
sub_4CCCC0,sub_4CDD30,sub_4CE400, andsub_4CE460evidence for hex integer parsing, bounded cvar metadata, VM cvar shadow flags, and ranged VM registration. - Added
Cvar_ParseInteger()and routed cvar creation/mutation integer-cache updates through the retail"0x"/"0x%08x"fallback path. - Reconstructed bounded-cvar registration metadata by forcing
CVAR_VM_CREATEDinCvar_GetBounded()and addingCvar_RegisterBounded()for the native cgame range-register import. - Added the retail
vmCvar_t.flagsshadow field and copied cvar flags during VM registration. - Updated cgame range registration to call the recovered qcommon wrapper and refreshed focused cvar/HUD parity tests for that source-visible path.
- Verification:
python -m pytest tests/test_cvar_console_write_parity.py -q --tb=short->6 passed;python -m pytest tests/test_cvar_console_write_parity.py tests/test_cgame_displaycontext_parity.py::test_register_cvars_publishes_retail_version_and_vote_reset tests/test_cgame_hud_parity.py::test_crosshair_team_health_default_matches_retail_mode_cvar tests/test_qcommon_full_parity_gate.py -q --tb=short->10 passed, 1 skipped;python -m pytest tests/test_cvar_alias_console.py -q --tb=short->1 passed.
Task A50: Re-audit focused retail g_* vote and complaint cvar parity tranche [COMPLETED]
Priority: Medium
Primary areas: src/code/game/g_main.c, src/game/g_config.c,
docs/gameplay/cvars.md, tests/test_game_callvote_option_parity.py,
references/hlil/quakelive/qagamex86.dll/qagamex86.dll.bndb_hlil_split/qagamex86.dll.bndb_hlil_part03.txt,
references/hlil/quakelive/qagamex86.dll/qagamex86.dll.bndb_hlil_split/qagamex86.dll.bndb_hlil_part02.txt
Parity estimate: before 80% -> after 100% for the scoped ten-cvar
vote/complaint tranche: g_allowSpecVote, g_allowVote,
g_allowVoteMidGame, g_allowForfeit, g_allowKill,
g_complaintLimit, g_complaintDamageThreshold, g_voteFlags,
g_voteDelay, and g_voteLimit. Repo-wide remains 98% pending the
active compatibility-only and runtime-evidence gaps.
Completed work:
- Rechecked the selected qagame registration rows against the committed HLIL cvar slab and string/default evidence.
- Corrected
g_allowForfeitto the retail1default and recoveredCVAR_GAMERULEflag, and correctedg_allowKillto the retailCVAR_GAMERULEflag. - Corrected the factory fallback constants for
g_complaintDamageThresholdandg_complaintLimitto retail400and5, matching the main registration table. - Confirmed the existing callvote, spectator vote, mid-game vote, vote-delay, vote-limit, vote-flag, forfeit, self-kill, complaint, and endvote wiring remains attached to the selected cvars.
- Refreshed gameplay cvar notes and added focused regression coverage for the selected defaults, flags, retail evidence, and behavioral wiring.
- Verification:
python -m pytest tests/test_game_callvote_option_parity.py -q --tb=short->7 passed;python -m pytest tests/test_game_callvote_option_parity.py tests/test_game_forfeit_parity.py tests/test_game_factory_regen_parity.py tests/test_game_module_retail_parity_gate.py -q --tb=short->35 passed, 1 skipped;python -m pytest tests/test_cvar_console_write_parity.py tests/test_game_callvote_option_parity.py tests/test_game_forfeit_parity.py tests/test_game_factory_regen_parity.py tests/test_game_module_retail_parity_gate.py -q --tb=short->39 passed, 1 skipped.
Task A49: Restore retail key item mover wiring [COMPLETED]
Priority: High
Primary areas: src/code/game/bg_misc.c, src/code/game/g_items.c,
src/code/game/g_mover.c, src/code/game/g_target.c,
src/code/cgame/cg_newdraw.c, tests/test_game_key_item_parity.py,
references/hlil/quakelive/qagamex86.dll/qagamex86.dll.bndb_hlil.txt,
references/symbol-maps/qagame.json, references/symbol-maps/cgame.json
Parity estimate: before 96% -> after 100% for scoped silver/gold/master
key item pickup, reset, keyed mover, remove-keys target, and HUD icon wiring;
repo-wide remains 98% pending the active portability/runtime-evidence gaps.
Completed work:
- Rechecked the retail qagame key item records,
G_ResetKeyItem,Touch_DoorTriggerKeyed,Touch_ButtonKeyed, andUse_Target_RemoveKeysevidence against the committed HLIL and symbol maps. - Restored the missing keyed-button touch path: silver-key buttons now accept
silver or master keys, gold-key buttons accept gold or master keys, and
keyed buttons only fire from
MOVER_POS1. - Kept the existing retail-aligned key pickup/reset surface: key pickup sets
the carried mask/stat and does not auto-respawn, dropped copies are freed
when keys are reset, and
target_remove_keysclears carried keys through the reset helper. - Added structural coverage for key item metadata, pickup/reset/drop,
keyed-door/keyed-button gates, and the
CG_PLAYER_HASKEYownerdraw path.
Task A48: Reconstruct core cvar handling and management wiring [COMPLETED]
Priority: High
Primary areas: src/code/qcommon/cvar.c, src/code/game/q_shared.h,
tests/test_cvar_console_write_parity.py,
docs/reverse-engineering/quakelive_steam_mapping_round_293.md,
references/analysis/quakelive_symbol_aliases.json,
references/hlil/quakelive/quakelive_steam.exe/quakelive_steam.exe_hlil_split/quakelive_steam.exe_hlil_part04.txt,
references/hlil/quakelive/quakelive_steam.exe/quakelive_steam.exe_hlil_split/quakelive_steam.exe_hlil_part06.txt
Parity estimate: before 92% -> after 97% for scoped core cvar
handling/management and source-visible WebView cvar-change wiring. Repo-wide
remains 98% pending the active compatibility-only and runtime-evidence
gaps.
Completed work:
- Rechecked retail
Cvar_Set2,Cvar_Get,Cvar_GetBounded, andQLWebView_PublishCvarChangeownership against the committed alias ledger and HLIL/string evidence. - Restored the retail
2048static cvar slot cap, added the recoveredCVAR_GAMERULEflag, and reconstructed the initialization-time GAMERULE consolesetrefusal gate. - Added retail cvar flag conflict cleanup for
CVAR_CHEATcombined with archive or replicated/protected flags, including the recovered warning strings. - Reconstructed the missing
Cvar_Set2publish call sites for user-created cvars and latched values while preserving the retail console write guard surface of ROM, INIT, LATCH, and CHEAT only. - Added mapping round 293 and focused regression coverage for the cvar core
wiring, while leaving the repo-owned
sets,setu, andsetcloudcompatibility helpers intact. - Verification:
python -m pytest tests/test_cvar_console_write_parity.py tests/test_client_config_parity.py tests/test_engine_command_parity.py -q --tb=short->24 passed;python -m pytest tests/test_qcommon_full_parity_gate.py -q --tb=short->2 passed, 1 skipped. A broadertests/test_engine_cvar_retail_parity.py tests/test_qcommon_full_parity_gate.pyrun reached this cvar work but still failed two unrelated existing platform/Steam-service string checks.
Task A47: Active-client pmove and playerState wiring reconstruction [COMPLETED]
Priority: High
Primary areas: src/code/game/g_main.c, src/code/game/g_active.c,
src/code/game/g_local.h, tests/test_game_active_pmove_wiring_parity.py,
docs/reverse-engineering/qagame-mapping.md
Parity estimate: before 99% -> after 100% for the scoped qagame
frame-step-to-ClientThink_real movement wiring edge. The broader shared
pmove/playerState reconstruction remains 100% after this source-level
call-site realignment and guard expansion.
Completed work:
- Rechecked qagame mappings for
G_RunFrame,ClientThink_real,SpectatorThink,ClientImpacts,G_TouchTriggers,SendPendingPredictableEvents, and related active-client movement wiring. - Reconstructed the frame entity-loop client slot so bot/synchronous client
frames run scheduled thinks inline and dispatch directly to
ClientThink_real, matching the recovered retailG_RunFrameshape instead of routing that call-site through the classic sourceG_RunClientwrapper. - Added
ClientThink_realto the game-local prototype surface so the recovered direct frame-loop dispatch is explicit and compile-visible. - Added focused structural coverage for the full active-client pmove wiring:
command-time clamping, spectator scoreboard
PMF_NO_MOVE, pmove setup, tracemask selection, fixed-move transport, playerState-to-entityState projection, predictable-event flushing, trigger touch, client impacts, respawn checks, timer actions, and committed symbol-map evidence. - Verification:
python -m pytest tests/test_game_active_pmove_wiring_parity.py -q --tb=short->4 passed;python -m pytest tests/test_game_active_pmove_wiring_parity.py tests/test_game_helper_seam_parity.py tests/test_game_spectator_connection_parity.py -q --tb=short->30 passed;python -m pytest tests/test_game_active_pmove_wiring_parity.py tests/test_pmove_validation_fixtures.py tests/test_pmove_air_control_runtime_parity.py tests/test_pmove_jump_timing_parity.py tests/test_pmove_movement_fixtures.py tests/test_pmove_helper_parity.py tests/test_pmove_acceleration_scope_parity.py tests/test_pmove_crouch_time_parity.py tests/test_pmove_crouch_slide_friction_parity.py tests/test_pmove_reload_fallback_parity.py tests/test_pmove_water_scale_parity.py tests/test_bg_playerstate_bridge_parity.py tests/test_cgame_playerstate_transition_parity.py tests/test_playerstate_replication.py tools/tests/test_pmove_settings_configstring.py tests/test_pmove_selected_cvar_parity.py -q --tb=short->162 passed, 107 subtests passed;python -m pytest tests/test_game_module_retail_parity_gate.py tests/test_qcommon_full_parity_gate.py -q --tb=short->4 passed, 2 skipped.
Task A46: Re-audit sixth focused retail cl_* cvar parity tranche [COMPLETED]
Priority: Medium
Primary areas: src/code/client/cl_main.c,
src/common/platform/platform_services.c,
tests/test_engine_cvar_retail_parity.py, docs/client_cvars.md,
references/hlil/quakelive/quakelive_steam.exe/quakelive_steam.exe_hlil_split/quakelive_steam.exe_hlil_part04.txt,
references/reverse-engineering/ghidra/quakelive_steam/decompile_top_functions.c
Parity estimate: before 100% -> after 100% for the scoped ten-cvar
service-disclosure tranche: cl_onlineServicesMode,
cl_onlineServicesPolicy, cl_onlineServicesParityScope,
cl_onlineServicesParityReason, cl_identityBootstrapMode,
cl_identityBootstrapPolicy, cl_voiceServiceMode,
cl_voiceServicePolicy, cl_workshopProvider, and cl_workshopPolicy.
These are intentional non-retail ROM diagnostics for the documented
online-services divergence; no production source patch was required. Repo-wide
remains 98% pending the active portability/runtime-evidence gaps.
Completed work:
- Rechecked the selected
cl_*service-disclosure cvars against the repository's online-services divergence policy: default disabled or unclassified values,CVAR_ROMflags, and refresh throughCL_RefreshPlatformServiceCvars. - Confirmed the active labels are sourced from the platform-services descriptor helpers and workshop descriptor helpers rather than being hardcoded as live-service state.
- Confirmed no selected disclosure cvar appears in the recovered retail
CL_InitHLIL/Ghidra evidence, keeping this compatibility surface outside the strict retail cvar slab. - Added a focused regression test that pins the defaults, flags, refresh wiring, descriptor ownership, and retail-evidence absence for all ten cvars.
- Refreshed
docs/client_cvars.mdwith the sixth focused cvar-tranche note. - Verification:
python -m pytest tests/test_engine_cvar_retail_parity.py::test_engine_cvar_thirtyninth_client_service_disclosure_tranche_matches_guarded_retail_divergence_contracts -q->1 passed.
Task A45: Re-audit fifth focused retail cl_* cvar parity tranche [COMPLETED]
Priority: Medium
Primary areas: src/code/client/cl_main.c, src/code/client/cl_input.c,
src/code/client/cl_parse.c, src/code/ui/ui_main.c,
tests/test_engine_cvar_retail_parity.py, docs/client_cvars.md,
references/hlil/quakelive/quakelive_steam.exe/quakelive_steam.exe_hlil_split/quakelive_steam.exe_hlil_part04.txt,
references/hlil/quakelive/uix86.all/uix86.dll_hlil_split/uix86.dll_hlil_part01.txt,
references/reverse-engineering/ghidra/quakelive_steam/decompile_top_functions.c,
references/reverse-engineering/ghidra/uix86/decompile_top_functions.c
Parity estimate: before 100% -> after 100% for the scoped ten-cvar
native-UI bridge tranche: cl_maxpackets, cl_packetdup,
cl_serverStatusResendTime, cl_maxPing, cl_motdString,
cl_downloadItem, cl_downloadName, cl_downloadTime,
cl_downloadCount, and cl_downloadSize. No production source patch was
required; this pass refreshed and pinned the retail/native UI evidence.
Repo-wide remains 98% pending the active portability/runtime-evidence gaps.
Completed work:
- Rechecked retail registration/default/flag evidence for the selected engine-owned cvars against the committed Quake Live HLIL/Ghidra corpus.
- Confirmed native
uix86bridge behavior for network preset writes, server-status resend publication, max-ping filtering reads, MOTD reads, and workshop progress reads. - Confirmed
cl_downloadCount/cl_downloadSizeremain UI-facing temp fallbacks for legacy download/QVM paths while the recovered native progress bridge stays keyed bycl_downloadItemplusGetItemDownloadInfoandcl_downloadTime. - Added a focused regression test that pins the retail evidence, source-visible registrations, flags, and wiring for all ten cvars.
- Refreshed
docs/client_cvars.mdwith the fifth focused cvar-tranche note. - Verification:
python -m pytest tests/test_engine_cvar_retail_parity.py::test_engine_cvar_sixth_client_tranche_matches_retail_contracts tests/test_engine_cvar_retail_parity.py::test_engine_cvar_thirtyfourth_client_cl_tranche_matches_retail_contracts tests/test_engine_cvar_retail_parity.py::test_engine_cvar_thirtyseventh_client_lifecycle_workshop_tranche_matches_retail_contracts tests/test_engine_cvar_retail_parity.py::test_engine_cvar_thirtyeighth_client_native_ui_bridge_tranche_matches_retail_contracts tests/test_ui_menu_files.py::test_ui_retail_download_info_reads_item_progress_through_native_slot -q->5 passed. Broader workshop/platform-service verification was not runnable in this worktree becausetests/test_client_workshop_bootstrap_parity.pyandtests/test_platform_services.pycurrently fail collection on unrelated indentation errors before the selected tests can execute.
Task A44: Profile and utility pmove/playerState wiring sweep [COMPLETED]
Priority: High
Primary areas: src/code/game/g_pmove.c, src/code/game/bg_pmove.c,
src/code/cgame/cg_servercmds.c, src/game/g_config.c,
src/code/game/g_main.c, tests/test_pmove_selected_cvar_parity.py,
docs/reverse-engineering/qagame-mapping.md,
docs/reverse-engineering/cgame-bg-parity-implementation-plan.md
Parity estimate: before 100% -> after 100% for scoped shared pmove,
playerState profile flag ownership, utility cvar transport, and
custom-settings wiring. Production source was already aligned with the
committed retail evidence; this pass added regression coverage for the
remaining profile/utility movement slab.
Completed work:
- Rechecked the remaining profile and utility
pmove_*fields against the retail qagame cvar slab and shared cgame/qagame movement consumers:pmove_AirStepFriction,pmove_AirSteps,pmove_BunnyHop,pmove_CrouchSlide,pmove_CrouchSlideFriction,pmove_CrouchSlideTime,pmove_CrouchStepJump,pmove_DoubleJump,pmove_noPlayerClip,pmove_StepHeight,pmove_StepJump,pmove_velocity_gh,pmove_WaterSwimScale,pmove_WaterWadeScale,pmove_WeaponDropTime, andpmove_WeaponRaiseTime. - Expanded
tests/test_pmove_selected_cvar_parity.pyso this cvar group is pinned from retail registration defaults/flags through factory reset, refresh callback/no-callback ownership,g_pmoveSettingscache assignment, compact and JSON cgame parsing, default shared movement constants, and active movement consumers. - Added coverage for the linked playerState and wiring edges: spawn-time
PMF_CROUCH_SLIDE/PMF_DOUBLE_JUMP/PMF_AIR_CONTROLseeding, crouch-slide friction/timer consumption, no-player-clip tracemask removal, step/crouch-step gates, water/step globals, grapple pull speed, weapon raise/drop timings, and custom-settings mask participation. - Refreshed the qagame and cgame/bg mapping notes with the new evidence lane.
- Verification:
python -m pytest tests/test_pmove_selected_cvar_parity.py -q --tb=short->12 passed;python -m pytest tests/test_pmove_validation_fixtures.py tests/test_pmove_air_control_runtime_parity.py tests/test_pmove_jump_timing_parity.py tests/test_pmove_movement_fixtures.py tests/test_pmove_helper_parity.py tests/test_pmove_acceleration_scope_parity.py tests/test_pmove_crouch_time_parity.py tests/test_pmove_crouch_slide_friction_parity.py tests/test_pmove_reload_fallback_parity.py tests/test_pmove_water_scale_parity.py tests/test_bg_playerstate_bridge_parity.py tests/test_cgame_playerstate_transition_parity.py tests/test_playerstate_replication.py tools/tests/test_pmove_settings_configstring.py tests/test_pmove_selected_cvar_parity.py -q --tb=short->158 passed, 107 subtests passed;python -m pytest tests/test_game_module_retail_parity_gate.py tests/test_qcommon_full_parity_gate.py -q --tb=short->4 passed, 2 skipped.
Task A43: Re-audit fourth focused retail cl_* cvar parity tranche [COMPLETED]
Priority: Medium
Primary areas: src/code/client/cl_main.c, src/code/client/cl_input.c,
src/code/client/cl_parse.c, src/code/client/cl_cgame.c,
src/code/client/cl_scrn.c, src/code/client/cl_ui.c,
src/code/qcommon/common.c, src/code/qcommon/cmd.c,
src/code/ui/ui_main.c, tests/test_engine_cvar_retail_parity.py,
docs/client_cvars.md,
references/hlil/quakelive/quakelive_steam.exe/quakelive_steam.exe_hlil_split/quakelive_steam.exe_hlil_part04.txt,
references/hlil/quakelive/uix86.all/uix86.dll_hlil_split/uix86.dll_hlil_part01.txt,
references/reverse-engineering/ghidra/quakelive_steam/decompile_top_functions.c,
references/reverse-engineering/ghidra/uix86/decompile_top_functions.c
Parity estimate: before 100% -> after 100% for the scoped ten-cvar
lifecycle/MOTD/workshop tranche: cl_motd, cl_motdString,
cl_timeout, cl_nodelta, cl_debugMove, cl_paused, cl_running,
cl_downloadItem, cl_downloadName, and cl_downloadTime. The selected
cvar registrations and source-visible owners were already aligned; the
expanded workshop verification found and fixed one adjacent callback diagnostic
string drift, bringing the scoped workshop handoff evidence from 99% -> 100%.
Repo-wide remains 98% pending the active portability/runtime-evidence gaps.
Completed work:
- Rechecked retail registration/default/flag evidence for the selected
CL_Init,CL_InitInput, and common runtimecl_*cvars against the committed HLIL/Ghidra corpus. - Confirmed source-visible owners already match retail: MOTD enable/ROM string publication, timeout disconnect checks, delta suppression, movement diagnostics, paused/running ROM state and command routing.
- Confirmed the retained workshop request cvars stay aligned with the
recovered retail/uix86 handoff:
cl_downloadItem,cl_downloadName, andcl_downloadTimeare seeded from the request owner and consumed by the native UI progress bridge. - Restored the retail
ItemInstalled_tinvalid-app diagnostic string, which reuses the recoveredOnDownloadItemResult skip, invalid app id %dtext. - Added a focused regression test that pins the retail evidence, source registrations, and source-visible wiring for all ten cvars.
- Refreshed
docs/client_cvars.mdwith the fourth focused cvar-tranche note. - Verification:
python -m pytest tests/test_engine_cvar_retail_parity.py::test_engine_cvar_sixth_client_tranche_matches_retail_contracts tests/test_engine_cvar_retail_parity.py::test_engine_cvar_seventh_client_tranche_matches_retail_contracts tests/test_engine_cvar_retail_parity.py::test_engine_cvar_twentieth_client_debug_tranche_matches_retail_contracts tests/test_engine_cvar_retail_parity.py::test_engine_cvar_thirtyseventh_client_lifecycle_workshop_tranche_matches_retail_contracts tests/test_client_workshop_bootstrap_parity.py -q->8 passed.
Task A42: Deep pmove/playerState mapping sweep [COMPLETED]
Priority: High
Primary areas: src/code/game/bg_pmove.c, src/code/game/g_pmove.c,
src/code/cgame/cg_servercmds.c, src/code/game/bg_public.h,
tests/pmove_validation_harness.c,
tests/test_pmove_validation_fixtures.py,
tests/test_pmove_selected_cvar_parity.py,
tests/test_pmove_helper_parity.py, tests/test_playerstate_replication.py,
references/symbol-maps/qagame.json, references/symbol-maps/cgame.json,
docs/reverse-engineering/qagame-mapping.md,
docs/reverse-engineering/cgame-bg-parity-implementation-plan.md
Parity estimate: before 100% -> after 100% for scoped shared pmove,
playerState command-gate management, pmove cvar transport, and qagame/cgame
prediction wiring. No production source patch was required; this pass added
retail-backed fixture and mapping coverage for the fragile remaining edges.
Completed work:
- Rechecked qagame/cgame
PmoveSinglesymbol evidence for the playerState command gate: command time advances beforePMF_NO_MOVE, while view-angle updates, command mirrors, trace dispatch, and movement side effects remain behind the no-move return. - Added an executable
PMF_NO_MOVEfixture intests/pmove_validation_harness.candtests/test_pmove_validation_fixtures.pyto pin that runtime behavior. - Validated the selected pmove cvar mapping sentinel, covering representative
pmove_*retail names across registration defaults/flags, factory reset, refresh callback ownership, cached settings, compact/JSON cgame parsing, default shared movement constants, activebg_pmove.cconsumers, and committed symbol-map evidence. - Re-ran the broad movement/playerState suite:
python -m pytest tests/test_pmove_validation_fixtures.py tests/test_pmove_air_control_runtime_parity.py tests/test_pmove_jump_timing_parity.py tests/test_pmove_movement_fixtures.py tests/test_pmove_helper_parity.py tests/test_pmove_acceleration_scope_parity.py tests/test_pmove_crouch_time_parity.py tests/test_pmove_crouch_slide_friction_parity.py tests/test_pmove_reload_fallback_parity.py tests/test_pmove_water_scale_parity.py tests/test_bg_playerstate_bridge_parity.py tests/test_cgame_playerstate_transition_parity.py tests/test_playerstate_replication.py tools/tests/test_pmove_settings_configstring.py tests/test_pmove_selected_cvar_parity.py -q --tb=short->154 passed, 107 subtests passed.
Task A41: Re-audit third focused retail cl_* cvar parity tranche [COMPLETED]
Priority: Medium
Primary areas: src/code/client/cl_main.c, src/code/client/cl_input.c,
src/code/client/cl_parse.c, src/code/qcommon/msg.c,
tests/test_engine_cvar_retail_parity.py, docs/client_cvars.md,
references/hlil/quakelive/quakelive_steam.exe/quakelive_steam.exe_hlil_split/quakelive_steam.exe_hlil_part04.txt,
references/reverse-engineering/ghidra/quakelive_steam/decompile_top_functions.c
Parity estimate: before 100% -> after 100% for the scoped ten-cvar
debug/identity/mouse tranche: cl_shownet, cl_showSend,
cl_anonymous, cl_platform, cl_maxPing, cl_mouseAccel,
cl_mouseAccelDebug, cl_mouseAccelOffset, cl_mouseAccelPower, and
cl_mouseSensCap. No source patch was required; this pass refreshed and
pinned the retail evidence. Repo-wide remains 98% pending the active
portability/runtime-evidence gaps.
Completed work:
- Rechecked retail
CL_Initdefault values and flags against the committed HLIL/Ghidra evidence for the ten selected client cvars. - Confirmed the current source already matches the source-visible retail owners: network/message debug printing, packet-send diagnostics, anonymous auth userinfo, platform ROM marker publication, max-ping timeout filtering, mouse acceleration math, mouse acceleration debug logging, and sensitivity cap behavior.
- Added a focused regression test that pins the retail evidence, source registrations, and source-visible wiring for all ten cvars.
- Refreshed
docs/client_cvars.mdwith the third focused cvar-tranche note. - Verification:
python -m pytest tests/test_engine_cvar_retail_parity.py::test_engine_cvar_thirtysixth_client_debug_identity_tranche_matches_retail_contracts -q->1 passed.
Task A40: Re-audit second focused retail cl_* cvar parity tranche [COMPLETED]
Priority: Medium
Primary areas: src/code/client/cl_main.c, src/code/client/cl_input.c,
tests/test_engine_cvar_retail_parity.py, docs/client_cvars.md,
references/hlil/quakelive/quakelive_steam.exe/quakelive_steam.exe_hlil_split/quakelive_steam.exe_hlil_part04.txt,
references/reverse-engineering/ghidra/quakelive_steam/decompile_top_functions.c
Parity estimate: before 100% -> after 100% for the scoped ten-cvar
demo/input tranche: cl_avidemo, cl_avidemo_latch,
cl_avidemo_mintime, cl_avidemo_maxtime, cl_forceavidemo,
cl_anglespeedkey, cl_yawspeed, cl_pitchspeed, cl_run, and
cl_freelook. No source patch was required; this pass refreshed and pinned
the retail evidence. Repo-wide remains 98% pending the active
portability/runtime-evidence gaps.
Completed work:
- Rechecked retail
CL_Initdefault values and flags against the committed HLIL/Ghidra evidence for the ten selected client demo/input cvars. - Confirmed the current source already matches the source-visible retail owners: avidemo latch/start/stop/screenshot/fixed-msec handling, keyboard and joystick angle-speed scaling, run/walk move-speed selection, and freelook center-view/mouse-pitch gating.
- Added a focused regression test that pins the retail evidence, source registrations, and source-visible wiring for all ten cvars.
- Refreshed
docs/client_cvars.mdwith the second focused cvar-tranche note. - Verification:
python -m pytest tests/test_engine_cvar_retail_parity.py::test_engine_cvar_thirtyfifth_client_demo_input_tranche_matches_retail_contracts -q->1 passed.
Task A39: Re-audit focused retail s_* sound cvar parity tranche [COMPLETED]
Priority: Medium
Primary areas: src/code/client/snd_dma.c,
tests/test_engine_cvar_retail_parity.py,
tests/test_client_sound_voice_parity.py,
references/hlil/quakelive/quakelive_steam.exe/quakelive_steam.exe_hlil_split/quakelive_steam.exe_hlil_part04.txt
Parity estimate: before 98% -> after 100% for the scoped ten-cvar tranche:
s_announcerVolume, s_doppler, s_initsound, s_mixahead,
s_mixPreStep, s_musicvolume, s_pvs, s_voiceVolume, s_voiceStep,
and s_volume. Repo-wide remains 98% pending the active
portability/runtime-evidence gaps.
Completed work:
- Rechecked retail
S_Initdefault values, flags, and registration order against the committed HLIL evidence for the selected sound cvars. - Realigned the retail sound-registration cluster so
s_show,s_testsound, ands_volumematch the recovered order, while the legacy source-onlys_separation/s_khzcompatibility cvars now sit outside the retail earlys_initsoundgate. - Restored the retail
S_Update_mix-ahead owner fors_mixaheadby removing the older source-onlysane/opcap;s_mixPreStepremains wired throughS_GetSoundtimeand the voice-buffer scheduler. - Expanded the focused regression guard so default value, flag set,
registration order, and source-visible wiring are pinned for the selected
cvars, including
s_pvsspatial culling ands_voiceStepvoice scheduling. - Verification:
python -m pytest tests/test_client_sound_voice_parity.py tests/test_engine_cvar_retail_parity.py::test_engine_cvar_eighteenth_sound_tranche_matches_retail_contracts -q --tb=short->9 passed.
Task A38: Re-audit focused retail cl_* cvar parity tranche [COMPLETED]
Priority: Medium
Primary areas: src/code/client/cl_keys.c, src/code/client/cl_main.c,
src/code/client/cl_input.c, src/code/client/cl_cgame.c,
src/code/client/cl_scrn.c, tests/test_engine_cvar_retail_parity.py,
docs/client_cvars.md,
references/hlil/quakelive/quakelive_steam.exe/quakelive_steam.exe_hlil_split/quakelive_steam.exe_hlil_part04.txt,
references/reverse-engineering/ghidra/quakelive_steam/decompile_top_functions.c
Parity estimate: before 96% -> after 100% for the scoped ten-cvar tranche:
cl_allowConsoleChat, cl_demoRecordMessage, cl_freezeDemo,
cl_maxpackets, cl_packetdup, cl_timeNudge, cl_autoTimeNudge,
cl_quitOnDemoCompleted, cl_serverStatusResendTime, and
cl_showTimeDelta. Repo-wide remains 98% pending the active
portability/runtime-evidence gaps.
Completed work:
- Rechecked retail
CL_Initdefault values and flags against the committed HLIL/Ghidra evidence for the ten selected client cvars. - Restored the retail
cl_allowConsoleChatconsole-enter owner so bare console text is forced to command form unless that cvar explicitly enables console chat. - Added a focused regression test that pins the retail evidence, source registrations, and source-visible wiring for all ten cvars.
- Refreshed
docs/client_cvars.mdwith the scoped cvar-tranche evidence note. - Verification:
python -m pytest tests/test_engine_cvar_retail_parity.py::test_engine_cvar_second_tranche_matches_retail_contracts tests/test_engine_cvar_retail_parity.py::test_engine_cvar_sixth_client_tranche_matches_retail_contracts tests/test_engine_cvar_retail_parity.py::test_engine_cvar_seventh_client_tranche_matches_retail_contracts tests/test_engine_cvar_retail_parity.py::test_engine_cvar_eighth_client_input_tranche_matches_retail_contracts tests/test_engine_cvar_retail_parity.py::test_engine_cvar_ninth_client_misc_tranche_matches_retail_contracts tests/test_engine_cvar_retail_parity.py::test_engine_cvar_twentieth_client_debug_tranche_matches_retail_contracts tests/test_engine_cvar_retail_parity.py::test_engine_cvar_thirtyfourth_client_cl_tranche_matches_retail_contracts -q->7 passed.
Task A37: Re-audit pmove factory wiring [COMPLETED]
Priority: High
Primary areas: src/code/game/g_pmove.c, src/code/game/g_factory.c,
src/game/g_config.c, src/code/game/g_main.c,
src/code/cgame/cg_servercmds.c,
tools/tests/test_pmove_settings_configstring.py,
tests/test_game_factory_regen_parity.py,
tests/test_game_weapon_parity.py, tests/test_ui_menu_files.py,
tests/test_cgame_displaycontext_parity.py,
references/hlil/quakelive/qagamex86.dll/qagamex86.dll.bndb_hlil.txt,
references/symbol-maps/qagame.json,
docs/reverse-engineering/qagame-mapping.md
Parity estimate: before 100% -> after 100% for scoped pmove factory
cvar registration, factory reset/apply ordering, cached movement-settings
refresh, custom-settings mask participation, and cgame/UI publication wiring.
Completed work:
- Rechecked the 36-entry retail
pmove_*cvar slab at0x1008F7C4..0x1008FB20against the current splitg_pmove.cowner: default strings, flag groups, callback/no-callback slots, reset defaults, cache fields, and minimum-positive clamps still match the committed HLIL and symbol-map evidence. - Rechecked factory selection flow:
Factory_Applyresets gameplay config and pmove-owned factory surfaces before overrides, refreshes all VM cvars, updates config mirrors, and only then rebuilds weapon/reload/knockback/ammo and match-factory mirrors.G_UpdateWeaponReloadConfigstill pushes reload overrides into the pmove cache and forces a pmove settings refresh. - Rechecked custom-settings ownership: air-control, ramp-jump, physics,
weapon-switching, no-player-clip, instagib, quad-hog, and grappling-hook
bits still mirror the retail
G_UpdateCustomSettingsMaskForCvargrouping whilepmove_velocity_ghremains distinct from projectileg_velocity_gh. - Added a focused regression guard in
tests/test_game_factory_regen_parity.pyto pin the factory null/active reset sequence, post-override refresh order, and reload-to-pmove handoff. - Re-ran the focused wiring suite:
python -m pytest tools/tests/test_pmove_settings_configstring.py tests/test_game_factory_regen_parity.py tests/test_game_weapon_parity.py::test_grappling_hook_full_server_and_cgame_wiring_matches_retail tests/test_ui_menu_files.py::test_ui_retail_server_settings_ownerdraw_restored tests/test_ui_menu_files.py::test_game_retail_weapon_reload_configstring_restored tests/test_cgame_displaycontext_parity.py::test_cgame_weapon_reload_configstring_bridge_restored tests/test_cgame_displaycontext_parity.py::test_cgame_server_settings_panel_reconstruction_uses_retail_custom_setting_configstrings -q --tb=short->32 passed, 107 subtests passed.
Task A36: Re-audit player movement, player states, and shared wiring [COMPLETED]
Priority: High
Primary areas: src/code/game/bg_pmove.c, src/code/game/bg_slidemove.c,
src/code/game/q_shared.h, src/code/qcommon/msg.c,
src/code/game/g_pmove.c, src/code/cgame/cg_servercmds.c,
tests/test_pmove_*.py, tests/test_playerstate_replication.py,
references/symbol-maps/qagame.json,
references/symbol-maps/cgame.json,
docs/reverse-engineering/cgame-bg-parity-implementation-plan.md
Parity estimate: before 100% -> after 100% for scoped player movement,
playerState layout/replication, pmove settings transport, and cgame/qagame
prediction wiring. No source patch was required; this pass refreshed the
evidence that the existing retail reconstruction remains intact.
Completed work:
- Rechecked the current source against the committed pmove/playerState mapping notes and symbol-map evidence for the shared qagame/cgame movement island.
- Confirmed the retail playerState prefix remains intact, including
clientNumat0x88,locationat0x8c,weaponPrimary,fov,crouchSlideTime, and the signed command-byte mirrors at0x1dc..0x1de. - Confirmed qcommon still delta-replicates the playerState command mirrors, holdable timer stats, movement flags, and jump/crouch timing fields used by retail prediction and demo/HUD consumers.
- Confirmed qagame still publishes the compact retail pmove settings stream,
cgame parses the 33-token retail core plus bounded reconstruction extension,
and
PmoveSingleconsumes the server-seeded movement-profile flags rather than mutating them locally. - Re-ran the focused movement/playerState suites:
python -m pytest tests/test_pmove_validation_fixtures.py tests/test_pmove_air_control_runtime_parity.py tests/test_pmove_jump_timing_parity.py tests/test_pmove_movement_fixtures.py tests/test_pmove_helper_parity.py tests/test_pmove_acceleration_scope_parity.py tests/test_pmove_crouch_time_parity.py tests/test_pmove_crouch_slide_friction_parity.py tests/test_pmove_reload_fallback_parity.py tests/test_pmove_water_scale_parity.py tests/test_bg_playerstate_bridge_parity.py tests/test_cgame_playerstate_transition_parity.py tests/test_playerstate_replication.py tools/tests/test_pmove_settings_configstring.py -q --tb=short->145 passed, 107 subtests passed. - Re-ran the shared projection and strict gate sentinels:
python -m pytest tests/test_bg_misc_validation_fixtures.py tests/test_bg_misc_runtime_parity.py tests/test_bg_misc_helper_parity.py -q --tb=short->39 passed;python -m pytest tests/test_game_module_retail_parity_gate.py tests/test_qcommon_full_parity_gate.py -q --tb=short->4 passed, 2 skipped.
Task A33: Audit retail UI feeder parity and wiring [COMPLETED]
Priority: High
Primary areas: src/code/ui/ui_main.c, src/code/cgame/cg_main.c,
src/ui/*.menu (read-only evidence), references/hlil/quakelive/uix86.all/,
references/symbol-maps/ui.json, tests/test_ui_menu_files.py,
tests/test_cgame_displaycontext_parity.py
Parity estimate: before 86% -> after 100% for scoped feeder ownership and
callback wiring after the retail matrix, player-model feeder repair, and
cgame scoreboard-family verification. Repo-wide remains 98% pending the
active portability/runtime-evidence gaps.
Feeder queue:
- Establish ownership buckets for the 0x00-0x13 Quake Live feeder ids:
UI-owned listboxes, cgame-owned scoreboard/team listboxes, and dormant
FEEDER_CLANS. - Verify UI-owned callbacks for
FEEDER_HEADS,FEEDER_MAPS,FEEDER_SERVERS,FEEDER_ALLMAPS,FEEDER_PLAYER_LIST,FEEDER_TEAM_LIST,FEEDER_MODS,FEEDER_DEMOS,FEEDER_Q3HEADS,FEEDER_SERVERSTATUS,FEEDER_FINDPLAYER,FEEDER_CINEMATICS, andFEEDER_CVMAPS. - Verify cgame-owned callbacks for
FEEDER_REDTEAM_LIST,FEEDER_BLUETEAM_LIST,FEEDER_SCOREBOARD,FEEDER_ENDSCOREBOARD,FEEDER_REDTEAM_STATS, andFEEDER_BLUETEAM_STATS. - Keep
FEEDER_CLANSas a defined-but-dormant retail id unless new committed evidence shows an active menu, host, or browser contract. - Run focused feeder parity tests and patch any concrete mismatch surfaced by the matrix.
- Repair
FEEDER_HEADS/FEEDER_Q3HEADSto use the validated retail player-model catalog, pass listbox item cvars throughfeederSelection, and drop the non-retail PunkBuster server-browser text column from the UI feeder. - Verification:
python -m pytest tests/test_ui_menu_files.py::test_ui_retail_feeder_matrix_matches_menu_consumers_and_callback_ownership tests/test_ui_menu_files.py::test_ui_retail_feeder_leaf_callbacks_match_remaining_ui_owned_ids tests/test_ui_menu_files.py::test_ui_retail_callvote_map_feeder_uses_active_map_slab tests/test_ui_menu_files.py::test_ui_retail_clan_feeder_scaffolding_is_removed tests/test_cgame_displaycontext_parity.py::test_cgame_scoreboard_feeder_matrix_owns_all_retail_scoreboard_feeders tests/test_cgame_displaycontext_parity.py::test_cgame_scoreboard_selection_callbacks_restore_cached_team_list_menu_seam - Verification: Debug Win32
ui.vcxprojandcgamex86.vcxprojbuilds succeeded;ui.vcxprojstill reports three pre-existing C4090 warnings inUI_RunOrdersScript/UI_RunVoiceOrdersScript.
Recent closure
Task A35: Re-audit match exit rules and round-mode wiring [COMPLETED]
Priority: High
Primary areas: src/code/game/g_main.c, src/code/game/g_active.c,
src/code/game/g_team.c, src/code/game/g_local.h,
tests/test_game_exit_rules_parity.py,
tests/test_game_round_controller_helper_parity.py,
tests/test_game_attack_defend_parity.py,
references/hlil/quakelive/qagamex86.dll/,
references/symbol-maps/qagame.json,
docs/reverse-engineering/qagame-mapping.md
Parity estimate: before 96% -> after 100% for scoped match-exit rule,
intermission, Red Rover tie, Freeze fallback, and A/D plus CA/Freeze mercy
window wiring; repo-wide remains 98% pending the active
portability/runtime-evidence gaps.
Completed work:
- Rechecked qagame
ScoreIsTied,CheckExitRules,G_ADCheckExitRules,G_CAFZCheckExitRules, andG_RRCheckExitRulesagainst the committed Binary Ninja HLIL and symbol-map entries. - Restored Red Rover to the retail non-team leader-score tie path instead of the red/blue team-score tie path.
- Restored the generic Freeze exit-rule fallback gate to use
g_freezeRoundDelay, matching the retail branch inCheckExitRules. - Shared the overtime-adjusted exit-limit helper with the A/D and CA/Freeze mercy checks, and removed the source-only CA/Freeze roundlimit leader guard so the red-first/blue-second threshold order matches retail.
- Refreshed focused structural coverage for the match-exit, round-controller, and Attack and Defend helper seams.
Task A34: Restore retail spectator player-name scorebox wiring [COMPLETED]
Priority: High
Primary areas: src/code/cgame/cg_newdraw.c,
tests/test_cgame_displaycontext_parity.py,
references/symbol-maps/cgame.json,
docs/reverse-engineering/cgame-mapping.md
Parity estimate: before 88% -> after 100% for scoped cgame spectator
player-name and scorebox score ownerdraw wiring, including follow-name anchor
alignment, first/second-place configstring label ownership, fixed retail
truncation thresholds, and missing/forfeit score fallbacks; repo-wide remains
98% pending the active portability/runtime-evidence gaps.
Completed work:
- Rechecked the cgame ownerdraw corridor against the Binary Ninja HLIL for
0x10033BF0,0x10035BD0, and0x10035F30, plus the committed Ghidra switch and symbol-map entries. - Restored retail anchor alignment for
CG_FOLLOW_PLAYER_NAMEandCG_FOLLOW_PLAYER_NAME_EXinstead of centering inside the authored rect. - Routed
CG_1ST_PLYR/CG_2ND_PLYRthrough cachedCS_FIRST_PLACE_NAME/CS_SECOND_PLACE_NAMElabels, including the tournament-fallback and the fixed 140/132-pixel ellipsis truncation thresholds observed in HLIL. - Routed
CG_1ST_PLYR_SCORE/CG_2ND_PLYR_SCOREthrough cachedCS_SCORES1/CS_SCORES2values with the retail unavailable marker forSCORE_NOT_PRESENTand forfeit scores. - Refreshed cgame display-context parity coverage and reran the focused spectator/scorebox suites.
Task A32: Restore retail Flight refuel-rate registration boundary [COMPLETED]
Priority: High
Primary areas: src/code/game/g_items.c, src/code/game/g_main.c,
src/code/game/g_local.h, references/symbol-maps/qagame.json,
tests/test_game_factory_regen_parity.py
Parity estimate: before 99% -> after 100% for scoped Flight powerup
pickup/fuel timer parity; repo-wide remains 98% pending the active
portability/runtime-evidence gaps.
Completed work:
- Rechecked qagame
Pickup_Powerupat0x1004DFE0against the committed Ghidra decompile and the qagame symbol-map evidence. - Confirmed retail keeps
g_flightThrustandg_flightRefuelRateregistered for cvar/factory parity, but exposes no Flight-specific pickup multiplier. - Restored the registered
g_flightRefuelRatestorage/default while keeping directquantity * 1000timer addition for Flight fuel/refill. - Added structural coverage so Flight cannot gain a separate refuel-rate
consumer while
PM_FlyMoveremains free ofg_flightThrustmovement input.
Task A31: Restore retail spectator follow command and fallback state [COMPLETED]
Priority: High
Primary areas: src/code/game/g_cmds.c, src/code/game/g_active.c,
src/code/game/g_local.h, tests/test_game_spectator_connection_parity.py,
docs/reverse-engineering/qagame-spectator-follow-reconstruction-2026-05-22.md
Parity estimate: before 88% -> after 96% for scoped qagame spectator
follow/stop-follow command handling, HUD auto-follow command compatibility,
saved-team restoration, and missing-target fallback; repo-wide remains 98%
pending broader runtime and remaining subsystem gaps.
Completed work:
- Rechecked the qagame symbol map entries for
SpectatorThink,SpectatorClientEndFrame,StopFollowing,Cmd_Follow_f, andFollowCycle, plus the cgame symbol-map evidence for the retailfollow %d%sHUD auto-follow command shape. - Added a shared qagame spectator fallback helper that preserves the local
g_teamSpecFreeCampolicy while giving stop-follow and missing-target paths a single state transition. - Restored
StopFollowingto preservesess.sessionTeam, restoreps.persistant[PERS_TEAM]from it, resetsess.spectatorClientto the caller's own slot, clearPMF_FOLLOW, and set scoreboard flags from the fallback state. - Restored
Cmd_Follow_fplayer-string parsing and optional cgame powerup suffix tolerance. A later 2026-05-26 HLIL pass corrected the boundary:follow1andfollow2areSetTeamtokens, notCmd_Follow_ftokens. - Routed unresolved active-player follow targets, removed POIs, and invalid
explicit follow targets through
StopFollowingfromSpectatorClientEndFrame. - Added focused static parity coverage for the stop-follow, follow-command, and end-frame fallback seams.
Task A30: Restore retail scoreboard feeder dispatch and team-row selection [COMPLETED]
Priority: High
Primary areas: src/code/cgame/cg_main.c,
tests/test_cgame_displaycontext_parity.py
Parity estimate: before 94% -> after 100% for scoped scoreboard feeder
dispatch, feeder-local row mapping, selection cursor synchronization, and
invalid-row guard behavior; repo-wide remains 98% pending the active
portability/runtime-evidence gaps.
Completed work:
- Rechecked cgame
CG_FeederCount,CG_SetScoreSelection,CG_InfoFromScoreIndex,CG_FeederItemText, andCG_FeederSelectionagainst the Binary Ninja HLIL feeder block and the committed cgame symbol map. - Restored retail text-dispatch ownership: red/blue team-list feeders enter the team-list leaves, red/blue stats feeders enter the rich stats leaves, and all other text feeder requests fall back to the race or normal scoreboard leaf instead of being misrouted through team-list fallbacks.
- Restored explicit team-local row mapping for team scoreboard cursors while
keeping
cg.selectedScoreas the absolutecg.scoresrow used by cgame. - Hardened score-row lookup so invalid feeder rows return no row context
instead of indexing past
cg.scores. - Updated cgame display-context parity tests and reran the focused scoreboard suite.
Task A29: Restore retail pmove_* cvar registration and callback wiring [COMPLETED]
Priority: High
Primary areas: src/code/game/g_pmove.c, src/code/game/g_main.c,
src/game/g_config.c, tools/tests/test_pmove_settings_configstring.py,
tests/test_game_factory_regen_parity.py,
references/symbol-maps/qagame.json,
docs/reverse-engineering/qagame-mapping.md,
docs/reverse-engineering/cgame-bg-parity-implementation-plan.md
Parity estimate: before 92% -> after 100% for scoped pmove_* cvar
default, flag, callback, cache, and transport wiring; repo-wide remains
98% pending the active portability/runtime-evidence gaps.
Completed work:
- Rechecked the qagame cvar-table slab at
0x1008F7C4..0x1008FB20, confirming the 36 retailpmove_*names, default strings, and four observed registration flag groups. - Restored those high-bit retail flags in the split
g_pmove.cregistration owner instead of registering every pmove cvar with flag0. - Revalidated the surrounding cache, custom-setting, configstring, and cgame compact-parser wiring; no payload order change was needed.
- Added structural coverage that pins each
pmove_*registration's default and flag group against the recovered retail table. - Reconstructed the retail callback-backed update path for the pmove cvar
slab: all callback-backed entries now update through named mirrors and the
three callback-less profile toggles (
pmove_AirControl,pmove_CrouchSlide, andpmove_DoubleJump) remain suppressed just like the retail table. - Restored the cached lower-bound behavior observed in
G_InitPublishedCvarStateand the pmove callbacks:pmove_velocity_gh,pmove_JumpVelocityTimeThreshold, andpmove_JumpVelocityTimeThresholdOffsetnow clamp to retail's0.001minimum before publication. - Rechecked the adjacent grapple-speed ownership: retail
PM_GrappleMovereads the dedicatedpmove_velocity_ghcache, whileg_velocity_ghremains a separate projectile-speed cvar with the recovered1800default. Source now keeps those paths decoupled and updates the grappling-hook custom-settings comparison accordingly. - Re-ran the full-name
pmove_*sweep and classifiedpmove_fixed/pmove_msecas legacy fixed-timestep controls outside the 36-entry QL factory-managed tuning slab. Coverage now pins their0/8defaults, server-sideCVAR_SYSTEMINFOregistration, cgame mirrors,8..33clamp, and sharedPmovechunking behavior.
Task A28: Re-audit retail step/crouch-step/chain-jump takeoff wiring [COMPLETED]
Priority: High
Primary areas: src/code/game/bg_pmove.c,
references/symbol-maps/qagame.json,
references/symbol-maps/cgame.json,
docs/reverse-engineering/qagame-mapping.md,
docs/reverse-engineering/cgame-mapping.md,
docs/reverse-engineering/cgame-bg-parity-implementation-plan.md,
tests/test_pmove_helper_parity.py,
tests/test_pmove_movement_fixtures.py
Parity estimate: before 91% -> after 100% for scoped crouch-step,
step-jump, and chain-jump takeoff wiring; repo-wide remains 98%
pending the active portability/runtime-evidence gaps.
Completed work:
- Rechecked qagame
PM_StepSlideMoveat0x1002EFE0, cgamePM_StepSlideMoveat0x100034B0, and the shared qagame/cgamePM_ApplyJumpTakeoffleaves at0x1002E2C0/0x10002790. - Restored the missing normal step-jump takeoff latch so the normal path
selects
pmove_StepJumpVelocityin the additive retail branches, while the crouch-step fallback continues to usepmove_ChainJumpVelocityand raises only the ramp-suppression latch. - Corrected chain-jump mode wiring so PMF_AIR_CONTROL overrides disabled
pmove_ChainJumpmode0, the post-offset air-control addend divides by the retail offset threshold, and max clamping applies after additive and ramp-accumulated takeoff velocity. - Added executable fixtures that pin mode
0air-control override, late-window air-control edge values, normal step additive takeoff, crouch-step chain-additive takeoff, step-jump scale-mode takeoff, step-jump air-control edge profiles, and non-ramp max clamping.
Task A27: Pin pmove command/vector math helper contracts [COMPLETED]
Priority: High
Primary areas: tests/test_pmove_movement_fixtures.py,
tests/test_pmove_helper_parity.py,
references/symbol-maps/qagame.json, references/symbol-maps/cgame.json,
docs/reverse-engineering/qagame-mapping.md,
docs/reverse-engineering/cgame-mapping.md,
docs/reverse-engineering/cgame-bg-parity-implementation-plan.md
Parity estimate: before 95% -> after 100% for scoped executable evidence
coverage of the retail PM_ClipVelocity, PM_Accelerate, PM_CmdScale, and
PM_SetMovementDir math helpers; repo-wide remains 98% pending the active
portability/runtime-evidence gaps.
Completed work:
- Rechecked qagame
PM_ClipVelocity,PM_Accelerate,PM_CmdScale, andPM_SetMovementDiragainst the cgame twins and the shared source helpers reached by walk, air, water, ladder, fly, and noclip movement. - Added executable fixtures for overbounce clip branches, acceleration clamp and overspeed no-op behavior, zero/axial/2D-diagonal/3D-diagonal command scaling, and the full movementDir 0..7 ring plus idle side-strafe snaps.
- Updated structural tests, symbol-map comments, and mapping notes so the command/vector layer beneath the movement leaves is source-validated.
Task A26: Pin low-level pmove animation helper gates [COMPLETED]
Priority: High
Primary areas: tests/test_pmove_movement_fixtures.py,
tests/test_pmove_helper_parity.py,
references/symbol-maps/qagame.json, references/symbol-maps/cgame.json,
docs/reverse-engineering/qagame-mapping.md,
docs/reverse-engineering/cgame-mapping.md,
docs/reverse-engineering/cgame-bg-parity-implementation-plan.md
Parity estimate: before 96% -> after 100% for scoped executable evidence
coverage of the retail low-level pmove animation start/continue/force gates;
repo-wide remains 98% pending the active portability/runtime-evidence gaps.
Completed work:
- Rechecked qagame
PM_StartTorsoAnim,PM_ContinueLegsAnim, andPM_ForceLegsAnimagainst the cgame twins plus the source-localPM_StartLegsAnim/PM_ContinueTorsoAnimcall chain they expose. - Added executable fixtures for torso toggle-bit writes,
PM_DEADsuppression, legs high-priority timer no-ops, current-animation no-ops, torso high-priority timer no-ops, and thePM_ForceLegsAnimtimer-clear behavior before the live/dead start gate. - Updated structural tests, symbol-map comments, and mapping notes so the animation helpers beneath jump, footstep, weapon, and gesture paths are source-validated.
Task A25: Pin PM_AddEvent and PM_AddTouchEnt queue wiring [COMPLETED]
Priority: High
Primary areas: tests/test_pmove_movement_fixtures.py,
tests/test_pmove_helper_parity.py,
references/symbol-maps/qagame.json, references/symbol-maps/cgame.json,
docs/reverse-engineering/qagame-mapping.md,
docs/reverse-engineering/cgame-mapping.md,
docs/reverse-engineering/cgame-bg-parity-implementation-plan.md
Parity estimate: before 97% -> after 100% for scoped executable evidence
coverage of the retail pmove predictable-event and touch-entity queue helpers;
repo-wide remains 98% pending the active portability/runtime-evidence gaps.
Completed work:
- Rechecked qagame
PM_AddEvent/PM_AddTouchEntat0x1002DAF0/0x1002DB20, cgamePM_AddEvent/PM_AddTouchEntat0x10001FC0/0x10001FF0, and their downstream use from trace/event leaves. - Added executable pmove fixtures for the predictable-event two-slot wrap with
zero event parms and for the touch accumulator's
ENTITYNUM_WORLD, duplicate-suppression, andMAXTOUCHcap gates. - Updated structural tests, symbol-map comments, and mapping notes so the low-level queues behind ground contacts, weapon events, water events, and prediction are source-validated.
Task A24: Pin PM_DropTimers misc and animation timer decay [COMPLETED]
Priority: High
Primary areas: tests/test_pmove_movement_fixtures.py,
tests/test_pmove_helper_parity.py,
references/symbol-maps/qagame.json, references/symbol-maps/cgame.json,
docs/reverse-engineering/qagame-mapping.md,
docs/reverse-engineering/cgame-mapping.md,
docs/reverse-engineering/cgame-bg-parity-implementation-plan.md
Parity estimate: before 96% -> after 100% for scoped executable evidence
coverage of the retail PM_DropTimers misc-time, animation-timer, and
crouch-slide decay behavior; repo-wide remains 98% pending the active
portability/runtime-evidence gaps.
Completed work:
- Rechecked qagame
PM_DropTimersat0x10031E30, cgamePM_DropTimersat0x10006300, and thePmoveSinglespectator/noclip/tail call sites against the committed pmove evidence. - Added executable fixture coverage for partial
pm_timedecay, exact/overrun misc timer expiry,PMF_ALL_TIMESclearing while preserving unrelated flags, independent legs/torso animation timer clamps, and the existing crouch-slide ground-plane decay gate. - Updated structural tests, symbol-map comments, and mapping notes so the timer helper is covered as a first-class reconstructed source leaf.
Task A23: Pin PM_TorsoAnimation ready-idle wiring [COMPLETED]
Priority: High
Primary areas: tests/test_pmove_movement_fixtures.py,
tests/test_pmove_helper_parity.py,
references/symbol-maps/qagame.json, references/symbol-maps/cgame.json,
docs/reverse-engineering/qagame-mapping.md,
docs/reverse-engineering/cgame-mapping.md,
docs/reverse-engineering/cgame-bg-parity-implementation-plan.md
Parity estimate: before 97% -> after 100% for scoped executable evidence
coverage of the retail PM_TorsoAnimation ready-state idle split and inherited
timer/dead-player suppression behavior; repo-wide remains 98% pending the
active portability/runtime-evidence gaps.
Completed work:
- Rechecked qagame
PM_TorsoAnimationat0x1002DB80, cgamePM_TorsoAnimationat0x10002050, and the surroundingPmoveSingletail calls against the committed Ghidra function lattice. - Added executable pmove fixture coverage for the ready gauntlet
TORSO_STAND2branch, the default readyTORSO_STANDbranch, the high-priority torso-timer no-op, the non-ready weaponstate no-op, and the inheritedPM_DEADanimation-start suppression. - Updated structural tests, symbol-map comments, and pmove mapping notes so the post-weapon torso-idle helper is pinned by source behavior rather than only by normalized names.
Task A22: Pin PM_Animate command-button source behavior [COMPLETED]
Priority: High
Primary areas: tests/test_pmove_movement_fixtures.py,
references/symbol-maps/qagame.json, references/symbol-maps/cgame.json,
docs/reverse-engineering/qagame-mapping.md,
docs/reverse-engineering/cgame-mapping.md,
docs/reverse-engineering/cgame-bg-parity-implementation-plan.md
Parity estimate: before 96% -> after 100% for scoped executable evidence
coverage of the retail PM_Animate command-button priority, torso-timer gate,
and predictable-event behavior; repo-wide remains 98% pending the active
portability/runtime-evidence gaps.
Completed work:
- Rechecked qagame
PM_Weapon,PM_Animate, andPmoveSingletail ordering against the committed qagame/cgame Ghidra evidence and found no production-source mismatch in the dispatcher tail. - Added an executable pmove fixture for the shared
PM_Animateleaf covering gesture priority over voice commands, the long gesture timer plusEV_TAUNTevent, the retail voice-command priority order, the 600 ms voice timer, and the existing-torso-timer suppression gate. - Updated the symbol maps and reverse-engineering notes so the mapped animation/timer helper records the tested source behavior instead of relying only on structural matching.
Task A21: Pin 3D water and ladder pmove leaves with executable fixtures [COMPLETED]
Priority: High
Primary areas: tests/test_pmove_movement_fixtures.py,
references/symbol-maps/qagame.json, references/symbol-maps/cgame.json,
docs/reverse-engineering/cgame-mapping.md,
docs/reverse-engineering/cgame-bg-parity-implementation-plan.md
Parity estimate: before 94% -> after 100% for scoped executable evidence
coverage of the retail water-jump, water-idle, ladder-probe, and ladder-move
leaves; repo-wide remains 98% pending the active portability/runtime-evidence
gaps.
Completed work:
- Rechecked qagame
PM_CheckDuck,PM_Footsteps, andPM_Weaponagainst the committed qagame/cgame Ghidra decompiles and found no production-source mismatch in that tail corridor. - Extended the pmove movement fixture harness with deterministic trace and pointcontents probes for the adjacent 3D movement leaves.
- Added executable coverage for the retail
MASK_PLAYERSOLID+SURF_LADDERladder probe, the0.66 * speedladder climb/descent clamp, the two-deep water-jump solid-lip/clearance sequence, and the idle-60water sink fallback throughPM_WaterMove.
Task A20: Rewire pmove_ChainJump as the retail jump velocity mode [COMPLETED]
Priority: High
Primary areas: src/code/game/bg_public.h,
src/code/game/bg_pmove.c, src/code/game/g_pmove.c,
src/code/cgame/cg_servercmds.c,
references/symbol-maps/qagame.json,
references/symbol-maps/cgame.json,
docs/reverse-engineering/qagame-mapping.md,
docs/reverse-engineering/cgame-mapping.md,
tests/test_pmove_helper_parity.py,
tests/test_pmove_movement_fixtures.py,
tools/tests/test_pmove_settings_configstring.py
Parity estimate: before 97% -> after 100% for scoped
pmove_ChainJump mode transport and takeoff-branch wiring; repo-wide remains
98% pending the active portability/runtime-evidence gaps.
Completed work:
- Rechecked the qagame cvar refresh evidence where
pmove_ChainJump's integer slot is copied into the cached jump velocity selector, then matched it against the recoveredPM_ApplyJumpTakeoffvelocity-mode branches. - Promoted
pmove_settings_t.chainJumpfrom a boolean to an integer mode and carried that value through server cvar caching, compact configstring serialization, cgame compact parsing, and the legacy JSON fallback parser. - Updated the shared takeoff selector so mode
0disables chain-jump timing, mode1uses the gradient scaler, mode2reaches the additive branch, and PMF_AIR_CONTROL still selects the retail air-control additive branch. - Added executable pmove fixtures that pin the vertical takeoff results for
modes
0,1, and2, plus the air-control override path.
Task A19: Restore retail pmove jump-takeoff velocity modes [COMPLETED]
Priority: High
Primary areas: src/code/game/bg_pmove.c,
src/code/game/bg_pmove_jump.h, references/symbol-maps/qagame.json,
references/symbol-maps/cgame.json,
docs/reverse-engineering/qagame-mapping.md,
docs/reverse-engineering/cgame-mapping.md,
docs/reverse-engineering/cgame-bg-parity-implementation-plan.md,
tests/test_jump_velocity_scaling.py, tests/test_pmove_helper_parity.py,
tests/test_pmove_jump_timing_parity.py,
tests/test_crouch_step_prediction.py,
tests/test_pmove_validation_fixtures.py,
tests/pmove_validation_harness.c
Parity estimate: before 96% -> after 100% for scoped
PM_ApplyJumpTakeoff vertical velocity-mode reconstruction; repo-wide remains
98% pending the active portability/runtime-evidence gaps.
Completed work:
- Rechecked qagame
PM_ApplyJumpTakeoffat0x1002E2C0, cgamePM_ApplyJumpTakeoffat0x10002790, andPM_LoadMoveTuningConstantsagainst the committed HLIL and Ghidra evidence. - Replaced the source-only wrapper-side
pmove_StepJumpVelocityaddition with the retail takeoff velocity-mode block: normal chain jumps use the gradient scaler, PMF_AIR_CONTROL switches to the additive chain/step branch, and ramp-jump accumulation applies to vertical velocity before the max clamp. - Updated structural, helper, and executable pmove fixtures to pin the
gradient
cmd.serverTime - jumpTimebehavior and the crouch-step fallback velocity produced by the shared takeoff leaf.
Task A18: Align pmove playerState byte mirrors and item timer stats [COMPLETED]
Priority: High
Primary areas: src/code/game/q_shared.h, src/code/qcommon/msg.c,
src/code/game/bg_pmove.c, src/code/game/bg_public.h,
src/code/game/g_active.c, src/code/game/g_team.c,
src/code/cgame/cg_newdraw.c, references/symbol-maps/qagame.json,
references/symbol-maps/cgame.json,
docs/reverse-engineering/cgame-bg-parity-implementation-plan.md,
tests/test_playerstate_replication.py,
tests/test_invulnerability_move_parity.py,
tests/test_pmove_movement_fixtures.py
Parity estimate: before 92% -> after 100% for scoped pmove
playerState sidecar layout, command-mirror transport, and progress-backed
holdable timer wiring; repo-wide remains 98% pending the active
portability/runtime-evidence gaps.
Completed work:
- Rechecked the retail engine playerState netfield table plus cgame/qagame
PmoveSingledecompiles, confirmingclientNumat0x88,locationat0x8c, and signed command mirrors at byte offsets0x1dc..0x1de. - Rebuilt the shared
playerState_tprefix to match those offsets, moved source-only local sidecars after the retail replicated prefix, and taughtMSG_WriteDeltaPlayerstate/MSG_ReadDeltaPlayerstateto encode the command mirrors as one-byte fields without clobbering adjacent bytes. - Reconstructed the progress-backed holdable timer as retail stats slots
STAT_PLAYER_ITEM_TIME_MAX,STAT_PLAYER_ITEM_TIME, andSTAT_PLAYER_ITEM_RECHARGE, including the PmoveSingle recharge clamp and the invulnerability move stale/clear gates. - Added server location mirroring into
ps.location, moved theCG_PLAYER_ITEMoverlay to the stats-backed timer slots, and pinned the recovered offsets and round-trip behavior with executable replication tests.
Task A17: Remove source-only replicated ground-trace cache [COMPLETED]
Priority: High
Primary areas: src/code/game/q_shared.h, src/code/qcommon/msg.c,
src/code/game/bg_pmove.c, references/symbol-maps/qagame.json,
references/symbol-maps/cgame.json,
docs/reverse-engineering/qagame-mapping.md,
docs/reverse-engineering/cgame-mapping.md,
docs/reverse-engineering/cgame-bg-parity-implementation-plan.md,
tests/test_pmove_helper_parity.py, tests/test_pmove_jump_timing_parity.py
Parity estimate: before 99% -> after 100% for scoped
playerState ground-trace layout and PM_GroundTrace storage parity; repo-wide
remains 98% pending the active portability/runtime-evidence gaps.
Completed work:
- Rechecked cgame
PM_GroundTraceat0x100053A0, qagamePM_GroundTraceat0x10030ED0, and the adjacentPM_CheckDuckplayerState offset evidence against the committed Ghidra decompile. - Removed the reconstruction-only
groundTraceHistory*andgroundTraceLatest*playerState fields plus their delta replication, leaving the retailgroundEntityNumstore as the only replicated ground-trace state. - Rewired ramp-jump reconstruction to consult the current frame-local
pml.groundTracenormal instead of a non-retail playerState cache, and updated symbol-map/docs/tests to pin the layout boundary.
Task A16: Restore autoHop-only held-jump release wiring [COMPLETED]
Priority: High
Primary areas: src/code/game/bg_pmove.c,
src/code/game/bg_slidemove.c, references/symbol-maps/qagame.json,
references/symbol-maps/cgame.json,
docs/reverse-engineering/qagame-mapping.md,
docs/reverse-engineering/cgame-mapping.md,
docs/reverse-engineering/cgame-bg-parity-implementation-plan.md,
tests/test_pmove_helper_parity.py, tests/test_step_jump_gate_parity.py,
tests/test_pmove_movement_fixtures.py
Parity estimate: before 99% -> after 100% for scoped
PM_CheckJump / PM_CanStepJump held-release parity; repo-wide remains
98% pending the active portability/runtime-evidence gaps.
Completed work:
- Rechecked qagame
PM_CanStepJumpat0x1002E510andPM_CheckJumpat0x1002E590, plus the cgame twins at0x100029E0and0x10002A60, against the committed HLIL and compact pmove-setting parse order. - Restored the retail release-bypass split:
autoHopcan bypass the held-jump release requirement unlessPMF_REQUIRE_JUMP_RELEASEis set, whilebunnyHopremains separate movement tuning and no longer bypasses release. - Added structural and executable fixture coverage so both normal jump and step-jump gates reject held input when only bunny-hop tuning is enabled.
Task A15: Restore retail step-jump crouch fallback wiring [COMPLETED]
Priority: High
Primary areas: src/code/game/bg_slidemove.c,
src/code/game/bg_pmove.c, references/symbol-maps/qagame.json,
references/symbol-maps/cgame.json,
docs/reverse-engineering/qagame-mapping.md,
docs/reverse-engineering/cgame-mapping.md,
docs/reverse-engineering/cgame-bg-parity-implementation-plan.md,
tests/test_step_jump_gate_parity.py,
tests/test_pmove_validation_fixtures.py,
tests/pmove_validation_harness.c,
tests/test_crouch_step_prediction.py,
tests/test_pmove_helper_parity.py
Parity estimate: before 98% -> after 100% for scoped
PM_StepSlideMove step-jump gate and crouch-fallback parity; repo-wide
remains 98% pending the active portability/runtime-evidence gaps.
Completed work:
- Rechecked qagame
PM_StepSlideMoveat0x1002EFE0, cgamePM_StepSlideMoveat0x100034B0, and the adjacentPM_CanStepJump/PM_CanCrouchStepJumpleaves against the committed HLIL plus qagame Ghidra decompile. - Replaced the source-only recent-ground-history step-jump delay helper with
the retail
cmd.serverTime - jumpTime >= jumpTimeDeltaMingate. - Restored the retail branch split where the general
PM_CanStepJumprecheck launches the normal step jump, while the failed-general path can still run the crouch-step fallback throughPM_CanCrouchStepJumpand the shrunken-box clearance trace. - Added direct and executable fixtures for the crouch-step fallback, including
the no-upmove case that retail permits after the general gate rejects the
command, and corrected the cgame
PM_StepSlideMovesymbol signature back to the one-argument retail boundary.
Task A14: Restore exact invulnerability pmove timer gate [COMPLETED]
Priority: High
Primary areas: src/code/game/bg_pmove.c,
references/symbol-maps/qagame.json, references/symbol-maps/cgame.json,
docs/reverse-engineering/cgame-bg-parity-implementation-plan.md,
tests/test_invulnerability_move_parity.py,
tests/test_pmove_movement_fixtures.py
Parity estimate: before 99% -> after 100% for scoped
PM_InvulnerabilityMove timer-gate and holdable-clear parity; repo-wide
remains 98% pending the active portability/runtime-evidence gaps.
Completed work:
- Rechecked qagame
PM_InvulnerabilityMoveat0x1002FA80and cgamePM_InvulnerabilityMoveat0x10003F50against the committed HLIL, focusing on the held-item dispatch predicate and timer-collapse block. - Restored the exact retail stale-timer gate
STAT_PLAYER_ITEM_RECHARGE != 0 && STAT_PLAYER_ITEM_TIME == 0, allowing negative countdown remnants to enter the active decay path instead of being filtered by a broader signed range test. - Moved the pending holdable-slot clear under the timer clamp and tied it to
STAT_PLAYER_ITEM_RECHARGE == 0, matching the retail collapse point. - Added structural and executable pmove coverage for exact zero with a max timer, negative decay with a max timer, and zero with no max timer.
Task A13: Remove source-only flight-thrust pmove override [COMPLETED]
Priority: High
Primary areas: src/code/game/bg_pmove.c,
src/code/game/bg_public.h, src/code/game/g_main.c,
src/code/game/g_pmove.c, src/code/cgame/cg_servercmds.c,
references/symbol-maps/qagame.json, references/symbol-maps/cgame.json,
docs/reverse-engineering/cgame-bg-parity-implementation-plan.md,
tests/test_pmove_helper_parity.py,
tests/test_game_factory_regen_parity.py,
tools/tests/test_pmove_settings_configstring.py
Parity estimate: before 99% -> after 100% for scoped PM_FlyMove
and g_flightThrust wiring parity; repo-wide remains 98% pending the
active portability/runtime-evidence gaps.
Completed work:
- Rechecked qagame
PM_FlyMoveat0x1002FA20and cgamePM_FlyMoveat0x10003EF0against the committed HLIL; both retail bodies runPM_Friction,PM_BuildWishMove3D,PM_Accelerate(..., 8), andPM_StepSlideMove(qfalse)without a flight-thrust branch. - Confirmed
g_flightThrustis still a retail qagame cvar table entry with default1200, but its vmCvar storage is not referenced by the shared pmove leaf or pmove settings transport. - Removed the source-only
flightThrustfield frompmove_settings_t, the compact/JSON pmove settings payload extension, andPM_FlyMove, while keeping the retail cvar registration. - Updated symbol-map/docs evidence and regression tests to pin the no-override movement leaf and cvar registration boundary.
Task A12: Restore invulnerability-aware dead pmove collision gate [COMPLETED]
Priority: High
Primary areas: src/code/game/bg_pmove.c,
references/symbol-maps/qagame.json, references/symbol-maps/cgame.json,
docs/reverse-engineering/qagame-mapping.md,
docs/reverse-engineering/cgame-mapping.md,
docs/reverse-engineering/cgame-bg-parity-implementation-plan.md,
tests/test_pmove_helper_parity.py,
tests/test_pmove_movement_fixtures.py
Parity estimate: before 99% -> after 100% for scoped PmoveSingle
dead-player trace-mask parity; repo-wide remains 98% pending the active
portability/runtime-evidence gaps.
Completed work:
- Rechecked qagame
PmoveSingleat0x10031FA0and cgamePmoveSingleat0x10006470against the committed Ghidra evidence, focusing on the top tracemask gate before command-time handling. - Restored the retail condition that clears
CONTENTS_BODYfrom the pmove trace mask only whenSTAT_HEALTH <= 0andPW_INVULNERABILITYis not active, preserving body collision for invulnerable dead-player states. - Updated symbol-map and mapping documentation to record the paired health/powerup gate.
- Added structural and executable pmove coverage for the dispatcher ordering and both dead-player tracemask outcomes.
Task A11: Move pmove profile-bit ownership back to spawn wiring [COMPLETED]
Priority: High
Primary areas: src/code/game/g_client.c, src/code/game/g_pmove.c,
src/code/game/bg_pmove.c, src/code/game/g_local.h,
references/symbol-maps/qagame.json, references/symbol-maps/cgame.json,
docs/reverse-engineering/qagame-mapping.md,
docs/reverse-engineering/cgame-bg-parity-implementation-plan.md,
tests/test_pmove_helper_parity.py, tests/test_pmove_crouch_time_parity.py,
tests/test_pmove_crouch_slide_friction_parity.py,
tests/pmove_validation_harness.c
Parity estimate: before 99% -> after 100% for scoped pmove
profile-flag ownership and prediction wiring parity; repo-wide remains
98% pending the active portability/runtime-evidence gaps.
Completed work:
- Rechecked qagame
ClientSpawnat0x1003BC30and sharedPmoveSingleat qagame0x10031FA0/ cgame0x10006470against the committed Ghidra evidence. - Restored the retail ownership split where spawn seeds
PMF_CROUCH_SLIDE,PMF_DOUBLE_JUMP, andPMF_AIR_CONTROLfrom the active movement profile, whilePmoveSingleconsumes those replicated bits instead of deriving them from settings every frame. - Rewired crouch-slide friction and air double-jump acceptance to respect the profile flags directly, preserving the existing tuning fields for friction strength, jump velocity, and prediction-side settings.
- Updated symbol-map/docs evidence and regression fixtures to lock the spawn profile helper, shared pmove dispatcher order, crouch-slide friction gate, and double-jump latch behavior.
Task A10: Reconstruct compact pmove settings configstring wiring [COMPLETED]
Priority: High
Primary areas: src/code/game/g_pmove.c,
src/code/cgame/cg_servercmds.c,
references/symbol-maps/cgame.json,
docs/reverse-engineering/cgame-mapping.md,
docs/reverse-engineering/cgame-bg-parity-implementation-plan.md,
tests/test_pmove_helper_parity.py,
tools/tests/test_pmove_settings_configstring.py
Parity estimate: before 99% -> after 100% for scoped pmove
settings transport/source wiring parity; repo-wide remains 98% pending
the active portability/runtime-evidence gaps.
Completed work:
- Rechecked
CG_ParsePmoveConfigStringat0x10048F30against the committed cgame Ghidra/HLIL evidence and mapped the retail 33-token compact numeric payload order, including the non-negative clamps on the recovered threshold and velocity fields. - Replaced the reconstruction-only JSON
CS_PMOVE_SETTINGSserver payload with the compact retail token stream fromG_PmoveSerializeSettings, while retaining current source-only fields as a trailing extension after the retail core. - Rewired cgame parsing so compact payloads take the retail path, JSON remains only as a backward-compatible fallback for older local artifacts, and reload timing stays owned by the dedicated compact reload configstring.
- Updated symbol-map/docs evidence and regression tests to pin the recovered token order, clamp behavior, extension boundary, and JSON fallback.
Task A9: Contain inherited Quake III service endpoints behind the online-services policy [COMPLETED]
Priority: High
Primary areas: src/code/qcommon/qcommon.h, src/code/client/cl_main.c,
src/code/server/, src/common/platform/platform_config.h,
docs/reverse-engineering/network-handshake.md,
docs/reverse-engineering/quakelive_steam_mapping_round_73.md,
docs/steam_platform_abstraction.md, tests/test_platform_services.py
Parity estimate: before 98% -> after 98% repo-wide; scoped
network-service policy parity improves from 82% -> 94%.
Completed work:
- Confirmed from the retail Quake Live evidence that the retained game port
remains
27960, while the inherited Quake III update, master, and authorize hostnames are not retail QL Steam service evidence. - Added
QL_ENABLE_LEGACY_Q3_SERVICES, defaulted it off, and forced it off wheneverQL_BUILD_ONLINE_SERVICES=0, so default builds no longer resolve the retired*.quake3arena.comhosts. - Kept
PORT_SERVERand the LAN server-port scan range unconditional, while quarantiningUPDATE_SERVER_NAME,MASTER_SERVER_NAME,AUTHORIZE_SERVER_NAME,PORT_MASTER,PORT_UPDATE, andPORT_AUTHORIZEbehind the legacy-service gate. - Restored the retail
sv_masterheartbeat gate assv_masterAdvertiseand left the oldersv_master1throughsv_master5array as an explicitly configured compatibility lane. - Replaced default build calls into the legacy Q3 MOTD, master query, authorize, getIpAuthorize, and remote-ban flows with policy-visible stubs or local challenge responses, and covered the boundary with focused tests.
Task A8: Re-audit renderer source and host wiring, then remove the non-retail FontStash prebuild [COMPLETED]
Priority: High
Primary areas: src/code/renderer/tr_font.c,
docs/reverse-engineering/renderer-wiring-reverse-engineering-round-2026-05-20.md,
docs/reverse-engineering/renderer-full-parity-audit-and-implementation-plan-2026-04-09.md,
docs/reverse-engineering/renderer-host-text-core-ownership-2026-04-10.md,
docs/platform/retail-font-stack.md,
tests/test_renderer_host_text_core_parity.py
Parity estimate: before 99% -> after 100% for scoped renderer
source/wiring parity; repo-wide remains 98% pending fresh runtime evidence.
Completed work:
- Re-ran the renderer source/wiring evidence walk against the committed
quakelive_steam.exeGhidra/HLIL corpus, current symbol aliases, renderer parity gates, and the tracked renderer/module runtime artifacts. - Confirmed that scene, world/model, shader, post-process, memory-image, export ABI, Win32 host glue, and native UI/cgame host-text import ownership still do not need a new renderer file-level gap note.
- Isolated one hidden retained-host-text mismatch: source eagerly prebuilt
every byte glyph for every retained FontStash face during
R_InitFontStash, while retail HLIL creates the atlas, installsR_fonsErrorCallback, loads the five faces, and leaves glyph population lazy through the draw/measure cache path. - Removed the eager
R_PrebuildFontStashAtlasstartup sweep fromtr_font.c, added focused source/docs coverage so the lazy retained-atlas ownership stays pinned, and documented that the olderR_fonsErrorCallbackretail-module artifact is now staleRW-G04evidence until the module runtime probe is rerun. - Followed up on the same FontStash overflow lane by preserving old atlas
pixels and cached glyph UVs during
R_ResizeFontStashAtlasexpansion, leaving full glyph-cache clearing reserved for the retail max-size flush path. - Matched the retail
*fontstashtexture callback by uploading the retained one-byte atlas throughGL_ALPHAtexture storage instead of expanding it into RGBA for every atlas refresh. - Restored the retail renderer export ABI shape around
GetRefAPI: source now usesREF_API_VERSION == 9, keeps the legacy post-ModelBoundsfont slot as a no-op, preservesSetColorimmediately after the loading-view bridge, and leavespostprocess_restartat the private tail offset recovered from the0x9cretail export table.
Task A7: Run the source-file parity audit campaign and isolate the remaining file-level gaps [COMPLETED]
Priority: High
Primary areas: docs/reverse-engineering/source-file-parity-ledger-2026-04-22.md,
docs/reverse-engineering/source-file-parity-audit-plan-2026-04-22.md,
docs/reverse-engineering/source-file-gap-notes/,
tools/reverse-engineering/generate_source_file_audit.py, all tracked
src/ source trees
Parity estimate: before 96% -> after 96%
Completed work:
- Closed the full source-file parity audit campaign by walking all
567tracked source entries across the primary runtime, compatibility-only, and secondary support trees in the generated plan order. - Kept inherited subsystem closure as the baseline while isolating concrete
file-level ownership only where the current evidence supported it, which
left the repo-wide source-file gap register concentrated in the seeded
RW-G01andRW-G02note set instead of reopening already-bounded surfaces. - Extended the source-file audit generator and its regression coverage so completed tranche metadata, compatibility wording, function-count fixes, and Phase 4 secondary-source summaries all survive regeneration on the current worktree.
- Regenerated the source-file ledger, source-file audit plan, gap-note index/readme, and historical audit index so the campaign snapshot is now self-consistent and no pending tranche remains in the generated plan.
- Returned the top-level queue to the remaining repo-wide workstreams, with the online-service compatibility boundary now back at the head of the active task list.
Task A7p: Audit src/q3radiant function-by-function and isolate file-level gap ownership [COMPLETED]
Priority: High
Primary areas: docs/reverse-engineering/source-file-parity-ledger-2026-04-22.md,
docs/reverse-engineering/source-file-parity-audit-plan-2026-04-22.md,
src/q3radiant/,
tests/test_source_file_audit_generator.py,
tools/reverse-engineering/generate_source_file_audit.py
Parity estimate: before 96% -> after 96%
Completed work:
- Completed the final Phase 4 secondary-source tranche in the source-file
campaign by walking all
97tracked files undersrc/q3radiantagainst the current generated ledger and the repo-wide parity register. - Confirmed that this tranche does not open any new file-level gap notes: the retained Radiant editor shell, plugin bridge, OpenGL host glue, and bundled spline/editor helper sources remain bounded secondary support trees on current evidence rather than concrete repo-wide gap owners.
- Extended the source-file audit generator and its regression coverage so
completed metadata for
src/q3radiantand the checked final Phase 4 plan item now survive regeneration too. - Re-ran the refreshed generator suite (
20 passed) and regenerated the source-file campaign docs so the final Phase 4 tranche is now recorded as complete in the generated outputs. - Closed the currently enumerated secondary-source file-walk queue in the generated source-file audit plan, leaving no remaining pending Phase 4 tranche in that campaign snapshot.
Task A7o: Audit src/lcc and src/libs function-by-function and isolate file-level gap ownership [COMPLETED]
Priority: High
Primary areas: docs/reverse-engineering/source-file-parity-ledger-2026-04-22.md,
docs/reverse-engineering/source-file-parity-audit-plan-2026-04-22.md,
src/lcc/,
src/libs/,
tests/test_source_file_audit_generator.py,
tools/reverse-engineering/generate_source_file_audit.py
Parity estimate: before 96% -> after 96%
Completed work:
- Completed the third Phase 4 secondary-source tranche in the source-file
campaign by walking all
99tracked files acrosssrc/lccandsrc/libsagainst the current generated ledger and the repo-wide parity register. - Confirmed that this tranche does not open any new file-level gap notes:
the retained LCC compiler/preprocessor/code-generator and bundled test
sources under
src/lcc, plus the tracked command-line, JPEG, and pak helper sources undersrc/libs, remain bounded secondary support trees on current evidence rather than concrete repo-wide gap owners. - Extended the source-file audit generator and its regression coverage so
completed metadata for
src/lcc,src/libs, and the checked third Phase 4 plan item now survive regeneration too. - Re-ran the refreshed generator suite (
19 passed) and regenerated the source-file campaign docs so the third Phase 4 tranche is now recorded as complete in the generated outputs. - Advanced the file-walk queue so the remaining Phase 4 target is now the
secondary-source tranche covering
src/q3radiant/.
Task A7n: Audit src/game, src/q3asm, and src/q3map function-by-function and isolate file-level gap ownership [COMPLETED]
Priority: High
Primary areas: docs/reverse-engineering/source-file-parity-ledger-2026-04-22.md,
docs/reverse-engineering/source-file-parity-audit-plan-2026-04-22.md,
src/game/,
src/q3asm/,
src/q3map/,
tests/test_source_file_audit_generator.py,
tools/reverse-engineering/generate_source_file_audit.py
Parity estimate: before 96% -> after 96%
Completed work:
- Completed the second Phase 4 secondary-source tranche in the source-file
campaign by walking all
40tracked files acrosssrc/game,src/q3asm, andsrc/q3mapagainst the current generated ledger and the repo-wide parity register. - Confirmed that this tranche does not open any new file-level gap notes:
the retained gameplay config helpers and standalone fixture/support
sources under
src/game, theq3asmbytecode assembler sources, and theq3mapcompile/light/vis toolchain all remain bounded secondary support trees on current evidence rather than concrete repo-wide gap owners. - Extended the source-file audit generator and its regression coverage so
completed metadata for
src/game,src/q3asm,src/q3map, and the checked second Phase 4 plan item now survive regeneration too. - Re-ran the refreshed generator suite plus focused
src/gamehelper coverage (41 passedacross the source-audit, factory-config, scoreboard-helper, and tournament-queue suites) so this tranche stays recorded as complete on the current worktree. - Regenerated the source-file campaign docs so the second Phase 4 tranche is
now recorded as complete in the generated outputs, and the next file-walk
target is now the secondary-source tranche covering
src/lcc/andsrc/libs/.
Task A7m: Audit src/code/bspc, src/code/jpeg-6, and src/code/splines function-by-function and isolate file-level gap ownership [COMPLETED]
Priority: High
Primary areas: docs/reverse-engineering/source-file-parity-ledger-2026-04-22.md,
docs/reverse-engineering/source-file-parity-audit-plan-2026-04-22.md,
src/code/bspc/,
src/code/jpeg-6/,
src/code/splines/,
tests/test_source_file_audit_generator.py,
tools/reverse-engineering/generate_source_file_audit.py
Parity estimate: before 96% -> after 96%
Completed work:
- Completed the first Phase 4 secondary-source tranche in the source-file
campaign by walking all
106tracked files acrosssrc/code/bspc,src/code/jpeg-6, andsrc/code/splinesagainst the current repo-wide ledger and the generated source-file register. - Corrected the audit generatorโs function extractor so the tranche now
counts libjpeg macro-style definitions and retained splines C++ method
definitions instead of leaving most of
jpeg-6and parts of the splines tree as misleading zero-function placeholders in the ledger. - Confirmed that this tranche does not open any new file-level gap notes:
the retained BSPC compiler/AAS toolchain, bundled
jpeg-6support sources, and legacy splines helper/editor sources remain bounded secondary trees on current evidence rather than concrete repo-wide gap owners. - Extended the source-file audit generator and its regression coverage so
completed secondary-section metadata and the checked first Phase 4 plan
item now survive regeneration too; the refreshed generator suite passes
on the current worktree (
17 passed). - Regenerated the source-file campaign docs so the first Phase 4 tranche is
now recorded as complete in the generated outputs, and the next file-walk
target is now the secondary-source tranche covering
src/game/,src/q3asm/, andsrc/q3map/.
Task A7l: Audit src/code/null function-by-function and isolate file-level gap ownership [COMPLETED]
Priority: High
Primary areas: docs/reverse-engineering/source-file-parity-ledger-2026-04-22.md,
docs/reverse-engineering/source-file-parity-audit-plan-2026-04-22.md,
docs/reverse-engineering/source-file-gap-notes/,
src/code/null/,
docs/reverse-engineering/repo-wide-parity-audit-2026-04-21.md,
tests/test_non_windows_portability.py,
tools/reverse-engineering/generate_source_file_audit.py
Parity estimate: before 96% -> after 96%
Completed work:
- Completed the next compatibility tranche in the source-file campaign by
walking all
7trackedsrc/code/nullentries against the current repo-wide parity ledger, the existingRW-G02portability notes, and the focused non-Windows portability regression lane. - Isolated
src/code/null/null_glimp.cas an additional concreteRW-G02owner because the null renderer host still consists of no-opGLimp_*entry points plus aQGL_Init()path that returns success without loading a real GL backend, whilenull_main.c,null_client.c,null_input.c, andnull_snddma.cremain the other null-runtime owners already tracked in dedicated notes. - Confirmed that no further null file needs a new file-level gap note in
this tranche:
null_net.candmac_net.cremain bounded loopback helper surfaces on current evidence rather than newly isolated repo-wide blockers, so they are now explicitly recorded as current compatibility function-walk completions. - Extended the source-file audit generator and its regression coverage so a
completed null compatibility tranche, the newly isolated
null_glimp.cnote, and the walked-complete helper rows all survive regeneration; the refreshed generator plus non-Windows portability suites now pass together (20 passed). - Regenerated the source-file campaign docs so Phase 3 is now fully closed
in the generated outputs, and the next file-walk target is now the first
Phase 4 secondary-source tranche covering
src/code/bspc/,src/code/jpeg-6/, andsrc/code/splines/.
Task A7k: Audit src/code/unix function-by-function and isolate file-level gap ownership [COMPLETED]
Priority: High
Primary areas: docs/reverse-engineering/source-file-parity-ledger-2026-04-22.md,
docs/reverse-engineering/source-file-parity-audit-plan-2026-04-22.md,
src/code/unix/,
docs/reverse-engineering/repo-wide-parity-audit-2026-04-21.md,
tests/test_non_windows_portability.py,
tools/reverse-engineering/generate_source_file_audit.py
Parity estimate: before 96% -> after 96%
Completed work:
- Completed the next compatibility tranche in the source-file campaign by
walking all
10trackedsrc/code/unixentries against the current repo-wide parity ledger, the existingRW-G02portability notes, and the focused non-Windows portability regression lane. - Confirmed that no additional
src/code/unixfile needs a new file-level gap note: the existingRW-G02ownership remains concentrated inunix_main.c,linux_glimp.c,linux_snd.c, andlinux_joystick.c, whilelinux_common.c,linux_qgl.c,linux_signals.c,unix_net.c,unix_shared.c, andvm_x86.care now explicitly recorded as current function-walk completions on present evidence. - Extended the source-file audit generator and its regression coverage so a
completed compatibility tranche now survives regeneration too, including
the checked Phase 3 Unix plan item, the compatibility-specific ledger row
wording, and the retained
RW-G02note ownership inside the still-open portability lane. - Re-ran the generator and the focused portability coverage (
18 passedacross the generator and non-Windows suites) so the Unix tranche now stays recorded as complete in the generated docs, and the next file-walk target is now the compatibility-onlysrc/code/nulltranche at the head of the remaining queue.
Task A7j: Audit src/code/ui function-by-function and isolate file-level gap ownership [COMPLETED]
Priority: High
Primary areas: docs/reverse-engineering/source-file-parity-ledger-2026-04-22.md,
docs/reverse-engineering/source-file-parity-audit-plan-2026-04-22.md,
src/code/ui/,
docs/reverse-engineering/ui-full-parity-audit-and-implementation-plan-2026-04-05.md,
tools/reverse-engineering/generate_source_file_audit.py
Parity estimate: before 96% -> after 96%
Completed work:
- Completed the next source-file campaign tranche by walking all
9trackedsrc/code/uientries against the refreshed strict-retail UI audit, the focused UI parity lane, and the current repo-wide gap ledger. - Confirmed that no
src/code/uifile needs a new file-level gap note: the current UI closure still holds on current evidence, the focused UI suite is green (56 passed,2 skipped), the clean read-onlysrc/uiruntime-panel parity proof still bounds the menu/data payload, and the read-only tree therefore did not require or permit a source correction in this tranche. - Extended the source-file audit generator and its regression coverage so completed read-only tranche metadata now survives regeneration too, including the UI checklist state, the read-only ledger row wording, and the UI tranche summary in the generated audit docs.
- Regenerated the source-file campaign docs from the hardened generator so
the UI tranche is now recorded as complete beside the earlier runtime
walks, and the next file-walk target is now the compatibility-only
src/code/unixtranche at the head of the remaining queue.
Task A7i: Audit src/code/cgame function-by-function and isolate file-level gap ownership [COMPLETED]
Priority: High
Primary areas: docs/reverse-engineering/source-file-parity-ledger-2026-04-22.md,
docs/reverse-engineering/source-file-parity-audit-plan-2026-04-22.md,
src/code/cgame/,
docs/reverse-engineering/game-module-parity-audit-and-implementation-plan-2026-04-10.md,
tools/reverse-engineering/generate_source_file_audit.py
Parity estimate: before 96% -> after 96%
Completed work:
- Completed the next module/gameplay tranche in the source-file campaign by
walking all
22trackedsrc/code/cgameentries against the refreshed strict-retail module audit, the focusedcgameparity lane, and the current repo-wide gap ledger. - Confirmed that no
src/code/cgamefile needs a new file-level gap note: the current module closure still holds on current evidence, the focusedcgamesuite is green (199 passed,1 skipped), and the shared native export-helper certification still bounds the tree without needing a source correction in this tranche. - Hardened the source-file audit generator so completed tranche checkmarks,
section result notes, and current-walk ledger rows now survive regeneration
instead of reverting already-audited runtime sections back to the default
pending wording;
--helpis also now a safe no-write path. - Regenerated the source-file campaign docs from the hardened generator so
the corrected
cgamefunction counts and the previously completed runtime tranches live in one durable output again, and the next file-walk target is now the read-onlysrc/code/uitranche at the head of the remaining module/gameplay queue.
Task A7h: Audit src/code/game function-by-function and isolate file-level gap ownership [COMPLETED]
Priority: High
Primary areas: docs/reverse-engineering/source-file-parity-ledger-2026-04-22.md,
docs/reverse-engineering/source-file-parity-audit-plan-2026-04-22.md,
src/code/game/,
docs/reverse-engineering/game-module-parity-audit-and-implementation-plan-2026-04-10.md,
tools/reverse-engineering/generate_source_file_audit.py
Parity estimate: before 96% -> after 96%
Completed work:
- Hardened the source-file audit generator again so it now ignores
control-flow keywords such as
if,for,while, andswitch, which keeps the source-file campaign counts aligned with real Quake-style C definitions in thesrc/code/gametranche instead of overcounting control blocks. - Completed the next module/gameplay tranche in the source-file campaign by
walking all
45trackedsrc/code/gameentries against the refreshed strict-retail module audit, the qagame retail gate, and the current repo-wide gap ledger. - Closed the concrete issues surfaced during the walk without opening a new
persistent gap note:
BG_CanGrabWeaponItem()now matches the retained retail world-weapon regrab gate, the Attack & Defend lifecycle/frame hooks are explicit in the module-side source layout again, and the standalone auto-shuffle countdown harness now uses the shared compiler-discovery path on Windows instead of assuminggcc. - Confirmed that no
src/code/gamefile needs a new file-level gap note: the current gameplay/module closure still holds on current evidence, and the newer auto-shuffle/countdown, Clan Arena shuffle, Race, ready-up, and sharedpmovecoverage all remain bounded inside the already-closed module register rather than opening a new repo-wide gap family. - Recorded the result directly in the source-file campaign docs so the game
rows now distinguish current function-walk completion from the
still-pending module trees, and the next file-walk target is now the
src/code/cgametranche at the head of the remaining module/gameplay queue.
Task A7g: Audit src/code/botlib function-by-function and isolate file-level gap ownership [COMPLETED]
Priority: High
Primary areas: docs/reverse-engineering/source-file-parity-ledger-2026-04-22.md,
docs/reverse-engineering/source-file-parity-audit-plan-2026-04-22.md,
src/code/botlib/,
docs/reverse-engineering/botlib-internal-parity-audit-and-implementation-plan-2026-04-10.md,
tools/reverse-engineering/generate_source_file_audit.py
Parity estimate: before 96% -> after 96%
Completed work:
- Fixed the source-file audit generator so it now counts Quake-style
brace-on-next-line C function definitions, which restores accurate
function-count coverage for the
src/code/botlibtranche instead of leaving most files reported as zero-function placeholders. - Completed the next primary-runtime tranche in the source-file campaign by
walking all
28trackedsrc/code/botlibentries against the dedicated botlib internal audit, the retained mapping-round61bridge/import ownership, and the current repo-wide gap ledger. - Confirmed that no
src/code/botlibfile needs a new file-level gap note: the retained bridge/import closures and the deterministic AAS/reachability/goal-state proof lane still bound the tree on current evidence, while the remaining live-map or gameplay-tuning nuance stays explicitly outside the repo-wide/file-level gap register. - Recorded the result directly in the source-file campaign docs so the
botlib rows now distinguish current function-walk completion from the
still-pending module and compatibility trees, and the next file-walk
target is now the
src/code/gametranche at the head of the remaining module/gameplay queue.
Task A7f: Audit src/code/win32 function-by-function and isolate file-level gap ownership [COMPLETED]
Priority: High
Primary areas: docs/reverse-engineering/source-file-parity-ledger-2026-04-22.md,
docs/reverse-engineering/source-file-parity-audit-plan-2026-04-22.md,
src/code/win32/,
docs/reverse-engineering/platform-specific-engine-parity-audit-and-implementation-plan-2026-04-16.md
Parity estimate: before 96% -> after 96%
Completed work:
- Completed the next primary-runtime tranche in the source-file campaign by
walking all
11trackedsrc/code/win32entries against the closed strict-retail Windows platform audit, renderer host-glue evidence, and the current repo-wide gap ledger. - Confirmed that no
src/code/win32file needs a new file-level gap note: the retained clipboard, raw-input, loading-window, renderer-host glue, andwin_glimp.cpixel-format closures still hold on current evidence, and no file in this tree currently owns a repo-wide gap family. - Recorded the result directly in the source-file campaign docs so the Win32 rows now distinguish current function-walk completion from the still-pending runtime trees, without reopening the closed strict-retail Windows platform register.
- Narrowed
A7procedurally again: the next file-walk target is now thesrc/code/botlibtranche at the head of the remaining strict-retail engine-core queue.
Task A7e: Audit src/code/renderer function-by-function and isolate file-level gap ownership [COMPLETED]
Priority: High
Primary areas: docs/reverse-engineering/source-file-parity-ledger-2026-04-22.md,
docs/reverse-engineering/source-file-parity-audit-plan-2026-04-22.md,
src/code/renderer/,
docs/reverse-engineering/renderer-full-parity-audit-and-implementation-plan-2026-04-09.md
Parity estimate: before 96% -> after 96%
Completed work:
- Completed the next primary-runtime tranche in the source-file campaign by
walking all
23trackedsrc/code/rendererentries against the closed strict-retail renderer audit, mapping notes, and the current repo-wide gap ledger. - Confirmed that no
src/code/rendererfile needs a new file-level gap note: the retained export, image, post-process, scene/runtime, font, and host-text closures still hold on current evidence, and the then-boundedR_fonsErrorCallbackmodule-runtime blocker remained classified underRW-G04evidence freshness rather than as a new renderer source-gap owner. The later 2026-05-20 renderer wiring pass patched the source-side eager FontStash prebuild behind that stale artifact. - Recorded the result directly in the source-file campaign docs so the renderer rows now distinguish current function-walk completion from the still-pending runtime trees, without reopening the closed strict-retail renderer register.
- Narrowed
A7procedurally again: the next file-walk target is now thesrc/code/win32tranche at the head of the remaining strict-retail engine-core queue.
Task A7d: Audit src/code/server function-by-function and isolate file-level gap ownership [COMPLETED]
Priority: High
Primary areas: docs/reverse-engineering/source-file-parity-ledger-2026-04-22.md,
docs/reverse-engineering/source-file-parity-audit-plan-2026-04-22.md,
src/code/server/,
docs/reverse-engineering/server-full-parity-audit-and-implementation-plan-2026-04-10.md
Parity estimate: before 96% -> after 96%
Completed work:
- Completed the next primary-runtime tranche in the source-file campaign by
walking all
11trackedsrc/code/serverentries against the closed strict-retail server audit, mapping notes, and the current repo-wide gap ledger. - Confirmed that no new
src/code/serverfile-level owners need opening beyond the already-seededRW-G01note forsv_rankings.c; the retained Steam GameServer/auth/stats andidZMQpublication/runtime owners remain closed on current evidence. - Recorded the result directly in the source-file campaign docs so the
server rows now distinguish current function-walk completion from the
still-pending runtime trees, while keeping the bounded rankings ownership
explicit in the existing
sv_rankings.cgap note instead of reopening the closed strict-retail server register. - Narrowed
A7procedurally again: the next file-walk target is now thesrc/code/renderertranche at the head of the remaining strict-retail engine-core queue.
Task A7c: Audit src/code/client function-by-function and isolate file-level gap ownership [COMPLETED]
Priority: High
Primary areas: docs/reverse-engineering/source-file-parity-ledger-2026-04-22.md,
docs/reverse-engineering/source-file-parity-audit-plan-2026-04-22.md,
src/code/client/,
docs/reverse-engineering/client-full-parity-audit-and-implementation-plan-2026-04-09.md
Parity estimate: before 96% -> after 96%
Completed work:
- Completed the next primary-runtime tranche in the source-file campaign by
walking all
22trackedsrc/code/cliententries against the closed strict-retail client audit, mapping notes, and the current repo-wide gap ledger. - Confirmed that no new
src/code/clientfile-level owners need opening beyond the already-seededRW-G01notes forql_auth.candcl_steam_resources.c. - Recorded the result directly in the source-file campaign docs so the client rows now distinguish current function-walk completion from the still-pending runtime trees, while keeping the bounded online-services ownership explicit in the two existing client gap notes instead of reopening the closed strict-retail client register.
- Narrowed
A7procedurally again: the next file-walk target is now thesrc/code/servertranche at the head of the remaining strict-retail engine-core queue.
Task A7b: Audit src/code/qcommon function-by-function and isolate file-level gap ownership [COMPLETED]
Priority: High
Primary areas: docs/reverse-engineering/source-file-parity-ledger-2026-04-22.md,
docs/reverse-engineering/source-file-parity-audit-plan-2026-04-22.md,
src/code/qcommon/,
docs/reverse-engineering/qcommon-full-parity-audit-and-implementation-plan-2026-04-10.md
Parity estimate: before 96% -> after 96%
Completed work:
- Completed the next primary-runtime tranche in the source-file campaign by
walking all
19trackedsrc/code/qcommonentries against the closed strict-retail qcommon audit, mapping rounds, and the current repo-wide ledger. - Confirmed that no new
src/code/qcommonfile-level owners need opening: the current strict-retail qcommon register remains closed, and no additional repo-wide gap family is concretely owned by a qcommon source file on the current worktree. - Recorded the result directly in the source-file campaign docs so the
qcommon rows now distinguish current function-walk completion from the
still-pending runtime trees, while keeping
vm_x86.cclassified as the already-bounded compatibility carry beneath the closedvm.chost-selection seam. - Narrowed
A7procedurally again: the next file-walk target is now thesrc/code/clienttranche at the head of the remaining strict-retail engine-core queue.
Task A7a: Audit src/common function-by-function and isolate file-level gap ownership [COMPLETED]
Priority: High
Primary areas: docs/reverse-engineering/source-file-parity-ledger-2026-04-22.md,
docs/reverse-engineering/source-file-parity-audit-plan-2026-04-22.md,
src/common/, src/common/platform/
Parity estimate: before 96% -> after 96%
Completed work:
- Completed the first primary-runtime tranche in the new source-file campaign
by walking all
18trackedsrc/commonentries against the current engine-wide closure and repo-wide gap ledgers. - Confirmed that no new
src/commonfile-level owners need opening beyond the already-seededRW-G01notes forplatform_config.h,platform_services.c, and the bounded auth backend shims. - Recorded the result directly in the source-file campaign docs so the
src/commonrows now distinguish current function-walk completion from the still-pending primary-runtime trees, while keepingplatform_steamworks.cclassified as a retained Steamworks wrapper surface gated by policy rather than as a newly opened repo-wide gap owner. - Narrowed
A7procedurally: the next file-walk target is now thesrc/code/qcommontranche at the head of the remaining strict-retail engine-core queue.
Task A4i: Replace the Unix Sys_CheckCD() unconditional pass with a bounded data-root probe [COMPLETED]
Priority: Medium
Primary areas: src/code/unix/unix_main.c,
tests/test_non_windows_portability.py,
docs/platform/toolchain-matrix.md, docs/build/linux-glibc-32bit.md
Parity estimate: before 96% -> after 96%
Completed work:
- Replaced the Unix
Sys_CheckCD()return qtrue;placeholder with a bounded Quake-data probe that now scans the configuredfs_basepath,fs_cdpath, default install roots, and current working directory forbaseq3/default.cfg,pak00.pk3, orpak0.pk3before reporting success. - Kept the reconstructed lane deliberately compatibility-scoped rather than
over-claiming retail parity: the probe is a coarse host-side data-root
guard for existing engine callers such as
SV_BotInitBotLib(), not a full filesystem bootstrap replacement. - Expanded the focused non-Windows portability suite so the new root list,
accepted asset markers, and
baseq3path contract are source-pinned alongside the previously restored low-memory, symbol-compare, release-marker, profiling, and clipboard seams. - Narrowed
RW-G02again: the remaining portability debt is now even more cleanly concentrated in the absent real Unix renderer/audio/input host modernization and broader non-Windows validation breadth, not in an unconditional Unix content-root success stub.
Task A4h: Restore a bounded Unix clipboard compatibility path [COMPLETED]
Priority: Medium
Primary areas: src/code/unix/unix_main.c,
tests/test_non_windows_portability.py,
docs/platform/toolchain-matrix.md, docs/build/linux-glibc-32bit.md
Parity estimate: before 96% -> after 96%
Completed work:
- Replaced the bare Unix
Sys_GetClipboardData()NULLstub with a bounded compatibility path that now reads clipboard text throughwl-paste,xclip, orxselwhen the surrounding Wayland/X11 environment and helper binaries are available, while still returningNULLcleanly on unsupported hosts. - Bounded the new lane explicitly so it mirrors the existing host contract instead of over-claiming parity: clipboard text is trimmed at the first newline/control break, capped to a fixed maximum size, and copied into the engine allocator before it reaches the existing client, UI, and browser clipboard consumers.
- Expanded the focused non-Windows portability suite so the Unix clipboard probe chain, PATH lookup, command gating, and Wayland/X11 fallback order are source-pinned alongside the earlier low-memory, symbol-compare, monkey-marker, profiling, and null-runtime compatibility seams.
- Narrowed
RW-G02again: the remaining portability debt is now even more clearly in the missing real Unix renderer/audio/input host modernization and broader non-Windows validation breadth, not in an unimplemented Unix clipboard host hook.
Task A2c: Refresh the repo-wide parity audit evidence on the current worktree [COMPLETED]
Priority: Medium
Primary areas: AUDIT.md, IMPLEMENTATION_PLAN.md,
docs/reverse-engineering/repo-wide-parity-audit-2026-04-21.md
Parity estimate: before 96% -> after 96%
Completed work:
- Re-ran a broad current-worktree parity sweep across the top-level
strict-retail gates, gameplay validation fixtures, portability suite, and
staged runtime-audit lane, producing
72 passed, 7 skipped. - Rebased the top-level ledgers on that sweep so the current repo-wide gap register is explicitly backed by one aggregated evidence pass instead of only by the individual runtime-probe refresh notes.
- Clarified that the remaining repo-wide gap families still collapse to
RW-G01,RW-G02, andRW-G04, with the staged retail-runtime DLL guard now treated as closed and the remainingRW-G04debt narrowed to fresh artifact regeneration/publication. - Cleaned up stale date language in the historical top-level audit anchors so
the repo-wide ledgers no longer point readers at the older
2026-04-17top-level state while describing the current 2026-04-21 worktree.
Task A6f: Add a strict staged retail-runtime DLL audit for native Windows validation [COMPLETED]
Priority: Medium
Primary areas: tools/ci/audit-retail-dependencies.ps1,
tools/ci/validate-windows-native.ps1, Windows/toolchain docs
Parity estimate: before 96% -> after 96%
Completed work:
- Extended the retail dependency auditor so it can now audit either the local Steam install or an explicit runtime root, checking for missing expected retail DLLs, extra non-retail DLLs, and byte-hash mismatches instead of only diffing the Steam tree opportunistically.
- Added a strict retail-runtime staging step to
tools/ci/validate-windows-native.ps1: the retail validation lane now assemblesbuild\win32\<Config>\retail-runtime\from the rebuilt host executables and gameplay/UI DLLs plus the exact retail launcher DLL payload fromassets\quakelive\, then fails fast if the staged root contains extra DLLs or is missing any retail payload DLLs. - Rebased the Windows/toolchain documentation on that explicit staging
boundary so the mixed developer build root
build\win32\<Config>\bin\is no longer described as the strict retail payload surface. - Narrowed
RW-G04again: the remaining freshness debt is now no longer the previously documented local/runtime DLL-guard follow-up, and is instead concentrated in refreshed native build outputs plus the broader glibc and self-hosted publication follow-ups.
Task A6e: Re-promote the retail module runtime alias through an explicit renderer-text bounded blocker [COMPLETED]
Priority: Medium
Primary areas: tools/modules/run_retail_module_runtime_probe.ps1,
tests/test_game_module_retail_parity_gate.py, runtime-evidence ledgers
Parity estimate: before 96% -> after 96%
Completed work:
- Expanded the retail-module probe's bounded-owner classification so the
current 2026-04-21 rerun can distinguish two renderer-owned live-map
blocker shapes outside module scope: the older fatal
R_LoadMD3drop path and the currentR_fonsErrorCallbackfont-atlas saturation lane that keeps retailuix86.dll,cgamex86.dll, andqagamex86.dllloaded but preventsCS_ACTIVE. - Rebased the module runtime probe on the current map-launch contract again by
threading the same
com_maxfps 30/ no-warmup assumptions used by the other runtime probes into the retail-module lane, while keeping the stable alias guarded so only sufficient reruns are promoted. - Reran
tools/modules/run_retail_module_runtime_probe.ps1on 2026-04-21 and refreshedartifacts/module_validation/logs/retail_module_runtime_evidence_latest.jsonto the current bounded20260421bundle instead of leaving it pinned to the older2026-04-09artifact. - Narrowed
RW-G04again: the remaining freshness debt is now no longer a non-promotable retail-module alias question, and is instead concentrated in fresh native build outputs plus the broader glibc/self-hosted publication follow-ups.
Task A4g: Restore a bounded Unix profiling control path [COMPLETED]
Priority: Medium
Primary areas: src/code/unix/unix_main.c,
src/code/unix/Makefile, tests/test_non_windows_portability.py,
portability ledgers
Parity estimate: before 96% -> after 96%
Completed work:
- Replaced the empty Unix profiling hooks with a bounded
gprof-compatible runtime path:Sys_Init()now pauses profiling early whenmoncontrolis available,Sys_BeginProfiling()re-enables it on first active play, andSys_Exit()now flushes_mcleanup()throughSys_EndProfiling(). - Added an explicit Unix build toggle
QL_ENABLE_GPROF=1so profiling is a reproducible opt-in lane rather than an undocumented linker accident. The Unix makefile now threads-pgthrough the relevant engine compile/link paths when that toggle is enabled. - Rebased the focused non-Windows portability checks and ledgers so they now record a bounded profiling lane instead of an empty Unix no-op while still keeping the broader Unix renderer/audio/input host gap open.
- Narrowed
RW-G02again: the remaining portability debt is now even more clearly in the modern Unix runtime boundary itself, not in stale host-side syscall placeholders.
Task A6d: Refresh renderer runtime evidence and stabilize alias promotion for the renderer/module probes [COMPLETED]
Priority: Medium
Primary areas: tools/renderer/run_renderer_runtime_probe.ps1,
tools/modules/run_retail_module_runtime_probe.ps1,
tests/test_renderer_full_parity_gate.py,
tests/test_renderer_text_runtime_validation_parity.py,
tests/test_game_module_retail_parity_gate.py, runtime-evidence docs
Parity estimate: before 96% -> after 96%
Completed work:
- Repaired the renderer runtime probe contract so the current
map <name> ffapath, quoted launch arguments, and normalized path handling work reliably again, then reran the probe on 2026-04-21 to refresh the clean dated bundleartifacts/renderer_validation/logs/renderer_runtime_evidence_20260421.json. - Added guarded
*_latest.jsonpromotion to both the renderer and retail module probes so only sufficient reruns replace the stable tracked alias. The renderer alias now points at the clean 2026-04-21 bundle, and the retail-module lane gained the guarded promotion rules that later enabledA6eto refresh the stable alias to the current bounded2026-04-21module artifact instead of silently accepting degraded reruns. - Rebased the renderer/module parity gates, the font audit script, and the
active runtime-evidence docs on those stable aliases plus the current
map <name> ffalaunch contract. - Narrowed
RW-G04again: the remaining freshness debt is now concentrated in fresh native build outputs and the broader glibc/self-hosted publication follow-ups.
Task A4f: Classify the Linux glibc preset as server-only portability evidence [COMPLETED]
Priority: Medium
Primary areas: docs/build/linux-glibc-32bit.md,
docs/platform/toolchain-matrix.md,
tests/test_non_windows_portability.py, portability ledgers
Parity estimate: before 96% -> after 96%
Completed work:
- Updated
docs/build/linux-glibc-32bit.mdso the helper is explicitly framed as aqagamei386.soserver-module reconstruction preset rather than as evidence of a retail-equivalent Linux client/runtime. - Mirrored that portability boundary in the native toolchain matrix so the top-level Linux lane description now points contributors at the correct server-only interpretation immediately.
- Expanded the focused non-Windows portability regression coverage so the server-module-only classification and the still-open Unix profiling or renderer/audio/input host gaps are pinned in the docs.
- Narrowed
RW-G02procedurally: the remaining work is now more cleanly about whether to modernise the real Unix host boundary, not about what the existing Linux build helper is supposed to prove.
Task A4e: Modernise the null input compatibility contract [COMPLETED]
Priority: Medium
Primary areas: src/code/null/null_input.c,
tests/test_non_windows_portability.py,
tests/test_engine_host_support_full_parity_gate.py, portability ledgers
Parity estimate: before 95% -> after 96%
Completed work:
- Modernised
src/code/null/null_input.cso the dedicated/null host now carries the current input bootstrap cvars (in_mouse,in_nograb,in_joystick,in_debugjoystick, andjoy_threshold) plus an explicit compatibility-state refresh that keepsui_joyavailpinned to0instead of leaving the file as a bare inert no-op. - Reconstructed the null input frame pump as an explicit no-device contract:
IN_Frame()now maintains the compatibility cvar surface and consumes joystick modification latches, whileSys_SendKeyEvents()now refreshes the same no-device state without emitting real input events. - Expanded both the focused non-Windows portability suite and the engine-host/support compatibility gate so the current null input lane is pinned alongside the earlier null host/client/audio modernization work.
- Narrowed
RW-G02again: the remaining portability debt is now concentrated even more tightly in the Unix profiling placeholders and the absence of a real modern Unix client/renderer/audio/input host, rather than in stale null input bootstrap/event-pump seams.
Task A4d: Modernise the null client/audio compatibility contracts [COMPLETED]
Priority: Medium
Primary areas: src/code/null/null_client.c,
src/code/null/null_snddma.c, tests/test_non_windows_portability.py,
portability ledgers
Parity estimate: before 94% -> after 95%
Completed work:
- Modernised
src/code/null/null_client.cso the null compatibility lane now exposes the current browser/advert/input-facingclient.hcontract instead of only the older partial web-host shim set: the null client now carriesCL_RefreshOnlineServicesBridgeState(), the current browser cursor and app activation hooks, mouse/button/wheel webview input stubs, and the retained advertisement-bridge entry points while explicitly forcing the browser cvars back to the non-live state. - Promoted
src/code/null/null_snddma.cfrom a narrow legacy dummy into an explicit current silent-audio compatibility seam by adding the currentSNDDMA_Activate()andS_AddVoiceSamples()entry points alongside the existing null DMA and local-sound hooks. - Expanded the focused non-Windows portability regression coverage so it now asserts the current null client/audio contract surfaces directly instead of only pinning the older null host/network/glimp tranche.
- Narrowed
RW-G02again: the remaining non-Windows debt is now concentrated in the profiling hooks plus the absence of a real modern Unix client/renderer/audio/input host, rather than in stale or missing null browser/advert/audio contract entry points.
Task A4c: Modernise the null host contracts and reconstruct the Unix monkey-marker hook [COMPLETED]
Priority: Medium
Primary areas: src/code/unix/unix_main.c, src/code/null/null_main.c,
src/code/null/null_net.c, src/code/null/mac_net.c,
src/code/null/null_glimp.c, tests/test_non_windows_portability.py,
portability ledgers
Parity estimate: before 93% -> after 94%
Completed work:
- Reconstructed the Unix
Sys_MonkeyShouldBeSpanked()compatibility hook as a retainedq3monkeyidrelease-marker probe rooted in the historicalConstructscript plus the committed retail string corpus, instead of leaving it as an unconditional placeholder. - Modernised the stale null host shims so they now match the current
qcommoncontracts:null_main.cnow carries current command-line, executable-name, timer, path, and homepath scaffolding;null_net.candmac_net.cnow exposeSys_StringToAdr()plus the current loopback packet stub signatures; andnull_glimp.cno longer carries the staleint GLimp_Init()signature. - Added focused non-Windows portability coverage for the new Unix marker probe and the null-host contract cleanup.
- Narrowed
RW-G02again: the remaining open portability debt is now concentrated in the profiling hooks plus the broader Unix/client/audio/input and still-stubbed null runtime surfaces, rather than in stale host-contract mismatches or the oldq3monkeyidplaceholder.
Task A6c: Refresh the qcommon, server, and WOW64 evidence contracts on the current machine [COMPLETED]
Priority: Medium
Primary areas: tools/qcommon/run_qcommon_runtime_probe.ps1,
tools/server/run_server_runtime_probe.ps1,
tools/ci/wow64-smoketest.ps1,
their tracked artifacts, and repo-wide validation ledgers
Parity estimate: before 93% -> after 93%
Completed work:
- Repaired the stale qcommon and dedicated-server probe contracts so both
runtime lanes now use the current
map <name> ffacommand shape, then re-ran them on 2026-04-21 to refreshartifacts/qcommon_validation/logs/qcommon_runtime_evidence_20260410.jsonandartifacts/server_validation/logs/server_runtime_evidence_20260410.json. - Rebased the qcommon and server gate/documentation expectations on the
current runtime markers, including the qcommon
game.errorplus nativestopRefreshfallback evidence and the current dedicatedgetstatusserver-type field spelling. - Updated the retained WOW64 smoke harness so it now prefers retail DLLs from
assets/quakelive/baseq3/when present but falls back to the current Win32 build outputs underbuild/win32/Debug/bin/baseq3/, then captured a successful 32-bit PowerShell run atartifacts/wow64-smoketest/wow64-smoketest.log. - Narrowed
RW-G04again: the remaining freshness debt is now concentrated in fresh native build outputs, the still-archived runtime bundles outside the refreshed client/qcommon/server lanes, and the broader glibc or self-hosted validation publication follow-ups.
Task A4b: Restore bounded Unix function compare/checksum coverage on the compatibility host lane [COMPLETED]
Priority: Medium
Primary areas: src/code/unix/unix_main.c,
tests/test_non_windows_portability.py, docs/platform/toolchain-matrix.md,
top-level portability ledgers
Parity estimate: before 93% -> after 93%
Completed work:
- Restored Unix
Sys_FunctionCmp()andSys_FunctionCheckSum()with a Linux/glibc symbol-backed path that resolves function byte ranges throughdladdr1(..., RTLD_DL_SYMENT)and hashes them withCom_BlockChecksum()when symbol sizes are available. - Added focused portability coverage that now checks the new source-side helper path directly instead of only tracking the old placeholder story in documentation.
- Narrowed
RW-G02again: the remaining open Unix helper debt is now concentrated in the historical profiling lane plus the broader non-Windows client/audio/input/toolchain boundary.
Task A6b: Re-baseline the src/ui runtime-panel contract to the clean current state [COMPLETED]
Priority: Medium
Primary areas: tests/test_ui_src_panel_parity.py,
tests/test_ui_full_parity_gate.py, docs/quakelive_asset_audit.md,
docs/ui/hud-audit.md, docs/ui/scripting-guide.md, top-level ledgers
Parity estimate: before 93% -> after 93%
Completed work:
- Tightened the repo/UI parity gates so the current worktree now expects the
src/uiruntime-panel compare to be clean (65 / 65,0content diffs) instead of tolerating the older historical non-zero drift contract. - Re-based the UI documentation and the repo-wide ledgers so they now distinguish clean checked-in runtime-panel parity from the separate bundle-staged retail art path.
- Documented that explicit runtime-root refreshes always write the runtime
package manifest, but only emit
pak_ui_src_retail_overlay.pk3whendrift_filesis non-empty.
Task A6a: Refresh the tracked client runtime evidence bundle after UI package-proof hardening [COMPLETED]
Priority: Medium
Primary areas: tools/client/run_client_runtime_probe.ps1,
tests/test_client_full_parity_gate.py,
artifacts/client_validation/logs/client_runtime_evidence_20260410.json,
client/runtime audit docs
Parity estimate: before 93% -> after 93%
Completed work:
- Tightened the client parity gate so the tracked runtime bundle must now prove the emitted UI runtime-package manifest plus the refreshed main package hashes instead of relying only on the older screenshot/log bundle.
- Rebased the main-menu offline-browser proof on the current retained runtime
behavior, using the observed
game.errorpublication and UI-sidestopRefreshfallback markers instead of the older stale probe expectations. - Re-ran
tools/client/run_client_runtime_probe.ps1on 2026-04-21 and refreshedartifacts/client_validation/logs/client_runtime_evidence_20260410.jsonwith fresh screenshots, logs, demo output, and UI package evidence. - Narrowed
RW-G04by refreshing the client runtime bundle while leaving the remaining archived runtime/build artifacts as the still-open repo-wide freshness debt.
Task A5: Harden the read-only src/ui parity path with runtime package proof [COMPLETED]
Priority: High
Primary areas: tools/build_ui_bundle.py, tests/test_ui_src_panel_parity.py,
tools/client/run_client_runtime_probe.ps1, docs/quakelive_asset_audit.md,
docs/ui/hud-audit.md, docs/ui/scripting-guide.md
Parity estimate: before 92% -> after 93%
Completed work:
- Added an explicit runtime-package manifest to
tools/build_ui_bundle.pyfor--runtime-rootruns so emittedpak_uiql.pk3andpak_ui_src_retail_overlay.pk3outputs are now machine-described instead of assumed from console output alone. - Added focused UI bundle coverage that proves the explicit runtime-root path emits the expected PK3s, includes the required runtime entries and compatibility aliases, and keeps any emitted overlay package in lockstep with the source-vs-retail drift contract.
- Tightened the client runtime probe so it now verifies the refreshed runtime package manifest and fails fast if the required UI runtime package was not emitted into the writable homepath.
- Refreshed the UI packaging docs so they consistently describe the current contract: staging/overlay manifests by default, explicit package emission only for runtime-root refreshes or probe flows, with the overlay PK3 remaining optional when the drift contract is empty.
Task A4a: Restore Unix low-memory detection on the compatibility host lane [COMPLETED]
Priority: Medium
Primary areas: src/code/unix/unix_main.c, docs/platform/toolchain-matrix.md
Parity estimate: before 92% -> after 92%
Completed work:
- Replaced the unconditional Unix
Sys_LowPhysicalMemory()placeholder with a nativesysconf()-backed physical page-count query so the renderer/cgame low-memory heuristic no longer hardcodes the non-low-memory path on Unix. - Refreshed the platform note so it now records the restored low-memory probe separately from the still-bounded checksum/comparison/profiling helpers.
- Narrowed the active
RW-G02description to the remaining portability debt instead of continuing to listSys_LowPhysicalMemory()as an unresolved placeholder.
Task A2: Repo-wide parity re-baseline and documentation convergence [COMPLETED]
Priority: Critical
Primary areas: AUDIT.md, IMPLEMENTATION_PLAN.md,
docs/reverse-engineering/repo-wide-parity-audit-2026-04-21.md,
docs/parity-plan.md, docs/ui_deltas.md, docs/ui_followup_issues.md,
docs/quakelive_asset_audit.md
Parity estimate: before 92% -> after 92%
Completed work:
- Re-ran the repo's top-level parity-gate suites on 2026-04-21 and confirmed that the strict-retail Windows gate set remains green on the current worktree.
- Re-based the top-level ledger so it now distinguishes the strict-retail Windows closure state from repo-wide parity across compatibility-only, portability, and packaging-dependent lanes.
- Published a dedicated repo-wide gap register in
docs/reverse-engineering/repo-wide-parity-audit-2026-04-21.md. - Demoted the most misleading broad-planning documents to explicit historical references so they no longer conflict with the current reverse-engineering ledgers.
Task A1: Client parity-gate revalidation and workflow restoration [COMPLETED]
Priority: Critical
Primary areas: .github/workflows/client-validation.yml,
tools/client/run_client_runtime_probe.ps1,
artifacts/client_validation/logs/*, client ledger docs
Parity estimate: before 99% -> after 100%
Completed work:
- Restored
.github/workflows/client-validation.ymlso the client validation lane again runs the focused platform, Steamworks, config, workshop, UI-menu, and unified parity-gate suites expected by the auditedCL-P6closure. - Repaired
tools/client/run_client_runtime_probe.ps1so it now:- runs against the default build-disabled client configuration
- uses the valid
map bloodrun ffacommand shape for the local-map probe - avoids helper-stdout pollution in the structured probe return path
- retries transient
pak_uiql.pk3rewrite locks on Windows - caps the probe at
com_maxfps 30, which lets the map pass reachCS_ACTIVEbefore the queued demo/screenshot/disconnect commands fire
- Refreshed
artifacts/client_validation/logs/client_runtime_evidence_20260410.jsonandartifacts/client_validation/logs/client_full_parity_gate.jsonwith a clean runtime bundle. - Revalidated the lane with:
pytest tests/test_client_full_parity_gate.py -q --tb=nopytest tests/test_platform_services.py tests/test_steamworks_harness.py tests/test_client_config_parity.py tests/test_client_workshop_bootstrap_parity.py tests/test_ui_menu_files.py tests/test_client_full_parity_gate.py -q --tb=no
Task A3a: Expose explicit compatibility-only provider/policy labels through auth, workshop, and browser-overlay surfaces [COMPLETED]
Priority: Critical
Primary areas: src/common/platform/, src/code/client/,
docs/platform/authentication.md, docs/steam_platform_abstraction.md
Parity estimate: before 96% -> after 96%
Completed work:
- Added
QL_DescribePlatformFeaturePolicy(...)as the shared companion label for platform-service descriptors and threaded that label through the client auth dispatcher so build-disabled, runtime-disabled, and provider-unavailable lanes stay explicit in auth lifecycle logs. - Mirrored the browser/advert overlay descriptor through the ROM cvars
ui_browserAwesomiumProviderandui_browserAwesomiumPolicy, and routed the blocked browser commands through provider-aware compatibility logging instead of generic โprovider unavailableโ messages. - Bounded the retained workshop bootstrap to the Steam UGC owner lane, documented provider/policy-aware fallback logging for non-Steam/bootstrap paths, and refreshed the focused platform/workshop regression coverage to keep those compatibility-only labels visible.
Task A3b: Expose explicit compatibility-only provider/policy labels through server auth and Steam GameServer surfaces [COMPLETED]
Priority: Critical
Primary areas: src/code/server/, src/code/qcommon/,
docs/platform/authentication.md, docs/steam_platform_abstraction.md
Parity estimate: before 96% -> after 96%
Completed work:
- Mirrored the retained server auth and matchmaking descriptors through the
ROM cvars
sv_platformAuthProvider,sv_platformAuthPolicy,sv_steamServerProvider, andsv_steamServerPolicyso dedicated-server diagnostics expose the active provider/policy pair just as explicitly as the client-side browser, workshop, and auth surfaces. - Bounded the Steam GameServer bootstrap/publication lane with provider/policy-aware fallback and callback logging, including the compatibility-only dedicated-server publication fallback when the retained GameServer owner is unavailable.
- Updated server-side auth telemetry so it now appends
provider=<...> policy=<...>to the message payload while intentionally preserving the legacycredential=steamfield, then refreshed the focused platform-service regression coverage to keep that compatibility labeling explicit.
Task A3c: Expose explicit compatibility-only provider/policy labels through client live-resource bridge surfaces [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_steam_resources.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-client-steam-resources.md
Parity estimate: before 96% -> after 96%
Completed work:
- Threaded the overlay service descriptorโs provider/policy labels into the
retained live-resource bridge so the
steam://avatar/resource path has the same explicit compatibility labeling as the browser overlay and workshop seams. - Replaced the generic Steam-resource and launcher-backend diagnostics with provider-aware logs that now spell out when the Steam resource bridge is disabled, when the retained SteamDataSource owner cannot satisfy a request, and when the launcher/web fallback owner is the remaining compatibility path.
- Refreshed the focused platform-service regression coverage and the
file-level
RW-G01gap note so the live-resource bridge now documents the bounded compatibility/fallback story it still implements instead of the older generic โbackend unavailableโ wording.
Task A3d: Expose explicit compatibility-only provider/policy labels through client matchmaking, stats, and social-overlay command surfaces [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md
Parity estimate: before 96% -> after 96%
Completed work:
- Mirrored the retained client matchmaking, stats, and social-overlay
descriptors through the ROM cvars
cl_matchmakingProvider,cl_matchmakingPolicy,cl_statsProvider,cl_statsPolicy,cl_socialOverlayProvider, andcl_socialOverlayPolicyso the active provider/policy pair remains visible at bootstrap and callback-init time. - Routed the retained
stats_clear,connect_lobby,clientviewprofile,clientfriendinvite, callback-bundle fallback, and main-menu rich-presence failure paths through provider-aware compatibility diagnostics instead of generic Steam-only wording. - Refreshed the focused platform-service regression coverage and the platform abstraction notes so this client command surface now documents the bounded compatibility lane it still implements.
Task A3e: Expose explicit compatibility-only provider/policy labels through the default-disabled server rankings surface [COMPLETED]
Priority: Critical
Primary areas: src/code/server/sv_rankings.c, src/code/server/sv_init.c,
tests/test_platform_services.py,
docs/reverse-engineering/source-file-gap-notes/rw-g01-server-rankings.md
Parity estimate: before 96% -> after 96%
Completed work:
- Added explicit rankings provider/policy helpers and mirrored them through
the ROM cvars
sv_rankingsProviderandsv_rankingsPolicyso the default-disabled rankings lane no longer hides behind the genericsv_rankingsActiveflag alone. - Threaded the provider/policy pair into the disabled rankings bootstrap
diagnostics so the forced
sv_enableRankings 0fallback and the retained compatibility-only rankings surface stay explicit at runtime. - Refreshed the focused server/platform-service parity checks and the
RW-G01rankings gap note so this retained GPL-era rankings lane is now documented using the same compatibility-labeling story as the other active repo-wide online-service seams.
Task A3f: Expose explicit heuristic compatibility labeling through auth backend responses and fallback traces [COMPLETED]
Priority: Critical
Primary areas: src/common/platform/backends/, src/code/client/ql_auth.c,
tools/integration/auth_flow_trace.py, docs/platform/authentication.md,
docs/steam_platform_abstraction.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the retained Steamworks and open-adapter auth backends so their response payloads explicitly identify themselves as heuristic compatibility backends instead of reading like retail live-service verdicts.
- Threaded an explicit
hybrid-fallbackstage plus fallback-dispatch log through the hybrid auth path so the open-adapter handoff is visible in lifecycle traces whenever Steamworks returns a retry-eligible result. - Refreshed the scripted auth-flow trace, the focused platform-service regression coverage, and the auth/backend gap notes so the documented QA evidence now matches the bounded compatibility story carried by the current source.
Task A3g: Expose explicit overall online-services mode/policy labels through the structural service-table surface [COMPLETED]
Priority: Critical
Primary areas: src/common/platform/platform_services.c,
src/code/client/cl_main.c, src/code/server/sv_init.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md
Parity estimate: before 96% -> after 96%
Completed work:
- Added common helpers that collapse the cached service table into overall online-services mode/policy labels, keeping the build-disabled, externally-disabled, Steamworks-only, open-adapter-only, and hybrid compatibility lanes explicit at the structural layer itself.
- Mirrored those summary labels through the new ROM cvars
cl_onlineServicesMode,cl_onlineServicesPolicy,sv_onlineServicesMode, andsv_onlineServicesPolicyso client/server diagnostics no longer require reading each per-feature provider cvar to understand the current repo-wide online-service boundary. - Refreshed the focused platform-service probes plus the
RW-G01platform-services/platform-config notes so the structural service-table and build-flag story now matches the bounded compatibility surface described by the current docs and tests.
Task A3h: Expose explicit overall online-services mode/policy labeling through auth policy-block and ticket-request failure paths [COMPLETED]
Priority: Critical
Primary areas: src/code/client/ql_auth.c,
tests/test_platform_services.py, docs/platform/authentication.md,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-client-auth.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the early Steam and standalone auth policy gates through a shared
helper that now emits explicit
policy-blockedlifecycle logs and response text naming the active overall online-services mode/policy lane instead of the older generic build/runtime wording. - Threaded that same structural mode/policy context through Steam ticket-request failure and backend-uninitialised responses so the bounded auth surface stays explicit even when no backend dispatch occurs.
- Refreshed the focused auth/platform-service regression coverage plus the
client-auth gap note and supporting docs so the documented
RW-G01compatibility story now matches those early auth exit paths too.
Task A3i: Expose explicit provider/policy labeling through the retained advert bridge surface [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_cgame.c, src/code/client/cl_main.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Mirrored the retained advert bridge through the new ROM cvars
ui_advertisementBridgeProviderandui_advertisementBridgePolicyso the active advert bridge lane is visible independently of the older browser overlay cvars. - Added bounded provider-aware advert lifecycle diagnostics for the UI/cgame
bridge transitions (
init-ui,activate,set-active, andshutdown-cgame) instead of leaving that seam implicit behind generic overlay state refreshes. - Refreshed the focused platform-service assertions plus the platform-service
abstraction/gap-note docs so the retained advert flow now matches the same
explicit compatibility-labeling story as the other active
RW-G01surfaces.
Task A3j: Expose explicit overall mode/policy labeling through the retained client voice fallback lane [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Mirrored the retained client voice compatibility lane through the new ROM
cvars
cl_voiceServiceModeandcl_voiceServicePolicyso the local speaking-state fallback no longer hides behind the broader online-services summary cvars alone. - Added explicit
voice fallbackdiagnostics for+voiceand-voice, naming the active overall online-services mode/policy lane whenever Steam voice is unavailable and the local speaking-state bridge is the remaining compatibility path. - Refreshed the focused platform-service assertions plus the
platform-service abstraction/gap-note docs so the retained voice surface now
matches the same explicit compatibility-labeling story as the other active
RW-G01seams.
Task A3k: Expose explicit overall mode/policy labeling through the retained client identity bootstrap and UI subscription lanes [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c, src/code/client/cl_ui.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Mirrored the retained client identity/bootstrap and UI app-subscription
lanes through the new ROM cvars
cl_identityBootstrapMode,cl_identityBootstrapPolicy,ui_subscriptionBridgeMode, andui_subscriptionBridgePolicyso these remaining Steam-owned shims no longer rely on the broader summary cvars alone for compatibility context. - Added explicit identity/subscription diagnostics for Steam persona-name
seeding, Steam country seeding, and the UI
IsSubscribedAppbridge, naming the active overall online-services mode/policy lane whenever the compatibility path falls back or the current provider is unavailable. - Refreshed the focused platform-service assertions plus the
platform-service abstraction/gap-note docs so the retained client bootstrap
and UI subscription surface now matches the same explicit
compatibility-labeling story as the other active
RW-G01seams.
Task A3l: Expose explicit provider/policy labeling through the retained live-resource and avatar bridge lane [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_steam_resources.c,
src/code/client/cl_main.c, src/code/client/cl_cgame.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Mirrored the retained live-resource bridge through the new ROM cvars
ui_resourceBridgeProviderandui_resourceBridgePolicyso thesteam:///launcher-backed image lane is visible independently of the older browser overlay and advert bridge cvars. - Routed the cgame avatar import through the existing provider-aware resource
stub path instead of returning before the compatibility diagnostics fired,
which keeps disabled
steam://avatar/...lookups explicit at runtime. - Refreshed the focused platform-service assertions plus the
platform-service abstraction/gap-note docs so the retained live-resource and
avatar lane now matches the same explicit compatibility-labeling story as
the other active
RW-G01seams.
Task A3m: Expose explicit provider/policy labeling through the retained client workshop lifecycle [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py,
tests/test_client_workshop_bootstrap_parity.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Mirrored the retained client workshop seam through the ROM cvars
cl_workshopProviderandcl_workshopPolicyso the active workshop owner is visible alongside the other client online-service descriptors. - Routed the workshop bootstrap, download, callback-ignore, queue-complete, and filesystem-restart diagnostics through a shared provider-aware helper, which keeps the current compatibility-only workshop lane explicit instead of falling back to generic Steamworks-only wording.
- Refreshed the focused workshop/platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so the documented workshop lifecycle now matches the same explicit compatibility-labeling story as the other active online-service seams.
Task A3n: Expose explicit provider/policy labeling through the retained dedicated-server P2P callback lane [COMPLETED]
Priority: Critical
Primary areas: src/code/server/sv_client.c,
tests/test_platform_services.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Added a shared dedicated-server P2P callback logger that reports the active Steam GameServer provider/policy pair for the retained session-request surface instead of leaving those diagnostics as raw Steam-only wording.
- Routed the server-side P2P request callback through that helper for missing client, unauthenticated client, and accept-failure paths so the bounded compatibility lane stays explicit during those callback exits too.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so the dedicated-server P2P callback path now matches the same explicit compatibility-labeling story as the other active online-service seams.
Task A3o: Expose explicit provider/policy labeling through the retained dedicated-server stats lane [COMPLETED]
Priority: Critical
Primary areas: src/code/server/sv_init.c, src/code/server/sv_client.c,
tests/test_platform_services.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Mirrored the retained dedicated-server stats seam through the ROM cvars
sv_statsProviderandsv_statsPolicyso the active GameServerStats owner is visible alongside the other server online-service descriptors. - Added a shared provider-aware server-stats logger and routed the request-current-values, session-bootstrap P2P hello failure, and stat-delta diagnostics through it so this compatibility-only lane no longer hides behind raw Steam-only wording.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so the dedicated-server stats path now matches the same explicit compatibility-labeling story as the other active online-service seams.
Task A3p: Expose explicit provider/policy labeling through the retained client rich-presence lifecycle [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c, src/code/client/cl_cgame.c,
src/code/client/client.h, tests/test_platform_services.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Exported the shared matchmaking-lane logger through
client.hso the retained first-snapshot rich-presence owner can report the active provider/policy pair instead of silently depending on a Steam-only path. - Routed the main-menu and first-snapshot rich-presence writes through explicit provider-aware fallback diagnostics for provider-unavailable and update-failed exits while preserving the existing retail status strings.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so the retained client rich-presence lifecycle now matches the same explicit compatibility-labeling story as the other active online-service seams.
Task A3q: Expose explicit provider/policy labeling through the retained dedicated-server auth rejection lane [COMPLETED]
Priority: Critical
Primary areas: src/code/server/sv_client.c,
tests/test_platform_services.py, docs/platform/authentication.md,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Added a shared dedicated-server auth rejection logger so the retained auth-session bootstrap reports the active provider/policy pair when session startup fails instead of falling back to raw Steam-only debug wording.
- Routed both auth-session bootstrap failure exits through that helper while
preserving the legacy outward
Failed to authenticate with Steam: ...message contract for stable client-facing and telemetry consumers. - Refreshed the focused platform-service regression coverage plus the auth and platform-service docs so the retained dedicated-server auth rejection path now matches the same explicit compatibility-labeling story as the other active online-service seams.
Task A3r: Expose explicit provider/policy labeling through the retained client callback and stats-registration bootstrap gates [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the disabled-services early exit in
CL_Steam_InitCallbacks()through the same provider-aware callback-bundle fallback diagnostic used by the registration-failure path, so the retained browser-event compatibility lane no longer stays silent when callbacks never become eligible. - Added explicit stats provider/policy-aware skip diagnostics to the
stats_clearregistration gate for provider-unavailable, initialisation- failed, and unsupported-app-id exits, which keeps that bootstrap boundary explicit even when the command is never registered. - Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so the retained client callback/stats bootstrap path now matches the same explicit compatibility-labeling story as the other active online-service seams.
Task A3s: Expose explicit provider/policy labeling through the retained dedicated-server callback bootstrap stub [COMPLETED]
Priority: Critical
Primary areas: src/code/server/sv_client.c,
tests/test_platform_services.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the build-disabled
SV_SteamServerInitCallbacks()stub through the same provider-aware callback-registration fallback diagnostic used by the active registration failure path, so the dedicated-server callback lane no longer disappears silently during startup. - Extended the focused platform-service regression coverage to pin that build-disabled callback-bootstrap fallback against the existing provider and policy labels.
- Refreshed the platform-service abstraction and
RW-G01gap note so the retained dedicated-server callback bootstrap now matches the same explicit compatibility-labeling story as the other active online-service seams.
Task A3t: Expose explicit mode/policy labeling through the retained client voice transport lifecycle [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Added a shared voice-transport lifecycle logger so the retained Steam voice send/receive lane now reports the active overall mode/policy pair instead of falling back to raw generic trace wording when the transport fails.
- Routed voice packet send failure, packet read failure, decompress failure,
and zero-byte-decompress diagnostics through that helper so the retained
voice transport now matches the same explicit compatibility story as the
+voice/-voicecommand surface. - Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so the retained client voice transport lifecycle now matches the same explicit compatibility-labeling story as the other active online-service seams.
Task A3u: Expose explicit provider/policy labeling through the retained dedicated-server stats-owner stubs [COMPLETED]
Priority: Critical
Primary areas: src/code/server/sv_client.c,
tests/test_platform_services.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Added a shared provider-aware stub logger for the build-disabled dedicated-
server stats owner path so the retained
SV_SteamStats_*surface no longer disappears silently when the current stats lane is unavailable. - Routed the build-disabled stat-delta, achievement-unlock, and achievement- query stubs through that helper with call-site detail strings, keeping the compatibility-only fallback explicit even when the owner functions still return without touching a live backend.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so the retained dedicated-server stats-owner stubs now match the same explicit compatibility-labeling story as the other active online-service seams.
Task A3v: Expose explicit provider/policy labeling through the retained dedicated-server networking maintenance lane [COMPLETED]
Priority: Critical
Primary areas: src/code/server/sv_main.c,
tests/test_platform_services.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Added a shared provider-aware networking logger for the retained Steam GameServer maintenance owner so keepalive and packet-relay failures no longer collapse into silent compatibility-only behavior.
- Routed keepalive send failure, inbound relay read failure, unknown relay sender, and relay-send failure exits through that helper, keeping the bounded Steam GameServer networking lane explicit whenever those paths fail.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so the retained dedicated-server networking maintenance lane now matches the same explicit compatibility-labeling story as the other active online-service seams.
Task A3w: Expose explicit provider/policy labeling through the retained dedicated-server published-state owner [COMPLETED]
Priority: Critical
Primary areas: src/code/server/sv_main.c,
tests/test_platform_services.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Added a shared provider-aware published-state logger for the retained Steam GameServer metadata owner so publication writes no longer fail silently behind the bounded compatibility lane.
- Routed max-player, password, hostname, map, game-description, game-tags, score key-value, player-data, and bot-count publication failures through that helper, keeping the retained GameServer metadata owner explicit when those writes cannot be applied.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so the retained dedicated-server published-state owner now matches the same explicit compatibility-labeling story as the other active online-service seams.
Task A3x: Expose explicit provider/policy labeling through the retained client P2P callback lane [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Added a shared matchmaking callback logger for the retained client P2P session-request owner so this callback lane no longer falls back to a raw generic Steam trace.
- Routed both the accept-failure and accepted-session callback exits through that helper with the requested remote SteamID detail, which keeps the bounded client matchmaking callback surface explicit whenever the callback fires.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so the retained client P2P callback lane now matches the same explicit compatibility-labeling story as the other active online-service seams.
Task A3y: Expose explicit provider/policy labeling through the retained client browser-event publish lane [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Added a shared browser-event lifecycle logger for the retained client
browser-event owner so this queue lane no longer falls back to generic
PublishEvent failedor rawsteam_eventtraces. - Routed the missing-view, missing-window-object, and queued-event exits through that helper with explicit queue metadata, keeping the retained overlay/browser seam honest about the current provider/policy pair whenever browser events are published.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so the retained client browser-event publish lane now matches the same explicit compatibility labeling story as the other active online-service seams.
Task A3z: Expose explicit provider/policy labeling through the retained client microtransaction callback lane [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Added a shared microtransaction callback logger for the retained client purchase-authorization lane so this callback no longer falls back to a raw generic payload dump.
- Routed the retained microtransaction authorization callback through that helper before it forwards the purchase update into the browser-event queue, keeping the overlay/browser compatibility owner explicit whenever this callback fires.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so the retained client microtransaction callback lane now matches the same explicit compatibility-labeling story as the other active online-service seams.
Task A3aa: Expose explicit provider/policy labeling through the retained dedicated-server workshop operator surface [COMPLETED]
Priority: Critical
Primary areas: src/code/server/sv_init.c, src/code/server/sv_ccmds.c,
tests/test_platform_services.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Mirrored the retained dedicated-server workshop seam through the ROM cvars
sv_workshopProviderandsv_workshopPolicyso the active workshop owner is visible alongside the other server online-service descriptors. - Added a shared provider-aware workshop operator logger plus a bounded
Steam-UGC support gate for
steam_downloadugc,steam_subscribeugc, andsteam_unsubscribeugc, which keeps those Steam-specific operator commands explicit about the current compatibility lane instead of pretending that every workshop provider owns the same surface. - Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so the retained server workshop operator surface now matches the same explicit compatibility-labeling story as the other active online-service seams.
Task A3ab: Expose explicit provider/policy labeling through the retained client web-host social and UGC export lanes [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_cgame.c, tests/test_platform_services.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Added retained web-host helpers for the overall online-service mode/policy plus matchmaking and workshop provider/policy labels, keeping the browser social/UGC export seams aligned with the repo-wide compatibility boundary.
- Updated
GetConfig, friend-list export, UGC export, andweb.ugc.failedpublication so browser callers see explicit provider/policy metadata while disabled or unavailable Steam-backed exports log bounded fallback diagnostics without changing the legacy array payload shape. - Refreshed focused regression coverage plus the platform-service abstraction
and
RW-G01gap note so the retained client web-host export lane now matches the same explicit compatibility-labeling story as the other active online-service seams.
Task A3ac: Expose explicit provider/policy labeling through the retained client lobby callback lane [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c, tests/test_platform_services.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Extended the retained matchmaking callback diagnostics so the client lobby callback owner now reports provider/policy-aware lifecycle detail for lobby create, enter, membership, chat, metadata, game-created, kicked, and join-requested events instead of only making the bounded queue visible once the browser-event publication layer runs.
- Kept the existing browser-event payload shapes intact while making the callback-origin seam explicit, which preserves the compatibility-only browser contract without letting those lobby callbacks read like silent Steam-owned behavior.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so the retained client lobby callback lane now matches the same explicit compatibility-labeling story as the other active online-service seams.
Task A3ad: Expose explicit provider/policy labeling through the retained client callback connect-handoff lane [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c, tests/test_platform_services.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained rich-presence join and server-change callback handoff through the shared matchmaking callback logger so the immediate join/connect command path now reports the active provider/policy pair instead of silently executing callback payloads.
- Added bounded callback detail for missing join commands, missing server targets, and password-seeded server-connect handoff without changing the legacy immediate-command behavior or the outward connect payload shape.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so the retained client callback connect-handoff lane now matches the same explicit compatibility-labeling story as the other active online-service seams.
Task A3ae: Expose explicit provider/policy labeling through the retained client stats callback lane [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c, tests/test_platform_services.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Added a shared stats callback logger so the retained user-stats callback owner now reports the active stats provider/policy pair instead of only becoming visible once the browser-event queue publishes the resulting payload.
- Routed the
users.stats.*.receivedcallback path through that helper with bounded SteamID, game-ID, and result detail while preserving the legacy browser-event payload shape and queue semantics. - Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so the retained client stats callback lane now matches the same explicit compatibility-labeling story as the other active online-service seams.
Task A3af: Expose explicit provider/policy labeling through the retained client social-presence and UGC callback lanes [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c, tests/test_platform_services.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained client persona-state and friend-rich-presence callback owners through the shared matchmaking callback logger so those browser-facing presence updates now report the active provider/policy pair instead of only becoming visible when the shared queue publishes them.
- Routed the retained client UGC query-complete callback through the
workshop lifecycle logger with bounded call/query/result detail while
preserving the legacy
web.ugc.results/web.ugc.failedpayload shapes and browser event names. - Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so the retained client social-presence and UGC callback lanes now match the same explicit compatibility-labeling story as the other active online-service seams.
Task A3ag: Expose explicit provider/policy labeling through the retained client workshop callback lane [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c, tests/test_platform_services.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained client workshop
ItemInstalledandDownloadItemResultcallback owners through provider/policy-aware lifecycle diagnostics so tracked completion, untracked-item ignore, and result-failure exits are explicit instead of only becoming visible through the downstream queue helpers. - Kept the existing workshop queue behavior intact: item completion still
flows through
CL_Workshop_FinalizeInstalledItem(), failures still flow throughCL_Workshop_FailActiveDownload(), and the legacy queue-advance behavior remains unchanged. - Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so the retained client workshop callback lane now matches the same explicit compatibility-labeling story as the other active online-service seams.
Task A3ah: Expose explicit provider/policy labeling through the retained dedicated-server connection callback lane [COMPLETED]
Priority: Critical
Primary areas: src/code/server/sv_client.c,
tests/test_platform_services.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained Steam GameServer connected, connect-failure, and disconnected callbacks through a shared provider/policy-aware callback lifecycle logger so those server callback-owner state changes no longer appear as isolated one-off print lines.
- Kept the existing server behavior intact: successful connects still publish identity and refreshed published state, failure/disconnect callbacks still clear the connected flag, and no auth/session routing changed.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so the retained dedicated-server connection callback lane now matches the same explicit compatibility-labeling story as the other active online-service seams.
Task A3ai: Expose explicit provider/policy labeling through the retained client workshop callback bootstrap gate [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c, tests/test_platform_services.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained client workshop callback registration-failure path through the shared workshop lifecycle logger so the polling-only fallback is explicit about the active provider/policy pair instead of appearing as a one-off raw debug line.
- Kept the existing bootstrap behavior intact: the client still enables the main callback bundle, leaves workshop progress on the polling fallback when workshop callback registration fails, and does not change queue or browser event behavior.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so the retained client workshop callback bootstrap gate now matches the same explicit compatibility-labeling story as the other active online-service seams.
Task A3aj: Expose explicit provider/policy labeling through the retained dedicated-server identity publication lane [COMPLETED]
Priority: Critical
Primary areas: src/code/server/sv_init.c, tests/test_platform_services.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained Steam GameServer identity-publication owner through a shared provider/policy-aware lifecycle logger so both the unavailable and successful publish paths are explicit instead of only surfacing a raw identity-unavailable debug line.
- Kept the existing identity behavior intact: the server still publishes the
0x2caSteamID configstring, mirrorssv_referencedSteamworks, and writes the0x2cbreferenced-workshop configstring without changing the outward contract. - Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so the retained dedicated-server identity publication lane now matches the same explicit compatibility-labeling story as the other active online-service seams.
Task A3ak: Expose explicit provider/policy labeling through the retained dedicated-server callback bootstrap gate [COMPLETED]
Priority: Critical
Primary areas: src/code/server/sv_client.c, tests/test_platform_services.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained Steam GameServer callback-registration fallback through a provider/policy-aware bootstrap lifecycle logger in both the live registration-failure path and the build-disabled stub path instead of leaving those exits as raw one-off debug lines.
- Kept the existing callback-registration behavior intact: successful
registration still clears
sv_steamServerConnected, while the unavailable paths still return immediately after surfacing the explicit compatibility diagnostic. - Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so the retained dedicated-server callback bootstrap gate now matches the same explicit compatibility-labeling story as the other active server-owned seams.
Task A3al: Expose explicit provider/policy labeling through the retained client callback bootstrap gate [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c, tests/test_platform_services.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained client callback-bundle fallback through a shared provider-aware bootstrap logger so the services-disabled and registration-failure exits now spell out the active matchmaking, stats, and social-overlay provider/policy pairs instead of staying as raw one-off debug lines.
- Kept the existing callback bootstrap behavior intact: the client still clears the browser-event and lobby state before registration, still returns early when online services stay disabled, and still unregisters the partial client/lobby/micro callback bundle before falling back.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so the retained client callback bootstrap gate now matches the same explicit compatibility-labeling story as the other active client-owned seams.
Task A3am: Expose explicit provider/policy labeling through the retained client workshop required-items bootstrap gate [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c, tests/test_platform_services.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained client workshop required-items bootstrap fallback through the shared workshop lifecycle logger so the non-Steam/bootstrap- unavailable exit no longer stays as a raw one-off print line.
- Kept the existing workshop bootstrap behavior intact: the client still logs the server-published required item list, still returns immediately when the current workshop lane cannot own Steam bootstrap, and still preserves the existing queue setup once a Steam UGC owner is available.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so the retained client workshop required-items bootstrap gate now matches the same explicit compatibility-labeling story as the other active workshop seams.
Task A3an: Expose explicit provider/policy labeling through the retained dedicated-server stats request/session lifecycle lane [COMPLETED]
Priority: Critical
Primary areas: src/code/server/sv_client.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed successful stats request issue plus the active-session reuse, fresh session-bootstrap, and backend reconnect requery transitions through the shared stats lifecycle logger, so those retained GameServerStats success paths now surface the same provider/policy pair as the existing failure diagnostics.
- Kept the retained stats owner behavior intact: existing request issuance, session reset/bootstrap, P2P hello delivery, and reconnect-driven requery semantics all remain unchanged apart from the new explicit compatibility labels.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so the retained dedicated-server stats owner now documents the same explicit compatibility-labeling story on both its request and session lifecycle paths.
Task A3ao: Expose explicit provider/policy labeling through the retained dedicated-server stats publish/store lane [COMPLETED]
Priority: Critical
Primary areas: src/code/server/sv_client.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained stats pending-value flush path through the shared stats lifecycle logger so stat publish failures, achievement publish failures, store-request failure, and successful store completion now all surface the same provider/policy pair instead of failing silently inside the GameServerStats owner.
- Kept the retained stats owner behavior intact: dirty stat/achievement accumulation, backend store submission, and dirty-bit clearing still follow the same recovered control flow, with the new compatibility labels only documenting the existing publish/store decisions.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so the retained dedicated-server stats owner now documents the same explicit compatibility-labeling story across its request, session, and publish/store lifecycle paths.
Task A3ap: Expose explicit provider/policy labeling through the retained dedicated-server stats query/load lane [COMPLETED]
Priority: Critical
Primary areas: src/code/server/sv_client.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained
GetUserStatIntandGetUserAchievementfetch paths through the shared stats lifecycle logger so stat/achievement query success and failure now surface the same provider/policy pair instead of silently returning through the dedicated-serverGameServerStatsowner. - Kept the retained stats owner behavior intact: request issuance, cached value reuse, pending-delta accumulation, and achievement unlock decisions still follow the same recovered control flow, with the new compatibility labels only documenting the existing query/load outcomes.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so the retained dedicated-server stats owner now documents the same explicit compatibility-labeling story across its request, session, query, and publish/store lifecycle paths.
Task A3aq: Expose explicit provider/policy labeling through the retained dedicated-server stats achievement owner/query lane [COMPLETED]
Priority: Critical
Primary areas: src/code/server/sv_client.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained achievement-owner entry points through the shared stats
lifecycle logger so invalid-achievement, gameplay-gated, unavailable,
session-unavailable, already-held, queued-unlock, and ownership-result
outcomes now surface the same provider/policy pair instead of returning
silently through the active
GameServerStatsowner. - Kept the retained stats owner behavior intact: achievement gate checks, session bootstrap, cached ownership reuse, and pending unlock/store flows still follow the same recovered control flow, with the new compatibility labels only documenting the existing owner/query decisions.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so the retained dedicated-server stats owner now documents the same explicit compatibility-labeling story across its request, session, query, achievement-owner, and publish/store lifecycle paths.
Task A3ar: Expose explicit provider/policy labeling through the retained dedicated-server stats field-owner lane [COMPLETED]
Priority: Critical
Primary areas: src/code/server/sv_client.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained stat-delta owner entry point through the shared stats
lifecycle logger so invalid/no-op, unavailable, session-unavailable, and
baseline-unavailable queue decisions now surface the same provider/policy
pair instead of returning silently through the active
GameServerStatsowner. - Kept the retained stats owner behavior intact: stat lookup, session bootstrap, pending-delta accumulation, and dirty-bit publication still follow the same recovered control flow, with the new compatibility labels only documenting the existing field-owner decisions.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so the retained dedicated-server stats owner now documents the same explicit compatibility-labeling story across its request, session, query, field-owner, achievement-owner, and publish/store lifecycle paths.
Task A3as: Expose explicit provider/policy labeling through the retained dedicated-server stats session-teardown lane [COMPLETED]
Priority: Critical
Primary areas: src/code/server/sv_client.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained stats session-teardown helper through the shared stats lifecycle logger so inactive-session skips and completed session clears now surface the same provider/policy pair instead of returning silently during auth/session shutdown.
- Kept the retained teardown behavior intact: pending stat/achievement flush, session reset, and caller-owned auth shutdown sequencing still follow the same recovered control flow, with the new compatibility labels only documenting the existing session-clear decisions.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so the retained dedicated-server stats owner now documents the same explicit compatibility-labeling story across its request, session, query, field-owner, achievement-owner, session-teardown, and publish/store lifecycle paths.
Task A3at: Expose explicit provider/policy labeling through the retained dedicated-server stats session-bootstrap gate [COMPLETED]
Priority: Critical
Primary areas: src/code/server/sv_client.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained stats session-bootstrap gate through the shared stats lifecycle logger so null, out-of-range, zombie, missing-gentity, missing-SteamID, bot-owned, and invalid-SteamID skips now surface the same provider/policy pair instead of returning silently before session creation.
- Kept the retained bootstrap behavior intact: valid clients still reuse live sessions, still create/reset sessions the same way, still request current values, and still send the Steam P2P hello packet with the same recovered control flow.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so the retained dedicated-server stats owner now documents the same explicit compatibility-labeling story across its request, session-bootstrap, query, field-owner, achievement-owner, session-teardown, and publish/store lifecycle paths.
Task A3au: Expose explicit provider/policy labeling through the retained dedicated-server stats client-slot gate [COMPLETED]
Priority: Critical
Primary areas: src/code/server/sv_client.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained stats client-slot helper through the shared stats lifecycle logger so out-of-range, inactive, zombie, missing-gentity, missing-SteamID, bot-owned, and invalid-SteamID gating now surface the same provider/policy pair instead of returning silently before the field and achievement owners can explain why the request stopped.
- Kept the retained owner behavior intact: valid stat/achievement callers still resolve the same live client slot, still bootstrap or reuse sessions the same way, and still apply the same field/achievement control flow once a valid slot is available.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so the retained dedicated-server stats owner now documents the same explicit compatibility-labeling story across its request, session-bootstrap, client-slot, query, field-owner, achievement-owner, session-teardown, and publish/store lifecycle paths.
Task A3av: Expose explicit provider/policy labeling through the retained dedicated-server stats request gate [COMPLETED]
Priority: Critical
Primary areas: src/code/server/sv_client.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained
SV_SteamStats_RequestCurrentValuesgate through the shared stats lifecycle logger so null-session, inactive-session, and missing-SteamID request skips now surface the same provider/policy pair instead of returning silently before the existing request issue/failure diagnostics run. - Kept the retained request behavior intact: valid sessions still issue the
same
SteamGameServerStatsrequest, still markbackendAvailableandrequestIssued, and still preserve the same success/failure control flow once the request gate is satisfied. - Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so the retained dedicated-server stats owner now documents the same explicit compatibility-labeling story across its request gate, session-bootstrap, client-slot, query, field-owner, achievement-owner, session-teardown, and publish/store lifecycle paths.
Task A3aw: Expose explicit provider/policy labeling through the retained dedicated-server stats value-query gate [COMPLETED]
Priority: Critical
Primary areas: src/code/server/sv_client.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained stat/achievement value-query gate through the shared stats lifecycle logger so null-session, inactive-session, invalid-id, unmapped-id, and already-cached paths now surface the same provider/policy pair instead of returning silently before the existing query result diagnostics run.
- Kept the retained query behavior intact: valid uncached stat and achievement requests still issue the same backend reads, still apply the same pending-delta merge or cached ownership update, and still preserve the same success/failure control flow once the query gate is satisfied.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so the retained dedicated-server stats owner now documents the same explicit compatibility-labeling story across its request gate, session-bootstrap, client-slot, value-query gate, field-owner, achievement-owner, session-teardown, and publish/store lifecycle paths.
Task A3ax: Expose explicit provider/policy labeling through the retained dedicated-server stats value-flush gate [COMPLETED]
Priority: Critical
Primary areas: src/code/server/sv_client.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained
SV_SteamStats_FlushPendingValuesgate through the shared stats lifecycle logger so null-session, inactive-session, missing-SteamID, and no-pending-update skips now surface the same provider/policy pair instead of returning silently before the existing publish/store diagnostics run. - Kept the retained flush behavior intact: dirty stat/achievement scans, backend publish attempts, store submission, and dirty-bit clearing still follow the same recovered control flow once the flush gate is satisfied.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so the retained dedicated-server stats owner now documents the same explicit compatibility-labeling story across its request gate, session-bootstrap, client-slot, value-query gate, value-flush gate, field-owner, achievement-owner, session-teardown, and publish/store lifecycle paths.
Task A3ay: Expose explicit provider/policy labeling through the retained dedicated-server stats session-reset helper [COMPLETED]
Priority: Critical
Primary areas: src/code/server/sv_client.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained
SV_SteamStats_ResetSessionhelper through the shared stats lifecycle logger so null-session skips and retained-session clears now surface the same provider/policy pair instead of clearing state silently inside the dedicated-serverGameServerStatsowner. - Kept the retained reset behavior intact: session memory still clears with
the same recovered
Com_Memsetflow, while the new compatibility labels only document when the helper is skipping or clearing retained state. - Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so the retained dedicated-server stats owner now documents the same explicit compatibility-labeling story across its request gate, session-bootstrap, client-slot, value-query gate, value-flush gate, session-reset helper, field-owner, achievement-owner, session-teardown, and publish/store lifecycle paths.
Task A3az: Expose explicit provider/policy labeling through the retained dedicated-server stats descriptor lookup helpers [COMPLETED]
Priority: Critical
Primary areas: src/code/server/sv_client.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained
SV_SteamStats_GetFieldNameandSV_SteamStats_GetAchievementNamehelpers through the shared stats lifecycle logger so invalid and unmapped descriptor lookups now surface the same provider/policy pair instead of returning silently beneath the dedicated-serverGameServerStatsowner. - Kept the retained stats behavior intact: the same caller-specific query, flush, stat-delta, and achievement owner paths still short-circuit on missing descriptors, while the helper signatures now accept the active lifecycle stage so those compatibility labels stay contextual.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so the retained dedicated-server stats owner now documents the same explicit compatibility-labeling story across its descriptor lookup helpers, request gate, session-bootstrap, client-slot, value-query gate, value-flush gate, session-reset helper, field-owner, achievement-owner, session-teardown, and publish/store lifecycle paths.
Task A3ba: Expose explicit provider/policy labeling through the retained client rich-presence join callback null-payload guard [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained
CL_Steam_Client_OnRichPresenceJoinRequestednull-event guard through the shared matchmaking callback logger so the compatibility lane now labels ignored null join payloads instead of silently returning. - Kept the retained callback handoff intact: non-null join payloads still
flow through
CL_Steam_OnRichPresenceJoinRequestedwithout behavioral changes beyond the new compatibility labeling. - Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so this client callback owner now documents the same explicit compatibility-labeling story.
Task A3bb: Expose explicit provider/policy labeling through the retained client user-stats callback null-payload guard [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained
CL_Steam_Client_OnUserStatsReceivednull-event guard through the shared stats callback logger so ignored null payloads now surface the active provider/policy pair instead of dropping silently. - Kept the retained stats browser-event behavior intact for non-null payloads: user-stat JSON publishing still follows the same recovered control flow.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so this client callback owner now documents the same explicit compatibility-labeling story.
Task A3bc: Expose explicit provider/policy labeling through the retained client persona callback null-payload guard [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained
CL_Steam_Client_OnPersonaStateChangenull-event guard through the shared matchmaking callback logger so ignored null persona payloads no longer return silently. - Kept the retained persona browser-event behavior intact for non-null payloads: the same summary formatting and publish path still applies.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so this client callback owner now documents the same explicit compatibility-labeling story.
Task A3bd: Expose explicit provider/policy labeling through the retained client P2P-session callback null-payload guard [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained
CL_Steam_Client_OnP2PSessionRequestnull-event guard through the shared matchmaking callback logger so ignored null session payloads no longer return silently. - Kept the retained accept/fail logging and
QL_Steamworks_AcceptP2PSessionbehavior intact for non-null payloads. - Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so this client callback owner now documents the same explicit compatibility-labeling story.
Task A3be: Expose explicit provider/policy labeling through the retained client server-change callback null-payload guard [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained
CL_Steam_Client_OnGameServerChangeRequestednull-event guard through the shared matchmaking callback logger so ignored null server-change payloads no longer return silently. - Kept the retained connect handoff intact: non-null payloads still flow
through
CL_Steam_OnGameServerChangeRequestedwithout behavioral changes. - Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so this client callback owner now documents the same explicit compatibility-labeling story.
Task A3bf: Expose explicit provider/policy labeling through the retained client friend rich-presence callback null-payload guard [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained
CL_Steam_Client_OnFriendRichPresenceUpdatenull-event guard through the shared matchmaking callback logger so ignored null rich-presence payloads no longer return silently. - Kept the retained friend-summary formatting and browser-event publishing intact for non-null payloads.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so this client callback owner now documents the same explicit compatibility-labeling story.
Task A3bg: Expose explicit provider/policy labeling through the retained client UGC-query callback null-payload guard [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained
CL_Steam_Client_OnUGCQueryCompletednull-event guard through the shared workshop lifecycle logger so ignored null query payloads no longer return silently. - Kept the retained UGC result/failure browser-event publishing intact for non-null payloads.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so this client callback owner now documents the same explicit compatibility-labeling story.
Task A3bh: Expose explicit provider/policy labeling through the retained client lobby-created callback null-payload guard [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained
CL_Steam_Lobby_OnLobbyCreatednull-event guard through the shared matchmaking callback logger so ignored null lobby-create payloads no longer return silently. - Kept the retained success/error lobby browser-event publishing intact for non-null payloads.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so this client callback owner now documents the same explicit compatibility-labeling story.
Task A3bi: Expose explicit provider/policy labeling through the retained client lobby-enter callback null-payload guard [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained
CL_Steam_Lobby_OnLobbyEnternull-event guard through the shared matchmaking callback logger so ignored null lobby-enter payloads no longer return silently. - Kept the retained lobby-enter success/error publishing and current-lobby tracking intact for non-null payloads.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so this client callback owner now documents the same explicit compatibility-labeling story.
Task A3bj: Expose explicit provider/policy labeling through the retained client lobby-chat-update callback null-payload guard [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained
CL_Steam_Lobby_OnLobbyChatUpdatenull-event guard through the shared matchmaking callback logger so ignored null lobby-chat payloads no longer return silently. - Kept the retained user-summary formatting and join/leave browser-event publishing intact for non-null payloads.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so this client callback owner now documents the same explicit compatibility-labeling story.
Task A3bk: Expose explicit provider/policy labeling through the retained client lobby-chat-message callback null-payload guard [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained
CL_Steam_Lobby_OnLobbyChatMessagenull-event guard through the shared matchmaking callback logger so ignored null lobby-chat message payloads no longer return silently. - Kept the retained friend-summary lookup, JSON escaping, and browser-event publishing intact for non-null payloads.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so this client callback owner now documents the same explicit compatibility-labeling story.
Task A3bl: Expose explicit provider/policy labeling through the retained client lobby-data-update callback null-payload guard [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained
CL_Steam_Lobby_OnLobbyDataUpdatenull-event guard through the shared matchmaking callback logger so ignored null lobby-data update payloads no longer return silently. - Kept the retained lobby/member detail formatting and browser-event publishing intact for non-null payloads.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so this client callback owner now documents the same explicit compatibility-labeling story.
Task A3bm: Expose explicit provider/policy labeling through the retained client lobby-game-created callback null-payload guard [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained
CL_Steam_Lobby_OnLobbyGameCreatednull-event guard through the shared matchmaking callback logger so ignored null lobby-game created payloads no longer return silently. - Kept the retained game-server detail formatting and browser-event publishing intact for non-null payloads.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so this client callback owner now documents the same explicit compatibility-labeling story.
Task A3bn: Expose explicit provider/policy labeling through the retained client lobby-kicked callback null-payload guard [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained
CL_Steam_Lobby_OnLobbyKickednull-event guard through the shared matchmaking callback logger so ignored null lobby-kicked payloads no longer return silently. - Kept the retained current-lobby clearing, detail formatting, and browser-event publishing intact for non-null payloads.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so this client callback owner now documents the same explicit compatibility-labeling story.
Task A3bo: Expose explicit provider/policy labeling through the retained client lobby-join-requested callback null-payload guard [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained
CL_Steam_Lobby_OnGameLobbyJoinRequestednull-event guard through the shared matchmaking callback logger so ignored null join-requested payloads no longer return silently. - Kept the retained lobby/friend detail formatting and browser-event publishing intact for non-null payloads.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so this client callback owner now documents the same explicit compatibility-labeling story.
Task A3bp: Expose explicit provider/policy labeling through the retained client microtransaction authorization callback null-payload guard [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained
CL_Steam_Micro_OnAuthorizationResponsenull-event guard through the shared microtransaction callback logger so ignored null authorization payloads no longer return silently. - Kept the retained purchase payload formatting and browser-event publishing intact for non-null payloads while extending the logger to spell out the null-payload compatibility path.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so this client callback owner now documents the same explicit compatibility-labeling story.
Task A3bq: Expose explicit provider/policy labeling through the retained client workshop item-installed callback null-payload guard [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained
CL_Steam_Workshop_OnItemInstallednull-event guard through the shared workshop lifecycle logger so ignored null item-installed payloads no longer return silently. - Kept the retained app-id validation, item lookup, and install-finalization behavior intact for non-null payloads.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so this client callback owner now documents the same explicit compatibility-labeling story.
Task A3br: Expose explicit provider/policy labeling through the retained client workshop item-installed inactive-download-state guard [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained
CL_Steam_Workshop_OnItemInstalledinactive-download guard through the shared workshop lifecycle logger so compatibility-owned installed callbacks now explain why no active download state can consume them. - Kept the retained unexpected-app-id, untracked-item, and install-complete handling intact once a live download state exists.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so this workshop callback guard now documents the same explicit compatibility-labeling story.
Task A3bs: Expose explicit provider/policy labeling through the retained client workshop download-result callback null-payload guard [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained
CL_Steam_Workshop_OnDownloadItemResultnull-event guard through the shared workshop lifecycle logger so ignored null download-result payloads no longer return silently. - Kept the retained app-id validation, active-item matching, and success/failure completion handling intact for non-null payloads.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so this workshop callback owner now documents the same explicit compatibility-labeling story.
Task A3bt: Expose explicit provider/policy labeling through the retained client workshop download-result inactive-lane guards [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained
CL_Steam_Workshop_OnDownloadItemResultinactive-download-state and active-item-index guards through the shared workshop lifecycle logger so compatibility-owned download callbacks now explain why no active lane can consume them. - Kept the retained unexpected-app-id, inactive-item, and success/failure-completion handling intact once a live download lane exists.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so these workshop guard exits now document the same explicit compatibility-labeling story.
Task A3bu: Expose explicit provider/policy labeling through the retained dedicated-server connect-failure callback null-payload guard [COMPLETED]
Priority: Critical
Primary areas: src/code/server/sv_client.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained
SV_SteamServerConnectFailureCallbacknull-event guard through the shared server-callback lifecycle logger so ignored null connect-failure payloads no longer return silently. - Kept the retained connected-flag clear and failure-result formatting intact for non-null payloads.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so this dedicated-server callback owner now documents the same explicit compatibility-labeling story.
Task A3bv: Expose explicit provider/policy labeling through the retained dedicated-server disconnected callback null-payload guard [COMPLETED]
Priority: Critical
Primary areas: src/code/server/sv_client.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained
SV_SteamServerDisconnectedCallbacknull-event guard through the shared server-callback lifecycle logger so ignored null disconnect payloads no longer return silently. - Kept the retained connected-flag clear and disconnect-result formatting intact for non-null payloads.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so this dedicated-server callback owner now documents the same explicit compatibility-labeling story.
Task A3bw: Expose explicit provider/policy labeling through the retained dedicated-server auth-ticket callback null-payload guard [COMPLETED]
Priority: Critical
Primary areas: src/code/server/sv_client.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained
SV_SteamServerValidateAuthTicketResponseCallbacknull-event guard through the shared server-callback lifecycle logger so ignored null auth-ticket payloads no longer return silently. - Kept the retained fake-VAC override, auth-state publication, and accept/drop handling intact for non-null payloads.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so this dedicated-server callback owner now documents the same explicit compatibility-labeling story.
Task A3bx: Expose explicit provider/policy labeling through the retained dedicated-server auth-ticket missing-client guard [COMPLETED]
Priority: Critical
Primary areas: src/code/server/sv_client.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained
SV_SteamServerValidateAuthTicketResponseCallbackmissing-client guard through the shared server-callback lifecycle logger so auth responses for no-longer-tracked clients no longer return silently. - Kept the retained client lookup and finalise/drop behavior intact once one live client session still owns the callback.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so this dedicated-server callback owner now documents the same explicit compatibility-labeling story.
Task A3by: Expose explicit provider/policy labeling through the retained dedicated-server P2P-session-request callback null-payload guard [COMPLETED]
Priority: Critical
Primary areas: src/code/server/sv_client.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained
SV_SteamServerP2PSessionRequestCallbacknull-event guard through the shared P2P-session lifecycle logger so ignored null session-request payloads no longer return silently. - Kept the retained client lookup, auth gate, and accept-call failure handling intact for non-null payloads.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so this dedicated-server callback owner now documents the same explicit compatibility-labeling story.
Task A3bz: Expose explicit provider/policy labeling through the Steamworks servers-connected dispatch guard [COMPLETED]
Priority: Critical
Primary areas: src/common/platform/platform_steamworks.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Added a shared
QL_Steamworks_LogServerCallbackDispatchhelper and routed the retainedQL_Steamworks_DispatchServersConnectedmissing-state and missing-binding guards through it so that dispatcher no longer returns silently. - Kept the retained zeroed event bootstrap and callback invocation intact once one registered dispatch target exists.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so this dispatcher guard now documents the same explicit compatibility-labeling story.
Task A3ca: Expose explicit provider/policy labeling through the Steamworks connect-failure dispatch guards [COMPLETED]
Priority: Critical
Primary areas: src/common/platform/platform_steamworks.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained
QL_Steamworks_DispatchServerConnectFailuremissing-state, missing-binding, and missing-payload guards through the shared server-dispatch logger so that dispatcher no longer returns silently. - Kept the retained raw-event translation and callback invocation intact once one valid dispatch surface and payload exist.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so these dispatcher guards now document the same explicit compatibility-labeling story.
Task A3cb: Expose explicit provider/policy labeling through the Steamworks disconnected dispatch guards [COMPLETED]
Priority: Critical
Primary areas: src/common/platform/platform_steamworks.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained
QL_Steamworks_DispatchServersDisconnectedmissing-state, missing-binding, and missing-payload guards through the shared server-dispatch logger so that dispatcher no longer returns silently. - Kept the retained raw-event translation and callback invocation intact once one valid dispatch surface and payload exist.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so these dispatcher guards now document the same explicit compatibility-labeling story.
Task A3cc: Expose explicit provider/policy labeling through the Steamworks auth-ticket dispatch guards [COMPLETED]
Priority: Critical
Primary areas: src/common/platform/platform_steamworks.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained
QL_Steamworks_DispatchValidateAuthTicketResponsemissing-state, missing-binding, and missing-payload guards through the shared server-dispatch logger so that dispatcher no longer returns silently. - Kept the retained raw auth-ticket response translation and callback invocation intact once one valid dispatch surface and payload exist.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so these dispatcher guards now document the same explicit compatibility-labeling story.
Task A3cd: Expose explicit provider/policy labeling through the Steamworks P2P-session-request dispatch guards [COMPLETED]
Priority: Critical
Primary areas: src/common/platform/platform_steamworks.c,
tests/test_platform_services.py, docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Routed the retained
QL_Steamworks_DispatchServerP2PSessionRequestmissing-state, missing-binding, and missing-payload guards through the shared server-dispatch logger so that dispatcher no longer returns silently. - Kept the retained raw P2P-session translation and callback invocation intact once one valid dispatch surface and payload exist.
- Refreshed the focused platform-service regression coverage plus the
platform-service abstraction and
RW-G01gap note so these dispatcher guards now document the same explicit compatibility-labeling story.
Task A3ce: Restore the retail direct-request workshop detail string [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c, tests/test_platform_services.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the retained client workshop direct-request lane so it now reuses
the retail-observed
Workshop item %llu: requesting download.detail. - Kept the existing compatibility wrapper ownership and queue-state updates intact around that retail string restoration.
- Refreshed the focused regression coverage and the matching abstraction/gap notes for the workshop request lane.
Task A3cf: Restore the retail queued-request workshop detail string [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c, tests/test_platform_services.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the retained client workshop bootstrap queueing lane so it now
reuses the retail-observed
Workshop item %llu: queueing download.detail. - Kept the existing deferred-download state model intact around that retail string restoration.
- Refreshed the focused regression coverage and the matching abstraction/gap notes for the queued-request lane.
Task A3cg: Restore the retail workshop cache-hit detail string [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c, tests/test_platform_services.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the retained client workshop bootstrap cache-hit lane so it now
reuses the retail-observed
Workshop item %llu: in cache.detail. - Kept the existing cached-item completion handling intact around that retail string restoration.
- Refreshed the focused regression coverage and the matching abstraction/gap notes for the cache-hit lane.
Task A3ch: Restore the retail queued-handoff workshop detail string [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c, tests/test_platform_services.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the retained client workshop queue-advance lane so it now reuses
the retail-observed
Workshop item %llu: was queued, requesting download.detail. - Kept the existing queue-advance ownership and state updates intact around that retail string restoration.
- Refreshed the focused regression coverage and the matching abstraction/gap notes for the queued handoff lane.
Task A3ci: Restore the retail workshop completion detail string [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c, tests/test_platform_services.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the retained client workshop active-item completion lane so it now
reuses the retail-observed
Steamworks download complete: %lludetail. - Kept the existing active-download clear path intact around that retail string restoration.
- Refreshed the focused regression coverage and the matching abstraction/gap notes for the workshop completion lane.
Task A3cj: Restore the retail workshop queue-complete detail string [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c, tests/test_platform_services.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the retained client workshop queue-settled lane so it now reuses
the retail-observed
Download completed for all steamworks itemsdetail. - Kept the existing queue-active reset behavior intact around that retail string restoration.
- Refreshed the focused regression coverage and the matching abstraction/gap notes for the queue-complete lane.
Task A3ck: Restore the retail workshop invalid-app skip detail in the item-installed callback [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c, tests/test_platform_services.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the retained client workshop item-installed invalid-app guard so it
now reuses the retail-observed
OnDownloadItemResult skip, invalid app id %ddetail. - Kept the existing compatibility wrapper ownership intact around that observed retail string restoration.
- Refreshed the focused regression coverage and the matching abstraction/gap notes for the item-installed invalid-app guard.
Task A3cl: Restore the retail workshop invalid-app skip detail in the download-result callback [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c, tests/test_platform_services.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the retained client workshop download-result invalid-app guard so
it now reuses the retail-observed
OnDownloadItemResult skip, invalid app id %ddetail. - Kept the existing callback wrapper ownership intact around that retail string restoration.
- Refreshed the focused regression coverage and the matching abstraction/gap notes for the download-result invalid-app guard.
Task A3cm: Restore the retail workshop active-download skip detail [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c, tests/test_platform_services.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the retained client workshop active-download mismatch guard so it
now reuses the retail-observed
OnDownloadItemResult skip, not the active download %lludetail. - Kept the existing active-item comparison and early-return behavior intact around that retail string restoration.
- Refreshed the focused regression coverage and the matching abstraction/gap notes for the active-download skip lane.
Task A3cn: Restore the retail workshop failure-result detail string [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c, tests/test_platform_services.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the retained client workshop download-result failure lane so it now
reuses the retail-observed
Download item %llu failed with EResult code %idetail. - Kept the existing failure-state and queue-advance behavior intact around that retail string restoration.
- Refreshed the focused regression coverage and the matching abstraction/gap notes for the failure-result lane.
Task A3co: Restore the retail workshop missing-pak00.pk3 warning [COMPLETED]
Priority: Critical
Primary areas: src/code/qcommon/files.c, tests/test_platform_services.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the filesystem-side workshop startup lane so it now reuses the
retail-observed
WARNING: Skipping workshop PK3s since pak00 doesn't exist.detail. - Kept the retained workshop mount pass active after that warning, matching the retail mount-mode toggle instead of turning the warning into a hard return.
- Refreshed the focused regression coverage and the matching abstraction/gap
notes for the missing-
pak00.pk3guard.
Task A3cp: Restore the retail fs_skipWorkshop skip detail [COMPLETED]
Priority: Critical
Primary areas: src/code/qcommon/files.c, tests/test_platform_services.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the filesystem-side workshop startup lane so the
fs_skipWorkshopgate now reuses the retail-observedSkipping workshop since fs_skipWorkshop is set.detail. - Kept the existing early-return ownership intact around that exact retail string restoration.
- Refreshed the focused regression coverage and the matching abstraction/gap
notes for the
fs_skipWorkshopgate.
Task A3cq: Restore the retail workshop build-mode skip detail [COMPLETED]
Priority: Critical
Primary areas: src/code/qcommon/files.c, tests/test_platform_services.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the filesystem-side workshop startup lane so the retained
com_build/com_buildScriptgate now reuses the retail-observedSkipping workshop since running in build mode.detail. - Kept the existing build-mode early return intact around that retail string restoration.
- Refreshed the focused regression coverage and the matching abstraction/gap notes for the build-mode gate.
Task A3cr: Restore the retail null-ISteamUGC skip detail [COMPLETED]
Priority: Critical
Primary areas: src/code/qcommon/files.c,
src/common/platform/platform_steamworks.c,
src/common/platform/platform_steamworks.h,
tests/test_platform_services.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the filesystem-side workshop startup lane so it now reuses the
retail-observed
WARNING: Skipping workshop, ISteamUGC is NULL.detail. - Kept the existing early-return behavior intact while splitting the null interface case away from the zero-subscribed-items case.
- Refreshed the focused regression coverage and the matching abstraction/gap
notes for the null-
ISteamUGCguard.
Task A3cs: Expose the exact workshop UGC-availability helper [COMPLETED]
Priority: Critical
Primary areas: src/common/platform/platform_steamworks.c,
src/common/platform/platform_steamworks.h,
tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Added
QL_Steamworks_HasUGCInterface()so the retained workshop startup lane can distinguish a nullISteamUGCowner from an empty subscription list. - Kept the helper thin by routing it straight through the retained
QL_Steamworks_GetUGCInterface()owner. - Refreshed the focused regression coverage for the new availability helper.
Task A3ct: Restore the retail basepath-only pak00.pk3 probe [COMPLETED]
Priority: Critical
Primary areas: src/code/qcommon/files.c, tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Updated
FS_HasBasePak0so it now mirrors the retailfs_basepath/baseq3/pak00.pk3probe instead of scanning the broader local root set. - Kept the helper bounded to the workshop startup gate, matching the retail
SteamWorkshop_Initownership. - Refreshed the focused regression coverage for the basepath-only probe.
Task A3cu: Restore the retail workshop raw-path mount toggle [COMPLETED]
Priority: Critical
Primary areas: src/code/qcommon/files.c, tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the workshop mount pass so it now forwards the retained
mountRawPathflag intoFS_AddGameDirectoryInternalinstead of always forcing the raw-path lane. - Mirrored the retail rule where the flag depends on whether
pak00.pk3was present when workshop startup began. - Refreshed the focused regression coverage for the mount-mode toggle.
Task A3cv: Restore the retail manual workshop direct-download detail [COMPLETED]
Priority: Critical
Primary areas: src/code/server/sv_ccmds.c,
tests/test_platform_services.py,
tests/test_engine_operator_command_parity.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the retained
steam_downloadugcimmediate-request lane so it now reuses the retail-observedWorkshop item %llu: downloaddetail. - Kept the existing provider/policy-aware operator logger intact around that exact retail string restoration.
- Refreshed the focused regression coverage and the matching abstraction/gap notes for the direct-download lane.
Task A3cw: Restore the retail manual workshop cache-hit detail [COMPLETED]
Priority: Critical
Primary areas: src/code/server/sv_ccmds.c,
tests/test_platform_services.py,
tests/test_engine_operator_command_parity.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the retained
steam_downloadugccache-hit lane so it now reuses the retail-observedWorkshop item %llu: in cache.detail. - Kept the existing immediate-return ownership intact around that retail string restoration.
- Refreshed the focused regression coverage and the matching abstraction/gap notes for the manual cache-hit lane.
Task A3cx: Remove the non-retail manual download failure-only diagnostic [COMPLETED]
Priority: Critical
Primary areas: src/code/server/sv_ccmds.c,
tests/test_platform_services.py,
tests/test_engine_operator_command_parity.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the retained
steam_downloadugcimmediate-request lane so it no longer emits the extra compatibility-onlydownload request faileddiagnostic that retail never printed. - Kept the existing command registration and provider-gated command surface intact while mirroring the retail immediate-request call shape more closely.
- Refreshed the focused regression coverage and the matching abstraction/gap notes for the removed non-retail failure-only diagnostic.
Task A3cy: Remove the non-retail client workshop request-failure gate [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c, tests/test_platform_services.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated
CL_Workshop_StartDownloadso it now ignores the rawQL_Steamworks_DownloadItemreturn value like the retailSteamWorkshop_RequestDownloadowner. - Kept the existing queue-state and active-item updates intact around that control-flow restoration.
- Refreshed the focused regression coverage and the matching abstraction/gap notes for the removed client request-failure gate.
Task A3cz: Remove the non-retail client workshop request-failure detail [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c, tests/test_platform_services.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Removed the extra
item %llu download request faileddetail fromCL_Workshop_StartDownload, which retail never printed. - Kept the retained retail request strings unchanged around that removal.
- Refreshed the focused regression coverage and the matching abstraction/gap notes for the removed request-failure detail.
Task A3da: Remove the duplicate client workshop failure trace [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c, tests/test_platform_services.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated
CL_Workshop_FailActiveDownloadso it no longer emits a seconditem %llu failed with EResult code %itrace after the callback owner has already logged the retail failure detail. - Kept the existing completed-state and active-download clear behavior intact.
- Refreshed the focused regression coverage and the matching abstraction/gap notes for the removed duplicate failure trace.
Task A3db: Restore the thin retail steam_subscribeugc command shape [COMPLETED]
Priority: Critical
Primary areas: src/code/server/sv_ccmds.c,
tests/test_platform_services.py,
tests/test_engine_operator_command_parity.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated
SV_SteamCmd_SubscribeUGC_fso it now mirrors the retail thin wrapper shape instead of stopping early behind the compatibility-only workshop-support gate. - Kept the existing one-argument item-ID parse surface intact.
- Refreshed the focused regression coverage and the matching abstraction/gap notes for the subscribe command shape.
Task A3dc: Remove the non-retail subscribe-request trace [COMPLETED]
Priority: Critical
Primary areas: src/code/server/sv_ccmds.c,
tests/test_platform_services.py,
tests/test_engine_operator_command_parity.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Removed the extra
subscribe requesteddiagnostic fromSV_SteamCmd_SubscribeUGC_f, which retail never printed. - Kept the retained command registration and parse surface unchanged.
- Refreshed the focused regression coverage and the matching abstraction/gap notes for the removed subscribe-request trace.
Task A3dd: Remove the non-retail subscribe-failure trace [COMPLETED]
Priority: Critical
Primary areas: src/code/server/sv_ccmds.c,
tests/test_platform_services.py,
tests/test_engine_operator_command_parity.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Removed the extra
subscribe request faileddiagnostic fromSV_SteamCmd_SubscribeUGC_f, which retail never printed. - Kept the retained direct wrapper call intact around that removal.
- Refreshed the focused regression coverage and the matching abstraction/gap notes for the removed subscribe-failure trace.
Task A3de: Restore the retail post-subscribe item-state refresh [COMPLETED]
Priority: Critical
Primary areas: src/code/server/sv_ccmds.c,
tests/test_platform_services.py,
tests/test_engine_operator_command_parity.py
Parity estimate: before 96% -> after 96%
Completed work:
- Updated
SV_SteamCmd_SubscribeUGC_fso it now re-readsQL_Steamworks_GetItemStateafter the subscribe call, matching the retailSteamWorkshop_SubscribeItemwrapper behavior. - Kept the existing one-argument item-ID parse surface intact.
- Refreshed the focused regression coverage for the post-subscribe state refresh.
Task A3df: Restore the retail post-subscribe filesystem restart fast path [COMPLETED]
Priority: Critical
Primary areas: src/code/server/sv_ccmds.c,
tests/test_platform_services.py,
tests/test_engine_operator_command_parity.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated
SV_SteamCmd_SubscribeUGC_fso it now callsFS_Restartwhen the newly subscribed item is already installed, matching the retail installed- item fast path recovered fromSteamWorkshop_SubscribeItem. - Kept the retained operator command surface intact around that restart hook.
- Refreshed the focused regression coverage and the matching abstraction/gap notes for the post-subscribe restart path.
Task A3dg: Restore the thin retail steam_unsubscribeugc command shape [COMPLETED]
Priority: Critical
Primary areas: src/code/server/sv_ccmds.c,
tests/test_platform_services.py,
tests/test_engine_operator_command_parity.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated
SV_SteamCmd_UnsubscribeUGC_fso it now mirrors the retail thin wrapper shape instead of stopping early behind the compatibility-only workshop-support gate. - Kept the existing one-argument item-ID parse surface intact.
- Refreshed the focused regression coverage and the matching abstraction/gap notes for the unsubscribe command shape.
Task A3dh: Remove the non-retail unsubscribe request/failure traces [COMPLETED]
Priority: Critical
Primary areas: src/code/server/sv_ccmds.c,
tests/test_platform_services.py,
tests/test_engine_operator_command_parity.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Removed the extra
unsubscribe requestedandunsubscribe request faileddiagnostics fromSV_SteamCmd_UnsubscribeUGC_f, which retail never printed. - Kept the retained direct wrapper call intact around those removals.
- Refreshed the focused regression coverage and the matching abstraction/gap notes for the removed unsubscribe traces.
Task A3di: Restore the thin retail steam_downloadugc command helper ownership [COMPLETED]
Priority: Critical
Primary areas: src/code/server/sv_ccmds.c,
tests/test_platform_services.py,
tests/test_engine_operator_command_parity.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated
SV_SteamCmd_DownloadUGC_fso it now mirrors the retail thin wrapper shape by handing the parsed item ID off toSV_SteamWorkshop_RequestDownloadinstead of inlining the workshop control-flow directly in the operator command. - Kept the existing one-argument item-ID parse surface intact.
- Refreshed the focused regression coverage and the matching abstraction/gap notes for the recovered command-helper ownership split.
Task A3dj: Restore the local SteamWorkshop_RequestDownload helper ownership [COMPLETED]
Priority: Critical
Primary areas: src/code/server/sv_ccmds.c,
tests/test_platform_services.py,
tests/test_engine_operator_command_parity.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Added
SV_SteamWorkshop_RequestDownloadso the compatibility-gated cache hit, restored retail detail strings, andQL_Steamworks_DownloadItemdispatch now sit under the same local helper boundary that the retailsteam_downloadugccommand calls into. - Kept the restored
Workshop item %llu: in cache.andWorkshop item %llu: downloaddetails intact around that helper recovery. - Refreshed the focused regression coverage and the matching abstraction/gap notes for the recovered request-download helper ownership.
Task A3dk: Restore the thin retail steam_subscribeugc command helper ownership [COMPLETED]
Priority: Critical
Primary areas: src/code/server/sv_ccmds.c,
tests/test_platform_services.py,
tests/test_engine_operator_command_parity.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated
SV_SteamCmd_SubscribeUGC_fso it now mirrors the retail thin wrapper shape by handing the parsed item ID off toSV_SteamWorkshop_SubscribeIteminstead of owning the workshop control flow directly. - Kept the existing one-argument item-ID parse surface intact.
- Refreshed the focused regression coverage and the matching abstraction/gap notes for the recovered subscribe-helper ownership split.
Task A3dl: Restore the thin retail steam_unsubscribeugc command helper ownership [COMPLETED]
Priority: Critical
Primary areas: src/code/server/sv_ccmds.c,
tests/test_platform_services.py,
tests/test_engine_operator_command_parity.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated
SV_SteamCmd_UnsubscribeUGC_fso it now mirrors the retail thin wrapper shape by handing the parsed item ID off toSV_SteamWorkshop_UnsubscribeIteminstead of owning the unsubscribe call path directly. - Kept the existing one-argument item-ID parse surface intact.
- Refreshed the focused regression coverage and the matching abstraction/gap notes for the recovered unsubscribe-helper ownership split.
Task A3dm: Move the recovered post-subscribe item-state refresh under the local helper owner [COMPLETED]
Priority: Critical
Primary areas: src/code/server/sv_ccmds.c,
tests/test_platform_services.py,
tests/test_engine_operator_command_parity.py
Parity estimate: before 96% -> after 96%
Completed work:
- Updated
SV_SteamWorkshop_SubscribeItemso the recoveredQL_Steamworks_GetItemStatere-read now sits under the same local helper owner that the thinsteam_subscribeugccommand calls into. - Kept the direct
QL_Steamworks_SubscribeItemwrapper call intact around that ownership correction. - Refreshed the focused regression coverage for the helper-owned post-subscribe state refresh.
Task A3dn: Move the recovered post-subscribe filesystem restart under the local helper owner [COMPLETED]
Priority: Critical
Primary areas: src/code/server/sv_ccmds.c,
tests/test_platform_services.py,
tests/test_engine_operator_command_parity.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated
SV_SteamWorkshop_SubscribeItemso the recovered installed-itemFS_Restartfast path now sits under the same local helper owner that the thinsteam_subscribeugccommand calls into. - Kept the retained operator command surface intact around that helper-owned restart path.
- Refreshed the focused regression coverage and the matching abstraction/gap notes for the helper-owned post-subscribe restart path.
Task A3do: Restore the retail platform subscribe-wrapper item-state refresh [COMPLETED]
Priority: Critical
Primary areas: src/common/platform/platform_steamworks.c,
tests/test_platform_services.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated
QL_Steamworks_SubscribeItemso it now re-readsQL_Steamworks_GetItemStateafter the raw subscribe vtable call, matching the retailSteamWorkshop_SubscribeItemhelper shape. - Kept the recovered
0xc0 / 4subscribe slot ownership intact around that state refresh. - Refreshed the focused regression coverage and the matching abstraction/gap notes for the platform subscribe-wrapper state refresh.
Task A3dp: Remove the unconditional platform subscribe success return [COMPLETED]
Priority: Critical
Primary areas: src/common/platform/platform_steamworks.c,
tests/test_platform_services.py,
tests/test_steamworks_harness.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Replaced the unconditional
return qtrue;tail inQL_Steamworks_SubscribeItemwith the recovereditemState != 0uresult, matching the retail helper's post-subscribe return contract. - Kept the wrapper ABI and surrounding UGC interface ownership unchanged.
- Refreshed the focused regression coverage and the matching abstraction/gap notes for the removed unconditional subscribe success return.
Task A3dq: Add harness coverage for the zero-state subscribe result [COMPLETED]
Priority: Critical
Primary areas: tests/test_steamworks_harness.py,
tests/steamworks_harness.c
Parity estimate: before 96% -> after 96%
Completed work:
- Extended the Steamworks harness so the enabled workshop helper test now
asserts that
QLR_Steamworks_SubscribeItemreturns false when the post- subscribe item state remains zero. - Kept the existing disabled-lane and installed-item success expectations intact around that new regression.
- Refreshed the harness support stubs so
platform_steamworks.ccontinues to compile directly under the test fixture after the newer platform-services diagnostics were added.
Task A3dr: Add harness coverage for dedicated-server installed-state subscribe success [COMPLETED]
Priority: Critical
Primary areas: tests/test_steamworks_harness.py
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the dedicated-server UGC ownership harness so it now primes the installed-item state before asserting subscribe success, matching the restored retail post-subscribe return contract.
- Kept the existing dedicated-server UGC call-count and item-ID assertions intact.
- Refreshed the focused harness coverage for the server-owned workshop lane.
Task A3ds: Restore the client bootstrap helper name to the retail request owner [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Renamed the retained client bootstrap helper to
CL_Workshop_RequestDownloadso the source-side owner now mirrors the retailSteamWorkshop_RequestDownloadhelper boundary again. - Dropped the synthetic queued-branch parameter from that helper.
- Refreshed the focused regression coverage for the recovered helper owner.
Task A3dt: Remove the non-retail queued-handoff branch from the request helper [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Removed the queued-handoff branch from
CL_Workshop_RequestDownloadso it now owns only the initialWorkshop item %llu: requesting download.detail recovered from retailSteamWorkshop_RequestDownload. - Kept the retained request-state updates intact around that narrower helper contract.
- Refreshed the focused regression coverage for the removed queued branch.
Task A3du: Restore the retail queued-handoff detail under SteamWorkshop_AdvanceDownloadQueue [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Moved the retail
Workshop item %llu: was queued, requesting download.detail underCL_Workshop_AdvanceQueue, matching the recoveredSteamWorkshop_AdvanceDownloadQueuestring owner. - Removed that detail from the initial-request helper owner.
- Refreshed the focused regression coverage for the recovered queued-handoff detail owner.
Task A3dv: Restore the queued download dispatch under the queue-pop helper [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Moved the queued
QL_Steamworks_DownloadItemdispatch underCL_Workshop_AdvanceQueue, matching the recovered retail queue-pop helper flow instead of reusing the initial-request helper. - Kept the retained queue-state bookkeeping intact around that owner shift.
- Refreshed the focused regression coverage for the recovered dispatch owner.
Task A3dw: Restore the queued active-item handoff under the queue-pop helper [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Moved the queued
CL_Workshop_SetActiveItemhandoff underCL_Workshop_AdvanceQueue, matching the retail helper that promotes the next queued item before issuing its download request. - Kept the retained progress-cvar updates intact around that recovered owner split.
- Refreshed the focused regression coverage for the queued active-item handoff owner.
Task A3dx: Restore the queue-advance owner split under SteamWorkshop_FinalizeItem [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Updated
CL_Workshop_FinalizeInstalledItemso it now returns theCL_Workshop_AdvanceQueueresult when the active item completes, matching the recovered retailSteamWorkshop_FinalizeItemhelper flow. - Kept the retained completion log and active-download clear intact around that owner split.
- Refreshed the focused regression coverage for the finalize-owned queue advance.
Task A3dy: Remove the explicit queued-handoff from the item-installed callback owner [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Removed the extra
CL_Workshop_AdvanceQueuecall fromCL_Steam_Workshop_OnItemInstalledso the callback now leaves queued handoff ownership withCL_Workshop_FinalizeInstalledItem, matching retail. - Kept the retained null/app-id/tracked-item guard surface intact.
- Refreshed the focused regression coverage for the callback-owner cleanup.
Task A3dz: Remove the explicit queued-handoff from the download-result success owner [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Removed the extra
CL_Workshop_AdvanceQueuecall from the successfulCL_Steam_Workshop_OnDownloadItemResultlane so the completion path now mirrors the retail finalize-helper ownership split. - Kept the recovered invalid-app, active-download, and failure-result details intact.
- Refreshed the focused regression coverage for the success-owner cleanup.
Task A3ea: Route bootstrap cache hits through the finalize helper owner [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the bootstrap cache-hit path so it now calls
CL_Workshop_FinalizeInstalledItemafter the retailWorkshop item %llu: in cache.detail instead of marking the item complete inline. - Kept the retained cache-hit logging intact around that recovered owner split.
- Refreshed the focused regression coverage for the finalize-owned cache-hit path.
Task A3eb: Update the bootstrap caller to use the recovered request helper split [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the client workshop bootstrap caller so the first request now goes
through
CL_Workshop_RequestDownload, while queued handoffs and completion handoffs stay with the recovered queue/finalize owners. - Refreshed the focused regression coverage plus the matching abstraction and gap-note documentation for the recovered helper ownership split.
- Kept the bounded compatibility-only workshop provider/policy diagnostics intact around that tighter retail flow.
Task A3ec: Add explicit retained state for queued workshop items [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Added an explicit
queuedflag to the retained client workshop item state so the source can distinguish queued-for-later items from items that have already issuedDownloadItem, matching the retail queue-container separation more closely. - Kept the retained
requestNumber,downloadRequested, andcompletedfields intact around that narrower queue-state split. - Refreshed the focused regression coverage for the new queued-item state.
Task A3ed: Restore bootstrap queueing ownership under SteamWorkshop_RequestDownload [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Updated
CL_Workshop_RequestDownloadso it now owns the retailWorkshop item %llu: queueing download.branch when a bootstrap download is already active, instead of leaving that detail under the caller. - Kept the recovered initial
requesting downloadbranch intact in the same helper. - Refreshed the focused regression coverage for the restored queueing-detail owner.
Task A3ee: Route every uncached bootstrap item through the recovered request helper [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the bootstrap loop so every uncached item now flows through
CL_Workshop_RequestDownload, matching the retailCL_InitDownloadscaller shape instead of splitting the queueing branch out in the caller. - Kept the retained cache-hit finalize path intact around that caller tightening.
- Refreshed the focused regression coverage for the unified request-helper routing.
Task A3ef: Mark queued bootstrap items explicitly when the request helper defers them [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Updated
CL_Workshop_RequestDownloadso it now marks later bootstrap items as explicitly queued when the active download already exists, matching the recovered retail helper's queue-container behavior more closely. - Kept the retained active-download issue path intact for the first item.
- Refreshed the focused regression coverage for the explicit queued-item mark.
Task A3eg: Make the queue-pop helper consume explicit queued items only [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Updated
CL_Workshop_AdvanceQueueso it now consumes only items marked as queued, instead of inferring queue membership from!completed && !downloadRequested. - Kept the recovered queued-handoff detail and
DownloadItemdispatch intact around that narrower scan. - Refreshed the focused regression coverage for the explicit queued scan.
Task A3eh: Clear the retained queued flag when a queued item becomes active [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Updated
CL_Workshop_AdvanceQueueso it now clears the retained queued flag before issuing the queued item'sDownloadItemrequest, matching the queue-pop ownership more closely. - Kept the retained
downloadRequestedtracking intact around that state handoff. - Refreshed the focused regression coverage for the queued-flag clear path.
Task A3ei: Restore bootstrap caller ownership of cl_downloadItem seeding [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Added
CL_Workshop_SetDownloadRequestCvarsand moved thecl_downloadItemseed under the bootstrap caller after successful request- helper returns, matching the retailCL_InitDownloadsownership split. - Kept the retained decimal SteamID formatting intact around that move.
- Refreshed the focused regression coverage for the caller-owned item cvar.
Task A3ej: Restore bootstrap caller ownership of cl_downloadName seeding [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Moved the
cl_downloadNameseed underCL_Workshop_SetDownloadRequestCvarsso the bootstrap caller now owns theWorkshop item %i of %irequest-label cvar after successful helper returns, matching retail. - Kept the retained
requestNumber/totalItemslabeling intact around that ownership split. - Refreshed the focused regression coverage for the caller-owned name cvar.
Task A3ek: Restore bootstrap caller ownership of cl_downloadTime seeding [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Moved the
cl_downloadTimeseed underCL_Workshop_SetDownloadRequestCvarsso the bootstrap caller now owns the request timestamp after successful helper returns, matching the retailCL_InitDownloadscall site. - Kept the retained
cls.realtimesource intact around that move. - Refreshed the focused regression coverage for the caller-owned time cvar.
Task A3el: Remove item/name/time cvar mutation from the active-item helper [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py,
docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Removed the
cl_downloadItem,cl_downloadName, andcl_downloadTimemutations fromCL_Workshop_SetActiveItem, leaving that helper focused on active-download state and progress-byte refresh rather than bootstrap-cvar ownership. - Kept the then-retained UI-facing
cl_downloadCount/cl_downloadSizetemp-cvar updates intact around that narrower helper contract. - Refreshed the focused regression coverage plus the matching abstraction and gap-note documentation for the recovered active-item helper split.
Task A3em: Restore installed-item handling under the client request helper [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Updated
CL_Workshop_RequestDownloadso it now owns the installed-item gate, matching the retailSteamWorkshop_RequestDownloadhelper shape instead of relying on a bootstrap-caller pre-check. - Kept the retained queued and active-download branches intact around that helper-owned cache-hit path.
- Refreshed the focused regression coverage for the recovered installed-item owner split.
Task A3en: Remove the bootstrap caller installed-state pre-check [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Removed the installed-state short-circuit from
CL_Workshop_BeginBootstrapso parsed workshop items now flow through the recovered request helper regardless of whether they are already installed. - Kept the retained parsed-item count, truncation guard, and SteamID parse surface intact.
- Refreshed the focused regression coverage for the removed caller pre-check.
Task A3eo: Restore the retail in cache detail under SteamWorkshop_RequestDownload [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Moved the retail
Workshop item %llu: in cache.detail underCL_Workshop_RequestDownload, matching the recovered helper that owns that string in retail. - Removed that detail from the bootstrap caller owner.
- Refreshed the focused regression coverage for the recovered cache-hit string owner.
Task A3ep: Restore finalize ownership for request-helper cache hits [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the request helper so installed-item cache hits now call
CL_Workshop_FinalizeInstalledItem, matching the retail helper/finalize handoff. - Removed that finalize call from the bootstrap caller cache-hit branch.
- Refreshed the focused regression coverage for the recovered finalize owner.
Task A3eq: Restore queue-gate activation for helper-owned cache hits [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Kept
CL_Workshop_RequestDownloadsetting the retained queue gate active before the installed-item branch, matching the retail helper that marks the queue lane active even when a bootstrap item is already in cache. - Left the later queue-complete owner unchanged around that recovered gate activation.
- Refreshed the focused regression coverage for the helper-owned queue gate.
Task A3er: Keep bootstrap request numbering limited to helper-success returns [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Kept
item->requestNumberassignment under the bootstrap caller's successfulCL_Workshop_RequestDownloadreturn path, matching the retailCL_InitDownloadscaller shape after the installed-item path moved under the helper. - Prevented cache-hit items from receiving bootstrap request ordinals.
- Refreshed the focused regression coverage for the request-number owner.
Task A3es: Route every parsed bootstrap item through the recovered request helper [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Tightened
CL_Workshop_BeginBootstrapso every parsed workshop item now flows throughCL_Workshop_RequestDownload, matching the retail caller that invokesSteamWorkshop_RequestDownloadfor each token. - Kept the retained truncation and parse guards intact around that caller recovery.
- Refreshed the focused regression coverage for the per-token request-helper routing.
Task A3et: Restore queue-complete eligibility for all-cached bootstrap passes [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- By moving cache-hit handling under
CL_Workshop_RequestDownload, the retained bootstrap lane now marks the queue gate active even when every required item is already installed, matching the retail path that still runs the later queue-complete helper. - Kept the retained no-download request-number and cvar behavior intact for those cache-hit items.
- Refreshed the focused regression coverage for the all-cached queue-complete eligibility lane.
Task A3eu: Update the focused workshop bootstrap regression for helper-owned cache hits [COMPLETED]
Priority: Critical
Primary areas: tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the focused client workshop regression so it now asserts the
installed-item
in cachedetail and finalize handoff underCL_Workshop_RequestDownloadinstead of under the bootstrap caller. - Added a direct assertion that the helper keeps the retained queue gate active around that installed-item branch.
- Kept the existing queued and active-download assertions intact.
Task A3ev: Refresh the abstraction notes for the helper-owned cache-hit split [COMPLETED]
Priority: Critical
Primary areas: docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md,
IMPLEMENTATION_PLAN.md
Parity estimate: before 96% -> after 96%
Completed work:
- Refreshed the abstraction notes so they now document the recovered
SteamWorkshop_RequestDownloadcache-hit ownership split and the retained all-cached queue-gate behavior. - Recorded the next ten micro-closures in the implementation ledger as
A3emthroughA3ev. - Kept the compatibility-boundary framing explicit around those retail-backed helper corrections.
Task A3ew: Restore the plain retail workshop bootstrap announcement string [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Updated
CL_Workshop_BeginBootstrapso it now prints the recovered retailServer requires the following workshop items: %sannouncement instead of the newer provider/policy-flavored compatibility detail. - Kept the retained bootstrap-unavailable compatibility log intact around that exact-string recovery.
- Refreshed the focused regression coverage for the restored announcement string.
Task A3ex: Remove the non-retail bootstrap provider/policy announcement locals [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Removed the bootstrap-only
workshopProvider/workshopPolicylocals fromCL_Workshop_BeginBootstrapafter restoring the plain retail announcement string. - Kept the later provider/policy-aware fallback diagnostics intact elsewhere in the workshop lane.
- Refreshed the focused regression coverage for the removed announcement locals.
Task A3ey: Update the bootstrap regression for the restored retail announcement [COMPLETED]
Priority: Critical
Primary areas: tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the focused client workshop bootstrap regression so it now asserts the plain retail announcement string and the absence of the removed provider/policy announcement locals.
- Kept the existing request-helper and queue-owner assertions intact.
- Reconfirmed the bootstrap regression against the current worktree.
Task A3ez: Restore the retail frame restart-required string [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Updated
CL_Workshop_Frameso the restart-required path now prints the recovered retailSteamworks downloads complete - FS restart is requireddetail. - Kept the retained
FS_Restart( clc.checksumFeed )behavior anddownloadsRequestedreset intact around that exact-string recovery. - Refreshed the focused regression coverage for the restored restart-required string.
Task A3fa: Remove the compatibility-only frame restart lifecycle trace [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Removed the compatibility-only
downloads complete; restarting filesystemworkshop lifecycle trace from the frame restart path, which retail never printed. - Replaced it with the recovered plain restart-required print under the same owner.
- Refreshed the focused regression coverage for the removed compatibility trace.
Task A3fb: Restore the retail frame completion string before pk3 validation [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Added the recovered
Steamworks downloads completeprint to the no-restart branch ofCL_Workshop_Frame, matching the retail completion helper before it performs the missing-pk3 compare. - Kept the retained state-clear and
CL_DownloadsCompletehandoff ordering unchanged around that exact-string recovery. - Refreshed the focused regression coverage for the restored completion string.
Task A3fc: Restore the retail missing-pk3 warning header under the frame helper [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Replaced the non-retail
WARNING: You are missing some files referenced by the server:wording inCL_Workshop_Framewith the recovered retailWARNING: Missing pk3s referenced by the server:header. - Kept the retained
FS_ComparePaks( ..., qfalse )gate intact around that warning path. - Refreshed the focused regression coverage for the restored warning header.
Task A3fd: Restore the retail missing-pk3 consequence line [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c,
tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Replaced the newer
You might not be able to join the game/Go to the setting menu...warning tail inCL_Workshop_Framewith the recovered retailThe server will most likely refuse the connection.line. - Kept the retained missing-file payload insertion intact around that exact warning tail.
- Refreshed the focused regression coverage for the restored consequence line.
Task A3fe: Add focused regression coverage for the retail frame strings [COMPLETED]
Priority: Critical
Primary areas: tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Added a dedicated
CL_Workshop_Frameregression so the restart-required, downloads-complete, and missing-pk3 warning strings now stay pinned to the recovered retail literals. - Included negative assertions for the removed compatibility-only restart and missing-file wording.
- Kept the retained
FS_Restart, state-clear, andCL_DownloadsCompleteowner assertions intact.
Task A3ff: Refresh the abstraction notes for the restored bootstrap/frame string surface [COMPLETED]
Priority: Critical
Primary areas: docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md,
IMPLEMENTATION_PLAN.md
Parity estimate: before 96% -> after 96%
Completed work:
- Refreshed the abstraction notes so they now document the restored plain workshop bootstrap announcement plus the recovered retail frame restart, completion, and missing-pk3 warning strings.
- Recorded the next ten micro-closures in the implementation ledger as
A3ewthroughA3ff. - Kept the compatibility-boundary framing explicit around those retail-backed exact-string corrections.
Task A3fg: Restore the retained no-restart workshop completion lane to the retail active-gate teardown [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c, tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Rechecked the retail
CL_Workshop_FrameHLIL helper and confirmed that the no-restart lane clears only the outer workshop-active gate before tailing intoCL_DownloadsComplete(). - Updated the retained frame helper to drop only
cl_steamWorkshopDownloadState.activeon the no-restart completion path instead of zeroing the full bootstrap state. - Refreshed the focused frame regression so it now pins that exact handoff.
Task A3fh: Remove the compatibility-only bootstrap-state reset from the retained workshop completion frame owner [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c, tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Removed the retained
CL_Workshop_ClearBootstrapState( qtrue )call from the workshop no-restart completion lane because the retail helper does not clear the full bootstrap structure there. - Kept the recovered retail completion/warning strings and the
CL_DownloadsComplete()handoff intact. - Added the matching negative assertion to the focused regression.
Task A3fi: Refresh the workshop frame regression for the retail active-gate handoff [COMPLETED]
Priority: Critical
Primary areas: tests/test_platform_services.py, IMPLEMENTATION_PLAN.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the focused frame test to assert the retained active-gate clear instead of the older bootstrap-state reset.
- Kept the surrounding retail restart-required, downloads-complete, and missing-pk3 string checks intact.
- Recorded the handoff correction in the implementation ledger.
Task A3fj: Bound retained workshop progress ownership to the recovered UI bridge [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c, tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Cross-checked the recovered
uix86workshop-progress path and confirmed that it readscl_downloadItem, calls the nativeGetItemDownloadInfoimport, and readscl_downloadTimerather than consumingcl_downloadCount/cl_downloadSize. - Used that evidence to trim the retained workshop helper ownership back to the native-item download-info bridge instead of generic download cvars.
- Added focused evidence coverage for that UI bridge sequence.
Task A3fk: Remove the compatibility-only generic progress-cvar write from the retained workshop active-item helper [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c, tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Removed the retained
CL_Workshop_UpdateProgressCvars()call fromCL_Workshop_SetActiveItem. - Kept the active-item byte reset and immediate native
CL_Workshop_RefreshProgress()query intact. - Refreshed the focused helper regression to pin the trimmed cvar surface.
Task A3fl: Remove the compatibility-only generic progress-cvar write from the retained workshop clear-active helper [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c, tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Removed the retained
CL_Workshop_UpdateProgressCvars()call fromCL_Workshop_ClearActiveDownload. - Kept the retained active-item and byte-count clear itself intact.
- Added the matching negative regression assertion for the helper body.
Task A3fm: Refresh the retained workshop helper regression for the trimmed progress-cvar surface [COMPLETED]
Priority: Critical
Primary areas: tests/test_platform_services.py, IMPLEMENTATION_PLAN.md
Parity estimate: before 96% -> after 96%
Completed work:
- Extended the workshop helper test to extract
CL_Workshop_ClearActiveDownload. - Added explicit negative assertions covering both the active-item helper and the clear-active helper so future edits do not reintroduce generic progress-cvar churn on workshop queue handoffs.
- Recorded that focused regression tightening in the plan ledger.
Task A3fn: Pin the recovered uix86 workshop progress bridge evidence [COMPLETED]
Priority: Critical
Primary areas: tests/test_platform_services.py,
references/reverse-engineering/ghidra/uix86/source-recreation/ui_reconstruction.c
Parity estimate: before 96% -> after 96%
Completed work:
- Added a focused evidence test covering the recovered workshop progress
bridge in
ui_reconstruction.c. - Pinned the
cl_downloadItemread, nativeGetItemDownloadInfoimport call, andcl_downloadTimeread as the companion evidence backing the retained client-side ownership trim. - Included negative assertions showing that same recovered bridge does not
use
cl_downloadCountorcl_downloadSize.
Task A3fo: Refresh the abstraction notes for the workshop completion and progress-bridge ownership correction [COMPLETED]
Priority: Critical
Primary areas: docs/steam_platform_abstraction.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the abstraction note so it now documents the retail no-restart frame handoff as an active-gate clear rather than a full bootstrap-state reset.
- Recorded the recovered
uix86workshop progress bridge evidence and the resulting removal of retained generic progress-cvar churn from the workshop active-item and clear-active helpers. - Kept the broader online-service compatibility-boundary framing explicit.
Task A3fp: Refresh the source-gap notes and ledger for the workshop completion/progress ownership correction [COMPLETED]
Priority: Critical
Primary areas: docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md,
IMPLEMENTATION_PLAN.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the
RW-G01source-gap note to match the restored workshop frame teardown and progress-bridge ownership story. - Recorded the next ten micro-closures in the implementation ledger as
A3fgthroughA3fp. - Kept the evidence wording explicit so the batch is framed as retail-backed ownership correction rather than freehand compatibility instrumentation.
Task A3fq: Restore the retained workshop queue-pop helper name to the recovered retail owner [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c, tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Rechecked the retail alias/evidence for
sub_469400and renamed the retained queue-pop helper toCL_Workshop_AdvanceDownloadQueueso it matches the recoveredSteamWorkshop_AdvanceDownloadQueueowner. - Updated the focused workshop regression to extract/assert that renamed helper directly.
- Kept the broader workshop bootstrap ownership split intact around the recovered helper family.
Task A3fr: Move the retained active-download clear under the shared queue-pop owner [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c, tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Rechecked the retail
SteamWorkshop_AdvanceDownloadQueueHLIL and restored the retained active-download clear under the shared queue-pop helper before it scans for queued items. - Removed the need for completion/failure callers to open-code that clear.
- Added focused regression coverage pinning the retained
CL_Workshop_ClearActiveDownload()call inside the queue-pop owner.
Task A3fs: Route the retained finalize helper through the shared queue-pop owner [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c, tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Updated
CL_Workshop_FinalizeInstalledItemso the active-item completion lane now tails directly intoCL_Workshop_AdvanceDownloadQueue(). - Removed the explicit active-download clear from the finalize helper body because that teardown now belongs to the shared queue-pop owner.
- Refreshed the focused helper regression so it now asserts the shared completion handoff instead of the old inline clear.
Task A3ft: Route the retained active-download failure helper through the shared queue-pop owner [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c, tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Updated
CL_Workshop_FailActiveDownloadso it now marks the active item completed and then tails intoCL_Workshop_AdvanceDownloadQueue(). - Kept the helper bounded to retained state management only; the retail failure detail still stays in the callback owner.
- Added the matching regression assertion for the shared failure handoff.
Task A3fu: Remove the ignored retained EResult parameter from the workshop failure helper [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c, tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Dropped the unused
resultparameter fromCL_Workshop_FailActiveDownloadbecause the retained helper never consumed it and the retail shared queue-pop handoff does not take that result code. - Kept the actual failure-detail formatting anchored to the
DownloadItemResultcallback owner where the retail string lives. - Updated the focused callback/helper regression to match the trimmed helper signature.
Task A3fv: Remove the callback-inline queue advance from the retained workshop download-result owner [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_main.c, tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Removed the retained
CL_Workshop_AdvanceDownloadQueue()call from theCL_Steam_Workshop_OnDownloadItemResultfailure lane. - Kept the retail failure detail log intact and let the failure helper own the shared queue-pop handoff instead.
- Added a focused negative assertion so that callback owner no longer grows a second inline queue-advance call.
Task A3fw: Refresh the retained workshop callback regression for the shared failure handoff [COMPLETED]
Priority: Critical
Primary areas: tests/test_platform_services.py, IMPLEMENTATION_PLAN.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the workshop callback regression so the download-result owner now
asserts
CL_Workshop_FailActiveDownload()without the older ignored result argument. - Added the matching negative assertion covering the removed callback-inline queue-advance call.
- Recorded that callback-owner tightening in the implementation ledger.
Task A3fx: Refresh the retained workshop helper regression for the shared queue-pop teardown [COMPLETED]
Priority: Critical
Primary areas: tests/test_platform_services.py, IMPLEMENTATION_PLAN.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the focused helper regression to extract
CL_Workshop_AdvanceDownloadQueue. - Added assertions covering the shared active-download clear in the queue-pop helper plus the new finalize/failure return handoffs.
- Tightened the downloads-settled assertion so it now references the renamed shared owner as well.
Task A3fy: Refresh the abstraction notes for the retained workshop failure/queue-pop owner split [COMPLETED]
Priority: Critical
Primary areas: docs/steam_platform_abstraction.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the abstraction note so it now documents the recovered
DownloadItemResultfailure handoff into the sharedSteamWorkshop_AdvanceDownloadQueueowner. - Recorded that the retained queue-pop helper now owns the active-download clear before scanning queued items.
- Kept the framing explicit that this batch is a bounded retail ownership correction inside the already-bounded online-services lane.
Task A3fz: Refresh the source-gap notes and ledger for the retained workshop failure/queue-pop owner split [COMPLETED]
Priority: Critical
Primary areas: docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md,
IMPLEMENTATION_PLAN.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the
RW-G01note to match the recovered shared queue-pop ownership for both workshop completion and failure lanes. - Recorded the next ten micro-closures in the implementation ledger as
A3fqthroughA3fz. - Kept the evidence wording explicit so the batch stays framed as retail helper-owner correction rather than new compatibility instrumentation.
Task A3ga: Rename the retained client UI workshop progress import parameters to the recovered low/high split [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_ui.c, tests/test_client_workshop_bootstrap_parity.py
Parity estimate: before 96% -> after 96%
Completed work:
- Rechecked the companion
uix86workshop-progress reconstruction and confirmed that the nativeGetItemDownloadInfoimport is reached from the parsedcl_downloadItemlow/high words. - Renamed the retained
QL_UI_trap_GetItemDownloadInfoparameters from genericarg1/arg2toitemIdLow/itemIdHighto match that recovered split without changing runtime behavior. - Refreshed the focused client workshop import assertion to pin the renamed retained bridge.
Task A3gb: Clarify the retained client workshop progress bridge comment against the recovered uix86 owner [COMPLETED]
Priority: Critical
Primary areas: src/code/client/cl_ui.c
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the retained client bridge comment so it now records that the
companion
uix86reconstruction parsescl_downloadItem, calls the native import with the low/high words, and then readscl_downloadTime. - Kept the retained bridge behavior unchanged: it still prefers retained client workshop state and falls back to the platform Steamworks helper.
- Preserved the workshop progress import as a naming/evidence correction rather than a behavior change.
Task A3gc: Rename the retained UI syscall wrapper parameters to the recovered low/high split [COMPLETED]
Priority: Critical
Primary areas: src/code/ui/ui_syscalls.c, tests/test_ui_menu_files.py
Parity estimate: before 96% -> after 96%
Completed work:
- Renamed
trap_QL_GetItemDownloadInfoto useitemIdLow/itemIdHighparameter names instead of the olderitemHi/itemLowording. - Kept the retained native import call order unchanged while making that order explicit in the wrapper surface.
- Refreshed the UI menu syscall regression to pin the renamed wrapper signature.
Task A3gd: Rename the retained UI local declaration for the workshop progress import to the recovered low/high split [COMPLETED]
Priority: Critical
Primary areas: src/code/ui/ui_local.h
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the retained
ui_local.hdeclaration fortrap_QL_GetItemDownloadInfoto useitemIdLow/itemIdHigh. - Kept the declaration aligned with the wrapper implementation and retained import cast signature.
- Preserved the rest of the native UI import surface unchanged.
Task A3ge: Extend the recovered workshop progress evidence test to pin the parsed item-ID split before the import call [COMPLETED]
Priority: Critical
Primary areas: tests/test_platform_services.py
Parity estimate: before 96% -> after 96%
Completed work:
- Extended the companion
uix86evidence test so it now asserts the recoveredsscanf( "%llu", ... )parse before theGetItemDownloadInfoimport call. - Kept the existing assertions covering the native import and
cl_downloadTimeread intact. - Tightened the evidence trail for the retained low/high parameter naming.
Task A3gf: Refresh the retained workshop progress import regression for the renamed client bridge parameters [COMPLETED]
Priority: Critical
Primary areas: tests/test_client_workshop_bootstrap_parity.py
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the focused workshop progress import regression so it now extracts
the renamed
QL_UI_trap_GetItemDownloadInfosignature. - Refreshed the retained bridge assertions to use
itemIdLow/itemIdHighin both the client-state and platform fallback calls. - Kept the negative assertions against generic download-count/size ownership intact.
Task A3gg: Refresh the CL-G03 parity gate for the retained workshop progress import naming correction [COMPLETED]
Priority: Critical
Primary areas: tests/test_client_full_parity_gate.py
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the
CL-G03parity gate so it now looks for the renameditemIdLow/itemIdHighsignature on the retained client workshop progress bridge. - Kept the broader workshop publication/bootstrap/mount ownership gate unchanged.
- Preserved the gate as a source-shape check rather than runtime behavior.
Task A3gh: Refresh the UI menu import-surface regression for the retained workshop progress naming correction [COMPLETED]
Priority: Critical
Primary areas: tests/test_ui_menu_files.py
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the UI menu native-import regression so it now asserts the renamed
trap_QL_GetItemDownloadInfo( itemIdLow, itemIdHigh, ... )wrapper. - Kept the rest of the recovered advert/cursor/subscription/measure-text import surface unchanged.
- Recorded the import-surface naming correction in the focused regression.
Task A3gi: Refresh the abstraction note for the recovered workshop progress import low/high split [COMPLETED]
Priority: Critical
Primary areas: docs/steam_platform_abstraction.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the abstraction note so it now explicitly records the recovered
GetItemDownloadInfolow/high-word call shape from the parsedcl_downloadItem. - Kept the surrounding workshop progress-bridge ownership story intact.
- Preserved the framing as companion-evidence-backed naming clarification.
Task A3gj: Refresh the source-gap notes and ledger for the retained workshop progress import low/high split [COMPLETED]
Priority: Critical
Primary areas: docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md,
IMPLEMENTATION_PLAN.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the
RW-G01note so it now explicitly describes the recovered low/high-wordGetItemDownloadInfobridge. - Recorded the next ten micro-closures in the implementation ledger as
A3gathroughA3gj. - Kept the batch framed as an evidence-backed interface-naming correction rather than a behavior change.
Task A3gk: Refresh the legacy workshop bootstrap parity suite for the recovered request-helper owner [COMPLETED]
Priority: Critical
Primary areas: tests/test_client_workshop_bootstrap_parity.py
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the legacy workshop parity suite to extract
CL_Workshop_RequestDownloadinstead of the removed pre-auditCL_Workshop_StartDownloadhelper. - Replaced the stale request-helper assertions with the current retail-backed
in cache,requesting download, andqueueing downloadowner split. - Kept the broader workshop bootstrap coverage anchored to current retained source instead of older compatibility wording.
Task A3gl: Refresh the legacy workshop bootstrap parity suite for the recovered shared queue-pop owner [COMPLETED]
Priority: Critical
Primary areas: tests/test_client_workshop_bootstrap_parity.py
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the legacy workshop parity suite to extract
CL_Workshop_AdvanceDownloadQueue. - Added the current shared-owner assertions for the active-download clear, queued-item clear, and retained queued download request.
- Removed the older assumptions that queue progression stayed inline under callback or finalize owners.
Task A3gm: Refresh the legacy workshop bootstrap parity suite for the recovered finalize/failure helper signatures [COMPLETED]
Priority: Critical
Primary areas: tests/test_client_workshop_bootstrap_parity.py
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the suite to match the current
qbooleanCL_Workshop_FinalizeInstalledItem/CL_Workshop_FailActiveDownloadhelper shapes. - Replaced the stale failure-helper expectation that still passed an ignored
EResultparameter. - Added the shared queue-pop handoff assertions for both completion and failure helpers.
Task A3gn: Refresh the legacy workshop bootstrap parity suite for the recovered bootstrap exact-string surface [COMPLETED]
Priority: Critical
Primary areas: tests/test_client_workshop_bootstrap_parity.py
Parity estimate: before 96% -> after 96%
Completed work:
- Replaced the stale provider/policy-decorated bootstrap string expectations
with the restored retail
Server requires the following workshop items: %sannouncement. - Updated the bootstrap-unavailable expectation to the current workshop lifecycle log detail instead of the older raw print wording.
- Kept the request-number/download-cvar ownership assertions aligned with the current retained bootstrap caller.
Task A3go: Refresh the legacy workshop bootstrap parity suite for the recovered callback bootstrap and failure-owner split [COMPLETED]
Priority: Critical
Primary areas: tests/test_client_workshop_bootstrap_parity.py
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the callback-bootstrap expectation to the current
CL_LogWorkshopLifecycle( "callback-bootstrap", detail )fallback lane. - Refreshed the item-installed and download-result callback assertions to match the current null-payload, invalid-app, untracked-item, and active-download guards.
- Added the current shared failure-handoff expectation so the callback owner no longer expects an inline queue advance.
Task A3gp: Refresh the legacy workshop bootstrap parity suite for the recovered workshop frame string surface [COMPLETED]
Priority: Critical
Primary areas: tests/test_client_workshop_bootstrap_parity.py
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the workshop frame assertions to the restored retail restart-required and downloads-complete print strings.
- Replaced the older compatibility-only restart log expectation with the current retail output plus missing-pk3 warning assertions.
- Kept the frame-order and
CL_DownloadsComplete()ownership checks intact.
Task A3gq: Refresh the legacy workshop bootstrap parity suite for the current queue-complete/request-cvar ownership split [COMPLETED]
Priority: Critical
Primary areas: tests/test_client_workshop_bootstrap_parity.py
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the queue-complete assertion to the current
Download completed for all steamworks itemsdetail. - Kept the request-number /
cl_downloadItem/cl_downloadName/cl_downloadTimeownership assertions aligned with the retained bootstrap caller and helper split. - Preserved the workshop progress owner assertions already tightened in the newer focused tests.
Task A3gr: Restore the full legacy workshop bootstrap parity suite to passing status [COMPLETED]
Priority: Critical
Primary areas: tests/test_client_workshop_bootstrap_parity.py
Parity estimate: before 96% -> after 96%
Completed work:
- Re-ran the full legacy workshop parity suite after the assertion refresh.
- Confirmed the older coverage now passes again instead of failing on removed pre-audit helper names.
- Kept the suite as supplemental validation beside the newer platform-services coverage.
Task A3gs: Refresh the abstraction note for the restored legacy workshop validation alignment [COMPLETED]
Priority: Critical
Primary areas: docs/steam_platform_abstraction.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the abstraction note so it now records that focused validation keeps the recovered workshop owner split aligned across both the platform-services and legacy workshop parity suites.
- Kept the note framed as validation coverage around the already-documented recovered owner split.
- Avoided re-framing the batch as a runtime behavior change.
Task A3gt: Refresh the source-gap notes and ledger for the restored legacy workshop validation alignment [COMPLETED]
Priority: Critical
Primary areas: docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md,
IMPLEMENTATION_PLAN.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the
RW-G01note so it now records that the recovered workshop owner split is validated in both focused workshop suites. - Recorded the next ten micro-closures in the implementation ledger as
A3gkthroughA3gt. - Kept the batch framed as validation-gap closure on top of already-restored retail-backed behavior.
Task A3gu: Refresh the Round 05 workshop wrapper note for the retained client-state progress bridge [COMPLETED]
Priority: Critical
Primary areas: docs/reverse-engineering/quakelive_steam_mapping_round_05.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the Round 05
SteamUGC_GetItemDownloadInfonote so it no longer describes the older legacy-download-counter fallback. - Recorded that the retained UI import now consults retained client workshop
state first and only then falls back to
QL_Steamworks_GetItemDownloadInfo, the retained wrapper over the same low/high-wordSteamUGC_GetItemDownloadInfoslot. - Kept the wrapper promotion itself unchanged.
Task A3gv: Refresh the Round 14 workshop import-call note for the recovered parsed low/high split [COMPLETED]
Priority: Critical
Primary areas: docs/reverse-engineering/quakelive_steam_mapping_round_14.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the Round 14 local-fact note so it now records the parsed
cl_downloadItemlow/high-word handoff before the UI import call. - Removed the stale
(itemHi, itemLo, ...)wording. - Kept the underlying wrapper identification unchanged.
Task A3gw: Refresh the Round 14 workshop import-owner note for the retained wrapper name and fallback story [COMPLETED]
Priority: Critical
Primary areas: docs/reverse-engineering/quakelive_steam_mapping_round_14.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the Round 14 note so import
96is described asQL_UI_trap_GetItemDownloadInfoinstead of the older placeholder wrapper name. - Recorded the retained-client-state-first progress bridge plus the direct Steam item-info fallback.
- Kept the wrapper role framed as a UI-owned import seam.
Task A3gx: Refresh the Round 14 alias summary for the recovered workshop import-entry wording [COMPLETED]
Priority: Critical
Primary areas: docs/reverse-engineering/quakelive_steam_mapping_round_14.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the alias-summary row for
QLUIImport_GetItemDownloadInfo. - Recorded that the wrapper is reached from the parsed
cl_downloadItemlow/high words. - Kept the alias candidate itself unchanged.
Task A3gy: Refresh the CL-G03 audit note for the retained workshop request-surface cvars [COMPLETED]
Priority: Critical
Primary areas: docs/reverse-engineering/client-full-parity-audit-and-implementation-plan-2026-04-09.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the CL-G03 closure note so it now records the retained
cl_downloadItem/cl_downloadName/cl_downloadTimerequest surface instead of the older byte-counter wording. - Kept the surrounding retained bootstrap-owner summary intact.
- Avoided re-framing the lane as a new runtime change.
Task A3gz: Refresh the CL-G03 audit note for the retained shared queue-pop callback-owner split [COMPLETED]
Priority: Critical
Primary areas: docs/reverse-engineering/client-full-parity-audit-and-implementation-plan-2026-04-09.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the CL-G03 closure note so it now records the shared queue-pop owner for installed-item completion and download-result failure.
- Removed the older phrasing that implied direct callback-owned queue advancement.
- Kept the polling-fallback note intact.
Task A3ha: Refresh the CL-P3 closure note for the retained workshop request-surface cvars [COMPLETED]
Priority: Critical
Primary areas: docs/reverse-engineering/client-full-parity-audit-and-implementation-plan-2026-04-09.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the CL-P3 completed-work note so it now records
cl_downloadItem/cl_downloadName/cl_downloadTimeinstead of the older byte-counter wording. - Kept the retained active/queued workshop bootstrap summary intact.
- Preserved the closure note as historical documentation rather than a new behavior claim.
Task A3hb: Refresh the CL-P3 closure note for the retained shared finalize/failure helper handoff [COMPLETED]
Priority: Critical
Primary areas: docs/reverse-engineering/client-full-parity-audit-and-implementation-plan-2026-04-09.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the CL-P3 callback-exactness closure note so it now records the
shared finalize/failure helper handoff into
SteamWorkshop_AdvanceDownloadQueue. - Removed the older immediate callback-owned queue-advancement wording.
- Kept the listed validation suites intact.
Task A3hc: Add focused validation for the stale reverse-engineering workshop note cleanup and tighten the CL-G03 parity gate [COMPLETED]
Priority: Critical
Primary areas: tests/test_client_workshop_bootstrap_parity.py,
tests/test_client_full_parity_gate.py
Parity estimate: before 96% -> after 96%
Completed work:
- Added a focused regression covering the refreshed Round 05 / Round 14 / client-parity-plan workshop notes.
- Tightened the
CL-G03parity gate so it now requires the current request- surface and shared queue-pop wording in the client parity plan. - Kept the gate scoped to current workshop ownership/validation shape rather than runtime artifacts.
Task A3hd: Refresh the abstraction notes, source-gap notes, and ledger for stale reverse-engineering workshop note cleanup [COMPLETED]
Priority: Critical
Primary areas: docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md,
IMPLEMENTATION_PLAN.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the abstraction/source-gap notes so they now explicitly record that the older reverse-engineering workshop notes were brought back into line with the recovered low/high import wording and shared queue-pop owner story.
- Recorded the next ten micro-closures in the implementation ledger as
A3guthroughA3hd. - Kept the batch framed as stale-note cleanup and validation tightening on top of already-restored retail-backed behavior.
Task A3he: Refresh the client CVar note for the retained workshop request-surface cvars [COMPLETED]
Priority: Critical
Primary areas: docs/client_cvars.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the client CVar note so it now records
cl_downloadItem,cl_downloadName, andcl_downloadTimeas the retained workshop request-surface trio. - Anchored that wording to the recovered
CL_InitDownloadsownership. - Kept the note scoped to documentation rather than new runtime behavior.
Task A3hf: Refresh the client CVar note for the recovered UI progress bridge [COMPLETED]
Priority: Critical
Primary areas: docs/client_cvars.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the same note so it now records the parsed
cl_downloadItemlow/high-word handoff into the nativeGetItemDownloadInfoprobe. - Kept
cl_downloadTimein the documented retained progress surface. - Avoided reintroducing the older legacy-byte-counter wording.
Task A3hg: Refresh the client CVar note for the non-authoritative counter cvars [COMPLETED]
Priority: Critical
Primary areas: docs/client_cvars.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the note so it now records
cl_downloadCountandcl_downloadSizeas UI-facing temp cvars rather than the authoritative workshop progress owner. - Kept the non-Steam fallback guidance explicit.
- Left the underlying CVar registration untouched.
Task A3hh: Refresh the CL-P3 closure note for the retained/direct workshop progress bridge [COMPLETED]
Priority: Critical
Primary areas: docs/reverse-engineering/client-full-parity-audit-and-implementation-plan-2026-04-09.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the historical
CL-P3closure note so it now describes the retained-client-state-first workshop progress bridge plus the directGetItemDownloadInfofallback keyed by parsedcl_downloadItemwords. - Removed the older generic "retained client owner" shorthand.
- Kept the rest of the closure summary intact.
Task A3hi: Add focused validation for the client workshop CVar-note alignment [COMPLETED]
Priority: Critical
Primary areas: tests/test_client_workshop_bootstrap_parity.py
Parity estimate: before 96% -> after 96%
Completed work:
- Extended the focused workshop-note regression so it now reads
docs/client_cvars.md. - Added assertions for the retained request-surface trio, direct
GetItemDownloadInfobridge wording, and the non-authoritativecl_downloadCount/cl_downloadSizenote. - Kept the test scoped to evidence-note drift rather than runtime behavior.
Task A3hj: Tighten the CL-G03 parity gate for current client workshop CVar wording [COMPLETED]
Priority: Critical
Primary areas: tests/test_client_full_parity_gate.py
Parity estimate: before 96% -> after 96%
Completed work:
- Added
docs/client_cvars.mdas a tracked CL-G03 documentation input. - Tightened the gate so it now requires the current retained/direct workshop progress wording in both the client CVar note and the client parity plan.
- Added a dedicated
client_cvar_notes_currentdetail lane for that check.
Task A3hk: Refresh the abstraction note for the aligned workshop CVar note [COMPLETED]
Priority: Critical
Primary areas: docs/steam_platform_abstraction.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the abstraction note so it now calls out the aligned
docs/client_cvars.mdwording. - Recorded that
cl_downloadItem,cl_downloadName, andcl_downloadTimeremain the retained workshop request/progress bridge. - Recorded that
cl_downloadCount/cl_downloadSizestay UI-facing temp cvars instead of the authoritative owner.
Task A3hl: Refresh the RW-G01 source-gap note for the aligned workshop CVar note [COMPLETED]
Priority: Critical
Primary areas: docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the
RW-G01note so it now calls out the aligneddocs/client_cvars.mdwording alongside the workshop progress bridge note. - Recorded the same retained trio versus UI-temp-counter split there.
- Kept the note framed as documentation alignment over already-restored behavior.
Task A3hm: Refresh the implementation ledger for the workshop CVar-note cleanup [COMPLETED]
Priority: Critical
Primary areas: IMPLEMENTATION_PLAN.md
Parity estimate: before 96% -> after 96%
Completed work:
- Recorded the client workshop CVar-note cleanup as explicit micro-closures instead of leaving it implicit.
- Kept the ledger framing evidence-backed and documentation-oriented.
- Preserved the active
A3scope summary unchanged.
Task A3hn: Record the next ten micro-closures for the client workshop CVar-note cleanup batch [COMPLETED]
Priority: Critical
Primary areas: IMPLEMENTATION_PLAN.md
Parity estimate: before 96% -> after 96%
Completed work:
- Recorded this batch in the implementation ledger as
A3hethroughA3hn. - Kept the batch framed as stale-note cleanup and validation tightening on top of already-restored retail-backed behavior.
- Avoided re-framing the batch as a runtime code change.
Task A3ho: Refresh the Round 05 workshop wrapper note for the retained direct-helper name [COMPLETED]
Priority: Critical
Primary areas: docs/reverse-engineering/quakelive_steam_mapping_round_05.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the Round 05
SteamUGC_GetItemDownloadInfonote so it now namesQL_Steamworks_GetItemDownloadInfodirectly instead of the older generic "direct Steam item-info probe" wording. - Kept the retained-client-state-first UI import story intact.
- Preserved the wrapper promotion itself unchanged.
Task A3hp: Refresh the Round 14 workshop import-call note for the retained direct-helper name [COMPLETED]
Priority: Critical
Primary areas: docs/reverse-engineering/quakelive_steam_mapping_round_14.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the Round 14 local-fact note so it now names
QL_Steamworks_GetItemDownloadInfoas the retained fallback helper. - Kept the parsed
cl_downloadItemlow/high-word handoff explicit. - Avoided changing the underlying wrapper identification.
Task A3hq: Refresh the Round 14 alias summary for the retained direct-helper bridge wording [COMPLETED]
Priority: Critical
Primary areas: docs/reverse-engineering/quakelive_steam_mapping_round_14.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the alias-summary row for
QLUIImport_GetItemDownloadInfo. - Recorded that the retained
cl_ui.cbridge falls back toQL_Steamworks_GetItemDownloadInfo. - Kept the alias candidate itself unchanged.
Task A3hr: Refresh the CL-G03 observed-source note for the retained direct-helper bridge [COMPLETED]
Priority: Critical
Primary areas: docs/reverse-engineering/client-full-parity-audit-and-implementation-plan-2026-04-09.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the historical
CL-G03observed-source note so it now namesQL_Steamworks_GetItemDownloadInfoinstead of the older generic direct Steam-item probe wording. - Kept the retained-client-state-first bridge summary intact.
- Left the surrounding workshop mount/bootstrap notes unchanged.
Task A3hs: Refresh the CL-P3 closure note for the retained direct-helper bridge [COMPLETED]
Priority: Critical
Primary areas: docs/reverse-engineering/client-full-parity-audit-and-implementation-plan-2026-04-09.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the historical
CL-P3closure note so it now namesQL_Steamworks_GetItemDownloadInfoas the retained fallback helper. - Kept the retained workshop owner split and legacy-counter exclusion intact.
- Preserved the closure note as historical documentation rather than a new runtime change.
Task A3ht: Refresh the CL-P3 exit criteria for the recovered low/high workshop progress bridge [COMPLETED]
Priority: Critical
Primary areas: docs/reverse-engineering/client-full-parity-audit-and-implementation-plan-2026-04-09.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the workshop-progress exit criterion so it now names the recovered
GetItemDownloadInfolow/high-word bridge explicitly. - Kept the negative contrast with the older generic legacy counters.
- Avoided re-framing the lane as a behavior change.
Task A3hu: Add focused validation for the refreshed workshop helper-note wording [COMPLETED]
Priority: Critical
Primary areas: tests/test_client_workshop_bootstrap_parity.py
Parity estimate: before 96% -> after 96%
Completed work:
- Extended the focused workshop-note regression to require the refreshed Round 05 / Round 14 helper wording.
- Added assertions for the current client-parity-plan wording around the retained/direct helper split and the low/high-word exit criterion.
- Kept the test scoped to evidence-note drift rather than runtime behavior.
Task A3hv: Tighten the CL-G03 parity gate for the refreshed workshop helper-note wording [COMPLETED]
Priority: Critical
Primary areas: tests/test_client_full_parity_gate.py
Parity estimate: before 96% -> after 96%
Completed work:
- Tightened the
CL-G03parity gate so it now requires the refreshed retained/direct helper wording in the client parity plan. - Kept the existing retained request-surface and shared queue-pop checks intact.
- Preserved the gate as a documentation/validation guard, not a runtime behavior claim.
Task A3hw: Refresh the abstraction and RW-G01 notes for the retained direct-helper wording alignment [COMPLETED]
Priority: Critical
Primary areas: docs/steam_platform_abstraction.md,
docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the abstraction and
RW-G01notes so they now record that the older client-parity notes were aligned to the explicitQL_Steamworks_GetItemDownloadInfofallback naming. - Kept the retained-client-state progress bridge and shared queue-pop owner story intact.
- Left the surrounding workshop/service-boundary notes unchanged.
Task A3hx: Record the next ten micro-closures for the workshop helper-note wording cleanup batch [COMPLETED]
Priority: Critical
Primary areas: IMPLEMENTATION_PLAN.md
Parity estimate: before 96% -> after 96%
Completed work:
- Recorded this batch in the implementation ledger as
A3hothroughA3hx. - Kept the batch framed as stale-note cleanup and validation tightening on top of already-restored retail-backed behavior.
- Avoided re-framing the batch as a runtime code change.
Task A3hy: Refresh the top-level CL-P3 summary for the retained direct-helper name [COMPLETED]
Priority: Critical
Primary areas: docs/reverse-engineering/client-full-parity-audit-and-implementation-plan-2026-04-09.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the top-level
CL-P3summary so it now namesQL_Steamworks_GetItemDownloadInfoinstead of the older generic direct probe wording. - Kept the retained-client-state-first bridge summary intact.
- Preserved the surrounding parity summary unchanged.
Task A3hz: Refresh the top-level CL-P3 summary for the recovered low/high-word bridge wording [COMPLETED]
Priority: Critical
Primary areas: docs/reverse-engineering/client-full-parity-audit-and-implementation-plan-2026-04-09.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the same summary so it now records the retail
SteamUGC_GetItemDownloadInfolow/high-word slot more explicitly. - Kept the parsed
cl_downloadItemownership visible in the wording. - Avoided reintroducing generic helper shorthand.
Task A3ia: Refresh the historical A3gu implementation-plan note for the retained direct-helper name [COMPLETED]
Priority: Critical
Primary areas: IMPLEMENTATION_PLAN.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the older
A3gucompleted-work note so it now namesQL_Steamworks_GetItemDownloadInfodirectly. - Kept the retained-client-state-first import story intact.
- Preserved the historical task framing.
Task A3ib: Refresh the historical A3el implementation-plan note for UI-facing temp-cvar wording [COMPLETED]
Priority: Critical
Primary areas: IMPLEMENTATION_PLAN.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the older
A3elnote so it now describes the then-retainedcl_downloadCount/cl_downloadSizeupdates as UI-facing temp cvars. - Kept the note historically accurate for that intermediate step.
- Avoided implying those counters were ever the authoritative progress owner.
Task A3ic: Add focused validation for the top-level CL-P3 workshop helper wording [COMPLETED]
Priority: Critical
Primary areas: tests/test_client_workshop_bootstrap_parity.py
Parity estimate: before 96% -> after 96%
Completed work:
- Extended the focused workshop-note regression to require the refreshed
top-level
CL-P3summary wording. - Kept the existing Round 05 / Round 14 note checks intact.
- Left the test scoped to evidence-note drift rather than runtime behavior.
Task A3id: Add focused validation for the historical implementation-plan workshop wording [COMPLETED]
Priority: Critical
Primary areas: tests/test_client_workshop_bootstrap_parity.py
Parity estimate: before 96% -> after 96%
Completed work:
- Extended the same regression so it now reads
IMPLEMENTATION_PLAN.md. - Added assertions for the refreshed
A3guhelper wording andA3eltemp-cvar wording. - Kept the validation surface narrow and evidence-backed.
Task A3ie: Tighten the CL-G03 parity gate for the refreshed implementation-plan workshop wording [COMPLETED]
Priority: Critical
Primary areas: tests/test_client_full_parity_gate.py
Parity estimate: before 96% -> after 96%
Completed work:
- Tightened the
CL-G03parity gate so it now requires the refreshed top-level client-plan wording plus the aligned implementation-plan notes. - Added a dedicated
implementation_plan_notes_currentdetail lane for that check. - Preserved the gate as a documentation/validation guard, not a runtime behavior claim.
Task A3if: Refresh the abstraction note for the aligned top-level summary and implementation-plan wording [COMPLETED]
Priority: Critical
Primary areas: docs/steam_platform_abstraction.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the abstraction note so it now calls out the aligned top-level
CL-P3summary and older implementation-plan workshop note wording. - Recorded the explicit helper naming and UI-facing temp-cvar framing there.
- Left the broader workshop boundary story unchanged.
Task A3ig: Refresh the RW-G01 note for the aligned top-level summary and implementation-plan wording [COMPLETED]
Priority: Critical
Primary areas: docs/reverse-engineering/source-file-gap-notes/rw-g01-platform-services.md
Parity estimate: before 96% -> after 96%
Completed work:
- Updated the
RW-G01note so it now records the aligned top-levelCL-P3summary and implementation-plan workshop wording. - Kept the explicit helper naming and UI-facing temp-cvar framing visible.
- Preserved the surrounding compatibility-boundary note unchanged.
Task A3ih: Record the next ten micro-closures for the workshop summary-and-ledger wording cleanup batch [COMPLETED]
Priority: Critical
Primary areas: IMPLEMENTATION_PLAN.md
Parity estimate: before 96% -> after 96%
Completed work:
- Recorded this batch in the implementation ledger as
A3hythroughA3ih. - Kept the batch framed as stale-note cleanup and validation tightening on top of already-restored retail-backed behavior.
- Avoided re-framing the batch as a runtime code change.
Task A3ii: Close RW-G01 as a documented bounded divergence across the repo-wide ledgers [COMPLETED]
Priority: Critical
Primary areas: AUDIT.md, IMPLEMENTATION_PLAN.md,
docs/reverse-engineering/repo-wide-parity-audit-2026-04-21.md,
docs/reverse-engineering/source-file-parity-ledger-2026-04-22.md,
docs/reverse-engineering/source-file-parity-audit-plan-2026-04-22.md,
docs/reverse-engineering/source-file-gap-notes/,
tools/reverse-engineering/generate_source_file_audit.py
Parity estimate: before 96% -> after 98%
Completed work:
- Reclassified the
RW-G01online-services lane as an intentional documented divergence instead of active repo-wide parity debt, while keeping the strict-retail Windows target unchanged at100%. - Updated the source-file audit generator and regenerated the plan, ledger,
and per-file note set so the seven
RW-G01owners now land under documented-divergence notes whileRW-G02remains the only active file-level compatibility gap family. - Refreshed the top-level repo-wide ledgers so the checked-in whole-repo
estimate now reads
98%, withRW-G02andRW-G04left as the active remaining repo-wide gap families.
Task A4j: Add a bounded silent Linux sound sink and close the OSS shutdown leak [COMPLETED]
Priority: Medium
Primary areas: src/code/unix/linux_snd.c,
tests/test_non_windows_portability.py,
docs/reverse-engineering/source-file-gap-notes/rw-g02-linux-snd.md,
docs/platform/toolchain-matrix.md, docs/build/linux-glibc-32bit.md
Parity estimate: before 98% -> after 98%
Completed work:
- Added an explicit silent Linux DMA sink selected through
snddevice null,none, orsilent, giving headless/client smoke probes a non-OSS sound path without pulling in ALSA, PulseAudio, SDL, or other external library code. - Reconstructed the Linux sound lifecycle around the retained OSS backend so
audio_fdstarts at-1, failed init paths route through shared cleanup, andSNDDMA_Shutdown()now unmaps the mmap DMA buffer and closes the sound descriptor instead of leaving restart/error cleanup implicit. - Kept the result deliberately bounded: the default Linux sound backend is
still the legacy
/dev/dspOSS path, the silent sink is not an audible backend, andRW-G02remains open until the broader Linux client renderer, audio, input, and validation boundary is settled. - Expanded the focused non-Windows portability suite and refreshed the platform/gap notes so the new silent sink, DMA-position simulation, and OSS shutdown cleanup stay source-pinned as compatibility work rather than strict-retail Windows parity.
Task A4k: Bound the retained Linux joystick device and restart lifecycle [COMPLETED]
Priority: Medium
Primary areas: src/code/unix/linux_joystick.c,
src/code/unix/linux_glimp.c, src/code/unix/linux_local.h,
tests/test_non_windows_portability.py,
docs/reverse-engineering/source-file-gap-notes/rw-g02-linux-joystick.md,
docs/reverse-engineering/source-file-gap-notes/rw-g02-linux-glimp.md,
docs/platform/toolchain-matrix.md
Parity estimate: before 98% -> after 98%
Completed work:
- Reworked the retained Linux joystick lane so startup now scans modern
/dev/input/js0through/dev/input/js3before the historical/dev/js0through/dev/js3nodes, while still avoiding SDL or any other external input library. - Added explicit joystick shutdown/restart handling:
IN_ShutdownJoystick()releases queued joystick key state, clears tracked axes/buttons, closesjoy_fd, and resetsui_joyavail;linux_glimp.cnow calls that path on input shutdown and when latchedin_joystickchanges trigger a restart. - Bounded event translation so Linux button events cannot exceed the
K_JOY1throughK_JOY32range and axis events cannot exceed the retained eight-axis / sixteen-direction-key table. - Kept
RW-G02open because this is still retained Linux joystick compatibility, not a validated modern Linux client input stack, and pinned that distinction in the focused portability suite and gap notes.
Task A4l: Bound the retained Linux mouse/input shutdown lifecycle [COMPLETED]
Priority: Medium
Primary areas: src/code/unix/linux_glimp.c,
tests/test_non_windows_portability.py,
docs/reverse-engineering/source-file-gap-notes/rw-g02-linux-glimp.md,
docs/reverse-engineering/function-parity-gap-audit-2026-04-24.md,
docs/platform/toolchain-matrix.md, docs/build/linux-glibc-32bit.md
Parity estimate: before 98% -> after 98%
Completed work:
- Reconstructed the Linux input shutdown path around the retained X11 mouse
grab lifecycle so
IN_Shutdown()now callsIN_DeactivateMouse()before clearingmouse_avail, avoiding stale grab/activity state acrossin_restartand normal input teardown. - Kept joystick teardown in the same host-owned shutdown path and now clears
mouse_activeexplicitly after the deactivate call, so a laterIN_Init()can reactivate the mouse according to the current cvar state instead of inheriting a stale active flag. - Added focused source assertions and refreshed the RW-G02 notes so this remains bounded Linux-host compatibility work rather than a claim that the legacy X11/GLX/DGA client path is modern or retail-equivalent.
Task A4m: Bound the retained Unix native-module loader roots and outputs [COMPLETED]
Priority: Medium
Primary areas: src/code/unix/unix_main.c,
tests/test_non_windows_portability.py,
docs/reverse-engineering/source-file-gap-notes/rw-g02-unix-main.md,
docs/reverse-engineering/function-parity-gap-audit-2026-04-24.md,
docs/platform/toolchain-matrix.md, docs/build/linux-glibc-32bit.md
Parity estimate: before 98% -> after 98%
Completed work:
- Reworked the retained Unix
Sys_LoadDll()root probe into an explicit bounded search over cwd,fs_homepath,fs_basepath, andfs_cdpath, so archived/native module roots can be reached through the same configured data-root lane used elsewhere in the Unix host. - Reset the legacy
entryPointoutput before probing, matching the safer failure contract used by the recovered Win32 loader shape and preventing a failed Unix load from leaving stale caller state behind. - Added focused source assertions and refreshed the RW-G02 notes so this remains Unix host compatibility work, not a claim that the non-Windows native-module runtime is retail-equivalent.
Task A4n: Bound the Unix event-loop packet payload copy [COMPLETED]
Priority: Medium
Primary areas: src/code/unix/unix_main.c,
tests/test_non_windows_portability.py,
docs/reverse-engineering/source-file-gap-notes/rw-g02-unix-main.md,
docs/reverse-engineering/function-parity-gap-audit-2026-04-24.md,
docs/platform/toolchain-matrix.md, docs/build/linux-glibc-32bit.md
Parity estimate: before 98% -> after 98%
Completed work:
- Reconstructed the retained Unix
Sys_GetEvent()packet queue copy soSE_PACKETevents preserve only unread bytes afternetmsg.readcount, matching the recovered Win32 event-loop packet path and its SOCKS-aware comment. - Kept the change deliberately bounded: the current Unix UDP receiver still
leaves
readcountat zero, but the event loop now honors that field if a future Unix packet transport consumes header bytes before queuing. - Added focused source assertions and refreshed the RW-G02 notes so this is recorded as Unix host event-loop compatibility, not proof of full non-Windows runtime parity.
Task A4o: Bound Unix native-module candidate validation [COMPLETED]
Priority: Medium
Primary areas: src/code/unix/unix_main.c,
tests/test_non_windows_portability.py,
docs/reverse-engineering/source-file-gap-notes/rw-g02-unix-main.md,
docs/reverse-engineering/function-parity-gap-audit-2026-04-24.md,
docs/platform/toolchain-matrix.md, docs/build/linux-glibc-32bit.md
Parity estimate: before 98% -> after 98%
Completed work:
- Reworked the retained Unix
Sys_LoadDll()probing loop so each opened native-module candidate is validated before returning a handle: it must exposedllEntryand then satisfy either the Quake Live export-table path, avmMainexport, or the legacydllEntry()-returned entry point path. - Closed incompatible
dlopen()handles, reset failed-load outputs, and continued to the next configured root instead of treating the first opened but incompatible shared object as the final loader outcome. - Added focused source assertions and refreshed the RW-G02 docs so this stays recorded as bounded Unix host compatibility work aligned with the recovered Win32 loader shape, not proof of full non-Windows runtime parity.
Task A4p: Bound the null sound host with an explicit silent DMA sink [COMPLETED]
Priority: Medium
Primary areas: src/code/null/null_snddma.c,
tests/test_non_windows_portability.py,
docs/reverse-engineering/source-file-gap-notes/rw-g02-null-snddma.md,
docs/reverse-engineering/function-parity-gap-audit-2026-04-24.md,
docs/platform/toolchain-matrix.md
Parity estimate: before 98% -> after 98%
Completed work:
- Replaced the null sound host's outright
SNDDMA_Init()failure with a local silent DMA sink that seeds the shareddmashape, owns a deterministic 22,050 Hz 16-bit stereo buffer, and advances its DMA cursor fromSys_Milliseconds(). - Added explicit buffer/state cleanup through
SNDDMA_Shutdown(),SNDDMA_BeginPainting(), andS_ClearSoundBuffer()while preserving the compatibility-only no-op behavior for submit, activation, sound registration, local sound, and voice samples. - Added focused source assertions and refreshed the RW-G02 docs so this remains a bounded null-host compatibility sink, not an audible backend or a broader runtime parity claim.
Task A4q: Make the null renderer host refuse fake GL initialization [COMPLETED]
Priority: Medium
Primary areas: src/code/null/null_glimp.c,
tests/test_non_windows_portability.py,
docs/reverse-engineering/source-file-gap-notes/rw-g02-null-glimp.md,
docs/reverse-engineering/function-parity-gap-audit-2026-04-24.md,
docs/platform/toolchain-matrix.md
Parity estimate: before 98% -> after 98%
Completed work:
- Replaced the null
QGL_Init()success stub with an explicitqfalseresult, so the compatibility host no longer claims that a GL backend was loaded when no renderer library or function pointers exist. - Made
GLimp_Init()fail with a clear fatal message for the null renderer host and routedGLimp_Shutdown()throughQGL_Shutdown(), which now clears retained extension pointers and logging state. - Added focused source assertions and refreshed the RW-G02 docs so this stays recorded as a bounded renderer-host compatibility boundary, not a real graphics context or swap path.
Task A4r: Route the null key-event pump through explicit no-device input state [COMPLETED]
Priority: Medium
Primary areas: src/code/null/null_input.c,
tests/test_non_windows_portability.py,
docs/reverse-engineering/source-file-gap-notes/rw-g02-null-input.md,
docs/reverse-engineering/function-parity-gap-audit-2026-04-24.md,
docs/platform/toolchain-matrix.md
Parity estimate: before 98% -> after 98%
Completed work:
- Extended the null input compatibility state so it clears the retained
in_joystick->modifiedlatch while continuing to pinui_joyavailto0. - Routed
Sys_SendKeyEvents()through that no-device refresh once null input is initialized, making the key-event pump an explicit disabled-input maintenance path instead of an unstructured empty placeholder. - Added focused source assertions and refreshed the RW-G02 docs so this stays recorded as a null-host input boundary, not a real input backend or event source.
Task A4s: Bound the Linux GLX shutdown and end-frame lifecycle [COMPLETED]
Priority: Medium
Primary areas: src/code/unix/linux_glimp.c,
tests/test_non_windows_portability.py,
docs/reverse-engineering/source-file-gap-notes/rw-g02-linux-glimp.md,
docs/reverse-engineering/function-parity-gap-audit-2026-04-24.md,
docs/platform/toolchain-matrix.md
Parity estimate: before 98% -> after 98%
Completed work:
- Reworked
GLimp_Shutdown()so partial Linux GLX init state is cleaned up instead of returning early whenctxis missing: the path now deactivates mouse state, detaches any current context, destroys retained context/window state only when present, restores VidMode/gamma state, closes the QGL log, clears the GLX globals, and releases QGL before clearing renderer state. - Guarded
GLimp_EndFrame()against missing display/window/swap state so a failed partial init or post-shutdown call cannot fall through into stale GLX function-pointer state. - Added focused source assertions and refreshed the RW-G02 docs so this stays recorded as Linux renderer-host lifecycle containment, not a modern GLX or SDL-style Linux client parity claim.
Active tasks
Task A4: Modernise or explicitly contain the non-Windows portability lanes [COMPLETED 2026-06-05]
Priority: High
Primary areas: src/code/unix/, src/code/null/,
docs/platform/toolchain-matrix.md, docs/build/linux-glibc-32bit.md,
docs/reverse-engineering/non-windows-portability-boundary-2026-06-05.md
Parity estimate: before 98% -> after 99%
Scope:
- Replace the remaining Unix
Sys_*helper placeholders that still matter after the restored low-memory, Linux/glibc function compare/checksum,q3monkeyidmarker-probe, boundedgprof-control paths, and bounded clipboard retrieval path, bounded data-root probe, and Linux silent sound sink / OSS shutdown cleanup plus bounded Linux joystick descriptor/restart handling plus Linux mouse-grab shutdown cleanup plus Linux GLX partial-init shutdown/end-frame containment and the bounded Unix native-module root probe plus candidate validation, Unix packet event copy, the null renderer GL-init refusal, the explicit null silent DMA sink, and the null no-device key pump, or keep them clearly classified as compatibility-only. The null host/client/audio shims now match the current contract surface closely enough that the remaining work is primarily about the real Unix host boundary rather than stale null host/client/audio/input entry points. - Decide whether Linux client/renderer/audio/input support is a real target or whether the current server-only path should remain the bounded endpoint.
- Refresh the toolchain/runtime guidance and validation coverage once the intended portability boundary is settled.
Completed work:
- Re-baselined the non-Windows portability lanes around the current target: hosted POSIX source builds and dedicated/server-module validation are the active support endpoints.
- Chose explicit containment for the legacy Linux client/runtime stack: the retained X11/GLX/DGA renderer/input path, OSS-first audio host, silent sink, and null host/client/audio/input/renderer shims are compatibility-only carries, not active modern Linux client parity targets.
- Added
docs/reverse-engineering/non-windows-portability-boundary-2026-06-05.mdand refreshed the RW-G02 gap notes, repo-wide audit, function-gap summary, toolchain matrix, Linux glibc preset note, and focused portability tests so this boundary is enforced as a documented closure. - Future Linux client/runtime work now needs a successor task that explicitly adopts a modern renderer/audio/input dependency stack and reproducible validation.
Task A6: Refresh build/runtime evidence for the repo-wide ledger [COMPLETED 2026-06-05]
Priority: Medium Primary areas: tracked runtime probe bundles, native build helpers, platform docs Parity estimate: before 99% -> after 99%
Scope:
- Refresh the archived runtime evidence bundles on a current toolchain instead
of relying solely on the April 2026 tracked artifacts, and promote the
stable
latestaliases only when reruns remain sufficient. - Re-run native build validation where the required Windows toolchain is available and fold the results back into the repo-wide audit.
- Capture the remaining glibc and continuous/self-hosted publication
follow-ups called out in
docs/platform/toolchain-matrix.md, including the remaining retail-module runtime freshness tail.
Completed work:
- Added
docs/reverse-engineering/runtime-build-evidence-refresh-2026-06-05.jsonanddocs/reverse-engineering/runtime-build-evidence-refresh-2026-06-05.mdas the A6 evidence ledger. - Confirmed the retail-module
latestalias now points atartifacts/module_validation/logs/retail_module_runtime_evidence_20260602.json, with no warnings, no missing markers, retailui/qagame/cgameloads,Server: bloodrun,Going from CS_PRIMED to CS_ACTIVE, screenshots, and vm-trace create/free/call traffic. - Verified Visual Studio 2022
v143availability and ran the modern native validation lane with optional codecs disabled. MSBuild produced a cleanRelease|x86build with0warnings and0errors; the wrapper timed out after the successful build while continuing post-build checks, sotools/ci/assert-dll-exports.ps1was rerun directly. - Tightened
tools/ci/assert-dll-exports.ps1so it prefers the newest Release artifact before inspecting exports. The direct export audit now validates the freshbuild/win32/Release/modules/qagamex86/qagamex86.dllandbuild/win32/Release/modules/cgamex86/cgamex86.dlloutputs rather than olderbin/baseq3copies. - Recorded that strict retail VC10 staged-runtime evidence is still blocked
on this checkout because
tools/ci/audit-retail-toolchain.ps1 -StrictexpectsPlatformToolsetv100, while the checked-in project files currently usev141. This is now a documented validation boundary, not an uninspected A6 freshness gap.
Earlier 2026-06-05 preflight, now superseded by the A6 refresh ledger:
docs/reverse-engineering/windows-native-validation-preflight-2026-06-05.mdnow records the local native Windows validation preflight. The wrapper-level repo-root inference issue was fixed intools/ci/audit-retail-toolchain.ps1andtools/ci/validate-windows-native.ps1, so documented-Fileinvocations now reach the project metadata checks.powershell -NoProfile -ExecutionPolicy Bypass -File .\tools\ci\audit-retail-toolchain.ps1 -Strictstops before build because the strict retail audit expectsPlatformToolset=v100whilesrc/code/quakelive_steam.vcxprojcurrently reportsv141.powershell -NoProfile -ExecutionPolicy Bypass -File .\tools\ci\validate-windows-native.ps1 -RuntimeProfile retailverifies the currentv141defaults forqagamex86,cgamex86,uix86,quakelive_steam, andawesomium_process, then hits the same strictv100audit blocker. The later A6 refresh above adds modern-host build evidence and current retail-module runtime evidence while keeping this strict VC10 blocker documented.
Task 23: Ownerdraw/stat payload completion and validation [COMPLETED]
Priority: High
Primary areas: src/code/game/, src/code/cgame/, runtime validation harnesses
Parity estimate: before 99% -> after 100%
Completed work:
- Revalidated the ownerdraw debug payload against the current runtime capture
path and confirmed that the live
pickupAvgslab is emitted as fixed-point seconds rather than the older integer-only fixture assumption. - Updated the ownerdraw runtime harness in
tests/test_ownerdraw_stats_logging.pyso the debug-ownerdraw assertion path now accepts and normalizes floatpickupAvgCSV payloads while keeping the integer stat families strict. - Re-ran the focused ownerdraw/stat validation surface on the current
worktree; no concrete unsupported ownerdraw or
PLAYER_STATSpayload field remains in the active repo-level gap register.
Task 24: Gameplay validation sweep [COMPLETED]
Priority: High Primary areas: physics, Race, gametype-specific rules Parity estimate: before 99% -> after 100%
Completed work:
- Expanded the gametype lifecycle harness so it now builds through the shared compiler helper on Windows as well as POSIX, and it directly validates duel warmup/configstring sequencing, Race lifecycle routing, and CA/RR round-warmup init dispatch.
- Tightened the ready-up and match-state regression guards around the retail gametype truth tables, including the both-teams-present gate and the Attack & Defend inclusion in the round-controller team-count publisher set.
- Reconfirmed the focused Race and shared
pmoveregression lanes on the current worktree; the gameplay validation sweep is now covered by dedicated fixtures rather than left as an open catch-all validation reminder.
Task 25: UI import contract retail remap guard [COMPLETED]
Priority: High
Primary areas: tests/test_ui_menu_files.py, src/code/ui/ui_public.h,
src/code/ui/ui_syscalls.c
Parity estimate: before 98% -> after 100% for the focused uiImport_t
legacy-to-retail-native import contract.
Completed work:
- Rechecked the committed
uix86.dllnative import evidence and preserved the current runtime split:uiImport_tremains the legacy source/QVM syscall ABI, whileuiQlImport_tcarries the recovered retail native slot numbers. - Added a parser-based parity guard that pins every
uiImport_tvalue, verifies the completeUI_MapNativeImporthandoff into recovered retail native slots, and keeps direct-only retail native slots out of the legacy syscall surface. - Re-ran the full UI static regression lane so future drift in either the enum or remap table fails before it can affect retail-module loading.
Working priority order
- Keep the online-service compatibility boundary explicitly documented if a future open replacement path is introduced.
Reference audits for closed surfaces
docs/reverse-engineering/non-windows-portability-boundary-2026-06-05.mddocs/reverse-engineering/runtime-build-evidence-refresh-2026-06-05.mddocs/reverse-engineering/repo-wide-parity-audit-2026-04-21.mddocs/reverse-engineering/source-file-parity-ledger-2026-04-22.mddocs/reverse-engineering/source-file-parity-audit-plan-2026-04-22.mddocs/reverse-engineering/historical-audit-index-2026-04-22.mddocs/reverse-engineering/engine-full-parity-audit-and-implementation-plan-2026-04-10.mddocs/reverse-engineering/game-module-parity-audit-and-implementation-plan-2026-04-10.mddocs/reverse-engineering/ui-full-parity-audit-and-implementation-plan-2026-04-05.mddocs/reverse-engineering/qcommon-full-parity-audit-and-implementation-plan-2026-04-10.mddocs/reverse-engineering/qshared-retail-helper-parity-audit-2026-04-17.mddocs/reverse-engineering/renderer-full-parity-audit-and-implementation-plan-2026-04-09.mddocs/reverse-engineering/server-full-parity-audit-and-implementation-plan-2026-04-10.mddocs/reverse-engineering/engine-host-support-full-parity-audit-and-implementation-plan-2026-04-10.mddocs/reverse-engineering/platform-specific-engine-parity-audit-and-implementation-plan-2026-04-16.mddocs/reverse-engineering/engine-netcode-parity-audit-2026-04-16.mddocs/reverse-engineering/awesomium-browser-host-parity-audit-and-implementation-plan-2026-04-16.md
Historical closure anchors kept for parity-gate compatibility
The entries below are intentionally terse. They preserve the exact historical task headings and parity-estimate lines that checked-in parity gates still read from this file, without keeping pages of duplicated completed-task prose in the active plan.
Task 34: Cgame Attack and Defend round-scoreboard owner parity closure [COMPLETED]
Task 31: Strict retail game-module parity closure [COMPLETED]
Task 73: Renderer internal helper-family ownership closure tranche [COMPLETED]
Parity estimate: before 93% -> after 96% (RG-P5 complete; RG-G06 closed)
Task 75: Renderer strict retail-font-stack re-audit and closure-plan refresh [COMPLETED]
Task 87: Client CL-P6 parity gate and runtime-evidence closure [COMPLETED]
Parity estimate: before 99% -> after 100%
Task 92: Qcommon QC-P2 parity gate and Windows-friendly harness closure [COMPLETED]
Task 94: Qcommon QC-P3 retail homepath closure [COMPLETED]
Task 97: Qcommon QC-P4 collision leaf ownership closure [COMPLETED]
Task 100: Server SV-P7 parity gate and dedicated runtime-evidence closure [COMPLETED]
Parity estimate: before 97% -> after 100%
Task 102: Qcommon QC-P5 fallback VM closure [COMPLETED]
Task 103: Remaining engine host/support EH-P2 Win32 Unicode clipboard closure [COMPLETED]
Task 104: Strict retail game-module final ledger and runtime-evidence reconciliation [COMPLETED]
Task 104: Qcommon QC-P6 runtime-evidence and ledger closure [COMPLETED]
Parity estimate: before 98% -> after 100%
Task 110: Qshared shared-helper exactness and validation-lane closure [COMPLETED]
Parity estimate: before 99% -> after 100%
Task 105: Remaining engine host/support EH-P3 raw-input host closure [COMPLETED]
Task 111: Client/input m_cpi and general mouse parity closure [COMPLETED]
Parity estimate: before 96% -> after 100% (m_cpi math was already retail-mapped; this closes the remaining Win32 mouse host/key-number gaps)
Task 112: Win32 game-cursor mouse ownership closure [COMPLETED]
Parity estimate: before 99% -> after 100% (browser/UI/cgame absolute-coordinate lanes now preserve the retail cursor-owner split; UI/cgame game cursors suppress the OS cursor while browser cursor overrides remain browser-owned)
Task 106: Remaining engine host/support EH-P6 parity gate and evidence closure [COMPLETED]
Parity estimate: before 89% -> after 92%
Task 107: Remaining engine host/support EH-P4 botlib internal proof closure [COMPLETED]
Parity estimate: before 92% -> after 95%
Task 109: Remaining engine host/support EH-P1 boundary formalisation closure [COMPLETED]
Parity estimate: before 100% -> after 100% (EH-P1 complete; strict-retail scope classification formalised)
Task 113: Clientinfo compact identity/color transport closure [COMPLETED]
Parity estimate: before 94% -> after 98% for the scoped CS_PLAYERS clientinfo color, SteamID, and country transport lane
Task 114: Clientinfo identity-tail and native sidecar reconstruction [COMPLETED]
Parity estimate: before 82% -> after 90% for the scoped cgame clientinfo
identity/speaking/avatar tail. This pass confirmed the retail 0x738
clientinfo stride, documented the 0x710..0x730 privilege, queue, speaking,
identity, and avatar tail, and reconstructed source wiring for cn, xcn,
rp, p, cached clean names, avatar handles, and in-record speaking state.
This pass left the binary-exact cgame animation/clientinfo layout split open:
retail uses 37 animation records of size 0x18, which is closed by the
follow-up Task 115 animation-record pass below.
Task 115: Clientinfo cgame animation record and retail stride closure [COMPLETED]
Parity estimate: before 90% -> after 94% for the scoped cgame clientinfo
layout/animation lane. This pass confirmed the retail animation cache at
clientinfo offset 0x318 with 37 records of size 0x18, custom sounds at
0x690, and the retail outer clientinfo stride of 0x738. Source cgame now
uses a local cgAnimation_t record without the shared GPL flipflop field,
cgame animation parsing/playback consumes that type, and clientInfo_t carries
an explicit temporary pad so the x86 source stride matches retail. The shared
game/UI animation_t remains untouched. The remaining gap is the internal
member-order repack to move the animation, sound, identity, avatar, and voice
fields to their retail byte offsets naturally, which is closed by Task 116.
Task 116: Clientinfo internal anchor-offset repack [COMPLETED]
Parity estimate: before 94% -> after 96% for the scoped cgame clientinfo
byte-layout lane. This pass moved the recovered native sidecar fields behind
sounds[MAX_CUSTOM_SOUNDS] and aligned the strongest retail anchors in the x86
source layout: fixed animation metadata at 0x2E0, model handles at 0x2FC,
animations at 0x318, custom sounds at 0x690, privilege/spectator queue at
0x710..0x718, speaking state at 0x71C..0x720, Steam identity at
0x728..0x72C, avatar cache at 0x730, and final size 0x738. The remaining
gap is the early 0x008..0x2DF mixed retail/source-compatibility region,
including model/head-model scratch strings, color override cache, country flag
cache, and scoreboard/team-overlay mirrors.
Task 117: Clientinfo early-slot retail offset map [COMPLETED]
Parity estimate: before 96% -> after 97% for the scoped cgame clientinfo
byte-layout lane. This pass promoted the early 0x000..0x2FC retail map into
named CG_CLIENTINFO_RETAIL_OFFSET_* constants and documented the evidence
chain from CG_NewClientInfo, CG_CopyClientIdentity, placement/profile text,
country flag lookup, and head/model scale consumers. High-confidence early
anchors now include display name 0x008, clean/native identity name 0x048,
country 0x0C8, team 0x108, bot skill 0x10C..0x110, colors
0x114..0x128, handicap 0x130, wins/losses 0x134..0x138, fixed animation
metadata 0x2E0..0x2F8, and model handles 0x2FC..0x314. The source struct is
not forcibly repacked around this early map yet because the current tree keeps
source-compatibility color override, country flag, and scoreboard/team-overlay
fields in that region; moving them should be a deliberate sidecar migration once
the remaining medium-confidence slots are closed.
Task 118: Clientinfo model-string band and pre-animation scalar reconstruction [COMPLETED]
Parity estimate: before 97% -> after 98% for the scoped cgame clientinfo
byte-layout lane. This pass promoted the six 64-byte retail model string slots
from a medium-confidence band to named high-confidence offsets: body model/skin
at 0x154..0x1D3, icon body model/skin at 0x1D4..0x253, and head
model/skin at 0x254..0x2D3. The adjacent pre-animation fields are now pinned
as deferred flag 0x2D4, model bounding-box scale 0x2D8, and new-animation
flag 0x2DC. Source reconstruction now separates clientInfo_t.modelScale
from the animation.cfg headOffset vector, moves newAnims onto the retail
0x2DC lane, and keeps focused regression coverage over the Ghidra/HLIL
constructor, load, copy, sound, icon, and tag-flag evidence.
Task 119: Clientinfo score, compact tinfo, and effect-timer lane closure [COMPLETED]
Parity estimate: before 98% -> after 99% for the scoped cgame clientinfo
byte-layout lane. This pass promoted the live score mirror at 0x12C,
team-task scalar at 0x13C, medkit timer at 0x144, and invulnerability
start/stop timers at 0x148..0x14C using HLIL/Ghidra producer and consumer
evidence. It also documents the remaining 0x150 breath-puff timer candidate
as medium confidence and reconstructs CG_ParseTeamInfo to accept the retail
compact tinfo <count> <client...> shape while preserving legacy six-field
source-server rows for teammate location, health, armor, weapon, and powerup
compatibility.
Task 120: Clientinfo animation metadata and render-handle slot closure [COMPLETED]
Parity estimate: before 99% -> after 99.3% for the scoped cgame
clientinfo byte-layout lane. This pass split the broad 0x2E0..0x314
animation metadata/model-handle bands into individually named retail offsets:
fixedlegs, fixedtorso, headOffset[3], footsteps, gender, legs/torso/
head model and skin handles, and modelIcon. The evidence now ties animation
cfg parsing, model/skin/icon registration, player/model-preview rendering, and
the retail deferred-asset copier together. It also preserves the retail detail
that CG_CopyClientInfoModel copies from 0x2E8 onward and intentionally does
not propagate fixedlegs or fixedtorso during deferred asset reuse.
Task 121: Steam callback ABI launch/runtime reconstruction [COMPLETED]
Parity estimate: before 74% -> after 93% for the scoped Steam callback ABI
lane. This pass aligned the source CCallbackBase-compatible vtable order to
the Steam runtime dispatcher shape (Run, RunCallResult,
GetCallbackSizeBytes), preserved the retail split where
SteamUGCQueryCompleted_t is a call-result rather than a normal registered
callback, and recorded the evidence in
docs/reverse-engineering/quakelive_steam_mapping_round_429.md.
Task 122: Steam initialization app-id ownership cleanup [COMPLETED]
Parity estimate: before 82% -> after 91% for the scoped Steam
initialization/app-id lane. This pass removed the init-time diagnostic
QL_Steamworks_GetAppID() side effect so app-id reads remain owned by the
retail-mapped wrapper callers, especially the stats_clear gate, and recorded
the evidence in docs/reverse-engineering/quakelive_steam_mapping_round_430.md.
Task 123: SteamClient_Init com_build launch guard reconstruction [COMPLETED]
Parity estimate: before 63% -> after 90% for the scoped Steam
com_build launch-guard lane. This pass added the source-side build-script
gate at the top of SteamClient_Init, before platform-service refresh,
callback/lobby bootstrap, voice command registration, stats-clear, and
rich-presence writes, and recorded the evidence in
docs/reverse-engineering/quakelive_steam_mapping_round_431.md.
Task 124: SteamClient_Frame retail pump-order reconstruction [COMPLETED]
Parity estimate: before 86% -> after 94% for the scoped
SteamClient_Frame runtime-pump lane. This pass moved the source-only callback
recovery shim behind the retail-equivalent frame pump so initialized frames run
SteamAPI_RunCallbacks, outgoing voice send, channel-0 stats-report packet
drain, and incoming voice packet processing in the order shown by the retail
HLIL, and recorded the evidence in
docs/reverse-engineering/quakelive_steam_mapping_round_432.md.
Task 125: Steam auth-ticket common error cleanup reconstruction [COMPLETED]
Parity estimate: before 78% -> after 92% for the scoped Steam auth-ticket
error-cleanup lane. This pass added the retail-observed
SteamClient_CancelAuthTicket() call to Com_Error after publishing
com_errorMessage and before the error-code branches diverge, keeping retained
ticket cleanup consistent across disconnect, drop, need-CD, and fatal paths.
The evidence is recorded in
docs/reverse-engineering/quakelive_steam_mapping_round_433.md.
Task 126: Pre-filesystem Steam com_build guard reconstruction [COMPLETED]
Parity estimate: before 70% -> after 91% for the scoped pre-filesystem
Steam startup guard lane. This pass added the retail-observed com_build skip
to Com_InitSteamClientForFilesystem() before its platform-service refresh, so
build-script launches do not probe Steam in the source-only early filesystem
SteamID path. The evidence is recorded in
docs/reverse-engineering/quakelive_steam_mapping_round_434.md.
Task 127: Lazy Steam service refresh guard reconstruction [COMPLETED]
Parity estimate: before 67% -> after 93% for the scoped lazy Steam refresh
lane. This pass added SteamClient_ShouldRefreshPlatformServices() and applied
it before source-only lazy QL_RefreshPlatformServices() calls in the SteamID,
auth-ticket, subscription, UGC download-info, IP-country, callback-recovery, and
frame-pump paths, keeping com_build launches aligned with retail retained
initialized-flag semantics. The evidence is recorded in
docs/reverse-engineering/quakelive_steam_mapping_round_435.md.
Task 128: Steam frame-pump initialized-state owner reconstruction [COMPLETED]
Parity estimate: before 78% -> after 96% for the scoped Steam frame-pump
owner lane. This pass removed source-only QL_RefreshPlatformServices() and
SteamClient_SetInitializedState() calls from SteamClient_Frame() and kept
callback recovery from re-latching Steam state, matching the retail
data_e30218 != 0 gate before SteamAPI_RunCallbacks(), voice send, stats
report packet drain, and voice packet drain. The evidence is recorded in
docs/reverse-engineering/quakelive_steam_mapping_round_436.md.
Task 129: Steam identity bootstrap retained-state reconstruction [COMPLETED]
Parity estimate: before 74% -> after 95% for the scoped client identity
bootstrap owner lane. This pass removed direct QL_Steamworks_Init() calls
from SteamClient_SyncPersonaNameCvar() and CL_Steam_SeedCountryCvar(),
gated both helpers on the retained SteamClient_IsInitialized() state after
the retail com_build skip, and kept the retail name=anon persona fallback
when Steam identity is unavailable. The evidence is recorded in
docs/reverse-engineering/quakelive_steam_mapping_round_437.md.
Task 130: Steam wrapper retained-state owner reconstruction [COMPLETED]
Parity estimate: before 72% -> after 94% for the scoped small Steam wrapper
owner lane. This pass added SteamClient_InitForFilesystem() as the explicit
source-only early filesystem Steam owner, moved the pre-filesystem platform
refresh into that client-owned helper, and removed wrapper-level
QL_RefreshPlatformServices() / SteamClient_SetInitializedState() calls from
the SteamID, auth-ticket, subscription, UGC download-info, and country wrapper
thunks. The evidence is recorded in
docs/reverse-engineering/quakelive_steam_mapping_round_438.md.
Task 131: Steam client shutdown resource-callback owner reconstruction [COMPLETED]
Parity estimate: before 78% -> after 95% for the scoped Steam client
shutdown/resource callback owner lane. This pass rechecked the retail
SteamAPI_Shutdown thunk at 0x00460540, the SteamDataSource_Shutdown
callback unregister path at 0x00464440, and the source platform avatar
callback owner, then moved CL_ShutdownSteamResources() into the public
SteamAPI_Shutdown() wrapper ahead of CL_Steam_ShutdownCallbacks() and
QL_Steamworks_Shutdown(). The evidence is recorded in
docs/reverse-engineering/quakelive_steam_mapping_round_440.md.
Task 132: Steam game-start rich-presence initialized-gate reconstruction [COMPLETED]
Parity estimate: before 82% -> after 96% for the scoped game.start /
rich-presence runtime lane. This pass rechecked retail sub_4F38F0, found the
demo playback early return before "game.start" publication, and matched the
lanIp and "Playing a match" rich-presence writes to the retained
SteamClient_IsInitialized() gate. The source now suppresses the packed
browser event during demo playback and only writes adjacent Steam presence
state when the retained Steam client initialization flag is live. The evidence
is recorded in
docs/reverse-engineering/quakelive_steam_mapping_round_442.md.
Task 133: SteamClient_Init post-success side-effect boundary reconstruction [COMPLETED]
Parity estimate: before 84% -> after 97% for the scoped
SteamClient_Init post-success bootstrap lane. This pass rechecked retail
sub_461500, confirmed the failed SteamAPI_Init() return before callback,
lobby, voice, stats, and main-menu rich-presence side effects, and moved the
source fallback branch to return immediately when the retained
SteamClient_IsInitialized() state is false. The evidence is recorded in
docs/reverse-engineering/quakelive_steam_mapping_round_443.md.
Task 134: SteamClient_Init terminal success diagnostic reconstruction [COMPLETED]
Parity estimate: before 90% -> after 99% for the scoped
SteamClient_Init terminal success diagnostic lane. This pass rechecked retail
sub_461500 at 0x004615CA, confirmed the "Steam API initialized.\n" log
after the initial "At the main menu" rich-presence write, and added the
matching client-owner success marker after CL_Steam_SetMainMenuRichPresence()
in the source bootstrap path. The evidence is recorded in
docs/reverse-engineering/quakelive_steam_mapping_round_445.md.
Task 135: Steam connect_lobby command and lobby bootstrap return reconstruction [COMPLETED]
Parity estimate: before 76% -> after 99% for the scoped connect_lobby
command handler lane, and before 88% -> after 97% for the scoped
SteamLobby_Init cvar/command/return boundary. This pass rechecked retail
sub_464AA0 and the SteamLobby_Init registration at 0x00465840, removed
source-only argc and provider guards from CL_Steam_ConnectLobby_f(), stopped
using the initial lobby callback registration result as a main Steam bootstrap
gate, and pinned the lobby cvar flags / command registration against retail
HLIL. The evidence is recorded in
docs/reverse-engineering/quakelive_steam_mapping_round_447.md.
Task 136: Steam lobby chat-message entry-type gate reconstruction [COMPLETED]
Parity estimate: before 82% -> after 99% for the scoped lobby chat-message
publish gate. This pass rechecked retail sub_4645A0, confirmed that
lobby.%s.chat is published only when Steam's lobby chat entry type is 1,
added the matching source gate in CL_Steam_Lobby_OnLobbyChatMessage(), and
pinned the HLIL branch / publish instruction in the Steam platform tests. The
evidence is recorded in
docs/reverse-engineering/quakelive_steam_mapping_round_448.md.
Task 137: Steam browser lobby method initialized-gate reconstruction [COMPLETED]
Parity estimate: before 78% -> after 97% for the scoped browser-facing
Steam lobby method initialized-state gate. This pass rechecked retail
sub_4649B0, sub_4649E0, sub_465630, sub_464AC0, sub_464B10, and
sub_464BB0, confirmed each route begins at the retained sub_460510
Steam-client initialized gate before SteamMatchmaking/SteamFriends calls, and
added the matching source gates to the lobby/social browser wrappers. The
evidence is recorded in
docs/reverse-engineering/quakelive_steam_mapping_round_450.md.
Task 138: Steam browser non-lobby method initialized-boundary reconstruction [COMPLETED]
Parity estimate: before 74% -> after 94% for the scoped browser-facing
non-lobby Steam method initialized boundary. This pass rechecked retail
sub_431E50 qz_instance dispatch cases for OpenSteamOverlayURL,
RequestUserStats, ActivateGameOverlayToUser, and GetAllUGC, plus mapped
sub_460DC0 (SteamWorkshop_GetAllUGC), then added the retained source
initialization gate before the source wrappers reach SteamFriends,
SteamUserStats, or SteamUGC. The evidence is recorded in
docs/reverse-engineering/quakelive_steam_mapping_round_451.md.
Task 139: Steam browser native server-list retained-state reconstruction [COMPLETED]
Parity estimate: before 80% -> after 95% for the scoped native
SteamMatchmakingServers list/detail availability boundary. This pass rechecked
retail sub_462E80, sub_462EB0, sub_463090, and sub_4630B0, confirmed
the retained JSBrowser owner directly uses SteamMatchmakingServers refresh,
cancel, gamedir=baseq3 filtered-list, and detail-request paths, and added the
retained SteamClient_IsInitialized() gate to the source native-list
availability guard before native list/detail requests can start. The evidence
is recorded in
docs/reverse-engineering/quakelive_steam_mapping_round_452.md.
Task 140: Steam browser favorite-server retained-state reconstruction [COMPLETED]
Parity estimate: before 82% -> after 96% for the scoped browser
SetFavoriteServer retained-state boundary. This pass rechecked retail
sub_431E50 qz_instance dispatch case 0x13, confirmed the browser dispatcher
uses SteamUtils and SteamMatchmaking directly for add/remove favorite-game
slots after the incoming argument conversion, and added the retained
SteamClient_IsInitialized() gate before the source web-host favorite wrapper
can reach QL_Steamworks_SetFavoriteServerForApp. The evidence is recorded in
docs/reverse-engineering/quakelive_steam_mapping_round_453.md.
Task 141: Steam GameServer frame retained-state reconstruction [COMPLETED]
Parity estimate: before 84% -> after 97% for the scoped Steam GameServer
packet/frame retained-state boundary. This pass rechecked retail sub_465D50
and sub_466850, confirmed both native packet ingress and the server callback /
P2P maintenance loop are gated by the retained data_e30358 GameServer
initialized flag before reaching SteamGameServer, SteamGameServerNetworking, or
SteamGameServer_RunCallbacks, and added the matching source owner guards in
SV_SteamServerHandleIncomingPacket and SV_SteamServerNetworkingFrame. The
evidence is recorded in
docs/reverse-engineering/quakelive_steam_mapping_round_454.md.
Task 142: Steam GameServer key-value retained-state reconstruction [COMPLETED]
Parity estimate: before 86% -> after 98% for the scoped Steam GameServer
serverinfo key-value publication boundary. This pass rechecked retail
sub_465A60, confirmed the info-string walker checks the retained
data_e30358 GameServer initialized flag before splitting serverinfo pairs or
calling SteamGameServer vtable slot 0x50, and added the matching source guard
to QL_Steamworks_ServerSetKeyValuesFromInfoString. The evidence is recorded
in docs/reverse-engineering/quakelive_steam_mapping_round_455.md.
Task 143: Steam GameServer heartbeat retained-state reconstruction [COMPLETED]
Parity estimate: before 88% -> after 98% for the scoped Steam GameServer
heartbeat publication boundary. This pass rechecked retail sub_465DB0,
confirmed it checks the retained data_e30358 GameServer initialized flag
before calling SteamGameServer vtable slot 0x9C, and added the matching
source guard to QL_Steamworks_ServerEnableHeartbeats before it reaches
QL_Steamworks_GetGameServer. The evidence is recorded in
docs/reverse-engineering/quakelive_steam_mapping_round_456.md.
Task 144: Steam GameServer unauthenticated client identity reconstruction [COMPLETED]
Parity estimate: before 45% -> after 96% for the scoped
unauthenticated server-client identity wrapper. This pass rechecked retail
sub_465DF0 and its SV_BotAllocateClient call site, corrected the alias away
from public server identity publication, reconstructed the retained
data_e30358-gated SteamGameServer vtable slot 0x64 wrapper as
QL_Steamworks_ServerCreateUnauthenticatedUserConnection, and wired bot/local
server-owned client allocation through that source bridge. The evidence is
recorded in docs/reverse-engineering/quakelive_steam_mapping_round_458.md.
Task 145: Steam GameServer connected serverinfo replay reconstruction [COMPLETED]
Parity estimate: before 84% -> after 97% for the scoped
connected-success Steam GameServer publication sequence. This pass rechecked
retail sub_466800, confirmed the connect callback marks the Steam server
connected flag, publishes identity, pushes a full state refresh, runs the
dedicated/server callback continuation, and finally replays the serverinfo
key/value batch through sub_465A60. The source callback now mirrors that
reconnect path by republishing CVAR_SERVERINFO with
QL_Steamworks_ServerSetKeyValuesFromInfoString after the identity/state/stats
refresh. The evidence is recorded in
docs/reverse-engineering/quakelive_steam_mapping_round_462.md.
Task 146: Steam GameServer negative callback log reconstruction [COMPLETED]
Parity estimate: before 72% -> after 98% for the scoped
connect-failure/disconnect callback lane. This pass rechecked retail
sub_465C10 and sub_465C30, confirmed both callbacks clear the retained
Steam server connected flag and emit fixed log messages without reading the
Steam callback payload/result fields, and updated the source callbacks to
ignore the adapter payload while preserving the wrapper signatures. The
evidence is recorded in
docs/reverse-engineering/quakelive_steam_mapping_round_464.md.