# demoinfocs-golang: A Counter-Strike Demo Parser Written in Go

> demoinfocs-golang parses Counter-Strike 2 and CS:GO demo files in Go, exposing game events, game state, grenade trajectories, entities and server classes through a typed API, with a heatmap example, live broadcast parsing for CSTV+ and a v6 line currently in alpha.

**markus-wa/demoinfocs-golang** — A Counter-Strike 2 Demo Parser for Go (demoinfo)

- Repository: https://github.com/markus-wa/demoinfocs-golang
- Website: https://pkg.go.dev/github.com/markus-wa/demoinfocs-golang/v4/pkg/demoinfocs?tab=doc
- Stars: 1,071 · Forks: 152
- Language: Go
- License: MIT
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/markus-wa-demoinfocs-golang

## A Parser for Two Generations of Counter-Strike

demoinfocs-golang is described as a blazing fast, feature complete and production ready Go library for parsing and analysing Counter-Strike 2 and Counter-Strike: Global Offensive demos, which are the replay files a match writes to disk.

The problem it solves is specific. A demo file is a binary record of everything that happened in a match, and extracting the events from it means understanding a proprietary format that changes with every game update. The library handles that, so an application can ask what happened rather than parse bytes.

The scope is broader than an event log. The feature list covers game events such as kills, shots, round starts and ends and footsteps, and tracking of game state including players, teams, grenades and ConVars. It covers grenade projectiles and trajectories, and it gives access to entities, server classes and data tables, which is the layer underneath everything else.

The technical floor is worth noting immediately. The library requires at least go 1.27 to run, and the go.mod in the repository declares go 1.27.0, so the toolchain requirement is current rather than conservative.

The project publishes on Go's module proxy with a versioned module path, and the home for the documentation is pkg.go.dev, with the API reference for the demoinfocs package.

## Events Are Registered Handlers, Not Returned Values

The API shape is a parser object with registered event handlers, and the quickstart example makes it concrete.

You call ParseFile with a context, a path and a function that receives the parser, and inside that function you register handlers and return. The events package defines the event types, and the godoc of the events package is where the full list lives.

The example registers a handler for the kill event and prints the killer, the weapon and the victim, plus whether it was a headshot or a wallbang:

```go
func onKill(kill events.Kill) {
	var hs string
	if kill.IsHeadshot {
		hs = " (HS)"
	}

	var wallBang string
	if kill.PenetratedObjects > 0 {
		wallBang = " (WB)"
	}

	log.Printf("%s <%v%s%s> %s\n", kill.Killer, kill.Weapon, hs, wallBang, kill.Victim)
}
```

The important design decision is that parsing is streaming and callback driven. The parser reads the demo and dispatches events as it goes, so a program that only cares about one kind of event does not have to build a data structure for the whole match.

The output for a match is a stream of lines like a kill entry with the headshot and wallbang markers in brackets, which is the kind of output that is already useful for a quick check and is the starting point for anything larger.

## Game State, Entities and the Server Class Tables

Events tell you what happened. Game state tells you what was true.

The library tracks the state of the game, which covers players, teams, grenades and ConVars, and the documentation links to the GameState section of the package docs for the details. That is the difference between an event log and a model you can query: a kill event names a player, and the game state knows that player's team, position, health and money at the time.

The grenade support goes further than listing throws. There is a dedicated feature for grenade projectiles and trajectories, with a linked example for nade trajectories, so a caller can reconstruct the path a grenade took rather than only when it was thrown and whether it landed.

The lowest layer is entities, server classes and data tables. Access to server classes and data tables is the part that matters for a tool that wants to show information the game itself does not display, because the data tables describe the networked properties of every entity class and the values in them for a given match. The examples folder has an entities example and a net-messages example for the lower level traffic.

This layering is what lets the same library serve an analyst asking for a heatmap of deaths and a developer asking what a particular networked property was set to.

## Live Broadcast Parsing for CSTV+

The library is not only about files on disk. The Go Get section leads with Counter-Strike 2 plus live broadcast parsing, described as CSTV+, and links to the broadcast example in the examples folder.

That is a different problem from parsing a finished demo. A broadcast feed is a live stream of the same underlying data, and consuming it means handling a connection that can start and stop, and data that arrives out of order relative to a finished match. The library exposes it through the same parsing model, so the event handlers you wrote for a file work against a live feed.

The example directory has a dedicated broadcasts/ folder, which is where to look for how that is set up.

There is a second live use case visible in the examples list, a voice-capture example, which suggests the library can also be used against a broadcast's audio and data together.

The practical value of the live path is for a tool that has to react during a match rather than after it, such as a live statistics overlay or a coaching display, and the same event handler code is what makes that reuse possible.

## The Examples Folder Is a Catalogue of Use Cases

The examples directory is unusually complete, and it is the fastest way to judge whether the library covers the analysis you have in mind.

The list in the repository covers print-events, which dumps the event stream, and print-defuse-time-left, which solves one very specific question. There is a heatmap example, with a rendered sample image, which is the kind of output people build statistics services around. There are nade-trajectories for grenade paths and player-actions for what players did.

There are also examples that reveal the library's reach beyond the obvious. A net-messages example works with the lower level network messages. A mocking example suggests the parser can be driven from a fixture, which is what you want for testing your own analysis code. A voice-capture example deals with voice chat data from a broadcast. A viewmodel-settings example reads the viewmodel configuration, which is a detail most players have opinions about. A web-assembly example shows the library being compiled to WebAssembly, which is a neat trick for a browser based analysis tool.

