Skip to content

fix: use CS2 player info slot for user id - #28

Closed
raylin01 wants to merge 1 commit into
akiver:mainfrom
raylin01:codex/fix-cs2-player-slots
Closed

raylin01 wants to merge 1 commit into
akiver:mainfrom
raylin01:codex/fix-cs2-player-slots

Conversation

@raylin01

@raylin01 raylin01 commented Jul 5, 2026

Copy link
Copy Markdown

Problem

CS2 player slots exported by the analyzer can be incorrect when relying on common.Player.UserID & 0xff.

I hit this with a Valve CS2 Ancient demo where two players were exported with the same userId / slot:

  • HaO...: userId = 0, slot 1
  • real: userId = 0, slot 1
  • slot 10 was missing entirely

This caused downstream tools such as CS Demo Manager video generation to focus the wrong POV with spec_player, even though SteamID-based data such as kills/deathnotices was correct.

Cause

For CS2 demos, demoinfocs emits events.PlayerInfo from the userinfo stringtable. That event includes Index, which is the stable player slot needed for slot-based spectator commands.

The analyzer was instead deriving the exported user ID from common.Player.UserID & 0xff. In this demo, that produced a low-byte collision, so two players resolved to the same exported slot.

Fix

This change records CS2 events.PlayerInfo.Index by SteamID and uses that value when creating analyzer players.

If the PlayerInfo mapping is unavailable, the analyzer falls back to the previous masked UserID behavior to avoid regressing demos that currently rely on it.

Verification

I tested this against three Valve CS2 demos from the same day:

  • Ancient: previously broken, now exports unique slots 1..10; target player real is correctly slot 10
  • Mirage: unchanged, still exports unique slots 1..10
  • Dust2: unchanged, still exports unique slots 1..10

Also ran:

go test ./cmd/... ./internal/... ./pkg/...

Note

This issue was debugged with help from Codex, and this patch was created as the solution I found while investigating a downstream CS Demo Manager POV bug. No worries if this is not the direction maintainers want to take or if the PR is not merged; I mainly wanted to share the concrete repro/root cause and a small proposed fix.

@akiver

akiver commented Jul 5, 2026

Copy link
Copy Markdown
Owner

Ancient: previously broken, now exports unique slots 1..10; target player real is correctly slot 10

Could you upload the de_ancient demo please?

@raylin01

raylin01 commented Jul 6, 2026

Copy link
Copy Markdown
Author

Sure, here is the de_ancient demo:

https://1drv.ms/u/c/71c97375cf3e6071/IQCzEw5EWPvVQoXmFDbIi4RKAQpSdn1AvYaS6d87KwjfRNw?e=4w9bUk

File: 003829462050216607807_1309254715.dem
Size: 301,593,308 bytes
SHA256: 0A35AB1D61887AC4E435F630A6A3898B562E17D34394ECCD616460FFD1471412

If the link does not work or you would prefer another host, please let me know and I can re-upload it somewhere else.

akiver added a commit to markus-wa/demoinfocs-golang that referenced this pull request Jul 6, 2026
@akiver

akiver commented Jul 6, 2026

Copy link
Copy Markdown
Owner

I think the root issue is that the parser doesn't update the player's userID (slot minus 1).
I pushed a fix in the v4 branch markus-wa/demoinfocs-golang@7ea2e93 and now the players slot are correct in the CS:DM database with your demo (it's the column index)
dbeaver_rXW9NCU97x
Could you confirm that it fixes the issue?

@raylin01

raylin01 commented Jul 7, 2026

Copy link
Copy Markdown
Author

Confirmed, this works on my end too.

I tested it with the Ancient demo and real now gets slot/index 10 correctly. I also checked the Mirage and Dust2 demos from the same day and they still look correct.

Thanks for looking into it in demoinfocs, that seems like the right place to fix it.

@akiver

akiver commented Jul 7, 2026

Copy link
Copy Markdown
Owner

The fix is also available on the master branch markus-wa/demoinfocs-golang#659, and the demo analyzer v1.10.2 includes it.
I'm closing this PR, thank you!

@akiver akiver closed this Jul 7, 2026
pull Bot pushed a commit to cs2-demo-slap/demoinfocs-golang that referenced this pull request Jul 7, 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.

2 participants