Author Topic: Monster rework  (Read 570 times)

andrewj

  • Developer
  • *****
  • Posts: 1490
Re: Monster rework
« Reply #15 on: June 29, 2017, 03:18:12 AM »
Also you mentioned a none option for ramping. Does that mean that currently, steeper ramping reduces the early difficulty. I just assumed that it made the end harder.
The ramping always starts at easiest monsters.

And it always ends at the chosen Strength setting.

It is more about how quickly the hard monsters get introduced, or in other words how quickly the mapset reaches the point where all monsters become fodder.  The "slow" setting would not actually reach that point by the end of the mapset.

The "NONE" idea just means that we reach that point instantaneously (no ramping up, getting there straight away).

Quote
If quantity controls hp-limit and strength controls dmg-limit, I'm not sure its possible to make a small dude filled wad.
I have been thinking about that, and I'm not sure yet whether that may be a problem or not.

Testing will shake that out -- if it turns out to not work so well, then I can try another way.

I should point out that the HP and DMG values won't be used directly (i.e. linearly), as they vary wildy between the monsters.  The values will be "massaged" somewhat, e.g. raising them to the power of 0.7 looks like it will work well.

andrewj

  • Developer
  • *****
  • Posts: 1490
Re: Monster rework
« Reply #16 on: June 29, 2017, 11:49:03 PM »
I am running some more analysis of UVMAX demos.  The new analysis includes the total area of all sectors visited by the player (a very good measure of the size of the map).

I also am looking at more megawads, so in addition to DOOM 2, TNT Evilution and the Plutonia Experiment, there is also Scythe 2, Valiant and Community Chest 1, 2 and 3.

I can compare the usage of a particular monster over the whole mapset and between the different wads, scaled by area of map.  One thing does stand out already -- monster usage (quantities) has no clear ramp up over the course of a mapset, except for some non-usage at the beginning.  The quantities is very random, throughout a mapset and between the different wads.

flyingdeath

  • Posts: 235
Re: Monster rework
« Reply #17 on: June 30, 2017, 02:52:15 AM »
One thing does stand out already -- monster usage (quantities) has no clear ramp up over the course of a mapset, except for some non-usage at the beginning.  The quantities is very random, throughout a mapset and between the different wads.

That's actually pretty cool. If you want to emulate the style of human made maps, variety is important.

It also probably means there is more of an emphasis on increasingly difficult situations rather then raw number of enemies - items.

Whilst that's pretty difficult to emulate, I would start with ; trap monsters are twice as dangerous as non-trap monsters (as a guess). I think that includes back-fill too (had some instances of enemies sneaking up on me from unexpected angles).

