25/06/2005 @08:26:14 ^11:32:36

damnation! is there anything i can post about that isn't doom and hasn't just been posted by somebody else!

Well, no, it would seem not. I was going to mention how there was a tornado in Coventry yesterday, and post that link, until df copied it into #warwick. Now it just looks like I'm stealing links. Also I was going to post about the ridiculously loud thunder that woke me up after only one and a half hour's sleep yesterday morning, until Stik said he had just posted it too.

So, I give up. Here's some more shit about Doom...

How to fix PrBoom 2.2.6

I must report an injustice in my review of Star Wars Doom last month. I said that the Dehacked patches confused killcount and itemcount. This has been demonstrated to be untrue. The problem is instead that the Dehacked patch loader in PrBoom 2.2.4 misinterprets the flag bits it is given, and sets item count when it should set kill count.

The way I found this out was that I have been playing the much-anticipated megawad Scythe 2 which came out a week or two ago. I guess I'll do a proper review when I've played all of it but I will happily recommend it to you now. It includes a Dehacked patch that creates a couple of new monsters, and having encountered one of them I noticed it was showing up as an item on the map cheat and not counting towards kills.

(Aside: Dehacked was a program that, before the Doom source code was released, would modify certain data tables found in doom(2).exe allowing you to make new monsters, weapons etc. Given its very nature was an unbelievable hack, it was impressive that it worked at all, let alone worked so well! Of course it was totally obsoleted by source ports, but since many famous wads relied on patches for correct operation many ports introduced a compatibility layer so that the patches could still be used)

I dug out the 2.2.6 source code, compiled it, and ran it as a test. Guess what, it fixed this. Of course 2.2.6 also fixes a number of other things, for example the patch overflow check that causes 2.2.4 to kill itself at the end of Doom E3M3 no longer happens. In fact 2.2.6 has been out for a year so why haven't I upgraded before?


Ever since Doom 2 when the archvile was introduced the problem of getting more than 100% kills has been around. Put simply, you kill a monster, the vile resurrects it, you kill it again. You get the kill counted twice, and if you go on to kill the vile and everything else, end up with more than 100% kills at the end of the map. I am anal enough that a percentage greater than 100% bothers me, but there's a more justifiable reason that it is a bug. It is to do with recording maxdemos.

Suppose you're trying for 100% kills but get resurrections. The kills counter thus says you've killed all the monsters, but you haven't, because of counting the kills of resurrected monsters twice. Imagine you do this unwittingly in a demo recording attempt, on which you've already spent weeks. After dozens or hundreds of attempts you finally manage to pull it off. You proudly release your demo... only to have it pointed out that there are missed monsters and it doesn't qualify. Screaming hairy ab-dabs!

I solved this annoyance in DIY a long time ago, firstly by increasing the global variable containing the number of monsters on a map (which is precalculated on level entry) on a resurrection. That didn't work though; if you happened to be using savegames, on reload the total number of monsters was recalculated, and resurrections were forgotten. So rather than change the savegame file format to save the counter and probably cause all sorts of problems later I instead made it reduce the player's kill count, which obviously is saved, upon a resurrection. This works fine in single player when there's only one player from whom to take away the kill, so you don't have to worry about which player to whom the kill was attributed. Since my Risc PC wasn't (and still isn't) networked I didn't see it as a problem.

PrBoom 2.2.6 solves the problem differently. It introduces a new global variable, the live monsters counter. Theoretically, instead of playing until your number of kills equals or exceeds the total number of monsters given, you play until the number of live monsters reaches zero. Obviously it is reduced on a kill; it increases on a resurrection, a boss brain spawn, or a Nightmare skill respawn. From a purist's point of view this solution is better because it maintains intermission screen percentage compatibility with doom2.exe.

But obviously there's a problem with the solution, else I would have upgraded ages ago and wouldn't be writing this! Quite simply, the live monsters counter is very easy to get into a state where it is completely wrong, made entirely useless by its incorrectness, and not only that but it annoys the hell out of me too.


Usually I'd just wait for a new version to come out but with Doom I really need this shit to be fixed. I did some research and this is what came up: totallive is implicitly initialised to zero on game start (it's a static global, so C zeroes it before entering main()) Then it is modified in one of the following ways

  1. It is incremented when a monster is spawned. This is either a nightmare respawn, a boss brain spawn, or most usually simply part of the level initialisation at the start of play or after a death or whatever
  2. It is also incremented on a resurrection (obviously) (this is technically different from a respawn though, it's a different function)
  3. It is decremented on the death of a monster.
  4. It is explicitly zeroed and recalculated on reload of a savegame.

Note the only time is it explicitly recalculated is when you reload a savegame. All the rest of the time it is supposed to maintain itself. Now consider the following

In the same way, if you exit a map with monsters still alive, when you start the next map it just adds the new map's number of monsters on instead of setting it zero first. It doesn't reset if you use the warp-to-level cheat code. It doesn't even reset it if you press F7, quit back to the menu, and then restart explicitly!

Okay I can see one possible application of carrying the live monsters counter over between levels; if you do a speedrun of an episode, it might be nice to see how many monsters you left behind. But it doesn't seem like enough of a justification. I know the guy who maintains PrBoom uses savegames extensively, if you read his map reviews at Doom Underground you can see this. I think that's why the only place it explicitly recalculates live monsters is on a savegame reload; it's the place he mostly likely noticed it goes wrong. It seems a weird omission though. The level setup code explicitly zeroes all the other similar counters.

Anyway here's the patch, it's really simple once I worked out where I thought it should best go

--- prboom-2.2.6/src/p_setup.c  2004-09-15 19:26:13.000000000 +0100
+++ prboom-2.2.6-lm/src/p_setup.c       2005-06-25 00:13:45.000000000 +0100
@@ -1332,8 +1332,8 @@
   char  gl_lumpname[9];
   int   gl_lumpnum;
-  totalkills = totalitems = totalsecret = wminfo.maxfrags = 0;
+  // [RjY] fix live monsters counter
+  totallive = totalkills = totalitems = totalsecret = wminfo.maxfrags = 0;
   wminfo.partime = 180;
   for (i=0; i<MAXPLAYERS; i++)

PS Just before I uploaded this article I was poking around the subversion repository and I found it has exactly the same fix in it as I spent half of last night working out! I'd be annoyed but I wouldn't have known where in the code to start looking if I hadn't worked it out myself, so I can't complain for once. It also means that all my speculation about why the omission might have been deliberate is so much hot air, though.