Game Map Gallery

What am I looking at?

Each image and animation on this page visualizes how players from both teams can move across a map from the start of the round, and where they are able to see each other for the first time.

Every frame represents a specific moment in time. At that moment, the visualization shows which parts of the map each team could theoretically have reached if they moved optimally from spawn and which areas can first see each other at this point in time.

Tile colors

Lines

Standard mesh with connections

The animated GIF at the top shows this process continuously over time, while the individual images below allow you to inspect specific moments in more detail.

How does this work? (technical details & limitations)

Project background

I recently came back to CS after a long break, and due to changes to existing maps and the addition of new ones, I had no idea about the timings anymore. None of my friends play the game, so I couldn't hop into a server with someone to check where the Ts and CTs meet at the start of the round.

I also didn't want to do this manually after every map update. So I decided to write a small program that calculates these meeting points automatically.

The main tool for this is Awpy, a Python library for CS2 demo parsing and analysis. It also provides functionality for navigation and visibility by reading the game files.

Grid structure & pathfinding

The maps are subdivided into a rectangular grid: typically 200x200 tiles, or 100x100 for more horizontal and square maps. From this grid, a graph is built representing which tiles are connected based on walkability and jumpability.

  • Walkability: a tile is considered reachable if a ray cast from player height at the tile center to the target tile (offset by player width left and right) does not hit any object or collision.
  • Jumpability: a tile can be reached if a normal crouch jump is sufficient to get there.

Computing reachability

Once the graph is built, the program calculates the shortest path to each tile from all CT and T spawn points separately, along with their distances. Then, step by step, it considers all tiles reachable after X time or at effective distance X.

For each newly reached tile, it checks which tiles reachable by the other team are visible. This identifies potential first-contact locations.

Generating images

Maps have 10,000-40,000 tiles, making it impossible to visualize each individually. To reduce clutter, an approximation is used: only groups of tiles that have not been previously spotted are plotted. This logic ensures images show meaningful steps without overwhelming detail.

To achieve this, tiles are first clustered into small spatial groups (the black rectangles). The grouping is based on the 2D grid used for pathfinding: neighbouring tiles in x/y are merged into blocks (roughly corresponding to 5x5-10x10 tiles in world space, depending on map granularity). Within each block, tiles are further split by height so that a single group never mixes levels that are more than one jump apart or stack multiple floors at the same x/y position. The result is that each group behaves like one "patch of ground" a player could stand on.

During the spread simulation, each team tracks two states per group:

  • Reached groups - groups that a team can physically reach by walking/jumping from spawn up to a certain distance or time.
  • Spotted groups - groups that are known to be dangerous because at least one reachable enemy position in them (or looking into them) has been seen.

CT and T tiles are then processed together, always taking the next closest tile to any spawn. For each newly reached tile, the algorithm:

  • Checks the previous step along the path to that tile. If that previous step lies in a group that was already spotted, the new tile's group is immediately treated as spotted as well. This models that if a player has been spotted at any previous point of their trajectory, they will count as spotted for the rest of the simulation.
  • Performs line-of-sight checks from the new tile to all previously reached tiles of the opposing team that belong to unspotted groups.
  • For every newly visible enemy tile, marks both its group and the current tile's group as spotted and records a visibility connection between them (these become the red solid lines in the images).

A new image (spread frame) is only saved when this logic reveals something new: either a previously unseen group is spotted for the first time, or a fixed distance/time interval since the last frame has passed. Combined with grouping, this keeps the number of frames per map to roughly 200-300 while still capturing the key moments where new areas of the map become visible and relevant for first contact.

Limitations

  • Granularity is still limited: not every reachable area in the actual game is accounted for (e.g., flower beds on Ancient A or the Nuke Silo).
  • Original bot navigation meshes are used as a base, which do not include all edges. Some jumps or small shortcuts are not captured (e.g., Mirage Window → Short, Ancient sign jump).
  • Boosts with multiple players are not simulated.
  • Ladder speed is approximated (currently 250*0.78*2), which may not be fully accurate.
  • Simulation does not consider ceilings or acceleration. For example, the shortest path for CTs to reach Train inner upper assumes an instant jump from the ladder, which is slightly unrealistic.

Updates

The website is automatically kept up-to-date via a nightly job that checks for CS2 updates, identifies changed maps, and regenerates the calculations and images for those maps.

Why standard nav meshes can't be used

CS2's standard navigation meshes are triangle-based and optimized for bots. Using their centroids for pathfinding produces suboptimal paths that can drastically distort timings, especially in tight areas like D2 Long. Additionally, these meshes are incomplete: some fast routes (e.g., Mirage A Default → Balcony) do not exist in the bot mesh, so shortest paths are missed.

Here is a visualization comparing paths from T spawn to the top of Con on Mirage:

Standard mesh path

Standard mesh path

200x200 grid mesh path

200x200 grid mesh path

You can see the standard mesh path is significantly longer, irregular, and misses shortcuts such as the jump between Tetris and stairs. This motivated the creation of the 200x200 grid approach used in this project.


Full original mirage mesh with connections for reference:

Standard mesh with connections

Explore a map