Also, maybe thinking about difficulty as the chance of death on a map might be helpful. Not sure how to flesh out that idea, but I just thought it might be a fresh way to think about increasing difficulty. At the moment oblige is pretty precise when it comes to ammo and health, which means the data you collected to refine them must of been good data. You extracted the averages, but what if you also extracted the variance (I'm a little rusty on my stats, maybe standard deviation or something else). So as oblige is calculating the ammo and health needs, its also keeping track of the growing error range in its calculations. As the error range pushes the minimum possible health and ammo below 0, the players chances of death increase. I'm not sure, something like that.

A system like that would understand that whilst it should not give you a billion health packs to face a cyberdemon, because of the extreme range of health loss the player can suffer, chances of death are extremely high.

andrewj

  • Developer
  • *****
  • Posts: 1490
Re: Monster rework
« Reply #18 on: June 30, 2017, 03:50:05 AM »
@fd : I'm finding it hard to image how a chance of death concept could be used.  Appreciate people thinking about these things and coming up with ideas :)

Here is a table showing usage of imps.  I added the first Memento Mori to the list, as it is a popular megawad and not slaughtermap-ish or super-hard on UV skill (as wads like Sunlust and Alien Vendetta claim to be).

The numbers are not the raw count of monsters on a map, they are adjusted based on the size of the map (more precisely: number of that monster to add in every 1000 seeds).  Zero is shown as a blank entry.  The "unk" represent demos that did not exist or failed somehow.

Code: [Select]
Map:   DOOM2   TNT    PLUT    MM   SCYT2  VALNT   CC1    CC2    CC3
01 :    106    223     24     77     98    149     98    220    120
02 :    132     63     21    133     70    264     20    146    324
03 :    130     76      5    276     85    240    280     76     55
04 :    207    176     22    114    154    149     43    162     76
05 :    209    141           113     93    180     46    290    171
06 :    156     60      3     43     85     59    126     45     72
07 :            73           134     28     29    224     71    119
08 :    152     64     36     39    105     20     35    186    296
09 :    189    304    191    225    300     64     45     84    233
10 :    123    252     37     12    127     27    106    124    108
11 :     35     56            97    101    110    unk     63    185
12 :     46     37     48     76    190    102    111    114     85
13 :    101     32     21    122     97    119    128     55     24
14 :     45     28     13    122     49    343    442    295     38
15 :     46     65      6     57    118     88    131     63    185
16 :     95     58      7     27     87    162     99     88     79
17 :    112     60     72     53    102     44    152    328    123
18 :     84      7     58     31     63     86     46    112     80
19 :     94     45    206    165     98    196    195    257    143
20 :     15     34     17     18     36    109     42     48     81
21 :    159     50     63     76    104     64     89     45     36
22 :    158     30     24    250     50     51    231     94    149
23 :     48     39     44     57     17     44    128    132    232
24 :     37     55      6     41     97     55    628    unk    169
25 :     52     28     25    160    105     91     77    144    127
26 :     74    142     32     79     10     78     99     14    101
27 :     29     76            83     59    unk    unk    101     70
28 :     35     32     28     87            99    147    unk    429
29 :     30     21     13     53     74    182     42     18    100

While DOOM2 and Valiant show a reduction in imps over the mapset, you can see other megawads are a lot more random.
« Last Edit: June 30, 2017, 04:22:24 AM by andrewj »

andrewj

  • Developer
  • *****
  • Posts: 1490
Re: Monster rework
« Reply #19 on: June 30, 2017, 05:43:13 AM »
Replies to earlier comments:

Quote from: hetdegon
This brings me to a certain issue, that the "less, more, heaps, ..., mix it up" settings are kind of nebulous for someone who hasn't dived into the guts of Oblige like you, Glaice or myself, so I theorize they are causing a bit of confusion for casual users.
Yeah it is not ideal, some settings are fairly absolute (like Outdoors and Caves) and some are relative to the default (Monster Control and Weapon Control).

I have thought about having sliders instead of choice-lists).  Space in the UI is an issue though, not really room to have a slider widget and a bit of text showing the current setting.  I guess a tooltip could show the current value?

Quote from: BobFromReboot
Since you have removed the coop/single player option, are there extra monsters spawning when playing an oblige map in cooperative?
No.  It could be done I guess (via coop monster flag), but I think the user can just use a higher Quantity setting (etc).

Quote from: Dante
Here's a catch 22 as I see it; If you consider that OBLIGE accounts for enough ammo for each monster encounter (as per fight.lua and user settings), but zombies always drop ammo, then it's going to be a balance between working on the monster distribution vs. weapon and ammo placement
Yeah zombies and shotgun guys do tend to keep the player stocked of bullet and shell ammo, this is shown with the demo analysis too.  The code accounts for those drops, and I don't plan to do anything more beyond that.

Quote from: Dante
Now as for boss monsters, I think every fifth level could be a special type of situation
Doing something a bit different for the "mid episode" map is a good idea.  The demo analysis shows that in some megawads, there is a big boss fight roughly twice per episode (others seem to like to end every map with a Cyberdemon or three).

