Gary L. Simmons  rev 09/30/03
Home  Marathon  Joke OT Weak  Web Building  Resumé  Lynx  Hobbies  Extra  Site Map Links Page Extra Go to next department

The Battle Cat's Litterbox

Forge Tips | Harper's Tutorials | Stacked Walkways | Heartbeat | Combination Lock | Clock | Pedestal Problem | Zig Zag Stairs | Illusory Bridges | Fake Elevators | Texture Flexing | Untextured Walls | Stacked Windows | Multi-Message Terms | Counters | Level Detector

Level detector

Level Detector

Level Detector
By Jason Harper,
Version 1.0, 4/6/99

The accompanying map illustrates a technique for making different things happen in a Marathon map depending on the difficulty level chosen, beyond the normal changes in monster toughness. It is based directly on the counting techniques shown in my Counter Revolutionary tutorial. You'll need to read the documentation included with that map, along with some earlier references that it builds upon, to understand what's going on here.

The map can be viewed in both Infinity and Forge, and in fact is designed to behave differently in each case. You haven't seen every capability of this map until you've played it in Infinity at multiple difficulty levels, and viewed it in Forge's visual mode. Note that Forge has some glitches with viewing certain merged maps, including this one: use the map file in the Unmerged Pieces folder instead.

In Infinity, DO NOT enter any of the doors until they have all stopped moving: you'll be trapped, and receive an incorrect terminal message. For demonstration purposes, I have placed the player starting position close enough to the doors that you can see them in operation. In an actual use of the technique, the player would start at a much more distant point (such as the far end of the corridor), and could not possibly reach the doors before they have reached their final state.

Counter Revolutionary showed how it was possible to open different doors based on a count of events that have happened. So, how can we get a different number of events to occur, based on the difficulty level? It might be possible to use the varying attack speeds of a creature at different levels, and count the number of attacks made in a fixed time period, but the count would vary due to random factors in the timing of the creature's behavior. Increasing the time period would tend to average out the randomness, but would raise the number of events to be counted into the dozens at least, which presents problems in the design of the counter mechanism.

The difficulty level also affects the identity and number of the creatures themselves. On high difficulties, some of the creatures flagged as Minor may be promoted to the Major version of that creature; on low difficulties, Major creatures may be demoted to Minor, and some creatures may simply be skipped. As you've probably noticed, the creatures that get changed or skipped are chosen randomly each time you play a level, so it may appear that this approach would be no more reliable than counting attacks. However, it turns out that the number of changed/skipped creatures is 100% repeatable: if a given map has two of its Minor Fighters skipped on Kindergarden level, then it will ALWAYS have exactly two of them skipped on that level, although it will not always be the same two. And these numbers are calculated separately for each creature type: if a map has both Minor Fighters and Minor Troopers, each will have a consistent number of skips, there's no chance of all the Fighters being skipped but none of the Troopers.