There is also a common.go file and a map_metadata.go file with its own test, and the examples directory has its own go.mod and go.sum, so the examples are a separate module that can be built independently of the library.

## Dependencies, Protobuf and the Tooling Around the Code

The go.mod tells you what the parsing work is built on. The module is github.com/markus-wa/demoinfocs-golang/v6, and the dependencies are mostly small and purpose-built.

github.com/markus-wa/gobitread is the bit reader that the binary parsing sits on, and github.com/markus-wa/godispatch is the event dispatch mechanism that the handler registration uses. github.com/markus-wa/ice-cipher-go handles the encryption used in part of the demo format, and github.com/markus-wa/quickhull-go/v2 is a convex hull implementation, which is what you need to build geometry from positions. github.com/golang/geo is a geometry library, and github.com/golang/snappy is a compression library, which the format uses. google.golang.org/protobuf is there for the protobuf based parts, and the README has a section on generating the protobuf code, which is a maintenance task you would have to repeat when the upstream definitions change. github.com/samber/lo is a generic utility library, and github.com/stretchr/testify with github.com/markus-wa/go-unassert are the testing tools.

The repository tooling is also visible. There is a.golangci.yml for linting, a.gitmodules file for the protobuf sources, a scripts/ directory, and a test/ directory. The CI story shows up in the badges: a build and test workflow, a codecov coverage badge, a FOSSA status badge and an OSV-Scanner workflow, which is a dependency vulnerability scan, the kind of badge worth having on a library that parses untrusted files.

## Versioning: v3, v5 and the v6 Alphas

The version story is the thing to get right before you depend on this, because the module path changes with the major version and the import lines in your code have to match.

The Go Get section lists two supported lines. For Counter-Strike 2 plus live broadcast parsing, that is CSTV+, it is the v5 module path:

```bash
go get -u github.com/markus-wa/demoinfocs-golang/v5/pkg/demoinfocs
```

For CS:GO, it is the v3 module path:

```bash
go get -u github.com/markus-wa/demoinfocs-golang/v3/pkg/demoinfocs
```

And the quickstart example in the README imports the v6 path, which is the line currently under development. The recent releases make that explicit: v6.0.0-alpha.0 on 2026-08-31 and v6.0.0-alpha.1 on 2026-10-11, with the last stable release being v5.2.0 on 2026-04-21.

So the choice is between the stable v5 line for current work and the v6 alphas, and the two are not interchangeable in an import path. The quickstart also shows the project setup itself, creating a directory, running go mod init and adding the dependency.

The project is MIT licensed, the repository is not archived, and the last push was on 2026-10-15. Questions go to Discord or GitHub Discussions, and the README points to the profile contact details for business inquiries.

## Conclusion

demoinfocs-golang fits an esports analyst, a stats site or a coaching tool that wants to read demo files programmatically, since it covers the full range from raw events to game state to the entity and server class tables, and it gives you a typed Go API rather than a file format to reverse. It is a poor fit if you need the v6 API today, since the current line is published as alpha releases, and a poor fit if you need to run on an older Go, because the module requires go 1.27. Before adopting it, decide which major version to pin, since the v3, v5 and v6 module paths coexist and the import path changes with them, and check the demos you care about against the examples folder. The library is MIT licensed, the newest release is v6.0.0-alpha.1 from 2026-10-11, and the last push was on 2026-10-15.

## FAQ

### What does demoinfocs-golang do?

It is a Go library for parsing and analysing Counter-Strike 2 and CS:GO demo files, exposing game events such as kills, shots, round starts and footsteps, tracking of game state including players, teams, grenades and ConVars, grenade projectiles and trajectories, and access to entities, server classes and data tables.

### How do I install demoinfocs-golang?

For Counter-Strike 2 and live broadcast parsing use `go get -u github.com/markus-wa/demoinfocs-golang/v5/pkg/demoinfocs`, and for CS:GO use the v3 path. The library requires at least go 1.27 to run.

### How are events handled in the parser?

Parsing is callback driven. You call ParseFile with a context, a path and a function that receives the parser, register event handlers such as one for events.Kill inside it, and return. The events package documentation lists the other available events.

### Can the library parse live broadcasts as well as demo files?

Yes. The Go Get section leads with Counter-Strike 2 plus live broadcast parsing, aka CSTV+, and the examples folder contains a broadcasts example, so the same event handlers can be used against a live feed.

### Which version of demoinfocs-golang should I use?

The stable line is v5, released as v5.2.0 on 2026-04-21, with v3 kept for CS:GO. The v6 line exists as alpha releases, v6.0.0-alpha.0 on 2026-08-31 and v6.0.0-alpha.1 on 2026-10-11, and the import path differs between the major versions.

## Sources

- [License: MIT](https://github.com/markus-wa/demoinfocs-golang/blob/main/LICENSE)
- [markus-wa/demoinfocs-golang on GitHub](https://github.com/markus-wa/demoinfocs-golang)
- [Project website](https://pkg.go.dev/github.com/markus-wa/demoinfocs-golang/v4/pkg/demoinfocs?tab=doc)
- [README](https://github.com/markus-wa/demoinfocs-golang/blob/main/README.md)
- [Releases](https://github.com/markus-wa/demoinfocs-golang/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/markus-wa-demoinfocs-golang