Quote from: Dante
Now as for both scenarios, I do miss the entirety of the level being big enough for a cyberdemon to stalk you all the way back to the start room. Can you make special accommodations to the ceiling and door height to consider this for a level featuring the cyberdemon?
Sorry, there are too many factors at play to guarantee that.

Quote from: Glaice
Using Archviles in those square cages in the room can make them a priority target, especially when there's other monsters being used. Providing there is other cover besides around a corner, this can work well.
Indeed.

Quote from: Glaice
The Mastermind just needs sufficient room to maneuver and could be a great guard monster
True but its almost impossible to ensure there will be sufficient room for such a large monster.  That is because we don't know what a room is (exit room, key room, etc) until after all the rooms in the level are fully grown.

Best we can do is build the exit room first, and use special grow rules to ensure a large space for the Mastermind.  This is actually being done already in 7.55, but I needed to make the code make the start room first.  The current code can actually do both, but is lacking some needed logic to tie everything together.

flyingdeath

  • Posts: 235
Re: Monster rework
« Reply #20 on: June 30, 2017, 10:50:33 PM »
@fd : I'm finding it hard to image how a chance of death concept could be used.

I did actually start fleshing out crude method where every enemy has a "player chance of survival" value, but I think this actually misses the point.

What if stats about the last map (number (combined health) of each enemy, also textures and structural feature... and ammo) were used to restrain the current map being generated. Were there lots of chaingunners on the last map, lets have few or none. To really emulate human maps, oblige should remember all the maps its made and try to be different, though that does seem unfeasible.

But that is what I imagine the stats show. The desire to make every map different and not to follow any trend that might become routine for the player.

Maybe make monster palettes less binary. I actually can't remember if there already is a finer degree of monster usage to the monster palette... Looked at the start of the thread, there is finer degree to room palettes, but not level wide as far as my brief skim could tell.

andrewj

  • Developer
  • *****
  • Posts: 1490
Re: Monster rework
« Reply #21 on: July 01, 2017, 02:21:20 AM »
I will probably re-introduce the "skip_prob" monster field, which used to exist but I removed it as I thought the zone palettes were enough.

So current thinking is to have a finer global palette, where a few monsters are marked "none", a few monsters are marked "restricted" (use them less) and the rest are "normal".

Plus each room has a palette with similar values.  And probably generate room palettes which differ from previous room.  Plus the HP-limit and DMG-limit will have some degree of randomness, it will hopefully produce a good diversity of battles.

andrewj

  • Developer
  • *****
  • Posts: 1490
Re: Monster rework
« Reply #22 on: July 09, 2017, 11:49:39 PM »
Some data on how many monster types are skipped per level.

This is from the demo analysis of three IWADs and six PWADs.  This data ignores the Cyberdemon and Spiderdemon, which leaves 15 monsters in DOOM 2, and simply counts how many of those were not used in each map.

