Skip to content

fix: clear PlayerActionManager placeholder input index as retail (Alt-tab freeze fix) - #65

Open
AndreasLauvhjell wants to merge 1 commit into
B2BF:mainfrom
AndreasLauvhjell:fix/spawn-freeze
Open

AndreasLauvhjell wants to merge 1 commit into
B2BF:mainfrom
AndreasLauvhjell:fix/spawn-freeze

Conversation

@AndreasLauvhjell

@AndreasLauvhjell AndreasLauvhjell commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

Fixes the client freezing right after spawn if you have alt-tabbed out at any point (connection problem).

The PlayerActionManager constructor builds three neutral send actions through PlayerAction::set,
which never writes m_inputIndex, so the index held stack garbage. transmit sends slot 0's index as
the packet base index, so a large garbage value pushed the server's received-action high-water mark
above every real index and all later actions were dropped.

Retail stores 0 before set():

  • bf2_w32ded.exe ctor 0x6173C0 (store at 0x61741C), set() 0x55C150
  • BF2.exe ctor 0x5BFFB0 (store at 0x5C0004), set() 0x5BC890
    Linux bf2 1.5.3153.0 (dedicated server) matches, no platform difference:
  • ia-32: set() 0x080884A0; ctor C2 0x0809D090 (store 0x0809D0E8), C1 0x0809D1A0 (store 0x0809D1F8)
  • amd-64: set() 0x0043B430; ctor C1 0x0044CC10 (store 0x0044CC80), C2 0x0044CD20 (store 0x0044CD90) (identical body to C1)
    set() writes only +0x04..+0x18, never +0x00. The constructed action is then copied into all three
    stored placeholder actions, so without the store the stack garbage reaches all three.

Files: Code/BF2/Game/Common/PlayerActionManager.cpp (3 lines).

Tested: rebuilt x86 client against a retail 1.50 dedicated server, played on strike_at_karkand and dragon_valley, spawned countless times, no freeze.
Not tested: rebuilt dedicated server, Linux server.
Frontiers: none added or removed.

Local CI check

Local mirror of the Windows jobs in .github/workflows/build.yml, run on main (ccf3099)
plus #64, #65 and #66 together (not one by one), from empty build dirs:

Step Result
x64 python / configure / bf2_w64ded pass
x86 python / configure pass
x86 bf2_run_checks (incl. bf2_runtime_pair, 5/5) + bf2_editor_run_checks (926 passed, 0 failed) pass
x86 bf2_w32ded pass
x86 bf2_aidll + bf2_client pass
x86 bf2_editor pass

Toolchain: VS 2026 (MSVC 19.51); CI uses VS 2022. Linux job not run locally.

The constructor builds the three neutral send actions through PlayerAction::set, which never writes m_inputIndex, so the index held stack garbage. transmit sends slot 0's index as the packet base index while add() slides the placeholders out; a large garbage value raised the server's received-action high-water mark above every real index, so all later actions were dropped and the client froze after spawn (connectionProblem). Retail stores 0 before set(): bf2_w32ded.exe ctor 0x6173c0 (store 0x61741c), BF2.exe ctor 0x5bffb0 (store 0x5c0004); set() at 0x55c150 / 0x5bc890 does not touch +0x00. Linux ELF not checked.
@AndreasLauvhjell AndreasLauvhjell changed the title fix: clear PlayerActionManager placeholder input index as retail fix: clear PlayerActionManager placeholder input index as retail (Alt-tab freeze fix) Nov 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant