Marathon Mapmaking: Snafus & Solutions
This is an advanced content creation guide for Marathon Aleph One, an open-source engine based on Bungie’s groundbreaking 1994-1996 first-person shooter trilogy (not its upcoming extraction shooter). It contains far more information than beginners will need (or even want) to know. If you’re just getting started, bookmark this page so you can return here when you’ve mastered the basics; then, consult my beginner’s guide for:
- links to editors
- detailed instructions on launching the texture editors Vasara, VAF, and Visual Mode.lua from the map editor Weland on Windows and MacOS
- links to the official Forge and Anvil documentation
- links to the official Forge tutorials
- links to other useful guides/resources
- explanations of how mapping in modern editors differs from mapping in the classic editors
- links to communities that may be able to solve problems my guides and the above resources don’t address
Meanwhile, this guide contains overviews of both common and uncommon problems creators may face (and solutions thereto). It’s meant to help troubleshoot several problems with Marathon content creation that, as far as I know, aren’t documented anywhere else well, if at all.
I’ve been reorganizing this guide into smaller, more digestible pages, though I’m mostly finished now – apologies for the inconvenience, but the ultimate form should be both more accessible and more logically organized.
Should you have any suggestions for improvements to this guide or notice any errors, please either contact me or submit to this page’s GitHub repository. (If you’d like to be credited, please let me know.)
Table of Contents
- Introduction
- Table of Contents (you’re looking at it?)
- General
- Mapmaking
- General Notes
- Aleph One Documentation Errata
- Scripts, Monster Limits, & Music
- Ambient Sound
- Marathon 1 Legacy Compatibility
- Those Weird Marathon 1 Polygon Types
- Marathon 1 Mission Types
- Marathon 1 Compatibility Flags
- 8-bit Software Mode
- The Images File
- Chapter Screens
- Directionality
- ShapeFusion
- General
- Restrictions on Number of Colors
- Transparency & Landscapes
- Sequence Timing & Film Compatibility
- ‘Weapons in Hand’ Sequences
- Appendices & Transplanted Content
- Acknowledgements
- Endnotes
Mapmaking
General Notes
- Test your maps extensively on Total Carnage. If you’re not good enough, get someone who is to test it. If you are good enough, note that you have a sort of ‘home field advantage’ in already knowing the maps and your intended strategies – other players will find your maps harder than you think they will. Also, if something annoys you, it’ll annoy other players ten times more.
- Monsters can’t move through lines shorter than their diameters, as Hastur’s Workshop explains. This link also features plenty of other vital information about monster path building.
- Aleph One lifts the vanilla 1,024-polygon limit (and many others), but as Aleph One developer treellama noted, the map index limit still constrains map complexity. (Note: The limit is now 65,535, not 32,767). The engine uses map indices to keep track of vertices, sides, polygons, sound objects, platforms, lines that are too small for the player to cross, and several other factors. The tl;dr:
- Use as few sound objects as possible (but see below).
- Avoid clusters of small polygons and/or short lines.
- If you can cut out a vertex, line, or polygon without negatively affecting the map’s appearance, collision detection, or monster path building (see the Hastur’s Workshop explanation above), always cut it out. I go into some detail on this on my appendix on reducing map indices, but take the map index counts on this page with a grain of salt for now; I’m not yet sure I understand their allocation perfectly.
- There are several hazards with the Activates Only Once flag for platforms (i.e., lifts and doors). Misusing this is one of the most common causes of incompletable levels.
- At the risk of being overly editorial: always, always, ALWAYS set Can’t Deactivate Externally for these. I can’t stress this strongly enough. If a door players need to pass through deactivates before they do so (or it traps them on the wrong side), that can render a level incompletable, and to compound the matter, they may save their games in such a state without having any idea they’ve done anything wrong – which can be as mundane as “shot switch with shotgun” or “accidentally hit Tab twice”. In a guide such as this, I’d rarely call something Objectively Bad Game Design. This is the exception.
- To make matters worse, Can’t Deactivate Externally is necessary but not sufficient to prevent soft locks – for starters, a platform set to activate only once must also not border any platforms that have either Activates: Deactivates Adjacent Platform or Deactivates: Deactivates Adjacent Platform selected, since those override Can’t Deactivate Externally.
- As an indication of how much you should know before you break this rule, I’ve encountered several otherwise professional-quality maps with Activates Only Once softlocks, including several levels of the original Tempus Irae that got their creator a job at Monolith Productions – so ‘professional-quality’ is in no sense hyperbole. Are your maps good enough to get you a game development job? That’s where they should probably be before you think about breaking this rule. (My maps haven’t gotten me a game dev job, just in case it sounds like I’m appealing to my own authority here.)
- The only possible acceptable exception to this rule is for missable secrets, but I’d strongly discourage even that. If you absolutely must have a missable secret (please don’t make your secrets missable), provide a way out for players caught on the wrong sides of doors (unless you mean to be Marathon 1-level sadistic – please, please don’t do this: secrets shouldn’t punish players who find them!), and make sure any teleporters are usable (i.e., test them in-game).
- Also, if such a door is Initially Extended, it should deactivate either At Each Level or Never. If it isn’t, it should deactivate either At Initial Level or Never.
- Meanwhile, lifts that activate Only Once should probably deactivate Never. Otherwise, a player might be able to activate it, get off the lift, and be unable to get back up; this can also cause problems in cooperative games (if those are enabled).
- Platforms that are Initially Extended and Deactivate at Each Level may be possible exceptions to this, but you should still test them extensively.
- Teleporters and automatic exits only function sporadically when submerged under liquids with nonzero currents. (“Submerged”, to be clear, means “liquid height exceeds polygon’s floor height by 1 IU (1/1024 WU) or greater”.) Unfortunately, requiring players to deactivate a liquid before they can teleport won’t work, since they may still be able to teleport while touching the wall, but this is a sufficiently unintuitive game behavior that I recommend giving any liquid you use on a teleporter or automatic exit polygon a current of 0.
- I really, really dislike tags and recommend avoiding them where possible. This page used to have an entire section going into detail on this, but I’ve moved it to its own page because, even by my standards, it’s both:
- very long
- very opinionated
I continue to stand by everything I wrote in it, but I’ve made it an appendix because I want the main part of this guide to be more objective in tone.
- Also in the “overly editorial for this page” category: my advice to anyone contemplating starting a new scenario in 2024.
- It isn’t necessary to move the player’s start point to texture maps in Weland; just select the arrow, hold down X, make sure caps lock is off, and click on a polygon to set a start point.
- If you have a slider selected, the + and - keys will increment and decrement its value, and the Page Up and Page Down keys will increment and decrement it more (by a factor of ten, to be exact). Note that you must have the slider selected, not its associated button.
- Hold down Ctrl (⌘ on Mac) and press = and - to zoom the map in and out without selecting the zoom tool.
- If the primary and secondary active or primary and secondary inactive periods of any light add up to 0, Aleph One freezes without explanation – the cause is an infinite loop with no escape hatch. (This is a bug; the game should instead print out an assertion failure and quit so that mapmakers have some idea what they did wrong, and hopefully it will in a future release.)
- Trying to create a new scenery object using Lua leads to a similar freeze if the scenery object’s sequence is set to “Display a random frame” with no defined frames (this is the equivalent of division by zero). This is probably also true for effects, ephemera, items, and monsters, and it may be true if the scenery object is created normally as well. (Again, this is a bug; the game should print an assertion failure explaining the problem, and hopefully it will in a future release.)
- On MacOS and Linux, Weland ignores its own folder’s “Plugins” subdirectory; instead, its plugins must go in:
/Users/username/.config/Weland/Plugins/
Replace username
with your actual username, of course. By way of example, my plugins must go in:
/Users/aaronfreed/.config/Weland/Plugins/
- If Weland plugins don’t load on Windows, you may need to unblock them by checking the box shown below:
I can’t stress the following strongly enough, so I’m printing it in large, bold, italicized, green capital letters:
Don’t make a habit of doing this with unknown software – only do it if you have reason to trust the source.
Unblocking untrustworthy software is a great way to get yourself subjected to spyware or worse.
Back to top · Table of contents · Beginners’ guide · Contact me · Website index
Aleph One Documentation Errata
Aleph One’s documentation is largely accurate, but it does have a few errors. In the Lua documentation:
-
Triggers
Platform
.cannot_be_externally_deactivated
when active, can only be deactivated by itself
This should read:
when active, can only be deactivated either by itself, or by an adjacent platform deactivating it
.type
the only thing the engine uses type for is the platform’s sound
This is incorrect; platform type also affects whether players can activate a switch or another door behind a non-player-controllable door of that type (it blocks activation if and only if it has an “uncontrollable” sound), and the type and amount of damage it deals when it crushes players or monsters. The latter error is particularly strange since the MML documentation details how to customize the damage a particular platform type deals.
- Polygon
.adjacent_polygons[n]
returns adjacent polygon n (across from line n), if one exists, or nil
Self-evidently, n
cannot be both a polygon and a line! This should read:
returns adjacent polygon across from polygon’s line n, if one exists; otherwise, returns nil
Note that n
does not correspond either to the line itself (i.e., .adjacent_polygons[Lines[42]]
will not work) or to the line index (i.e., .adjacent_polygons[42]
also will not work); it appears to be an internally selected value from 0 to l−1
, where l
is the number of lines the polygon contains.
Scripts, Monster Limits, & Music
<marathon_levels>
<level index="0">
<lua resource="420">
<mml resource="10000"/>
<music file="Eternal-Data/Music/Craig/SwirlsPiano.ogg"/>
</level>
</marathon_levels>
Or by including MML in each individual level’s folder (i.e., 00 The Far Side of Nowhere/Monster Limits.mml).
On the other hand, if you’re making a multiplayer level for an existing scenario (this includes cooperative play), it’s actually mandatory to use the latter method in most cases, since the game doesn’t send TEXT resources to other players. Thus, if you use it for something that affects the game world, which includes limit-removing MML and most Lua, players will desync almost immediately. If you don’t know if your script will affect the game world, it’s safest to just assume it will. MML texture replacements, fog, and Treellama’s ephemera-based precipitation script are some examples of things that don’t affect the game world.
On the third hand⁽¹⁾, if you’re making a standalone scenario, you can include an MML script that includes the scenario and version number, which prevents anyone who
isn’t running that scenario and version number from joining network games. In these cases, you can safely assume anyone who
does join your game already has the map, in which case they’ll also have the scripts already and won’t desync.
<marathon>
<scenario id="Eternal X" id="Eternal X" version="1.3pre6" />
</marathon>
(Moving the map file out of the scenario folder or overwriting it with a different version of the map would fall into what I’d consider ‘Play stupid games, win stupid prizes’ territory. You may wish to put a caveat about this in your game’s documentation, but I’d imagine this would be a relatively rare occurrence.)
OpenGL replacement graphics are a special case. They don’t affect the game world, but they also shouldn’t be merged in with the map. It’s ideal to make these into a plugin so that players can choose whether to use them or not – some players may dislike the extra loading time or prefer chunky 128×128 pixel² textures. (While replacement textures could theoretically be included in a map for another scenario, that would be quite odd – if you’re to the point that you have replacement textures for your map, I’d advise making that into a standalone scenario.)
The <marathon_levels>
code excerpt above also shows how to merge in music (i.e., the ‘music file’ line). It’s also possible to use Lua to implement music; doing so will in fact give you more options: you can control when to start the music (Apotheosis X contains some examples of this), or change the music midlevel based on game events (Eternal X 1.3 contains some examples of this). A full explanation of Lua music is beyond this guide’s current scope, although ‘write a guide to Lua’ is on my lengthy to-do list.
Monsters must be active to take passive damage from sources like lava. This is why you can soft-lock yourself by not killing enough enemies in “What About Bob?” before you flood the basement with lava – many of them will deactivate and not take damage, and because you’ve flooded the basement with lava, you have no way to go back and reactivate them without dying. If you’re going to duplicate a setup like the “What About Bob?” basement, make sure to raise the monster activation limits.
Back to top · Table of contents · Beginners’ guide · Contact me · Website index
Ambient Sound
- Platforms or doors with associated ambient sounds should have sound objects marked ‘Is On Platform’ so that their ‘moving’ sounds don’t suddenly cut off when players walk off the platform, which sounds unnatural. This doesn’t apply to platforms without ambient sounds (i.e., S’pht Door, S’pht Platform Silent).
- Liquids should have the correct associated sound objects near their edges. Failure to include these causes sudden cutoffs when players move from polygons with liquids to polygons without them (or vice versa). These should be marked ‘Floats’ so they align to their liquids’ heights; if they fall below the liquids, they’ll become almost inaudible, which defeats the purpose of placing them.
- If you place ambient sounds on polygons, boundaries between different ambient sounds (or between ambient sounds and silence) should have sound objects to avoid sudden cutoffs when players move between ‘sound boundaries’. This also results in directional sound, which enhances immersion.
- At the same time, avoid overusing sound objects, which eat up map indices worst of all factors that use them: one per polygon within a 10-world unit X/Y radius (Z is irrelevant). If this all sounds like a delicate juggling act, it is! No one said making maps for an ancient engine was easy. I recommend avoiding complicated ‘sound boundaries’ or too many discrete polygon sounds per level.
Back to top · Table of contents · Beginners’ guide · Contact me · Website index
Marathon 1 Legacy Compatibility
Those Weird Marathon 1 Polygon Types
- Minor Ouch behaves like M1 lava: it only damages monsters and players that are touching the ground.
- Major Ouch behaves like M1 Pfhor goo: it damages monsters and players even if they’re airborne.
- Both Ouch polygon types have additional behavior that only becomes active if Ouch Is Lava is checked in the Level Parameters box’s M1 Compatibility section (see below).
- If and only if Glue is checked in M1 Compatibility:
- Monsters on Glue act deaf (but not blind) until players walk onto their polygons (or they’re activated by other means). Sounds don’t enter Glue polygons but can leave them.
- A Glue Trigger activates all monsters that aren’t on or beyond Superglue or Zone Borders.
- Superglue is M1’s zone border equivalent; it stops Glue Trigger monster activation (as do Zone Borders).
- Otherwise, these three related polygon types behave like Normal polygons.
Back to top · Table of contents · Beginners’ guide · Contact me · Website index
Marathon 1 Mission Types
- Exploration (M1): Like regular Exploration, except that rather than requiring players to walk on all Must Be Explored polygons (as in M2/Infinity-style Exploration missions), it merely requires players to look at them.
- As mentioned above, looking at these in Visual Mode.lua or Vasara 1.0.3 resets them to ‘Normal’, so be careful. (VAF overrides this behavior at the cost of making it impossible to complete Exploration missions while VAF is active, but that’s not what it’s for, anyway; if all you want is to play the game without monsters, just use Nature’s Peace instead.)
- If recollection serves, Marathon 1’s vanilla 64° field of view (how did anyone cope?) is used to decide what players should be able to see. I’ll eventually perform a deep dive of the code to confirm this.
- If both this and Exploration are set, I suspect this may take precedence. I’ll confirm whether this is the case later, as well.
- Rescue (M1): Does what the Forge manual erroneously claims the Rescue mission flag does. Remember to set at least one other mission type if you want this to have any significant impact on gameplay.
- Repair (M1): Like Repair except that the player must only activate one repair switch to successfully complete the mission. This raises the obvious question, ‘Why would anyone program this into their game?’ The answer is that they probably wouldn’t do it on purpose – unless they were maintaining legacy compatibility with a rather buggy 1994 game by a relatively inexperienced Macintosh developer.
Back to top · Table of contents · Beginners’ guide · Contact me · Website index
Marathon 1 Compatibility Flags
All of these are found under Special → Level Parameters → M1 Compatibility.
- Glue: Superglue, Glue Trigger, and Glue (see above) only function if this is selected.
- Ouch Is Lava: Prevents monsters from leaving corpses on Minor Ouch or Major Ouch polygons if it’s checked. (Those polygons will still damage players and monsters even if it isn’t.)
- Use Song Index: Overrides the landscape collection selector with a number used to select a song index. I believe that, e.g., music index 0 must be stored at a path like Music/00.mp3, Music/00.ogg, Music/00.wav, or Music/00.aif, and to my knowledge, these are the only four audio formats that will work with this method of playing music. I strongly recommend using any other method instead.
- Terminals Stop Time: In the single-player game, game time will stop whenever the player is reading a terminal: oxygen won’t deplete, monsters won’t attack or move, the player won’t even fall. In multiplayer games, this has no effect (because cooperative games literally do not exist in vanilla Marathon 1, the game mode has no legacy compatibility requirements).
- Activation Range: Something to do with switch or monster activation, maybe? I can’t find the reference for it right now. Watch this space.
- Weapon Behavior: On Total Carnage, walking over a weapon that the player already has will cause the player to undergo M1’s fun equivalent of ‘picking up’ the weapon. In reality, this actually overwrites the player’s shot counter for that weapon with however many shots the new weapon would have had (which may or may not actually be greater than the player’s current shot count, thanks to the alien weapon having random shot counts). The player will not actually be able to use any of this backlog of weapons.
If this sounds extremely unfun (and against the purpose of a first-person shooter), you’re right! It’s a vanilla Marathon 1 bug. Please don’t use this flag for anything that isn’t a painstakingly accurate Marathon 1 remake (we’re talking a ‘didn’t even touch the “Colony Ship” puzzle’ level of accuracy).
Back to top · Table of contents · Beginners’ guide · Contact me · Website index
8-bit Software Mode
Aleph One 1.4 restored 8-bit software mode after it had been unavailable for over a decade. This causes potential havoc in territory related to both ShapeFusion (shapes sequences) and Atque (images files, map resources). I address the latter immediately below; see the ShapeFusion section further below for the former.
Chapter Screens & Sounds
Aleph One won’t display a chapter screen in 8-bit software mode unless it has an associated CLUT resource sharing the chapter screen’s resource ID. Make sure to include these if you care about 8-bit software mode at all. Chapter screens go from 1500 (for level 0) to 1599 (for the end screen or, God help us all, level 99). Add 10,000 for ‘24-bit’ versions and (I found this one out the hard way – by noticing it after a scenario release) 20,000 for ‘32-bit’ versions. (This effectively makes 115xx and 215xx unusable if you have a level xx – but I’m not sure if Aleph One will ever display the 115xx picture when the 215xx exists, so if you use 215xx for the chapter screen, you might be able to get away with using 115xx for a terminal picture.)
Also, if there’s an associated sound sharing the 15xx ID, Aleph One will play it. This includes ending screens (though Aleph One also plays the music file, so it’s probably not worth including a sound 1599 unless you plan for your scenario not to have opening music).
Back to top · Table of contents · Beginners’ guide · Contact me · Website index
The Images File
The Images file should have at least images 1100 and 1101 (‘enabled’ and ‘disabled’ versions of the main menu) and 1700 (the vanilla HUD). It also needs CLUT resources with the same IDs. If it lacks images 1100 and 1101 (and their accompanying CLUTs), the menu will show up black if a player selects 8-bit software, and if they then quit the game, they’ll either need to delete their scenario preferences or manually edit them to fix the graphics settings (on the very slim chance they even know how to do this) – which will effectively render the scenario unplayable for many players.
For full reference, the resources in Images correspond to the following:
- 1000: Opening splash screen. If 1001, 1002, 1003, etc., are defined, the game subsequently displays each before loading the main menu. (Please don’t overdo this.)
- 1100: ‘Disabled’ main menu.
- 1101: ‘Enabled’ main menu.
- 1400, 1401, 1402, etc.: Credits pages. The game loads as many consecutive resources as are defined.
- 1700: Default HUD.
Add 1,000 to each of these numbers for the ‘24-bit’ versions. It’s ideal to have separate 8-bit and 24-bit versions, as IIRC, Photoshop and GIMP dither images much better than Aleph One does.
Back to top · Table of contents · Beginners’ guide · Contact me · Website index
Directionality
Angles in Weland can vary in two, not three, but four different ways. Its representation of objects’ angles corresponds to the game’s representation of the player’s yaw (non-vertical angle)⁽²⁾.
Angle |
Yaw |
Objects |
Sounds |
Liquids |
Lines |
0° |
Faces east |
Faces east |
From west |
East to west |
West to east |
90° |
Faces south |
Faces south |
From north |
South to north |
South to north |
180° |
Faces west |
Faces west |
From east |
West to east |
East to west |
270° |
Faces north |
Faces north |
From south |
North to south |
North to south |
Back to top · Table of contents · Beginners’ guide · Contact me · Website index
ShapeFusion
General
- You can rename ShapeFusion resources by adding a file called DefaultNames.txt to your ShapeFusion folder. (You can also, of course, keep multiple ShapeFusion installs with different DefaultNames.txt files in each folder if you need versions for multiple scenarios.) I have a version of DefaultNames.txt that incorporates complete lists of the Lua mnemonics for all possible resources, with a few specific changes, all detailed at the start of the file. Feel free to use these as needed to create names for your own scenarios.
- ShapeFusion has most of Anvil’s functionality, plus some functionality Anvil lacks (e.g. the ability to add new sound slots or alter the frames in a sequence). However, it lacks two major features:
- Anvil’s help balloons. I have compiled these with asides that correct inaccuracies and provide updates where ShapeFusion differs from Anvil.
- It can’t create new physics models. The physics model that ships with Infinity is a Marathon 2 physics model and thus lacks SMG and VacBob slots, but Simplici7y has a complete Infinity physics model.
- An annoying bug displays the Scale Factors of new frames as being above 0, but actually sets them to 0. The game doesn’t display frames with 0 scale factors (well, technically it still does, but because it’s multiplying their sizes by 0, you won’t ever see them). Be sure to fix this.
- A probably related bug results in fields not updating correctly when they lose focus in the frame editor. I recommend always tabbing out of any field you’ve changed before switching to another frame – this will prevent the values you’ve entered from being written to the wrong frame.
- Yet another bug: If you overwrite a bitmap with another bitmap of a different size or proportion, you’ll need to edit the Origin X, Origin Y, and Scale Factor of any frame that points to this bitmap. You can set them to a different value and then set them back to whatever they were, but you will need to edit them in some fashion for the frames that use bitmap to display with the correct proportion.
- The copy command works with a monster definition on Windows if you have the monster name selected; you can then paste it if you have another monster name selected. This can be used to copy a monster definition to another slot or to copy a monster to another physics file. (The same principle applies for other parts of the physics file; e.g., to copy a weapon definition, select the weapon.) Alas, this doesn’t currently appear to work on Mac. I have no idea if it works on Linux – try it!
- ShapeFusion can read FLAC on Windows. Again, I don’t think the Mac version can do this, and I have no idea about Linux.
- The game handles X-mirroring differently for first-person weapon sprites than it handles it for all other game sprites: it will also mirror the X origin point. ShapeFusion does not currently have any functionality to take this directly into account, so you will need to flip your X origin points for “weapons in hand” sprites that have X-mirroring. One possible workaround: uncheck “X mirror”, set your X and Y origin points, and then re-check ”X mirror” when they look good. Another possibility: just don’t use X-mirrored weapon sprites at all (i.e., flip your fist bitmaps horizontally from the vanilla versions).
Back to top · Table of contents · Beginners’ guide · Contact me · Website index
Restrictions on Number of Colors
Palettes (also called CLUTs, short for Color Look-Up Tables, the name for these resources in MacOS’ resource fork in the classic OS) can pose particular problems. One particular issue occurs with non-standard CLUTs.
- We’re restricted to 256 colors not just within one palette but across all eight palettes within a collection. If there are more than 256, then once it runs out, Aleph One will simply use the closest color it encounters among the first 256.
- Aleph One counts colors that are imperceptibly different as separate colors. For instance, it regards #0100FF (red 1, green 0, blue 255) as different from #0200FF (red 2, green 0, blue 255).
- Unlike Anvil (which tried to restrict itself to vanilla-safe colors unless you specifically enabled a setting to override this), ShapeFusion isn’t guaranteed to use the same colors each time it creates a color ramp unless each ramp starts and ends with the same colors and contains the same number of colors.
It’s a mess. Two ways to ensure you’re getting the 256 colors you want:
- Export all color tables in a collection to GIMP format (.gpl) and go through them with a fine-toothed comb. GIMP palettes are human-readable and can be edited in any text editor; each color is simply listed in RGB format, with values ranging from 0 to 255 for all three colors. After weeding out the unwanted near-identical colors across palettes, save and reimport.
- Simply use all 256 colors you want in CLUT 0 and rearrange them as desired in the others if needed. Be warned, however, that ShapeFusion currently has no option to reduce the number of colors per CLUT, should you decide you want fewer. You’d currently need to open the shapes file in Anvil or Hakvil (using an emulator or a classic Mac) and adjust the palettes there.
Note that using more than 253 colors across all 8-bit palettes in a shapes file can look very, very stupid in 8-bit software mode, in case anyone even cares about that in 2024. I don’t actually know how 8-bit software mode selects colors, but sticking strictly to vanilla colors averts the issue. To that end, I’ve compiled the safe colors for Marathon 1 and Marathon 2/∞. (To be clear: use M1 colors for M1 shapes and M2/∞ colors for M2/∞ shapes.)
The other possibility is to pick a set of 253 colors and ensure that every “8-bit color version” sticks exclusively to those colors. This is more challenging, since you’ll have to edit every existing 8-bit palette in your shapes file, but it can result in a distinctive aesthetic.
Back to top · Table of contents · Beginners’ guide · Contact me · Website index
Transparency & Landscapes
Marathon counts the first three colors of each CLUT as transparent, whether you want it to or not. Why does it need three? Why not just one? In all likelihood, only Jason Jones might be able to answer this question, assuming he even remembers the answer. This poses problems with custom landscape CLUTs. Why do landscapes even have transparency? Another question Jason Jones probably doesn’t recall the answer to. The first three colors in a landscape CLUT are still considered transparent, and in OpenGL mode, Marathon changes anything it regards as transparent to show up as white.
As a result, for all practical purposes, landscape CLUTs are restricted to 253 colors, so when generating landscape CLUTs, you must account for transparency and fill the CLUT’s first three colors with garbage that won’t show up in the landscape. Alternately (in Photoshop), you can:
- Convert to 253-color indexed color.
- Convert back to RGB.
- Using Forced > Custom with #0000FF, #FF00FF, and #00FFFF, convert to 256-color indexed color.
- Export the new CLUT.
Either way. (I don’t use GIMP, but I’m guessing you can do something similar by making a 253-color bitmap, exporting the CLUT, and editing it in a text editor.)
Back to top · Table of contents · Beginners’ guide · Contact me · Website index
Sequence Timing & Film Compatibility
- Ideally, ‘Transfer mode period’ should equal ‘Frames per view’ times ‘Number of frames’.
- Probably obvious: Changing a sequence’s timing, loop frame, or key frame can and almost certainly will desync films and network games.
- Probably not obvious: Changing either the number of frames or the duration thereof is also likely to desync films and network games, even if the ‘transfer mode period’ remains unchanged! There are several off-by-one errors in this game’s source code, and it’d require a deep dive into the game source code to describe all the arcane rules one would have to obey to avoid causing issues.
- Also not obvious: Sequences with more than fifteen frames tend to have all sorts of errors, and I strongly recommend against using them. Weirdly, texture animations specified with MML are an exception here; they can have as many frames as you want.
- Another surprising factor affecting film sync: ‘Display a random frame’ (even if only one frame is defined) is different from ‘Animation with 1 view’ (or any other number). Altering this alters the PRNG when the game loads maps, since it runs the PRNG for each sequence that uses ‘Display a random frame’, even if it only has one frame. Thus, changing a sequence from or to ‘Display a random frame’ desyncs old films made with the same shapes. (I haven’t tested whether this also desyncs network games.)
Back to top · Table of contents · Beginners’ guide · Contact me · Website index
‘Weapons in Hand’ Sequences
For years, Aleph One didn’t have 8-bit software mode, so ‘8-bit color’ and ‘true color’ sequences being out of alignment wasn’t a problem. Aleph One 1.4 restored it, so it’s worth taking note if a sequence is present in one and not the other. A physics model calling said sequence in 8-bit software mode will crash Aleph One (or cause an assertion failure; I forget which, but either way, it closes the game). Plus, if a sequence has a different timing between the two versions of a collection, it’ll desync films and may desync network games if one player uses 8-bit software mode and the other doesn’t.
As tempting as it is to tell players not to use 8-bit software mode, some will inevitably disregard it out of ignorance, and others out of pure spite (insert out-of-context ‘Killing in the Name’ quote here). The best solution is to make sure each sequence in both versions has the same sequence type, frames per view, ticks per frame, loop frame, key frame, transfer mode period, and frame sound, then update one anytime you update the other.
By default, the only other collections with ‘true color’ versions are the landscape palettes, and it’s very rare (though not unthinkable) for something to call one of the sequences in these (assuming any are even defined). I think a classic Mac utility could create ‘true color’ versions of other collections (all 32 collections can have them; it’s just that, by default, only the Weapons in Hand and Landscapes did), and if a shapes file had these, their sequences should align between ‘8-bit’ and ‘true color’ wherever they’re defined.
Back to top · Table of contents · Beginners’ guide · Contact me · Website index
Appendices & Transplanted Content
I’ve split several sections off onto their own pages. Please update your links accordingly:
- Circles and the Custom Grid, including its subsection Radii and Rotations for 1 WU-long Sides with Regular Polygons.
- Map Complexity: A Case Study
- The Sounds section, including Vanilla Infinity Sound ID List and Sound Sources.
- The Annotated Anvil Help Balloons. The following corollaries were very likely inevitable:
- The Annotated Forge Manual, which remains a work in progress, currently consists of:
- The Annotated Anvil Manual will, naturally, follow that.
- I’d like to remake the Forge tutorial videos for Weland. I don’t know when I’ll find time, but I’d like to.
- Example DefaultNames.txt (see reference above).
- Tags Are Terrible (though sometimes inexorable) and its subsection Ways to Avoid Tags have been moved to their own page because they are very long and opinionated even by my standards. I continue to stand by everything I wrote in them, but I felt the main body of this guide should be more objective in tone.
- I’ve also written up advice on making a new scenario as another new editorial appendix to this page.
- Looping Music (Aleph One 1.7 renders this mostly superfluous).
- Another new appendix, Where Are Monsters in Marathon…Maps, examines what monsters appear in what Marathon trilogy levels to demonstrate an important game design paradox: sometimes decreasing variety within a small span of a game can increase variety across a much larger span of it (or all of it).
- Two further new appendices collect the Marathon trilogy’s 8-bit palettes:
Additionally, to avoid duplicating content, I’ve moved several sections to the beginners’ mapmaking page. Here are direct links to the relevant sections – again, please update your links.
Lastly, I’ve moved my biography and contact info to a dedicated page: aaronfreed.github.io/aboutme.html.
Back to top · Table of contents · Beginners’ guide · Contact me · Website index
Acknowledgements
- Paul S. on Stack Overflow for his table sort script, and Fla for a revision that enabled it to sort numeric values. (My knowledge of JavaScript is effectively nonexistent.)
- Jason Karns and Davide Cannizzo on Stack Overflow for the CSS table of contents, which is beyond my relatively competent level of CSS ability.
- Solra Bizna for an incomprehensible amount of programming help, including the CSS that makes this exact page follow your computer’s dark mode settings.
- W’rkncacnter for pointing out a sound source that eluded me (namely the fighter death) and providing a better solution than I was using for ShapeFusion’s bug with pasting in a bitmap of a different size.
- The numerous mapmakers I’ve learned from or been influenced by over the years. I couldn’t possibly hope to list them all, but James Hastings-Trew, CryoS, hypersleep, RyokoTK, windbreaker, Don-Martin Antell, Drictelt, Mike Trinder, Jason Harper, Chris Lund, Courtney Evans, Frank Rooke, Devon Belcher, Borzz, Rich Dierkes, Shebob, Jason Jones, Greg Kirkpatrick, Randy Reddig, Antonio de Llamas, and FM have to number among them.
- The numerous people who have helped write and maintain Aleph One and its editors over the years.
- Bungie, for obvious reasons.
Back to top · Table of contents · Beginners’ guide · Contact me · Website index
Endnotes
# |
Note |
1 |
What, you don’t have a third hand? I guess your name isn’t “Zaphod Beeblebrox”. |
2 |
The game actually represents the player’s yaw internally as a 9-bit value, ranging from 0 to 511; an increase of 1 in its internal representation corresponds to an increase of 0.703125°, i.e., 360/512. If you press F10, it shows the angle as a value ranging from –179.296875° to 180°, but this is because it subtracts 360° from angles greater than 180° – printing the value in the Lua console returns values from 0° to 359.296875°. |
Back to top · Table of contents · Beginners’ guide · Contact me · Website index