Code: [Select]
MAP01 : 13  10   7  10   7   7   6   7   9  : avg  8
MAP02 : 11   3   5  11   7   5   8   8   8  : avg  7
MAP03 :  9   4   4  10   5   9   8   6   1  : avg  6
MAP04 :  9   3   4   7   4   5   3   3   7  : avg  5
MAP05 :  6   6   6   6   5   4   5   0   0  : avg  4
MAP06 :  6   4   4   7   8   6   0   1   1  : avg  4
MAP07 : 13   2   7   4   9   5   3   2   0  : avg  4
MAP08 :  7   6   4   9   5   3   3   3   8  : avg  5
MAP09 :  4  10   3   1   2   2   2  10   2  : avg  4
MAP10 :  5   2   1   3   5   3   4   3   1  : avg  3
MAP11 :  2   7  14   4   5   2   1   5 ---  : avg  5
MAP12 :  7   4   3   3   3   2   1   4   0  : avg  3
MAP13 :  7   4   1   2   4   3   2   3   9  : avg  3
MAP14 :  6   7   6   2   4   4   7   5   0  : avg  4
MAP15 :  5   2   3   0   1   3   4   0  10  : avg  3
MAP16 :  8   2   5   0  14   4   7   3   1  : avg  4
MAP17 :  4   1   4   2   4   2   6   4   3  : avg  3
MAP18 :  6   0   5   1   1   3   0   2   1  : avg  2
MAP19 :  7   3   4   3   0   7   3   2   4  : avg  3
MAP20 :  5   0   2   1   4   4   0   1   1  : avg  2
MAP21 :  7   1   2   2   5   2   0   6   6  : avg  3
MAP22 :  9   2   1   3   1   3   7   0   3  : avg  3
MAP23 :  6   6   2   2   3   3   1   4   3  : avg  3
MAP24 :  7   8   6   4   4   2   9   2 ---  : avg  5
MAP25 :  4   2   2   1   4   6   1   1   2  : avg  2
MAP26 :  7   3   2   3   4   6   0   4   3  : avg  3
MAP27 :  1   2   6   0   3   1   8 --- ---  : avg  3
MAP28 :  1   3   4   3   8   0   5   0 ---  : avg  3
MAP29 :  3   2   3   0   2   2   0   2   0  : avg  1

As expected, more monsters are skipped at the start, and not many monsters are skipped at the end.  The average value fairly clearly ramps down over a wad, but still a lot of variation.

I will replicate something similar for OBLIGE shortly.

andrewj

  • Developer
  • *****
  • Posts: 1490
Re: Monster rework
« Reply #23 on: July 11, 2017, 02:52:28 AM »
Well, I have mostly finished rewriting the monster planning code for the new systems (as described in earlier posts).

I still have a lot of work to do, about dozen things on this to-do, plus it will need a lot of fine-tuning once it is complete (and comparing with the demo analyses).

For anyone interested, here is an example output of the new monster planning code.  It is not hugely different from the old one, though "fodder" is one of the new things here.

Code: [Select]
Planned monsters:

MAP01
  ranks  =   30.0 /   15.0 /    5.0
  global = { imp, shooter, skull, zombie }
  skip   = NONE
  fodder = { imp, zombie }
  guards = { skull }
  majors = { shooter }
  fights = { skull, skull }
  boss   = { shooter }

MAP02
  ranks  =   33.0 /   17.0 /    7.0
  global = { arach, demon, gunner, imp, knight, revenant, shooter, zombie }
  skip   = { caco, skull, spectre }
  fodder = { demon, imp, shooter, zombie }
  guards = { gunner, knight, revenant }
  majors = { arach }
  fights = { knight, revenant, gunner, revenant, knight }
  boss   = { arach }

MAP03
  ranks  =   36.0 /   20.0 /    9.0
  global = { arach, caco, demon, gunner, imp, shooter, spectre, zombie }
  skip   = { revenant, skull, knight }
  fodder = { demon, imp, shooter, spectre, zombie }
  guards = { caco, gunner }
  majors = { arach }
  fights = { caco, gunner, gunner, caco }
  boss   = { arach }

MAP04
  ranks  =   40.0 /   23.0 /   12.0
  global = { arach, caco, demon, gunner, imp, revenant, shooter, skull, zombie }
  skip   = { knight, spectre }
  fodder = { caco, demon, gunner, imp, shooter, skull, zombie }
  guards = { revenant }
  majors = { arach }
  fights = { revenant, revenant }
  boss   = { arach }

MAP05
  ranks  =   43.0 /   26.0 /   14.0
  global = { caco, demon, gunner, imp, knight, mancubus, shooter, zombie }
  skip   = { revenant, skull, arach, spectre }
  fodder = { caco, demon, gunner, imp, knight, shooter, zombie }
  guards = {}
  majors = { mancubus }
  fights = {}
  boss   = { mancubus }