Taking advantage of this effect required determining the rules which control it. Here's a summary of my results:

  • Total Carnage: All Minor creatures are promoted.
  • Major Damage: 50% of Minors (rounded down, if there's an odd number) are promoted.
  • Normal: No change to any creatures.
  • Easy: About 20% of Majors are demoted, 10% of all creatures are skipped.
  • Kindergarden: About 35% of Majors are demoted, 25% of all creatures are skipped.

Note that promotion and demotion consist of replacing the creature with the next or previous one, respectively, as listed in the physics model in use. Normally, this will be the other variant of the same creature type, but there's no actual requirement for this. By rearranging the creatures in the physics model, you can have the promoted or demoted version of any creature be absolutely anything you want. In particular, the promoted version of a Minor creature doesn't have to be flagged as Major, and vice versa. It's unclear what would happen if only one of the two has the Can't Skip flag set: the results would depend on whether demotion is handled before or after skipping.

To determine the difficulty level, you just need to put some number of Major and Minor versions of some creature in the map, and count the number of one type that actually appear when the map is played. Note that you must count only Majors or only Minors - a count of the total that appear does you no good, as this number does not change between the three highest difficulty levels. The minimum number of creatures that will work, resulting in distinct counts for each difficulty level, is 4 Majors plus 2 Minors. However, the counts resulting from that configuration turn out to present some extra difficulties in the design of the counter mechanism. For reasons I'll explain later, I instead chose to use 6 Majors and 3 Minors. Here's a chart of how many actually appear on each level:

 Difficulty  #Majors  #Minors  Notes
 Total Carnage  9  0  All Minors Promoted
 Major Damage  7  2  1 Minor promoted
 Normal  6  3  No change
 Easy  4  4  1 Major demoted, 1 Major Skipped
 Kindergarden  2  5  2 Majors demoted 2 Majors skipped

All that remains is to somehow wake up all of the creatures, and get only those of one type (I chose Majors) to walk over a trigger platform so that they can be counted. I accomplish both tasks by having the creatures start underneath a crushing platform: the damage wakes them up (I believe this is the only way of doing so that doesn't somehow involve the player walking over a monster trigger polygon), and the physics model is adjusted so that the Minors are all killed by the damage, but the Majors survive. All of the creatures are set to be activated by a goal polygon, which is nearby: in the process of getting there, the surviving creatures walk over a trigger which advances the counter mechanism as described in Counter Revolutionary.

As a side note, here are a couple of other possibilities for counting only the Major creatures:

  • Give the Minors a movement speed of 0, so they can never reach the trigger.
  • Have a step up or down, or a lowered polygon height, that only the Majors are capable of passing due to their physics settings.
  • Have an area of liquid that only the Majors are capable of walking through or flying over.

With any of these techniques, there is a severe risk of a Major getting stuck behind a Minor, and therefore not being counted. Perhaps more seriously, the Minors will be left active until the end of the map level, limiting the number of creatures that can be active in combats elsewhere on the level.

I used Major and Minor Fighters for the demo map, but any Major/Minor pair could have been used. It is critical that the creatures not be used anywhere else on the level, since the number that actually appear inside the mechanism would no longer be predictable. The required physics model settings are:

  • Minors should have a low vitality (such as 0), so that the crushing platform is guaranteed to kill them instantly.
  • Majors should have enough vitality that the platform doesn't kill them: the default setting is probably high enough, but I set them to 800 vitality just to make sure. Making them immune to Crushing damage may also work.
  • Majors should be set to have no enemies, so that nothing can distract them from their goal polygon.
  • Can't Skip must not be set for either type (actually it could, but you'd have to redesign the counter mechanism to adjust for the resulting change in counts).

The counter mechanism itself is designed using the same basic techniques shown in Counter Revolutionary. The only innovation here is that ALL of the doors are initially open, specifically to make it easier to work on the map in Forge. There's no need to texture a small area, exit visual mode, set a new starting position, reenter visual mode, etc.: you always have access to all difficulty-specific areas. That's not a big deal in this map, where those areas consist of a tiny room with a terminal, but imagine a map in which those areas were extensive, with no other way to freely move between them.

This change does complicate the mechanism design somewhat, since all of the doors but one must now open twice during normal operation. There is simply no way, without the use of additional control platforms, to make a door that opens twice but doesn't continue to open at the same frequency. This technique is therefore only usable in cases where no two of the possible event counts (excepting the smallest one, which can be handled differently) are a multiple of each other. With this restriction, some of the doors may reopen after their proper time, but this can only happen at a count value that isn't actually used - as the count proceeds to one of its possible final values, the door will close again. This is why I'm using 6 Major and 3 Minor creatures to trigger the counter, rather than the minimum possible of 4 and 2: 6/3 was the smallest configuration I could find whose resulting counts met the restriction.

On the other hand, having the doors initially open does have one benefit: the platforms themselves only have to be half as high, since they will reverse direction in the middle of their count. This allows the construction of a counter with twice the maximum value otherwise possible in the same amount of vertical space.

Here's a chart of the door parameters as used in this map:

Common to all: not initially active or extended, floor height 0, ceiling height 5

Open initially and on level Event count Min height Max height Extends from Deactivates at level Note Height at counts 0..9(underlined if open)
Total Carnage 9 0 4.5 floor intiial 1 0, 1, 2, 3, 4, 4, 3, 2, 1, 0
Major Damage 7 0 3.5 floor initial 1 0, 1, 2, 3, 3, 2, 1, 0, 1, 2
Normal 6 0 3 floor each   0, 1, 2, 3, 2, 1, 0, 1, 2, 3
Easy 4 0 2 floor each 2 0, 1, 2, 1, 0, 1, 2, 1, 0, 1
Kindergarden 2 -1 3 ceiling N/A 3 3, 2, 1, 0, jammed at 0

Note 1: These platforms must have a delay time of 0, since they must reverse direction in the middle of a count (due to their fractional max height, which is required by the fact that the count on which they should reopen is an odd number). Any delay would put the platform out of sync with the rest on its way back down. The delay setting for the other doors is irrelevant.

Note 2: The Easy door reopens properly at the count of 4, but then unavoidably opens again at a count of 8 (and 12, 16, etc.). This is acceptable only because the number of creatures to be counted have been chosen so that a final count of 8 never occurs.

Note 3: The Kindergarden door must not be set to reverse direction when it hits an obstruction, otherwise it will not jam upon trying to go below its floor height at count 4.

The always-open door at the entrance to the octagonal room is there solely for the purpose of misdirection: it helps to conceal the fact that the room itself is a platform. Without the door, the south edge of the room would have an unexplained heavy line. If you can't afford to use a platform for this purpose, see Missed Island, Level 4 for other techniques for concealing the heavy lines around secret platforms.

Here's an important detail about building multi-stop platforms that I discovered while working on this map: the amount by which the controlled platform moves will vary slightly depending on whether the control platform was created before or after it. I'm not sure whether it's the time that the polygon was filled in that counts, or the time that the polygon was set to be a platform: in my usual mapmaking style, both tend to occur in the same order. It appears that Marathon processes platform activation/deactivation events in strict order: if a platform does something to affect one that's already been processed, the effect gets delayed until the next clock tick (1/30 second). To ensure consistent results, especially in cases (such as this map) where a single control platform activates multiple other platforms, make sure you create the control platform first.

In actual use, you may not need all five doors, or not have them all in one place. For example, let's say that your goal is to add additional enemies to certain combats, on Total Carnage level only. You'd need several copies of the Total Carnage door, one in each combat area, concealing the extra enemies: the other four door designs wouldn't be used at all. You'd have to somehow place the control platform so that it is adjacent to all of those doors, or have multiple control platforms each activated by the trigger platform. Note that if you don't need all of the doors, the counter mechanism design may be simplified considerably. In the specific case of detecting Total Carnage only, you just need one Minor creature: it will be promoted to Major on that level only.

This map was specifically designed to be incorporated into the works of other mapmakers. I hereby grant permission for you to do so, subject to the following two conditions:

  1. Please give me credit, either in your README file or in a terminal that a player can reasonably be expected to read in the course of playing the map. Something like "Level detector mechanism by Jason Harper" would be fine.
  2. Please do not use this mechanism for the purpose of making levels unplayable at low difficulty levels. Not everyone has the skill to play on Total Carnage. And not everyone has the desire to focus exclusively on the combat aspects of the game. I commonly play downloaded maps on Kindergarden: if they aren't interesting to me at that level, I'm not going to bother replaying them at a harder level.

I have supplied the individual components of the level in the Unmerged Pieces folder, for your ease in incorporating it. At the very least, you'll want to change the terminal messages, and set the player starting position much further from the mechanism. It is also intended for you to add to the map if desired, either before the mechanism, or after it in place of the existing terminals.

Send any questions or comments to:

Skully is on the level

Level Detector

Download Jason Harper's example map and tutorial.

Forge Tips | Harper's Tutorials | Stacked Walkways | Heartbeat | Combination Lock | Clock | Pedestal Problem | Zig Zag Stairs | Illusory Bridges | Fake Elevators | Texture Flexing | Untextured Walls | Stacked Windows | Multi-Message Terms | Counters | Level Detector

Top of page

Back to the Litterbox