Frag heat maps from MVD demos

Each frag is plotted as transparent dot, so if there are many frags in an area it will show up more bright/solid:

400 4on4 games, 120000 frags on DM3.

170 4on4 games, 70000 frags on DM2.

140 4on4 games, 60000 frags on E1M2.

8000 1on1 frags on DM4.

DM2 with smaller points, I think it is the same 70000 frags but I am not sure. Did not matter much though when I tried with ~10000. I like how this shows how deaths are likely to happen next to walls.

This is very not scientific. For example some frags from baldm3 and even ztndm3 matches did sneak into the DM3 one because I did not care. Also since the demos came from 2002-2009 there's got to be rule changes involved. Anyways, the majority should be good and thus those good frags easily outnumber the bad ones. Yay for stochastic(?).

If you have a specific request, just provide Spirit with urls to the (mvd) demos.

How to do it yourself (on Linux)

Warning: This is very very ugly. Manual work is needed way too much. If you plan to do more than 4-5 I urge you to write a quick shell script.

Prerequisites: gnuplot 4.3+, imagemagick and some knowledge of your shell.

1. Get and compile Cokeman's amazing MVD Parser. svn co mvdparser

2. Get bsp2bmp (is there a official host of it?). Set maxX, maxY and maxZ to 4096 and minX, minY, minZ to -4096 by uncommenting the for loop after printf("Collecting min/max\n"); and, well, setting those fixed values instead. Compile bsp2bmp then (and I recommend renaming the binary, I called mine bsp2bmp_spiritugh).

3. Get the demos you want to use and put them to mvdparser and its .dat files. Smart people would modify the template.dat now so it only outputs the *events.log files with the coordinates as "xxx yyy zzz" (or even "xxx yyy 15", see below). I noticed that possibility way too late and cannot be arsed to play with it now. Well, run mvdparser for each mvd you want now. I used find . -name "*.mvd" -print0|xargs -0 ./mvdparser

4. cat *events.log > map_events.log

5. Remove all the unneeded stuff and set all Z values to the same (15 is good for the render later). The view is from above so only X and Y are interesting. Gnuplot treats the Z value as actual value of the XY point which is why you want the same value for them all. I used my precious jEdit for this step. Using sed would be much much better…

6. Now create the map outline with your fresh bsp2bmp hack. ./bsp2bmp_spiritugh -p0 -s4 map.bsp map.bmp. p0 means no padding, s4 sets the scale.

7. gnuplotheatmap.gnu:

set nokey

set notics

set bmargin 0

set tmargin 0

set lmargin 0

set rmargin 0

set view map

set pm3d

set xrange [-4096:4096]

set yrange [-4096:4096]

set terminal pngcairo transparent size 2310,2049 #You cannot set a fixed size of the actual graph, only the whole render. So this is an awkward hack (together with the cropping later). This MUST be pngcairo for transparency

set output "tmp_heatmap.png"

#plot 'map_events.log' with circles linecolor 1 fillstyle transparent solid 0.2 noborder

#plot 'map_events.log' with points

8. This is ugly. First the cropping to remove the clutter on the plot. Then I flip and flip because I couldn't figure out how to do without. Well, it works, so … party!

gnuplot gnuplotheatmap.gnu && convert tmp_heatmap.png -crop 2048x2048+1+1 -flip tmp_heatmap.png && composite tmp_heatmap.png map.bmp map_heatmap.png && convert map_heatmap.png -flip map_heatmap.png

10. Crop the image and give it a more verbose name.

Further reading in the original thread at

TODO for smart people

-Create a tailored template.dat

-Write a bash script that takes a map name (AAA.bsp) and does the rest all by itself….

-Crop the end image automatically.

-Pick two players and a map they frequently play(ed), then paint them in different colours.

-Create those really gorgeous heatmaps by using a raster on the map and counting frags per square (that's how I would do it).

Further links that might be of interest: (talk to Cokeman if you want to give this ago)

Written by Spirit. Special thanks for their help to Cokeman and _KaszpiR_.