MAP06
  ranks  =   47.0 /   29.0 /   17.0
  global = { arach, baron, caco, demon, gunner, imp, knight, mancubus, revenant, shooter, skull, spectre, zombie }
  skip   = NONE
  fodder = { caco, demon, gunner, imp, knight, revenant, shooter, skull, spectre, zombie }
  guards = { arach, mancubus }
  majors = { baron }
  fights = { arach, mancubus, arach, mancubus }
  boss   = { baron }

MAP07
  ranks  =   50.0 /   32.0 /   19.0
  global = { baron, caco, demon, gunner, imp, knight, mancubus, pain, revenant, shooter, skull, spectre, zombie }
  skip   = { arach }
  fodder = { caco, demon, gunner, imp, knight, revenant, shooter, skull, spectre, zombie }
  guards = { mancubus }
  majors = { baron, pain }
  fights = { mancubus, mancubus }
  boss   = { pain }

MAP08
  ranks  =   54.0 /   35.0 /   21.0
  global = { demon, gunner, imp, knight, pain, revenant, shooter, spectre, zombie }
  skip   = { caco, arach, mancubus, skull, vile, baron }
  fodder = { demon, gunner, imp, knight, revenant, shooter, spectre, zombie }
  guards = {}
  majors = { pain }
  fights = {}
  boss   = { pain }

MAP09
  ranks  =   57.0 /   38.0 /   24.0
  global = { arach, baron, caco, demon, imp, knight, revenant, shooter, spectre, zombie }
  skip   = { pain, mancubus, skull, gunner, vile }
  fodder = { caco, demon, imp, knight, revenant, shooter, spectre, zombie }
  guards = { arach }
  majors = { baron }
  fights = { arach, arach }
  boss   = { baron }

MAP10
  ranks  =   61.0 /   41.0 /   26.0
  global = { baron, caco, demon, gunner, imp, knight, mancubus, revenant, shooter, skull, zombie }
  skip   = { pain, arach, spectre, vile }
  fodder = { caco, demon, gunner, imp, knight, mancubus, revenant, shooter, skull, zombie }
  guards = {}
  majors = { baron }
  fights = {}
  boss   = { baron }

MAP11
  ranks  =   64.0 /   44.0 /   29.0
  global = { arach, baron, caco, demon, gunner, imp, knight, mancubus, pain, revenant, shooter, skull, spectre, vile, zombie }
  skip   = NONE
  fodder = { arach, caco, demon, gunner, imp, knight, mancubus, revenant, shooter, skull, spectre, zombie }
  guards = { pain }
  majors = { baron, vile }
  fights = { pain, pain }
  boss   = { vile }

MAP12
  ranks  =   67.0 /   47.0 /   31.0
  global = { arach, baron, caco, demon, gunner, imp, knight, mancubus, pain, shooter, spectre, zombie }
  skip   = { revenant, skull, vile }
  fodder = { arach, caco, demon, gunner, imp, knight, mancubus, shooter, spectre, zombie }
  guards = { pain }
  majors = { baron }
  fights = { pain, pain }
  boss   = { baron }

MAP13
  ranks  =   71.0 /   50.0 /   33.0
  global = { arach, caco, demon, gunner, imp, knight, mancubus, revenant, shooter, skull, spectre, vile, zombie }
  skip   = { pain, baron }
  fodder = { arach, caco, demon, gunner, imp, knight, mancubus, revenant, shooter, skull, spectre, zombie }
  guards = {}
  majors = { vile }
  fights = {}
  boss   = { vile }

MAP14
  ranks  =   74.0 /   53.0 /   36.0
  global = { arach, baron, demon, gunner, imp, knight, mancubus, revenant, shooter, skull, zombie }
  skip   = { caco, pain, spectre, vile }
  fodder = { arach, demon, gunner, imp, knight, mancubus, revenant, shooter, skull, zombie }
  guards = {}
  majors = { baron }
  fights = {}
  boss   = { baron }

MAP15
  ranks  =   78.0 /   56.0 /   38.0
  global = { arach, baron, caco, demon, gunner, imp, knight, pain, revenant, shooter, skull, vile, zombie }
  skip   = { mancubus, spectre }
  fodder = { arach, caco, demon, gunner, imp, knight, revenant, shooter, skull, zombie }
  guards = { baron, pain }
  majors = { vile }
  fights = { baron, pain, pain, baron }
  boss   = { vile }

MAP16
  ranks  =   81.0 /   58.0 /   41.0
  global = { arach, baron, caco, demon, gunner, imp, pain, revenant, shooter, spectre, zombie }
  skip   = { mancubus, skull, knight, vile }
  fodder = { arach, caco, demon, gunner, imp, revenant, shooter, spectre, zombie }
  guards = { pain }
  majors = { baron }
  fights = { pain, pain }
  boss   = { baron }

MAP17
  ranks  =   85.0 /   61.0 /   43.0
  global = { arach, baron, caco, demon, gunner, imp, knight, mancubus, pain, revenant, shooter, skull, spectre, Spiderdemon, vile, zombie }
  skip   = NONE
  fodder = { arach, caco, demon, gunner, imp, knight, mancubus, pain, revenant, shooter, skull, spectre, zombie }
  guards = { baron, vile }
  majors = { Spiderdemon }
  fights = { baron, vile, vile, baron }
  boss   = { Spiderdemon }

MAP18
  ranks  =   88.0 /   64.0 /   46.0
  global = { baron, caco, demon, gunner, imp, knight, mancubus, pain, revenant, shooter, skull, spectre, vile, zombie }
  skip   = { Spiderdemon, arach }
  fodder = { caco, demon, gunner, imp, knight, mancubus, pain, revenant, shooter, skull, spectre, zombie }
  guards = { vile }
  majors = { baron }
  fights = { vile, vile }
  boss   = { baron }

MAP19
  ranks  =   92.0 /   67.0 /   48.0
  global = { arach, baron, caco, Cyberdemon, demon, imp, knight, mancubus, pain, revenant, shooter, skull, spectre, Spiderdemon, zombie }
  skip   = { gunner, vile }
  fodder = { arach, baron, caco, demon, imp, knight, mancubus, pain, revenant, shooter, skull, spectre, zombie }
  guards = {}
  majors = { Cyberdemon, Spiderdemon }
  fights = {}
  boss   = { Cyberdemon }

MAP20
  ranks  =   95.0 /   70.0 /   50.0
  global = { arach, baron, caco, Cyberdemon, demon, gunner, imp, knight, mancubus, pain, revenant, shooter, skull, Spiderdemon, vile, zombie }
  skip   = { spectre }
  fodder = { arach, baron, caco, demon, gunner, imp, knight, mancubus, pain, revenant, shooter, skull, zombie }
  guards = { vile }
  majors = { Cyberdemon, Spiderdemon }
  fights = { vile, vile }
  boss   = { Cyberdemon }

MAP21
  ranks  =   98.0 /   73.0 /   53.0
  global = { arach, baron, caco, demon, gunner, imp, knight, mancubus, pain, revenant, shooter, skull, zombie }
  skip   = { Spiderdemon, vile, Cyberdemon, spectre }
  fodder = { arach, baron, caco, demon, gunner, imp, knight, mancubus, pain, revenant, shooter, skull, zombie }
  guards = {}
  majors = {}
  fights = {}
  boss   = {}

MAP22
  ranks  =  102.0 /   76.0 /   55.0
  global = { baron, caco, Cyberdemon, demon, gunner, imp, knight, mancubus, pain, shooter, skull, spectre, Spiderdemon, vile, zombie }
  skip   = { revenant, arach }
  fodder = { baron, caco, demon, gunner, imp, knight, mancubus, pain, shooter, skull, spectre, vile, zombie }
  guards = {}
  majors = { Cyberdemon, Spiderdemon }
  fights = {}
  boss   = { Cyberdemon }

MAP23
  ranks  =  105.0 /   79.0 /   58.0
  global = { arach, baron, caco, Cyberdemon, demon, gunner, imp, knight, mancubus, pain, revenant, shooter, skull, spectre, Spiderdemon, zombie }
  skip   = { vile }
  fodder = { arach, baron, caco, demon, gunner, imp, knight, mancubus, pain, revenant, shooter, skull, spectre, zombie }
  guards = {}
  majors = { Cyberdemon, Spiderdemon }
  fights = {}
  boss   = { Cyberdemon }

MAP24
  ranks  =  109.0 /   82.0 /   60.0
  global = { arach, baron, caco, Cyberdemon, demon, gunner, imp, knight, mancubus, pain, revenant, shooter, skull, spectre, Spiderdemon, vile, zombie }
  skip   = {}
  fodder = { arach, baron, caco, demon, gunner, imp, knight, mancubus, pain, revenant, shooter, skull, spectre, vile, zombie }
  guards = { Spiderdemon }
  majors = { Cyberdemon }
  fights = { Spiderdemon, Spiderdemon }
  boss   = { Cyberdemon }

MAP25
  ranks  =  112.0 /   85.0 /   62.0
  global = { baron, caco, demon, gunner, imp, knight, mancubus, pain, revenant, shooter, skull, spectre, Spiderdemon, vile, zombie }
  skip   = { Cyberdemon, arach }
  fodder = { baron, caco, demon, gunner, imp, knight, mancubus, pain, revenant, shooter, skull, spectre, vile, zombie }
  guards = {}
  majors = { Spiderdemon }
  fights = {}
  boss   = { Spiderdemon }

MAP26
  ranks  =  116.0 /   88.0 /   65.0
  global = { arach, baron, caco, demon, gunner, imp, knight, mancubus, pain, revenant, shooter, spectre, Spiderdemon, vile, zombie }
  skip   = { skull, Cyberdemon }
  fodder = { arach, baron, caco, demon, gunner, imp, knight, mancubus, pain, revenant, shooter, spectre, vile, zombie }
  guards = {}
  majors = { Spiderdemon }
  fights = {}
  boss   = { Spiderdemon }

MAP27
  ranks  =  119.0 /   91.0 /   67.0
  global = { arach, baron, caco, Cyberdemon, demon, gunner, imp, knight, mancubus, pain, revenant, shooter, skull, vile, zombie }
  skip   = { Spiderdemon, spectre }
  fodder = { arach, baron, caco, demon, gunner, imp, knight, mancubus, pain, revenant, shooter, skull, vile, zombie }
  guards = {}
  majors = { Cyberdemon }
  fights = {}
  boss   = { Cyberdemon }

MAP28
  ranks  =  123.0 /   94.0 /   70.0
  global = { arach, baron, caco, Cyberdemon, demon, gunner, imp, knight, mancubus, pain, revenant, shooter, skull, spectre, vile, zombie }
  skip   = { Spiderdemon }
  fodder = { arach, baron, caco, demon, gunner, imp, knight, mancubus, pain, revenant, shooter, skull, spectre, vile, zombie }
  guards = {}
  majors = { Cyberdemon }
  fights = {}
  boss   = { Cyberdemon }

MAP29
  ranks  =  126.0 /   97.0 /   72.0
  global = { arach, baron, caco, Cyberdemon, demon, gunner, imp, knight, mancubus, pain, revenant, shooter, skull, spectre, vile, zombie }
  skip   = { Spiderdemon }
  fodder = { arach, baron, caco, demon, gunner, imp, knight, mancubus, pain, revenant, shooter, skull, spectre, vile, zombie }
  guards = {}
  majors = { Cyberdemon }
  fights = {}
  boss   = { Cyberdemon }